diff --git a/src/runtime/components/Accordion.vue b/src/runtime/components/Accordion.vue index caa76401..66db5163 100644 --- a/src/runtime/components/Accordion.vue +++ b/src/runtime/components/Accordion.vue @@ -85,23 +85,3 @@ const ui = computed(() => tv({ extend: accordion, slots: props.ui })()) - - diff --git a/src/runtime/components/Collapsible.vue b/src/runtime/components/Collapsible.vue index 3871bf9f..ca86463b 100644 --- a/src/runtime/components/Collapsible.vue +++ b/src/runtime/components/Collapsible.vue @@ -47,23 +47,3 @@ const ui = computed(() => tv({ extend: collapsible, slots: props.ui })()) - - diff --git a/src/runtime/components/DropdownMenu.vue b/src/runtime/components/DropdownMenu.vue index eb84ec79..4c11e60d 100644 --- a/src/runtime/components/DropdownMenu.vue +++ b/src/runtime/components/DropdownMenu.vue @@ -77,26 +77,3 @@ const ui = computed(() => tv({ extend: dropdownMenu, slots: props.ui })()) - - diff --git a/src/runtime/components/Modal.vue b/src/runtime/components/Modal.vue index 10e9e265..ab016f6e 100644 --- a/src/runtime/components/Modal.vue +++ b/src/runtime/components/Modal.vue @@ -128,42 +128,3 @@ const ui = computed(() => tv({ extend: modal, slots: props.ui })({ - - diff --git a/src/runtime/components/Popover.vue b/src/runtime/components/Popover.vue index 5c9b0a74..6e6149b5 100644 --- a/src/runtime/components/Popover.vue +++ b/src/runtime/components/Popover.vue @@ -51,7 +51,7 @@ const rootProps = useForwardPropsEmits(pick, emits) const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8 }) as PopoverContentProps) const arrowProps = toRef(() => props.arrow as PopoverArrowProps) -const ui = computed(() => tv({ extend: popover, slots: props.ui })()) +const ui = computed(() => tv({ extend: popover, slots: props.ui })({ side: contentProps.value.side })) const Component = computed(() => props.mode === 'hover' ? HoverCard : Popover) @@ -71,86 +71,3 @@ const Component = computed(() => props.mode === 'hover' ? HoverCard : Popover) - - diff --git a/src/runtime/components/Slideover.vue b/src/runtime/components/Slideover.vue index 6f7c4e90..37f0706d 100644 --- a/src/runtime/components/Slideover.vue +++ b/src/runtime/components/Slideover.vue @@ -129,86 +129,3 @@ const ui = computed(() => tv({ extend: slideover, slots: props.ui })({ - - diff --git a/src/runtime/components/Tooltip.vue b/src/runtime/components/Tooltip.vue index 99c78217..7201cecd 100644 --- a/src/runtime/components/Tooltip.vue +++ b/src/runtime/components/Tooltip.vue @@ -45,7 +45,7 @@ const rootProps = useForwardPropsEmits(reactivePick(props, 'defaultOpen', 'open' const contentProps = toRef(() => defu(props.content, { side: 'bottom', sideOffset: 8 }) as TooltipContentProps) const arrowProps = toRef(() => props.arrow as TooltipArrowProps) -const ui = computed(() => tv({ extend: tooltip, slots: props.ui })()) +const ui = computed(() => tv({ extend: tooltip, slots: props.ui })({ side: contentProps.value.side })) - - diff --git a/src/templates.ts b/src/templates.ts index cbc04e82..c6e16a92 100644 --- a/src/templates.ts +++ b/src/templates.ts @@ -12,30 +12,149 @@ export function addTemplates (options: ModuleOptions, nuxt: Nuxt) { write: true, getContents: () => `@import "tailwindcss"; - @layer base { - :root { - color-scheme: light dark; - } - } +@layer base { + :root { + color-scheme: light dark; + } - @theme { - --color-gray-*: initial; - --color-cool-50: #f9fafb; - --color-cool-100: #f3f4f6; - --color-cool-200: #e5e7eb; - --color-cool-300: #d1d5db; - --color-cool-400: #9ca3af; - --color-cool-500: #6b7280; - --color-cool-600: #4b5563; - --color-cool-700: #374151; - --color-cool-800: #1f2937; - --color-cool-900: #111827; - --color-cool-950: #030712; + @keyframes accordion-up { + from { height: var(--radix-accordion-content-height); } + to { height: 0; } + } + @keyframes accordion-down { + from { height: 0; } + to { height: var(--radix-accordion-content-height); } + } - ${shades.map(shade => `--color-primary-${shade}: var(--color-primary-${shade});`).join('\n')} - ${shades.map(shade => `--color-gray-${shade}: var(--color-gray-${shade});`).join('\n')} - } - ` + @keyframes collapsible-up { + from { height: var(--radix-collapsible-content-height); } + to { height: 0; } + } + @keyframes collapsible-down { + from { height: 0; } + to { height: var(--radix-collapsible-content-height); } + } + + @keyframes fade-in { + from { opacity: 0; } + to { opacity: 1; } + } + @keyframes fade-out { + from { opacity: 1; } + to { opacity: 0; } + } + + @keyframes scale-in { + from { opacity: 0; transform: scale(0.95); } + to { opacity: 1; transform: scale(1); } + } + @keyframes scale-out { + from { opacity: 1; transform: scale(1); } + to { opacity: 0; transform: scale(0.95); } + } + + @keyframes slide-in-from-top { + from { transform: translateY(-100%); } + to { transform: translateY(0); } + } + @keyframes slide-out-to-top { + from { transform: translateY(0); } + to { transform: translateY(-100%); } + } + @keyframes slide-in-from-right { + from { transform: translateX(100%); } + to { transform: translateX(0); } + } + @keyframes slide-out-to-right { + from { transform: translateX(0); } + to { transform: translateX(100%); } + } + @keyframes slide-in-from-bottom { + from { transform: translateY(100%); } + to { transform: translateY(0); } + } + @keyframes slide-out-to-bottom { + from { transform: translateY(0); } + to { transform: translateY(100%); } + } + @keyframes slide-in-from-left { + from { transform: translateX(-100%); } + to { transform: translateX(0); } + } + @keyframes slide-out-to-left { + from { transform: translateX(0); } + to { transform: translateX(-100%); } + } + + @keyframes slide-in-from-top-and-fade { + from { opacity: 0; transform: translateY(-4px); } + to { opacity: 1; transform: translateY(0); } + } + @keyframes slide-out-to-top-and-fade { + from { opacity: 1; transform: translateY(0); } + to { opacity: 0; transform: translateY(-4px); } + } + @keyframes slide-in-from-right-and-fade { + from { opacity: 0; transform: translateX(4px); } + to { opacity: 1; transform: translateX(0); } + } + @keyframes slide-out-to-right-and-fade { + from { opacity: 1; transform: translateX(0); } + to { opacity: 0; transform: translateX(4px); } + } + @keyframes slide-in-from-bottom-and-fade { + from { opacity: 0; transform: translateY(4px); } + to { opacity: 1; transform: translateY(0); } + } + @keyframes slide-out-to-bottom-and-fade { + from { opacity: 1; transform: translateY(0); } + to { opacity: 0; transform: translateY(4px); } + } + @keyframes slide-in-from-left-and-fade { + from { opacity: 0; transform: translateX(-4px); } + to { opacity: 1; transform: translateX(0); } + } + @keyframes slide-out-to-left-and-fade { + from { opacity: 1; transform: translateX(0); } + to { opacity: 0; transform: translateX(-4px); } + } + + @keyframes enter-from-right { + from { opacity: 0; transform: translateX(200px); } + to { opacity: 1; transform: translateX(0); } + } + @keyframes enter-from-left { + from { opacity: 0; transform: translateX(-200px); } + to { opacity: 1; transform: translateX(0); } + } + @keyframes exit-to-right { + from { opacity: 1; transform: translateX(0); } + to { opacity: 0; transform: translateX(200px); } + } + @keyframes exit-to-left { + from { opacity: 1; transform: translateX(0); } + to { opacity: 0; transform: translateX(-200px); } + } +} + +@theme { + --color-gray-*: initial; + --color-cool-50: #f9fafb; + --color-cool-100: #f3f4f6; + --color-cool-200: #e5e7eb; + --color-cool-300: #d1d5db; + --color-cool-400: #9ca3af; + --color-cool-500: #6b7280; + --color-cool-600: #4b5563; + --color-cool-700: #374151; + --color-cool-800: #1f2937; + --color-cool-900: #111827; + --color-cool-950: #030712; + + ${shades.map(shade => `--color-primary-${shade}: var(--color-primary-${shade});`).join('\n\t')} + ${shades.map(shade => `--color-gray-${shade}: var(--color-gray-${shade});`).join('\n\t')} +} +` }) nuxt.options.css.push(template.dst) diff --git a/src/theme/dropdown-menu.ts b/src/theme/dropdown-menu.ts index 01b35034..db599c28 100644 --- a/src/theme/dropdown-menu.ts +++ b/src/theme/dropdown-menu.ts @@ -1,6 +1,6 @@ export default { slots: { - content: 'min-w-48 bg-white dark:bg-gray-900 shadow-lg rounded-md ring ring-gray-200 dark:ring-gray-800 divide-y divide-gray-200 dark:divide-gray-800 will-change-[transform,opacity] data-[state=open]:animate-[dropdown-menu-open_100ms_ease-out] data-[state=closed]:animate-[dropdown-menu-closed_100ms_ease-in]', + content: 'min-w-48 bg-white dark:bg-gray-900 shadow-lg rounded-md ring ring-gray-200 dark:ring-gray-800 divide-y divide-gray-200 dark:divide-gray-800 will-change-[transform,opacity] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in]', arrow: 'fill-gray-200 dark:fill-gray-800', group: 'p-1', label: 'w-full flex items-center gap-1.5 p-1.5 text-sm font-medium select-none', diff --git a/src/theme/modal.ts b/src/theme/modal.ts index c1feafdb..3b9a2b1c 100644 --- a/src/theme/modal.ts +++ b/src/theme/modal.ts @@ -12,8 +12,8 @@ export default { variants: { transition: { true: { - overlay: 'data-[state=open]:animate-[modal-overlay-open_200ms_ease-out] data-[state=closed]:animate-[modal-overlay-closed_200ms_ease-in]', - content: 'data-[state=open]:animate-[modal-content-open_200ms_ease-out] data-[state=closed]:animate-[modal-content-closed_200ms_ease-in]' + overlay: 'data-[state=open]:animate-[fade-in_200ms_ease-out] data-[state=closed]:animate-[fade-out_200ms_ease-in]', + content: 'data-[state=open]:animate-[scale-in_200ms_ease-out] data-[state=closed]:animate-[scale-out_200ms_ease-in]' } }, fullscreen: { diff --git a/src/theme/popover.ts b/src/theme/popover.ts index a2480d0e..3778b6c4 100644 --- a/src/theme/popover.ts +++ b/src/theme/popover.ts @@ -1,6 +1,22 @@ export default { slots: { - content: 'bg-white dark:bg-gray-900 shadow-lg rounded-md ring ring-gray-200 dark:ring-gray-800 will-change-[transform,opacity] data-[state=open]:data-[side=top]:animate-[popover-down-open_200ms_ease-out] data-[state=closed]:data-[side=top]:animate-[popover-down-closed_200ms_ease-in] data-[state=open]:data-[side=right]:animate-[popover-left-open_200ms_ease-out] data-[state=closed]:data-[side=right]:animate-[popover-left-closed_200ms_ease-in] data-[state=open]:data-[side=left]:animate-[popover-right-open_200ms_ease-out] data-[state=closed]:data-[side=left]:animate-[popover-right-closed_200ms_ease-in] data-[state=open]:data-[side=bottom]:animate-[popover-up-open_200ms_ease-out] data-[state=closed]:data-[side=bottom]:animate-[popover-up-closed_200ms_ease-in]', + content: 'bg-white dark:bg-gray-900 shadow-lg rounded-md ring ring-gray-200 dark:ring-gray-800 will-change-[transform,opacity]', arrow: 'fill-gray-200 dark:fill-gray-800' + }, + variants: { + side: { + top: { + content: 'data-[state=open]:animate-[slide-in-from-top-and-fade_200ms_ease-out] data-[state=closed]:animate-[slide-out-to-top-and-fade_200ms_ease-in]' + }, + right: { + content: 'data-[state=open]:animate-[slide-in-from-right-and-fade_200ms_ease-out] data-[state=closed]:animate-[slide-out-to-right-and-fade_200ms_ease-in]' + }, + bottom: { + content: 'data-[state=open]:animate-[slide-in-from-bottom-and-fade_200ms_ease-out] data-[state=closed]:animate-[slide-out-to-bottom-and-fade_200ms_ease-in]' + }, + left: { + content: 'data-[state=open]:animate-[slide-in-from-left-and-fade_200ms_ease-out] data-[state=closed]:animate-[slide-out-to-left-and-fade_200ms_ease-in]' + } + } } } diff --git a/src/theme/slideover.ts b/src/theme/slideover.ts index 9427ded5..72338be5 100644 --- a/src/theme/slideover.ts +++ b/src/theme/slideover.ts @@ -11,24 +11,48 @@ export default { }, variants: { side: { - left: { - content: 'left-0 inset-y-0 w-full max-w-md' + top: { + content: 'inset-x-0 top-0' }, right: { content: 'right-0 inset-y-0 w-full max-w-md' }, - top: { - content: 'inset-x-0 top-0' - }, bottom: { content: 'inset-x-0 bottom-0' + }, + left: { + content: 'left-0 inset-y-0 w-full max-w-md' } }, transition: { true: { - overlay: 'data-[state=open]:animate-[slideover-overlay-open_200ms_ease-out] data-[state=closed]:animate-[slideover-overlay-closed_200ms_ease-in]', - content: 'data-[state=open]:data-[side=left]:animate-[slideover-content-left-open_200ms_ease-in-out] data-[state=closed]:data-[side=left]:animate-[slideover-content-left-closed_200ms_ease-in-out] data-[state=open]:data-[side=right]:animate-[slideover-content-right-open_200ms_ease-in-out] data-[state=closed]:data-[side=right]:animate-[slideover-content-right-closed_200ms_ease-in-out] data-[state=open]:data-[side=top]:animate-[slideover-content-top-open_200ms_ease-in-out] data-[state=closed]:data-[side=top]:animate-[slideover-content-top-closed_200ms_ease-in-out] data-[state=open]:data-[side=bottom]:animate-[slideover-content-bottom-open_200ms_ease-in-out] data-[state=closed]:data-[side=bottom]:animate-[slideover-content-bottom-closed_200ms_ease-in-out]' + overlay: 'data-[state=open]:animate-[fade-in_200ms_ease-out] data-[state=closed]:animate-[fade-out_200ms_ease-in]' } } - } + }, + compoundVariants: [{ + transition: true, + side: 'top', + class: { + content: 'data-[state=open]:animate-[slide-in-from-top_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-top_200ms_ease-in-out]' + } + }, { + transition: true, + side: 'right', + class: { + content: 'data-[state=open]:animate-[slide-in-from-right_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-right_200ms_ease-in-out]' + } + }, { + transition: true, + side: 'bottom', + class: { + content: 'data-[state=open]:animate-[slide-in-from-bottom_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-bottom_200ms_ease-in-out]' + } + }, { + transition: true, + side: 'left', + class: { + content: 'data-[state=open]:animate-[slide-in-from-left_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-left_200ms_ease-in-out]' + } + }] } diff --git a/src/theme/tooltip.ts b/src/theme/tooltip.ts index 49cc492e..6f0b15a0 100644 --- a/src/theme/tooltip.ts +++ b/src/theme/tooltip.ts @@ -1,9 +1,25 @@ export default { slots: { - content: 'flex items-center gap-1 bg-white dark:bg-gray-900 text-gray-900 dark:text-white shadow rounded ring ring-gray-200 dark:ring-gray-800 h-6 px-2 py-1 text-xs select-none will-change-[transform,opacity] data-[state=delayed-open]:data-[side=top]:animate-[tooltip-down_200ms_ease-out] data-[state=delayed-open]:data-[side=right]:animate-[tooltip-left_200ms_ease-out] data-[state=delayed-open]:data-[side=left]:animate-[tooltip-right_200ms_ease-out] data-[state=delayed-open]:data-[side=bottom]:animate-[tooltip-up_200ms_ease-out]', + content: 'flex items-center gap-1 bg-white dark:bg-gray-900 text-gray-900 dark:text-white shadow rounded ring ring-gray-200 dark:ring-gray-800 h-6 px-2 py-1 text-xs select-none will-change-[transform,opacity]', arrow: 'fill-gray-200 dark:fill-gray-800', text: 'truncate', // eslint-disable-next-line quotes shortcuts: `hidden lg:inline-flex items-center shrink-0 gap-0.5 before:content-['ยท'] before:mr-0.5` + }, + variants: { + side: { + top: { + content: 'data-[state=delayed-open]:animate-[slide-in-from-top-and-fade_200ms_ease-out]' + }, + right: { + content: 'data-[state=delayed-open]:animate-[slide-in-from-right-and-fade_200ms_ease-out]' + }, + bottom: { + content: 'data-[state=delayed-open]:animate-[slide-in-from-bottom-and-fade_200ms_ease-out]' + }, + left: { + content: 'data-[state=delayed-open]:animate-[slide-in-from-left-and-fade_200ms_ease-out]' + } + } } }