diff --git a/docs/content/3.forms/7.toggle.md b/docs/content/3.forms/7.toggle.md index aac446f15f..3e3cf2905b 100644 --- a/docs/content/3.forms/7.toggle.md +++ b/docs/content/3.forms/7.toggle.md @@ -26,6 +26,17 @@ props: --- :: +### Size + +Use the `size` prop to change the size of the Toggle. + +::component-card +--- +props: + size: 'md' +--- +:: + ### Icon Use any icon from [Iconify](https://icones.js.org) by setting the `on-icon` and `off-icon` props by using this pattern: `i-{collection_name}-{icon_name}` or change it globally in `ui.toggle.default.onIcon` and `ui.toggle.default.offIcon`. diff --git a/src/runtime/components/forms/Toggle.vue b/src/runtime/components/forms/Toggle.vue index 22892d9d0a..dce1982b4d 100644 --- a/src/runtime/components/forms/Toggle.vue +++ b/src/runtime/components/forms/Toggle.vue @@ -7,7 +7,7 @@ :class="switchClass" v-bind="attrs" > - + @@ -77,6 +77,13 @@ export default defineComponent({ type: [String, Object, Array] as PropType, default: undefined }, + size: { + type: String as PropType, + default: config.default.size, + validator (value: string) { + return Object.keys(config.size).includes(value) + } + }, ui: { type: Object as PropType>, default: undefined @@ -101,20 +108,31 @@ export default defineComponent({ const switchClass = computed(() => { return twMerge(twJoin( ui.value.base, + ui.value.size[props.size], ui.value.rounded, ui.value.ring.replaceAll('{color}', color.value), (active.value ? ui.value.active : ui.value.inactive).replaceAll('{color}', color.value) ), props.class) }) + const containerClass = computed(() => { + return twJoin( + ui.value.container.base, + ui.value.container.size[props.size], + (active.value ? ui.value.container.active[props.size] : ui.value.container.inactive) + ) + }) + const onIconClass = computed(() => { return twJoin( + ui.value.icon.size[props.size], ui.value.icon.on.replaceAll('{color}', color.value) ) }) const offIconClass = computed(() => { return twJoin( + ui.value.icon.size[props.size], ui.value.icon.off.replaceAll('{color}', color.value) ) }) @@ -128,6 +146,7 @@ export default defineComponent({ inputId, active, switchClass, + containerClass, onIconClass, offIconClass } diff --git a/src/runtime/ui.config.ts b/src/runtime/ui.config.ts index 9a973a47b8..f22e6bbbe0 100644 --- a/src/runtime/ui.config.ts +++ b/src/runtime/ui.config.ts @@ -802,27 +802,63 @@ export const checkbox = { } export const toggle = { - base: 'relative inline-flex h-5 w-9 flex-shrink-0 border-2 border-transparent disabled:cursor-not-allowed disabled:opacity-50 focus:outline-none', + base: 'relative inline-flex flex-shrink-0 border-2 border-transparent disabled:cursor-not-allowed disabled:opacity-50 focus:outline-none', rounded: 'rounded-full', ring: 'focus-visible:ring-2 focus-visible:ring-{color}-500 dark:focus-visible:ring-{color}-400 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-gray-900', active: 'bg-{color}-500 dark:bg-{color}-400', inactive: 'bg-gray-200 dark:bg-gray-700', + size: { + '2xs': 'h-3 w-5', + xs: 'h-3.5 w-6', + sm: 'h-4 w-7', + md: 'h-5 w-9', + lg: 'h-6 w-11', + xl: 'h-7 w-[3.25rem]', + '2xl': 'h-8 w-[3.75rem]' + }, container: { - base: 'pointer-events-none relative inline-block h-4 w-4 rounded-full bg-white dark:bg-gray-900 shadow transform ring-0 transition ease-in-out duration-200', - active: 'translate-x-4 rtl:-translate-x-4', - inactive: 'translate-x-0 rtl:-translate-x-0' + base: 'pointer-events-none relative inline-block rounded-full bg-white dark:bg-gray-900 shadow transform ring-0 transition ease-in-out duration-200', + active: { + '2xs': 'translate-x-2 rtl:-translate-x-2', + xs: 'translate-x-2.5 rtl:-translate-x-2.5', + sm: 'translate-x-3 rtl:-translate-x-3', + md: 'translate-x-4 rtl:-translate-x-4', + lg: 'translate-x-5 rtl:-translate-x-5', + xl: 'translate-x-6 rtl:-translate-x-6', + '2xl': 'translate-x-7 rtl:-translate-x-7' + }, + inactive: 'translate-x-0 rtl:-translate-x-0', + size: { + '2xs': 'h-2 w-2', + xs: 'h-2.5 w-2.5', + sm: 'h-3 w-3', + md: 'h-4 w-4', + lg: 'h-5 w-5', + xl: 'h-6 w-6', + '2xl': 'h-7 w-7' + } }, icon: { base: 'absolute inset-0 h-full w-full flex items-center justify-center transition-opacity', active: 'opacity-100 ease-in duration-200', inactive: 'opacity-0 ease-out duration-100', - on: 'h-3 w-3 text-{color}-500 dark:text-{color}-400', - off: 'h-3 w-3 text-gray-400 dark:text-gray-500' + size: { + '2xs': 'h-2 w-2', + xs: 'h-2 w-2', + sm: 'h-2 w-2', + md: 'h-3 w-3', + lg: 'h-4 w-4', + xl: 'h-5 w-5', + '2xl': 'h-6 w-6' + }, + on: 'text-{color}-500 dark:text-{color}-400', + off: 'text-gray-400 dark:text-gray-500' }, default: { onIcon: null, offIcon: null, - color: 'primary' + color: 'primary', + size: 'md' } }