Skip to content

Commit

Permalink
feat: added switch three sizes (#286)
Browse files Browse the repository at this point in the history
  • Loading branch information
vtrbo committed Oct 7, 2023
1 parent 7c9bcd4 commit 477f56b
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 46 deletions.
20 changes: 13 additions & 7 deletions components/Switch/__test__/__snapshots__/switch.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Test: KSwitch > props: attrs 1`] = `"<div class=\\"k-switch--base k-switch__un_checked\\" aria-hidden=\\"true\\" you=\\"world\\"><div class=\\"k-switch-tx__un_checked\\"></div> <div class=\\"k-switch-circle\\"></div> </div>"`;
exports[`Test: KSwitch > props: attrs 1`] = `"<div class=\\"k-switch k-switch--base k-switch--md k-switch__unchecked\\" aria-hidden=\\"true\\" you=\\"world\\"><span class=\\"k-switch-tx__unchecked k-switch-tx__unchecked--md\\"></span> <span class=\\"k-switch-circle k-switch-circle--md\\"></span> </div>"`;
exports[`Test: KSwitch > props: cls 1`] = `"<div class=\\"k-switch--base k-switch__un_checked 关关雎鸠,在河之洲\\" aria-hidden=\\"true\\"><div class=\\"k-switch-tx__un_checked\\"></div> <div class=\\"k-switch-circle\\"></div> </div>"`;
exports[`Test: KSwitch > props: cls 1`] = `"<div class=\\"k-switch k-switch--base k-switch--md k-switch__unchecked 关关雎鸠,在河之洲\\" aria-hidden=\\"true\\"><span class=\\"k-switch-tx__unchecked k-switch-tx__unchecked--md\\"></span> <span class=\\"k-switch-circle k-switch-circle--md\\"></span> </div>"`;
exports[`Test: KSwitch > props: disabled 1`] = `"<div class=\\"k-switch--base k-switch__un_checked\\" aria-hidden=\\"true\\"><div class=\\"k-switch-tx__un_checked\\"></div> <div class=\\"k-switch-circle\\"></div> </div>"`;
exports[`Test: KSwitch > props: disabled 1`] = `"<div class=\\"k-switch k-switch--base k-switch--md k-switch__unchecked\\" aria-hidden=\\"true\\"><span class=\\"k-switch-tx__unchecked k-switch-tx__unchecked--md\\"></span> <span class=\\"k-switch-circle k-switch-circle--md\\"></span> </div>"`;
exports[`Test: KSwitch > props: loading 1`] = `"<div class=\\"k-switch--base k-switch__un_checked\\" aria-hidden=\\"true\\"><div class=\\"k-switch-tx__un_checked\\"></div> <div class=\\"k-switch-circle\\"></div> </div>"`;
exports[`Test: KSwitch > props: loading 1`] = `"<div class=\\"k-switch k-switch--base k-switch--md k-switch__unchecked\\" aria-hidden=\\"true\\"><span class=\\"k-switch-tx__unchecked k-switch-tx__unchecked--md\\"></span> <span class=\\"k-switch-circle k-switch-circle--md\\"></span> </div>"`;
exports[`Test: KSwitch > props: unCheckedColor and checkedColor 1`] = `"<div class=\\"k-switch--base k-switch__checked #1314\\" aria-hidden=\\"true\\"> <div class=\\"k-switch-circle\\"></div> <div class=\\"k-switch-tx__checked\\"></div></div>"`;
exports[`Test: KSwitch > props: size 1`] = `"<div class=\\"k-switch k-switch--base k-switch--sm k-switch__unchecked\\" aria-hidden=\\"true\\"><span class=\\"k-switch-tx__unchecked k-switch-tx__unchecked--sm\\"></span> <span class=\\"k-switch-circle k-switch-circle--sm\\"></span> </div>"`;
exports[`Test: KSwitch > props: unCheckedValue and checkedValue 1`] = `"<div class=\\"k-switch--base k-switch__checked k-switch-tra\\" aria-hidden=\\"true\\"> <div class=\\"k-switch-circle\\" style=\\"right: 1px;\\"></div> <div class=\\"k-switch-tx__checked\\"></div></div>"`;
exports[`Test: KSwitch > props: size 2`] = `"<div class=\\"k-switch k-switch--base k-switch--md k-switch__unchecked\\" aria-hidden=\\"true\\"><span class=\\"k-switch-tx__unchecked k-switch-tx__unchecked--md\\"></span> <span class=\\"k-switch-circle k-switch-circle--md\\"></span> </div>"`;
exports[`Test: KSwitch > props: value 1`] = `"<div class=\\"k-switch--base k-switch__un_checked\\" aria-hidden=\\"true\\"><div class=\\"k-switch-tx__un_checked\\"></div> <div class=\\"k-switch-circle\\"></div> </div>"`;
exports[`Test: KSwitch > props: size 3`] = `"<div class=\\"k-switch k-switch--base k-switch--lg k-switch__unchecked\\" aria-hidden=\\"true\\"><span class=\\"k-switch-tx__unchecked k-switch-tx__unchecked--lg\\"></span> <span class=\\"k-switch-circle k-switch-circle--lg\\"></span> </div>"`;
exports[`Test: KSwitch > props: unCheckedColor and checkedColor 1`] = `"<div class=\\"k-switch k-switch--base k-switch--md k-switch__checked #1314\\" aria-hidden=\\"true\\"> <span class=\\"k-switch-circle k-switch-circle--md\\"></span> <span class=\\"k-switch-tx__checked k-switch-tx__checked--md\\"></span></div>"`;
exports[`Test: KSwitch > props: unCheckedValue and checkedValue 1`] = `"<div class=\\"k-switch k-switch--base k-switch--md k-switch__checked k-switch-tra\\" aria-hidden=\\"true\\"> <span class=\\"k-switch-circle k-switch-circle--md\\" style=\\"right: 1px;\\"></span> <span class=\\"k-switch-tx__checked k-switch-tx__checked--md\\"></span></div>"`;
exports[`Test: KSwitch > props: value 1`] = `"<div class=\\"k-switch k-switch--base k-switch--md k-switch__unchecked\\" aria-hidden=\\"true\\"><span class=\\"k-switch-tx__unchecked k-switch-tx__unchecked--md\\"></span> <span class=\\"k-switch-circle k-switch-circle--md\\"></span> </div>"`;
30 changes: 28 additions & 2 deletions components/Switch/__test__/switch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('Test: KSwitch', () => {
value: false
});
await tick();
expect(host.innerHTML.includes('k-switch__un_checked')).toBe(true);
expect(host.innerHTML.includes('k-switch__unchecked')).toBe(true);
expect(host.innerHTML).matchSnapshot();
});

