From 21808909419924be31791ab5f249ec14b69c512c Mon Sep 17 00:00:00 2001 From: daief <1437931235@qq.com> Date: Mon, 21 Mar 2022 20:19:37 +0800 Subject: [PATCH] feat: add toggle --- docs/src/pages/components/swap.md | 14 +++--- docs/src/pages/components/toggle.md | 50 ++++++++++++++++++++ docs/src/pages/demo.md | 4 +- src/@types/dom.ts | 5 ++ src/components/index.tsx | 1 + src/components/swap/index.tsx | 7 ++- src/components/toggle/index.tsx | 71 ++++++++++++++++++++++++++++ src/components/toggle/style/index.ts | 5 ++ 8 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 docs/src/pages/components/toggle.md create mode 100644 src/@types/dom.ts create mode 100644 src/components/toggle/index.tsx create mode 100644 src/components/toggle/style/index.ts diff --git a/docs/src/pages/components/swap.md b/docs/src/pages/components/swap.md index ff4148a..7568d54 100644 --- a/docs/src/pages/components/swap.md +++ b/docs/src/pages/components/swap.md @@ -84,12 +84,14 @@ export default { ### Attributes -| name | description | type | default | -| --------- | ---------------- | ------------ | ------- | -| on | render on | - | - | -| off | render off | - | - | -| tag | wrap elemnt tag | string | label | -| animation | animation effect | rotate, flip | - | +| name | description | type | default | +| --------- | ------------------------------- | ------------ | ------- | +| on | render on | - | - | +| off | render off | - | - | +| tag | wrap elemnt tag | string | label | +| animation | animation effect | rotate, flip | - | +| active | swap active status | boolean | - | +| onChange | swap active status change event | Function | - | ### Solts diff --git a/docs/src/pages/components/toggle.md b/docs/src/pages/components/toggle.md new file mode 100644 index 0000000..2500105 --- /dev/null +++ b/docs/src/pages/components/toggle.md @@ -0,0 +1,50 @@ +# Toggle + +## Examples + +Toggle + +```html :::demo +
+ +
+``` + +Toggle color + +```html :::demo +
+ +
+ +
+ +
+ +
+``` + +Toggle size + +```html :::demo +
+ +
+ +
+ +
+ +
+``` + +## Toggle + +### Attributes + +| name | description | type | default | +| -------- | ---------------------------------- | ----------------------------------- | ------- | +| checked | toggle checked status | boolean | - | +| onChange | toggle checked status change event | Function | - | +| type | toogle color type | netural, primary, secondary, accent | netural | +| size | toogle size | xs, sm, md, lg | - | diff --git a/docs/src/pages/demo.md b/docs/src/pages/demo.md index e167c77..737b5d1 100644 --- a/docs/src/pages/demo.md +++ b/docs/src/pages/demo.md @@ -1,5 +1,7 @@ # Demo for development ```html :::demo -
+
+ +
``` diff --git a/src/@types/dom.ts b/src/@types/dom.ts new file mode 100644 index 0000000..7cf646f --- /dev/null +++ b/src/@types/dom.ts @@ -0,0 +1,5 @@ +import { InputHTMLAttributes } from 'vue'; + +export type InputChangeEvent = Omit & { + target: HTMLInputElement; +}; diff --git a/src/components/index.tsx b/src/components/index.tsx index 738052f..9432973 100644 --- a/src/components/index.tsx +++ b/src/components/index.tsx @@ -17,4 +17,5 @@ export * from './progress'; export * from './swap'; export * from './tab'; export * from './table'; +export * from './toggle'; export * from './tooltip'; diff --git a/src/components/swap/index.tsx b/src/components/swap/index.tsx index 3e75fd3..1d9e65b 100644 --- a/src/components/swap/index.tsx +++ b/src/components/swap/index.tsx @@ -23,6 +23,10 @@ const props = { type: String as PropType<'rotate' | 'flip'>, default: '', }, + onChange: { + type: Function as PropType<(e: boolean) => void>, + default: void 0, + }, }; export type ISwapProps = ExtractFromProps; @@ -57,7 +61,8 @@ export const Swap = componentV2( { class: cls.value, onClick: () => { - state.active = !state.active; + state.active = !finalActive.value; + props.onChange?.(state.active); }, }, [
{on}
,
{off}
], diff --git a/src/components/toggle/index.tsx b/src/components/toggle/index.tsx new file mode 100644 index 0000000..b900839 --- /dev/null +++ b/src/components/toggle/index.tsx @@ -0,0 +1,71 @@ +import { InputChangeEvent } from '@/@types/dom'; +import { componentV2 } from '@/shared/styled'; +import { ExtractFromProps, IBrandColor, ISize } from '@/shared/types/common'; +import { isUndefined } from '@/shared/utils'; +import { computed, nextTick, PropType, reactive } from 'vue'; +import styles from './style'; + +export const toggleProps = { + checked: { + type: Boolean, + default: void 0, + }, + onChange: { + type: Function as PropType<(e: InputChangeEvent) => void>, + default: void 0, + }, + type: { + type: String as PropType, + default: 'netural', + }, + size: { + type: String as PropType, + default: 'md', + }, +}; + +export type IToggleProps = ExtractFromProps; + +export const Toggle = componentV2( + { + name: 'Toggle', + props: toggleProps, + setup: (props) => { + const state = reactive({ + checked: props.checked, + }); + + const finalVal = computed(() => + isUndefined(props.checked) ? state.checked : props.checked, + ); + + const cls = computed(() => [ + 'dv-toggle toggle', + { + [`toggle-${props.type}`]: props.type, + [`toggle-${props.size}`]: props.size, + }, + ]); + + return () => { + return ( + { + const newVal = !finalVal.value; + state.checked = newVal; + props.onChange?.(e); + nextTick(() => { + // force sync with finalVal + e.target.checked = finalVal.value; + }); + }} + /> + ); + }; + }, + }, + styles, +); diff --git a/src/components/toggle/style/index.ts b/src/components/toggle/style/index.ts new file mode 100644 index 0000000..6411965 --- /dev/null +++ b/src/components/toggle/style/index.ts @@ -0,0 +1,5 @@ +import s1 from '@styles/components/unstyled/toggle.css'; +import s2 from '@styles/components/styled/toggle.css'; +import s3 from '@styles/utilities/unstyled/toggle.css'; + +export default [s1, s2, s3];