Browse Source

feat: improve `tippy` demo (#5357)

pull/5359/head
Netfan 2 years ago
committed by GitHub
parent
commit
cb9c8db5ba
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 27
      packages/effects/common-ui/src/components/tippy/index.ts
  2. 2
      playground/src/router/routes/modules/examples.ts
  3. 229
      playground/src/views/examples/tippy/index.vue

27
packages/effects/common-ui/src/components/tippy/index.ts

@ -10,25 +10,26 @@ import { usePreferences } from '@vben-core/preferences';
import useTippyDirective from './directive'; import useTippyDirective from './directive';
import 'tippy.js/dist/tippy.css'; import 'tippy.js/dist/tippy.css';
import 'tippy.js/dist/backdrop.css';
import 'tippy.js/themes/light.css'; import 'tippy.js/themes/light.css';
import 'tippy.js/animations/scale.css'; import 'tippy.js/animations/scale.css';
import 'tippy.js/animations/scale-subtle.css'; import 'tippy.js/animations/shift-toward.css';
import 'tippy.js/animations/scale-extreme.css';
import 'tippy.js/animations/shift-away.css'; import 'tippy.js/animations/shift-away.css';
import 'tippy.js/animations/perspective.css'; import 'tippy.js/animations/perspective.css';
const { isDark } = usePreferences(); const { isDark } = usePreferences();
export type TippyProps = Props & { export type TippyProps = Partial<
animation?: Props & {
| 'fade' animation?:
| 'perspective' | 'fade'
| 'scale' | 'perspective'
| 'scale-extreme' | 'scale'
| 'scale-subtle' | 'shift-away'
| 'shift-away' | 'shift-toward'
| boolean; | boolean;
theme?: 'auto' | 'dark' | 'light'; theme?: 'auto' | 'dark' | 'light';
}; }
>;
export function initTippy(app: App<Element>, options?: DefaultProps) { export function initTippy(app: App<Element>, options?: DefaultProps) {
setDefaultProps({ setDefaultProps({

2
playground/src/router/routes/modules/examples.ts

@ -253,7 +253,7 @@ const routes: RouteRecordRaw[] = [
path: '/examples/tippy', path: '/examples/tippy',
component: () => import('#/views/examples/tippy/index.vue'), component: () => import('#/views/examples/tippy/index.vue'),
meta: { meta: {
icon: 'material-symbols:chat-bubble', icon: 'mdi:message-settings-outline',
title: 'Tippy', title: 'Tippy',
}, },
}, },

229
playground/src/views/examples/tippy/index.vue

@ -1,5 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, reactive } from 'vue'; import type { TippyProps } from '@vben/common-ui';
import { reactive } from 'vue';
import { Page, Tippy } from '@vben/common-ui'; import { Page, Tippy } from '@vben/common-ui';
@ -7,84 +9,175 @@ import { Button, Card, Flex } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form'; import { useVbenForm } from '#/adapter/form';
const props = reactive({ const tippyProps = reactive<TippyProps>({
animation: 'shift-away', animation: 'shift-away',
arrow: true, arrow: true,
content: '这是一个提示', content: '这是一个提示',
delay: 200, delay: [200, 200],
duration: 200, duration: 200,
followCursor: '', followCursor: false,
hideOnClick: '', hideOnClick: false,
inertia: true,
maxWidth: 'none', maxWidth: 'none',
placement: 'top', placement: 'top',
theme: 'dark', theme: 'dark',
trigger: 'mouseenter focusin',
}); });
const tippyProps = computed(() => { function parseBoolean(value: string) {
return { switch (value) {
...props, case 'false': {
followCursor: ['', 'true'].includes(props.followCursor) return false;
? !!props.followCursor }
: props.followCursor, case 'true': {
hideOnClick: ['', 'true'].includes(props.hideOnClick) return true;
? !!props.hideOnClick }
: props.hideOnClick, default: {
}; return value;
}); }
}
}
const [Form] = useVbenForm({ const [Form] = useVbenForm({
handleValuesChange(values) { handleValuesChange(values) {
Object.assign(props, { ...values }); Object.assign(tippyProps, {
...values,
delay: [values.delay1, values.delay2],
followCursor: parseBoolean(values.followCursor),
hideOnClick: parseBoolean(values.hideOnClick),
trigger: values.trigger.join(' '),
});
}, },
schema: [ schema: [
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
class: 'w-full',
options: [
{ label: '自动', value: 'auto' },
{ label: '暗色', value: 'dark' },
{ label: '亮色', value: 'light' },
],
optionType: 'button',
},
defaultValue: tippyProps.theme,
fieldName: 'theme',
label: '主题',
},
{ {
component: 'Select', component: 'Select',
componentProps: { componentProps: {
class: 'w-full', class: 'w-full',
options: [ options: [
{ label: 'shift-away', value: 'shift-away' }, { label: '向上滑入', value: 'shift-away' },
{ label: 'scale', value: 'scale' }, { label: '向下滑入', value: 'shift-toward' },
{ label: 'scale-extreme', value: 'scale-extreme' }, { label: '缩放', value: 'scale' },
{ label: 'scale-subtle', value: 'scale-subtle' }, { label: '透视', value: 'perspective' },
{ label: 'perspective', value: 'perspective' }, { label: '淡入', value: 'fade' },
{ label: 'fade', value: 'fade' },
], ],
}, },
defaultValue: props.animation, defaultValue: tippyProps.animation,
fieldName: 'animation', fieldName: 'animation',
label: '动画', label: '动画类型',
},
{
component: 'RadioGroup',
componentProps: {
buttonStyle: 'solid',
options: [
{ label: '是', value: true },
{ label: '否', value: false },
],
optionType: 'button',
},
defaultValue: tippyProps.inertia,
fieldName: 'inertia',
label: '动画惯性',
},
{
component: 'Select',
componentProps: {
class: 'w-full',
options: [
{ label: '顶部', value: 'top' },
{ label: '顶左', value: 'top-start' },
{ label: '顶右', value: 'top-end' },
{ label: '底部', value: 'bottom' },
{ label: '底左', value: 'bottom-start' },
{ label: '底右', value: 'bottom-end' },
{ label: '左侧', value: 'left' },
{ label: '左上', value: 'left-start' },
{ label: '左下', value: 'left-end' },
{ label: '右侧', value: 'right' },
{ label: '右上', value: 'right-start' },
{ label: '右下', value: 'right-end' },
],
},
defaultValue: tippyProps.placement,
fieldName: 'placement',
label: '位置',
}, },
{ {
component: 'InputNumber', component: 'InputNumber',
defaultValue: props.duration, componentProps: {
addonAfter: '毫秒',
},
defaultValue: tippyProps.duration,
fieldName: 'duration', fieldName: 'duration',
label: '动画时长', label: '动画时长',
}, },
{
component: 'InputNumber',
componentProps: {
addonAfter: '毫秒',
},
defaultValue: 100,
fieldName: 'delay1',
label: '显示延时',
},
{
component: 'InputNumber',
componentProps: {
addonAfter: '毫秒',
},
defaultValue: 100,
fieldName: 'delay2',
label: '隐藏延时',
},
{ {
component: 'Input', component: 'Input',
defaultValue: props.content, defaultValue: tippyProps.content,
fieldName: 'content', fieldName: 'content',
label: '内容', label: '内容',
}, },
{ {
component: 'Switch', component: 'RadioGroup',
defaultValue: props.arrow, componentProps: {
buttonStyle: 'solid',
options: [
{ label: '是', value: true },
{ label: '否', value: false },
],
optionType: 'button',
},
defaultValue: tippyProps.arrow,
fieldName: 'arrow', fieldName: 'arrow',
label: '箭头', label: '指示箭头',
}, },
{ {
component: 'Select', component: 'Select',
componentProps: { componentProps: {
class: 'w-full', class: 'w-full',
options: [ options: [
{ label: '不跟随', value: '' }, { label: '不跟随', value: 'false' },
{ label: '完全跟随', value: 'true' }, { label: '完全跟随', value: 'true' },
{ label: '仅横向', value: 'horizontal' }, { label: '仅横向', value: 'horizontal' },
{ label: '仅纵向', value: 'vertical' }, { label: '仅纵向', value: 'vertical' },
{ label: '仅初始', value: 'initial' }, { label: '仅初始', value: 'initial' },
], ],
}, },
defaultValue: props.followCursor, defaultValue: tippyProps.followCursor?.toString(),
fieldName: 'followCursor', fieldName: 'followCursor',
label: '跟随指针', label: '跟随指针',
}, },
@ -92,69 +185,53 @@ const [Form] = useVbenForm({
component: 'Select', component: 'Select',
componentProps: { componentProps: {
class: 'w-full', class: 'w-full',
mode: 'multiple',
options: [ options: [
{ label: '否', value: '' }, { label: '鼠标移入', value: 'mouseenter' },
{ label: '是', value: 'true' }, { label: '被点击', value: 'click' },
{ label: '仅内部点击', value: 'toggle' }, { label: '获得焦点', value: 'focusin' },
{ label: '无触发,仅手动', value: 'manual' },
], ],
}, },
defaultValue: props.hideOnClick, defaultValue: tippyProps.trigger?.split(' '),
fieldName: 'hideOnClick', fieldName: 'trigger',
label: '点击后隐藏', label: '触发方式',
},
{
component: 'InputNumber',
defaultValue: 100,
fieldName: 'delay',
label: '延时',
}, },
{ {
component: 'RadioGroup', component: 'Select',
componentProps: { componentProps: {
class: 'w-full',
options: [ options: [
{ label: 'auto', value: 'auto' }, { label: '', value: 'false' },
{ label: 'dark', value: 'dark' }, { label: '', value: 'true' },
{ label: 'light', value: 'light' }, { label: '仅内部', value: 'toggle' },
], ],
}, },
defaultValue: props.theme, defaultValue: tippyProps.hideOnClick?.toString(),
fieldName: 'theme', dependencies: {
label: '主题', componentProps(_, formAction) {
return {
disabled: !formAction.values.trigger.includes('click'),
};
},
triggerFields: ['trigger'],
},
fieldName: 'hideOnClick',
help: '只有在触发方式为`click`时才有效',
label: '点击后隐藏',
}, },
{ {
component: 'Input', component: 'Input',
componentProps: { componentProps: {
allowClear: true,
placeholder: 'none、200px', placeholder: 'none、200px',
}, },
defaultValue: props.maxWidth, defaultValue: tippyProps.maxWidth,
fieldName: 'maxWidth', fieldName: 'maxWidth',
label: '最大宽度', label: '最大宽度',
}, },
{
component: 'Select',
componentProps: {
class: 'w-full',
options: [
{ label: '顶部', value: 'top' },
{ label: '顶左', value: 'top-start' },
{ label: '顶右', value: 'top-end' },
{ label: '底部', value: 'bottom' },
{ label: '底左', value: 'bottom-start' },
{ label: '底右', value: 'bottom-end' },
{ label: '左侧', value: 'left' },
{ label: '左上', value: 'left-start' },
{ label: '左下', value: 'left-end' },
{ label: '右侧', value: 'right' },
{ label: '右上', value: 'right-start' },
{ label: '右下', value: 'right-end' },
],
},
defaultValue: 'top',
fieldName: 'placement',
label: '位置',
},
], ],
showDefaultActions: false,
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3', wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
}); });

Loading…
Cancel
Save