Expand All @@ -57,7 +57,7 @@ describe('Test: KSwitch', () => {
checkedValue: '微笑'
});
});
const switchElm = host.getElementsByTagName('div')[0];
const switchElm = host.getElementsByTagName('span')[0];
switchElm.click();
await tick();
expect(value).toBe('哭泣');
Expand Down Expand Up @@ -123,6 +123,32 @@ describe('Test: KSwitch', () => {
expect(host.innerHTML).matchSnapshot();
});

test('props: size', async () => {
const instance = new KSwitch({
target: host,
props: {
size: 'sm'
}
});
await tick();
expect(instance).toBeTruthy();
expect(host.innerHTML.includes('k-switch--sm')).toBeTruthy();
expect(host.innerHTML.includes('k-switch-circle--sm')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();

instance.$set({ size: 'md' });
await tick();
expect(host.innerHTML.includes('k-switch--md')).toBeTruthy();
expect(host.innerHTML.includes('k-switch-circle--md')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();

instance.$set({ size: 'lg' });
await tick();
expect(host.innerHTML.includes('k-switch--lg')).toBeTruthy();
expect(host.innerHTML.includes('k-switch-circle--lg')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();
});

test('props: cls', async () => {
const instance = new KSwitch({
target: host,
Expand Down
65 changes: 38 additions & 27 deletions components/Switch/src/index.svelte
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
<script lang="ts">
import { KIcon } from '@ikun-ui/icon';
import type { KSwitchProps } from './types';
import { createEventDispatcher, onMount } from 'svelte';
import type { SwitchValueType } from './types';
import { clsx, type ClassValue } from 'clsx';
import { KIcon } from '@ikun-ui/icon';
import { clsx } from 'clsx';
import { getPrefixCls } from '@ikun-ui/utils';
export let value: SwitchValueType = false;
export let disabled: boolean = false;
export let cls: ClassValue = undefined;
export let attrs: Record<string, string> = {};
export let loading: boolean = false;
export let checkedValue: SwitchValueType = true;
export let unCheckedValue: SwitchValueType = false;
export let value: KSwitchProps['value'] = false;
export let checkedValue: KSwitchProps['checkedValue'] = true;
export let unCheckedValue: KSwitchProps['unCheckedValue'] = false;
export let checkedColor: KSwitchProps['checkedColor'] = '';
export let unCheckedColor: KSwitchProps['unCheckedColor'] = '';
export let size: KSwitchProps['size'] = 'md';
export let loading: KSwitchProps['loading'] = false;
export let disabled: KSwitchProps['disabled'] = false;
export let cls: KSwitchProps['cls'] = undefined;
export let attrs: KSwitchProps['attrs'] = {};
export let checkedColor = '';
export let unCheckedColor = '';
const dispatch = createEventDispatcher();
$: innerState = value === checkedValue;
/**
* 切换状态方法
*/
let changeData: {
newVal: SwitchValueType;
oldVal: SwitchValueType;
newVal: KSwitchProps['value'];
oldVal: KSwitchProps['value'];
};
const emitChangeEvt = (): void => {
changeData = innerState
Expand All @@ -43,7 +45,7 @@
let switchCircleRef: null | HTMLElement = null;
const changeClass = (checked: boolean) => {
return new Promise((resolve) => {
switching = 'k-switch-tra';
switching = `${prefixCls}-tra`;
if (switchCircleRef) {
const circleWidth = switchCircleRef.getClientRects()[0]?.width;
switchCircleRef.style.right = checked ? '1px' : `calc(100% - ${circleWidth}px - 1px)`;
Expand Down Expand Up @@ -87,31 +89,40 @@
};
onMount(init);
$: cnames = clsx(
'k-switch--base',
innerState ? ['k-switch__checked', checkedColor] : ['k-switch__un_checked', unCheckedColor],
const prefixCls = getPrefixCls('switch');
$: switchCls = clsx(
`${prefixCls}`,
`${prefixCls}--base`,
`${prefixCls}--${size}`,
innerState
? [`${prefixCls}__checked`, checkedColor]
: [`${prefixCls}__unchecked`, unCheckedColor],
{
'k-switch__disabled': disabled || loading
[`${prefixCls}__disabled`]: disabled || loading
},
switching,
cls
);
$: loadingCls = clsx(`${prefixCls}-loading`, `${prefixCls}-loading__dark`);
$: circleCls = clsx(`${prefixCls}-circle`, `${prefixCls}-circle--${size}`);
$: unCheckedTxCls = clsx(`${prefixCls}-tx__unchecked`, `${prefixCls}-tx__unchecked--${size}`);
$: checkedTxCls = clsx(`${prefixCls}-tx__checked`, `${prefixCls}-tx__checked--${size}`);
</script>

<div class={cnames} aria-hidden="true" {...attrs} on:click={handleClick}>
<div class={switchCls} aria-hidden="true" {...$$restProps} {...attrs} on:click={handleClick}>
{#if !innerState}
<div class="k-switch-tx__un_checked">
<span class={unCheckedTxCls}>
<slot name="unCheckedRender" state={innerState} />
</div>
</span>
{/if}
<div class="k-switch-circle" bind:this={switchCircleRef}>
<span class={circleCls} bind:this={switchCircleRef}>
{#if loading}
<KIcon icon="i-carbon-circle-dash" cls="k-switch-loading k-switch-loading__dark" />
<KIcon cls={loadingCls} icon="i-carbon-circle-dash" />
{/if}
</div>
</span>
{#if innerState}
<div class="k-switch-tx__checked">
<span class={checkedTxCls}>
<slot name="checkedRender" state={innerState} />
</div>
</span>
{/if}
</div>
15 changes: 14 additions & 1 deletion components/Switch/src/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
/// <reference types="svelte" />
import type { ClassValue } from 'clsx';
import type { IKunSize } from '@ikun-ui/utils';

export type SwitchValueType = string | number | boolean;
export type KSwitchProps = {
value: string | number | boolean;
checkedValue: string | number | boolean;
unCheckedValue: string | number | boolean;
checkedColor: string;
unCheckedColor: string;
size: IKunSize;
loading: boolean;
disabled: boolean;
cls: ClassValue;
attrs: Record<string, string>;
};
12 changes: 10 additions & 2 deletions docs/components/KSwitch.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,25 @@ Use `disabled` attribute to determine whether a switch is loading.

<demo src="switch/render.svelte" github="Switch"></demo>

## Sizes

Use the `size` property to control the switch size.
It supports enumerations such as `md`, `sm`, and `lg`.

<demo src="switch/sizes.svelte" github="Switch"></demo>

## Switch Props

| Name | Type | Default | Description |
| -------------- | --------------------------- | ------- | ---------------------------- |
| value | `boolean` | `false` | Binding value |
| unCheckedValue | `string / number / boolean` | `false` | UnChecked state switch value |
| checkedValue | `string / number / boolean` | `true` | Checked state switch value |
| disabled | `boolean` | `false` | Disabled the switch |
| loading | `boolean` | `-` | Loading state switch |
| unCheckedColor | `string` | `-` | unChecked state switch color |
| checkedColor | `string` | `-` | Checked state switch color |
| size | `sm \| md \| lg` | `md` | size of switch |
| loading | `boolean` | `-` | Loading state switch |
| disabled | `boolean` | `false` | Disabled the switch |
| cls | `string` | `-` | Additional class |
| attrs | `Record<string, string>` | `{}` | Additional attributes |

Expand Down
13 changes: 13 additions & 0 deletions docs/example/switch/sizes.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script>
import { KSwitch } from '@ikun-ui/switch';
let smValue = false;
let mdValue = false;
let lgValue = false;
</script>

<div class="fi">
<KSwitch cls="mx4" size="lg" value={smValue} on:updateValue={(e) => (smValue = e.detail)} />
<KSwitch cls="mx4" size="md" value={mdValue} on:updateValue={(e) => (mdValue = e.detail)} />
<KSwitch cls="mx4" size="sm" value={lgValue} on:updateValue={(e) => (lgValue = e.detail)} />
</div>
29 changes: 22 additions & 7 deletions preset/src/shortcuts/src/swtich.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
export const switchShortcuts: Record<string, string> = {
// switch
'k-switch--base': 'rounded-full w-10 h-5 fi pr cursor-pointer',
'k-switch': 'infi pr',
'k-switch--base': 'rounded-full cursor-pointer',
'k-switch__disabled': 'k-cur-disabled',
'k-switch__unchecked': 'ikun:40:bg-ikun-main',
'k-switch__checked': 'bg-ikun-main',
'k-switch__un_checked': 'ikun:40:bg-ikun-main',
'k-switch-tx__un_checked': 'p1 ml-5',
'k-switch-tx__checked': 'p1 mr-5',
'k-switch-loading': 'animate-spin h-4 w-4',
'k-switch-circle':
'h-4.5 w-4.5 shadow rounded-full bg-ikun-white fcc pa right-2px k-switch-transition pl-1px',
'k-switch-tx__unchecked': 'line-height-1',
'k-switch-tx__checked': 'line-height-1',
'k-switch-loading': 'animate-spin',
'k-switch-circle': 'infcc pa right-2px shadow rounded-full bg-ikun-white k-switch-transition',
'k-switch-tra': 'animate-ikun-switching',

// size
'k-switch--sm': 'h-16px text-12px min-w-30px',
'k-switch--md': 'h-20px text-14px min-w-40px',
'k-switch--lg': 'h-24px text-16px min-w-50px',
'k-switch-circle--sm': 'w-14px h-14px',
'k-switch-circle--md': 'w-18px h-18px',
'k-switch-circle--lg': 'w-22px h-22px',
'k-switch-tx__unchecked--sm': 'ml-16px',
'k-switch-tx__checked--sm': 'ml-2px',
'k-switch-tx__unchecked--md': 'ml-22px',
'k-switch-tx__checked--md': 'ml-3px',
'k-switch-tx__unchecked--lg': 'ml-28px',
'k-switch-tx__checked--lg': 'ml-4px',

// dark
'k-switch-loading__dark': 'dark:text-ikun-tx-base'
};

0 comments on commit 477f56b

Please sign in to comment.