sigma-ui 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/__generated/registry-schemes/index.json +11 -0
  2. package/__generated/registry-schemes/style-system/css/badge.json +1 -1
  3. package/__generated/registry-schemes/style-system/css/button.json +6 -2
  4. package/__generated/registry-schemes/style-system/css/card-lightbox.json +1 -1
  5. package/__generated/registry-schemes/style-system/css/checkbox.json +1 -1
  6. package/__generated/registry-schemes/style-system/css/combobox.json +1 -1
  7. package/__generated/registry-schemes/style-system/css/dialog.json +1 -1
  8. package/__generated/registry-schemes/style-system/css/faceted-filter.json +16 -0
  9. package/__generated/registry-schemes/style-system/css/input.json +1 -1
  10. package/__generated/registry-schemes/style-system/css/number-field.json +1 -1
  11. package/__generated/registry-schemes/style-system/css/pin-input.json +1 -1
  12. package/__generated/registry-schemes/style-system/css/radio-group.json +1 -1
  13. package/__generated/registry-schemes/style-system/css/resizable.json +1 -1
  14. package/__generated/registry-schemes/style-system/css/select.json +1 -1
  15. package/__generated/registry-schemes/style-system/css/sheet.json +1 -1
  16. package/__generated/registry-schemes/style-system/css/slider.json +1 -1
  17. package/__generated/registry-schemes/style-system/css/switch.json +1 -1
  18. package/__generated/registry-schemes/style-system/css/tabs.json +2 -2
  19. package/__generated/registry-schemes/style-system/css/tags-input.json +1 -1
  20. package/__generated/registry-schemes/style-system/css/textarea.json +1 -1
  21. package/__generated/registry-schemes/style-system/css/toggle.json +1 -1
  22. package/__generated/registry-schemes/style-system/tailwind/badge.json +1 -1
  23. package/__generated/registry-schemes/style-system/tailwind/button.json +5 -1
  24. package/__generated/registry-schemes/style-system/tailwind/card-lightbox.json +1 -1
  25. package/__generated/registry-schemes/style-system/tailwind/checkbox.json +1 -1
  26. package/__generated/registry-schemes/style-system/tailwind/combobox.json +1 -1
  27. package/__generated/registry-schemes/style-system/tailwind/dialog.json +1 -1
  28. package/__generated/registry-schemes/style-system/tailwind/faceted-filter.json +16 -0
  29. package/__generated/registry-schemes/style-system/tailwind/input.json +1 -1
  30. package/__generated/registry-schemes/style-system/tailwind/number-field.json +1 -1
  31. package/__generated/registry-schemes/style-system/tailwind/pin-input.json +1 -1
  32. package/__generated/registry-schemes/style-system/tailwind/radio-group.json +1 -1
  33. package/__generated/registry-schemes/style-system/tailwind/resizable.json +1 -1
  34. package/__generated/registry-schemes/style-system/tailwind/select.json +1 -1
  35. package/__generated/registry-schemes/style-system/tailwind/sheet.json +1 -1
  36. package/__generated/registry-schemes/style-system/tailwind/slider.json +1 -1
  37. package/__generated/registry-schemes/style-system/tailwind/switch.json +1 -1
  38. package/__generated/registry-schemes/style-system/tailwind/tabs.json +2 -2
  39. package/__generated/registry-schemes/style-system/tailwind/tags-input.json +1 -1
  40. package/__generated/registry-schemes/style-system/tailwind/textarea.json +1 -1
  41. package/__generated/registry-schemes/style-system/tailwind/toggle.json +1 -1
  42. package/dist/index.js +1 -1
  43. package/dist/index.js.map +1 -1
  44. package/package.json +1 -1
@@ -85,6 +85,7 @@
85
85
  "registryDependencies": [],
86
86
  "files": [
87
87
  "button/Button.vue",
88
+ "button/ConfirmButton.vue",
88
89
  "button/index.ts"
89
90
  ],
90
91
  "type": "components:ui"
@@ -373,6 +374,16 @@
373
374
  ],
374
375
  "type": "components:ui"
375
376
  },
377
+ {
378
+ "name": "faceted-filter",
379
+ "dependencies": [],
380
+ "registryDependencies": [],
381
+ "files": [
382
+ "faceted-filter/FacetedFilter.vue",
383
+ "faceted-filter/index.ts"
384
+ ],
385
+ "type": "components:ui"
386
+ },
376
387
  {
377
388
  "name": "form",
378
389
  "dependencies": [
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "name": "Badge.vue",
8
- "content": "<script setup lang=\"ts\">\nimport { type BadgeVariants, badgeVariants } from '.';\n\nconst props = defineProps<{\n variant?: BadgeVariants['variant'];\n\n}>();\n</script>\n\n<template>\n <div :class=\"[badgeVariants({ variant }), $attrs.class]\">\n <slot />\n </div>\n</template>\n\n<style>\n.sigma-ui-badge {\n display: inline-flex;\n align-items: center;\n padding: 0.125rem 0.625rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n transition-duration: 150ms;\n transition-property: color, background-color, border-color;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-badge:focus {\n box-shadow:\n 0 0 0 var(--ring-offset) hsl(var(--background)),\n 0 0 0 calc(var(--ring-offset) + var(--ring-width)) hsl(var(--ring));\n outline: none;\n\n --ring-offset: 2px;\n --ring-width: 2px;\n}\n\n.sigma-ui-badge--default {\n border-color: transparent;\n background-color: hsl(var(--primary));\n color: hsl(var(--primary-foreground));\n}\n\n.sigma-ui-badge--default:hover {\n background-color: hsl(var(--primary) / 80%);\n}\n\n.sigma-ui-badge--secondary {\n border-color: transparent;\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-badge--secondary:hover {\n background-color: hsl(var(--secondary) / 80%);\n}\n\n.sigma-ui-badge--destructive {\n border-color: transparent;\n background-color: hsl(var(--destructive));\n color: hsl(var(--destructive-foreground));\n}\n\n.sigma-ui-badge--destructive:hover {\n background-color: hsl(var(--destructive) / 80%);\n}\n\n.sigma-ui-badge--outline {\n color: hsl(var(--foreground));\n}\n</style>\n"
8
+ "content": "<script setup lang=\"ts\">\nimport { type BadgeVariants, badgeVariants } from '.';\n\nconst props = defineProps<{\n variant?: BadgeVariants['variant'];\n\n}>();\n</script>\n\n<template>\n <div :class=\"[badgeVariants({ variant }), $attrs.class]\">\n <slot />\n </div>\n</template>\n\n<style>\n.sigma-ui-badge {\n display: inline-flex;\n align-items: center;\n padding: 0.125rem 0.625rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n transition-duration: 150ms;\n transition-property: color, background-color, border-color;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-badge:focus {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-badge--default {\n border-color: transparent;\n background-color: hsl(var(--primary));\n color: hsl(var(--primary-foreground));\n}\n\n.sigma-ui-badge--default:hover {\n background-color: hsl(var(--primary) / 80%);\n}\n\n.sigma-ui-badge--secondary {\n border-color: transparent;\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-badge--secondary:hover {\n background-color: hsl(var(--secondary) / 80%);\n}\n\n.sigma-ui-badge--destructive {\n border-color: transparent;\n background-color: hsl(var(--destructive));\n color: hsl(var(--destructive-foreground));\n}\n\n.sigma-ui-badge--destructive:hover {\n background-color: hsl(var(--destructive) / 80%);\n}\n\n.sigma-ui-badge--outline {\n color: hsl(var(--foreground));\n}\n</style>\n"
9
9
  },
10
10
  {
11
11
  "name": "index.ts",
@@ -5,11 +5,15 @@
5
5
  "files": [
6
6
  {
7
7
  "name": "Button.vue",
8
- "content": "<script setup lang=\"ts\">\nimport { Primitive, type PrimitiveProps } from 'reka-ui';\nimport { Loader2Icon } from 'lucide-vue-next';\nimport { type ButtonVariants, buttonVariants } from '.';\n\ninterface Props extends PrimitiveProps {\n variant?: ButtonVariants['variant'];\n size?: ButtonVariants['size'];\n isLoading?: boolean;\n loadingText?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n isLoading: false,\n loadingText: '',\n});\n</script>\n\n<template>\n <Primitive\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"[buttonVariants({ variant, size }), $attrs.class]\"\n :disabled=\"isLoading || $attrs.disabled\"\n >\n <Loader2Icon\n v-if=\"isLoading\"\n class=\"sigma-ui-button__loader\"\n />\n <template v-if=\"!isLoading || (isLoading && !loadingText)\">\n <slot />\n </template>\n <template v-else>\n {{ loadingText }}\n </template>\n </Primitive>\n</template>\n\n<style>\n.sigma-ui-button {\n display: inline-flex;\n width: fit-content;\n align-items: center;\n justify-content: center;\n border-radius: var(--radius);\n font-size: 0.875rem;\n font-weight: 500;\n outline: none;\n transition: background-color 0.1s ease, colors 0.2s;\n user-select: none;\n white-space: nowrap;\n}\n\n.sigma-ui-button:focus-visible {\n box-shadow:\n 0 0 0 2px hsl(var(--background)),\n 0 0 0 4px hsl(var(--ring));\n outline: none;\n}\n\n.sigma-ui-button:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.sigma-ui-button--default {\n background-color: hsl(var(--primary));\n color: hsl(var(--primary-foreground));\n}\n\n.sigma-ui-button--default:hover {\n background-color: hsl(var(--primary) / 90%);\n}\n\n.sigma-ui-button--destructive {\n background-color: hsl(var(--destructive));\n color: hsl(var(--destructive-foreground));\n}\n\n.sigma-ui-button--destructive:hover {\n background-color: hsl(var(--destructive) / 90%);\n}\n\n.sigma-ui-button--outline {\n border: 1px solid hsl(var(--border));\n background-color: transparent;\n}\n\n.sigma-ui-button--outline:hover {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-button--secondary {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-button--secondary:hover {\n background-color: hsl(var(--secondary) / 80%);\n}\n\n.sigma-ui-button--ghost:hover {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-button--link {\n color: hsl(var(--primary));\n text-underline-offset: 4px;\n}\n\n.sigma-ui-button--link:hover {\n text-decoration: underline;\n}\n\n.sigma-ui-button--size-default {\n height: 2.5rem;\n padding: 0.5rem 1rem;\n}\n\n.sigma-ui-button--size-xs {\n height: 1.75rem;\n padding: 0 0.5rem;\n border-radius: 0.25rem;\n}\n\n.sigma-ui-button--size-sm {\n height: 2.25rem;\n padding: 0 0.75rem;\n border-radius: var(--radius);\n}\n\n.sigma-ui-button--size-lg {\n height: 2.75rem;\n padding: 0 2rem;\n border-radius: var(--radius);\n}\n\n.sigma-ui-button--size-icon {\n width: 2.5rem;\n height: 2.5rem;\n}\n\n.sigma-ui-button__loader {\n width: 1rem;\n height: 1rem;\n margin-right: 0.5rem;\n animation: sigma-ui-spin 1s linear infinite;\n}\n</style>\n"
8
+ "content": "<script setup lang=\"ts\">\nimport { Primitive, type PrimitiveProps } from 'reka-ui';\nimport { Loader2Icon } from 'lucide-vue-next';\nimport { type ButtonVariants, buttonVariants } from '.';\n\ninterface Props extends PrimitiveProps {\n variant?: ButtonVariants['variant'];\n size?: ButtonVariants['size'];\n isLoading?: boolean;\n loadingText?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n isLoading: false,\n loadingText: '',\n});\n</script>\n\n<template>\n <Primitive\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"[buttonVariants({ variant, size }), $attrs.class]\"\n :disabled=\"isLoading || $attrs.disabled\"\n >\n <Loader2Icon\n v-if=\"isLoading\"\n class=\"sigma-ui-button__loader\"\n />\n <template v-if=\"!isLoading || (isLoading && !loadingText)\">\n <slot />\n </template>\n <template v-else>\n {{ loadingText }}\n </template>\n </Primitive>\n</template>\n\n<style>\n.sigma-ui-button {\n display: inline-flex;\n width: fit-content;\n align-items: center;\n justify-content: center;\n border-radius: var(--radius);\n font-size: 0.875rem;\n font-weight: 500;\n transition: background-color 0.1s ease, colors 0.2s;\n user-select: none;\n white-space: nowrap;\n}\n\n.sigma-ui-button:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-button:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.sigma-ui-button--default {\n background-color: hsl(var(--primary));\n color: hsl(var(--primary-foreground));\n}\n\n.sigma-ui-button--default:hover {\n background-color: hsl(var(--primary) / 90%);\n}\n\n.sigma-ui-button--destructive {\n background-color: hsl(var(--destructive));\n color: hsl(var(--destructive-foreground));\n}\n\n.sigma-ui-button--destructive:hover {\n background-color: hsl(var(--destructive) / 90%);\n}\n\n.sigma-ui-button--outline {\n border: 1px solid hsl(var(--border));\n background-color: transparent;\n}\n\n.sigma-ui-button--outline:hover {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-button--secondary {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-button--secondary:hover {\n background-color: hsl(var(--secondary) / 80%);\n}\n\n.sigma-ui-button--ghost:hover {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-button--link {\n color: hsl(var(--primary));\n text-underline-offset: 4px;\n}\n\n.sigma-ui-button--link:hover {\n text-decoration: underline;\n}\n\n.sigma-ui-button--size-default {\n height: 2.5rem;\n padding: 0.5rem 1rem;\n}\n\n.sigma-ui-button--size-xs {\n height: 1.75rem;\n padding: 0 0.5rem;\n border-radius: 0.25rem;\n}\n\n.sigma-ui-button--size-sm {\n height: 2.25rem;\n padding: 0 0.75rem;\n border-radius: var(--radius);\n}\n\n.sigma-ui-button--size-lg {\n height: 2.75rem;\n padding: 0 2rem;\n border-radius: var(--radius);\n}\n\n.sigma-ui-button--size-icon {\n width: 2.5rem;\n height: 2.5rem;\n}\n\n.sigma-ui-button__loader {\n width: 1rem;\n height: 1rem;\n margin-right: 0.5rem;\n animation: sigma-ui-spin 1s linear infinite;\n}\n</style>\n"
9
+ },
10
+ {
11
+ "name": "ConfirmButton.vue",
12
+ "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { CheckIcon } from 'lucide-vue-next';\nimport { Button } from '.';\nimport { type ButtonVariants } from '.';\n\ninterface Props {\n variant?: ButtonVariants['variant'];\n size?: ButtonVariants['size'];\n confirmDuration?: number;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'outline',\n size: 'default',\n confirmDuration: 1000,\n});\n\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n}>();\n\nconst isConfirmed = ref(false);\nlet confirmTimeout: ReturnType<typeof setTimeout> | null = null;\n\nasync function handleClick(event: MouseEvent) {\n if (isConfirmed.value) {\n return;\n }\n\n emit('click', event);\n\n isConfirmed.value = true;\n\n if (confirmTimeout) {\n clearTimeout(confirmTimeout);\n }\n\n confirmTimeout = setTimeout(() => {\n isConfirmed.value = false;\n confirmTimeout = null;\n }, props.confirmDuration);\n}\n</script>\n\n<template>\n <Button\n :variant=\"variant\"\n :size=\"size\"\n class=\"sigma-ui-confirm-button\"\n :class=\"{ 'sigma-ui-confirm-button--confirmed': isConfirmed }\"\n @click=\"handleClick\"\n >\n <span\n class=\"sigma-ui-confirm-button__content\"\n :class=\"{ 'sigma-ui-confirm-button__content--hidden': isConfirmed }\"\n >\n <slot />\n </span>\n <Transition name=\"sigma-ui-confirm-button-check\">\n <span\n v-if=\"isConfirmed\"\n class=\"sigma-ui-confirm-button__check-wrapper\"\n >\n <CheckIcon\n :size=\"14\"\n class=\"sigma-ui-confirm-button__check\"\n />\n </span>\n </Transition>\n </Button>\n</template>\n\n<style>\n.sigma-ui-confirm-button {\n position: relative;\n overflow: hidden;\n gap: 0.5rem;\n}\n\n.sigma-ui-confirm-button__content {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n transition: opacity 0.15s ease;\n}\n\n.sigma-ui-confirm-button__content--hidden {\n opacity: 0;\n}\n\n.sigma-ui-confirm-button__check-wrapper {\n position: absolute;\n top: 50%;\n left: 50%;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transform: translate(-50%, -50%);\n}\n\n.sigma-ui-confirm-button__check {\n color: hsl(var(--success, 142 76% 36%));\n}\n\n.sigma-ui-confirm-button--confirmed {\n border-color: hsl(var(--success, 142 76% 36%) / 50%);\n}\n\n.sigma-ui-confirm-button-check-enter-active,\n.sigma-ui-confirm-button-check-leave-active {\n transition:\n opacity 0.15s ease,\n transform 0.15s ease;\n}\n\n.sigma-ui-confirm-button-check-enter-from {\n opacity: 0;\n transform: translate(-50%, -50%) scale(0.5);\n}\n\n.sigma-ui-confirm-button-check-leave-to {\n opacity: 0;\n transform: translate(-50%, -50%) scale(0.5);\n}\n</style>\n"
9
13
  },
10
14
  {
11
15
  "name": "index.ts",
12
- "content": "import { type VariantProps, cva } from 'class-variance-authority';\n\nexport { default as Button } from './Button.vue';\n\nexport const buttonVariants = cva(\n 'sigma-ui-button',\n {\n variants: {\n variant: {\n default: 'sigma-ui-button--default',\n destructive: 'sigma-ui-button--destructive',\n outline: 'sigma-ui-button--outline',\n secondary: 'sigma-ui-button--secondary',\n ghost: 'sigma-ui-button--ghost',\n link: 'sigma-ui-button--link',\n },\n size: {\n default: 'sigma-ui-button--size-default',\n xs: 'sigma-ui-button--size-xs',\n sm: 'sigma-ui-button--size-sm',\n lg: 'sigma-ui-button--size-lg',\n icon: 'sigma-ui-button--size-icon',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n"
16
+ "content": "import { type VariantProps, cva } from 'class-variance-authority';\n\nexport { default as Button } from './Button.vue';\nexport { default as ConfirmButton } from './ConfirmButton.vue';\n\nexport const buttonVariants = cva(\n 'sigma-ui-button',\n {\n variants: {\n variant: {\n default: 'sigma-ui-button--default',\n destructive: 'sigma-ui-button--destructive',\n outline: 'sigma-ui-button--outline',\n secondary: 'sigma-ui-button--secondary',\n ghost: 'sigma-ui-button--ghost',\n link: 'sigma-ui-button--link',\n },\n size: {\n default: 'sigma-ui-button--size-default',\n xs: 'sigma-ui-button--size-xs',\n sm: 'sigma-ui-button--size-sm',\n lg: 'sigma-ui-button--size-lg',\n icon: 'sigma-ui-button--size-icon',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n"
13
17
  }
14
18
  ],
15
19
  "type": "components:ui"
@@ -7,7 +7,7 @@
7
7
  "files": [
8
8
  {
9
9
  "name": "CardLightbox.vue",
10
- "content": "<script setup lang=\"ts\">\nimport { onMounted, onUnmounted, ref } from 'vue';\nimport { AnimatePresence, motion } from 'motion-v';\nimport type { Item } from './types';\nimport { XIcon } from 'lucide-vue-next';\n\ntype Props = {\n items: Item[];\n};\n\nconst props = defineProps<Props>();\n\nconst openId = ref<string | null>(null);\n\nonMounted(() => {\n document.addEventListener('keydown', handleEscKeydown);\n});\n\nonUnmounted(() => {\n document.removeEventListener('keydown', handleEscKeydown);\n});\n\nfunction getTheme(id: string) {\n return props.items.find(item => item.id === id)?.theme;\n}\n\nfunction open(id: string) {\n openId.value = id;\n}\n\nfunction close() {\n openId.value = null;\n}\n\nfunction handleEscKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n close();\n }\n}\n</script>\n\n<template>\n <div class=\"card-lightbox\">\n <ul class=\"card-lightbox__grid\">\n <motion.button\n v-for=\"card in props.items\"\n :key=\"card.id\"\n :data-open=\"openId === card.id\"\n :class=\"[\n 'card-lightbox__card',\n {\n 'theme-dark': getTheme(card.id) === 'dark',\n 'theme-light': getTheme(card.id) === 'light'\n }\n ]\"\n @click=\"() => open(card.id)\"\n >\n <motion.div\n class=\"card-lightbox__card-content animate-fade-in\"\n :layout-id=\"`card-container-${card.id}`\"\n >\n <motion.div\n class=\"card-lightbox__card-image-container\"\n :layout-id=\"`card-image-container-${card.id}`\"\n >\n <motion.img\n class=\"card-lightbox__card-image\"\n :src=\"card.image\"\n alt=\"\"\n />\n <div class=\"card-lightbox__image-overlay\" />\n </motion.div>\n <motion.div\n class=\"card-lightbox__card-title-container\"\n :layout-id=\"`title-container-${card.id}`\"\n layout=\"position\"\n >\n <span class=\"card-lightbox__card-category\">{{ card.category }}</span>\n <h2 class=\"card-lightbox__card-title\">\n {{ card.title }}\n </h2>\n </motion.div>\n </motion.div>\n </motion.button>\n </ul>\n <AnimatePresence>\n <motion.div\n v-if=\"openId\"\n :initial=\"{ opacity: 0 }\"\n :animate=\"{ opacity: 1 }\"\n :exit=\"{ opacity: 0 }\"\n :transition=\"{ duration: 0.2 }\"\n style=\"pointer-events: auto\"\n class=\"card-lightbox__expanded-overlay\"\n @click=\"close\"\n />\n </AnimatePresence>\n <AnimatePresence>\n <div\n v-if=\"openId\"\n :class=\"[\n 'card-lightbox__expanded-container',\n {\n 'theme-dark': getTheme(openId) === 'dark',\n 'theme-light': getTheme(openId) === 'light'\n }\n ]\"\n >\n <motion.div\n class=\"card-lightbox__expanded-content\"\n :layout-id=\"`card-container-${openId}`\"\n >\n <motion.div\n class=\"card-lightbox__expanded-image-container\"\n :layout-id=\"`card-image-container-${openId}`\"\n >\n <motion.img\n class=\"card-lightbox__expanded-image\"\n :src=\"props.items.find(item => item.id === openId)?.image\"\n alt=\"\"\n :layout-id=\"`card-image-${openId}`\"\n :initial=\"{ opacity: 0, filter: 'blur(12px)' }\"\n :animate=\"{ opacity: 1, filter: 'blur(0px)' }\"\n :exit=\"{ opacity: 0, filter: 'blur(12px)' }\"\n :transition=\"{ duration: 0.5 }\"\n />\n <div class=\"card-lightbox__image-overlay\" />\n <motion.div\n class=\"card-lightbox__expanded-title-container\"\n :layout-id=\"`title-container-${openId}`\"\n layout=\"position\"\n >\n <span class=\"card-lightbox__expanded-category\">{{ props.items.find(item => item.id === openId)?.category }}</span>\n <h2 class=\"card-lightbox__expanded-title\">\n {{ props.items.find(item => item.id === openId)?.title }}\n </h2>\n </motion.div>\n <motion.div\n class=\"card-lightbox__expanded-close-button\"\n @click=\"close\"\n >\n <XIcon />\n </motion.div>\n </motion.div>\n <motion.div class=\"card-lightbox__expanded-body\">\n <div v-html=\"props.items.find(item => item.id === openId)?.content\" />\n </motion.div>\n </motion.div>\n </div>\n </AnimatePresence>\n </div>\n</template>\n\n<style scoped>\n.card-lightbox {\n display: flex;\n width: 100%;\n max-width: 990px;\n flex-direction: column;\n margin: 0 auto;\n container-type: inline-size;\n}\n\n.card-lightbox,\n.card-lightbox * {\n box-sizing: border-box;\n}\n\n.card-lightbox__grid {\n display: grid;\n padding: 0;\n margin: 0;\n gap: 20px;\n grid-template-columns: repeat(10, 1fr);\n list-style: none;\n}\n\n.card-lightbox__card {\n position: relative;\n overflow: hidden;\n height: 420px;\n box-sizing: border-box;\n padding: 0;\n grid-column: span 4;\n}\n\n.card-lightbox__card:focus-visible {\n border-radius: 20px;\n box-shadow:\n 0 0 0 2px hsl(var(--background)),\n 0 0 0 4px hsl(var(--ring));\n outline: none;\n}\n\n.card-lightbox__card:nth-child(4n + 1),\n.card-lightbox__card:nth-child(4n + 4) {\n grid-column: span 6;\n}\n\n.theme-light .card-lightbox__image-overlay {\n position: absolute;\n z-index: 1;\n background: linear-gradient(160deg, rgb(0 0 0 / 95%) -8%, rgb(0 0 0 / 0%) 30%);\n content: '';\n inset: 0;\n pointer-events: none;\n}\n\n.theme-dark .card-lightbox__image-overlay {\n position: absolute;\n z-index: 1;\n background: linear-gradient(160deg, rgb(255 255 255 / 95%) -8%, rgb(255 255 255 / 0%) 30%);\n content: '';\n inset: 0;\n pointer-events: none;\n}\n\n.card-lightbox__expanded-container {\n position: fixed;\n z-index: 51;\n top: 0;\n right: 0;\n left: 0;\n display: flex;\n overflow: hidden;\n width: 100%;\n height: 100%;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 0;\n pointer-events: none;\n}\n\n.card-lightbox__card-content,\n.card-lightbox__expanded-content {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 100%;\n border-radius: 20px;\n margin: 0 auto;\n background: hsl(var(--background));\n pointer-events: auto;\n user-select: none;\n}\n\n.card-lightbox__expanded-content {\n overflow: hidden;\n width: unset;\n max-width: 700px;\n height: 70dvh;\n overflow-y: auto;\n pointer-events: auto;\n}\n\n.card-lightbox__card-image-container,\n.card-lightbox__expanded-image-container {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 420px;\n}\n\n.card-lightbox__card-image,\n.card-lightbox__expanded-image {\n position: absolute;\n z-index: 1;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n pointer-events: none;\n transform: none;\n}\n\n.card-lightbox__card-title-container {\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n max-width: 300px;\n padding: 20px;\n text-align: left;\n}\n\n.card-lightbox__expanded-title-container {\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n padding: 20px;\n}\n\n.card-lightbox__expanded-close-button {\n position: absolute;\n z-index: 2;\n top: 0;\n right: 0;\n padding: 20px;\n cursor: pointer;\n}\n\n.card-lightbox__card-title,\n.card-lightbox__expanded-title {\n margin: 8px 0;\n color: hsl(0deg 0% 100%);\n font-size: 20px;\n font-weight: 600;\n}\n\n.card-lightbox__card-category,\n.card-lightbox__expanded-category {\n padding: 4px 8px;\n border-radius: 12px;\n backdrop-filter: blur(8px);\n background: hsl(0deg 0% 100% / 12%);\n color: hsl(0deg 0% 100%);\n font-size: 12px;\n text-transform: uppercase;\n}\n\n.theme-dark .card-lightbox__card-category,\n.theme-dark .card-lightbox__expanded-category {\n background: hsl(240deg 10% 3.9% / 20%);\n}\n\n.card-lightbox__expanded-overlay {\n position: fixed;\n z-index: 50;\n backdrop-filter: blur(12px);\n background: rgb(0 0 0 / 20%);\n inset: 0;\n will-change: opacity;\n}\n\n.card-lightbox__expanded-body {\n width: 100vw;\n max-width: 700px;\n padding: 35px;\n color: hsl(var(--primary));\n}\n\n.theme-dark .card-lightbox__card-category,\n.theme-dark .card-lightbox__card-title,\n.theme-dark .card-lightbox__expanded-title-container,\n.theme-dark .card-lightbox__expanded-title,\n.theme-dark .card-lightbox__expanded-category {\n color: hsl(240deg 10% 3.9% / 90%);\n}\n\n.theme-dark svg {\n stroke: hsl(240deg 10% 3.9% / 90%);\n}\n\n.theme-light svg {\n stroke: hsl(0deg 0% 100%);\n}\n\n@media only screen and (width <= 990px) {\n .card-lightbox__expanded-container {\n padding: 0;\n }\n\n .card-lightbox__expanded-content {\n overflow: hidden;\n width: 100vw;\n max-width: 100vw;\n height: 100dvh;\n border-radius: 0;\n overflow-y: auto;\n pointer-events: auto;\n }\n\n .card-lightbox__card-image-container,\n .card-lightbox__expanded-image-container {\n height: 280px;\n }\n}\n\n@container (max-width: 600px) {\n #sandbox {\n align-items: stretch;\n }\n\n .card-lightbox {\n padding: 60px 20px;\n padding-right: 10px;\n padding-left: 10px;\n }\n\n .card-lightbox__grid {\n gap: 10px;\n grid-template-columns: 1fr;\n }\n\n .card-lightbox__card {\n width: 100%;\n height: 280px;\n grid-column: auto / auto;\n }\n\n .card-lightbox__card:nth-child(4n + 1),\n .card-lightbox__card:nth-child(4n + 4) {\n grid-column: auto / auto;\n }\n\n .card-lightbox__card-image {\n position: absolute;\n width: 100%;\n height: 100%;\n inset: 0;\n object-fit: cover;\n }\n}\n</style>\n"
10
+ "content": "<script setup lang=\"ts\">\nimport { onMounted, onUnmounted, ref } from 'vue';\nimport { AnimatePresence, motion } from 'motion-v';\nimport type { Item } from './types';\nimport { XIcon } from 'lucide-vue-next';\n\ntype Props = {\n items: Item[];\n};\n\nconst props = defineProps<Props>();\n\nconst openId = ref<string | null>(null);\n\nonMounted(() => {\n document.addEventListener('keydown', handleEscKeydown);\n});\n\nonUnmounted(() => {\n document.removeEventListener('keydown', handleEscKeydown);\n});\n\nfunction getTheme(id: string) {\n return props.items.find(item => item.id === id)?.theme;\n}\n\nfunction open(id: string) {\n openId.value = id;\n}\n\nfunction close() {\n openId.value = null;\n}\n\nfunction handleEscKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n close();\n }\n}\n</script>\n\n<template>\n <div class=\"card-lightbox\">\n <ul class=\"card-lightbox__grid\">\n <motion.button\n v-for=\"card in props.items\"\n :key=\"card.id\"\n :data-open=\"openId === card.id\"\n :class=\"[\n 'card-lightbox__card',\n {\n 'theme-dark': getTheme(card.id) === 'dark',\n 'theme-light': getTheme(card.id) === 'light'\n }\n ]\"\n @click=\"() => open(card.id)\"\n >\n <motion.div\n class=\"card-lightbox__card-content animate-fade-in\"\n :layout-id=\"`card-container-${card.id}`\"\n >\n <motion.div\n class=\"card-lightbox__card-image-container\"\n :layout-id=\"`card-image-container-${card.id}`\"\n >\n <motion.img\n class=\"card-lightbox__card-image\"\n :src=\"card.image\"\n alt=\"\"\n />\n <div class=\"card-lightbox__image-overlay\" />\n </motion.div>\n <motion.div\n class=\"card-lightbox__card-title-container\"\n :layout-id=\"`title-container-${card.id}`\"\n layout=\"position\"\n >\n <span class=\"card-lightbox__card-category\">{{ card.category }}</span>\n <h2 class=\"card-lightbox__card-title\">\n {{ card.title }}\n </h2>\n </motion.div>\n </motion.div>\n </motion.button>\n </ul>\n <AnimatePresence>\n <motion.div\n v-if=\"openId\"\n :initial=\"{ opacity: 0 }\"\n :animate=\"{ opacity: 1 }\"\n :exit=\"{ opacity: 0 }\"\n :transition=\"{ duration: 0.2 }\"\n style=\"pointer-events: auto\"\n class=\"card-lightbox__expanded-overlay\"\n @click=\"close\"\n />\n </AnimatePresence>\n <AnimatePresence>\n <div\n v-if=\"openId\"\n :class=\"[\n 'card-lightbox__expanded-container',\n {\n 'theme-dark': getTheme(openId) === 'dark',\n 'theme-light': getTheme(openId) === 'light'\n }\n ]\"\n >\n <motion.div\n class=\"card-lightbox__expanded-content\"\n :layout-id=\"`card-container-${openId}`\"\n >\n <motion.div\n class=\"card-lightbox__expanded-image-container\"\n :layout-id=\"`card-image-container-${openId}`\"\n >\n <motion.img\n class=\"card-lightbox__expanded-image\"\n :src=\"props.items.find(item => item.id === openId)?.image\"\n alt=\"\"\n :layout-id=\"`card-image-${openId}`\"\n :initial=\"{ opacity: 0, filter: 'blur(12px)' }\"\n :animate=\"{ opacity: 1, filter: 'blur(0px)' }\"\n :exit=\"{ opacity: 0, filter: 'blur(12px)' }\"\n :transition=\"{ duration: 0.5 }\"\n />\n <div class=\"card-lightbox__image-overlay\" />\n <motion.div\n class=\"card-lightbox__expanded-title-container\"\n :layout-id=\"`title-container-${openId}`\"\n layout=\"position\"\n >\n <span class=\"card-lightbox__expanded-category\">{{ props.items.find(item => item.id === openId)?.category }}</span>\n <h2 class=\"card-lightbox__expanded-title\">\n {{ props.items.find(item => item.id === openId)?.title }}\n </h2>\n </motion.div>\n <motion.div\n class=\"card-lightbox__expanded-close-button\"\n @click=\"close\"\n >\n <XIcon />\n </motion.div>\n </motion.div>\n <motion.div class=\"card-lightbox__expanded-body\">\n <div v-html=\"props.items.find(item => item.id === openId)?.content\" />\n </motion.div>\n </motion.div>\n </div>\n </AnimatePresence>\n </div>\n</template>\n\n<style scoped>\n.card-lightbox {\n display: flex;\n width: 100%;\n max-width: 990px;\n flex-direction: column;\n margin: 0 auto;\n container-type: inline-size;\n}\n\n.card-lightbox,\n.card-lightbox * {\n box-sizing: border-box;\n}\n\n.card-lightbox__grid {\n display: grid;\n padding: 0;\n margin: 0;\n gap: 20px;\n grid-template-columns: repeat(10, 1fr);\n list-style: none;\n}\n\n.card-lightbox__card {\n position: relative;\n overflow: hidden;\n height: 420px;\n box-sizing: border-box;\n padding: 0;\n grid-column: span 4;\n}\n\n.card-lightbox__card:focus-visible {\n border-radius: 20px;\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.card-lightbox__card:nth-child(4n + 1),\n.card-lightbox__card:nth-child(4n + 4) {\n grid-column: span 6;\n}\n\n.theme-light .card-lightbox__image-overlay {\n position: absolute;\n z-index: 1;\n background: linear-gradient(160deg, rgb(0 0 0 / 95%) -8%, rgb(0 0 0 / 0%) 30%);\n content: '';\n inset: 0;\n pointer-events: none;\n}\n\n.theme-dark .card-lightbox__image-overlay {\n position: absolute;\n z-index: 1;\n background: linear-gradient(160deg, rgb(255 255 255 / 95%) -8%, rgb(255 255 255 / 0%) 30%);\n content: '';\n inset: 0;\n pointer-events: none;\n}\n\n.card-lightbox__expanded-container {\n position: fixed;\n z-index: 51;\n top: 0;\n right: 0;\n left: 0;\n display: flex;\n overflow: hidden;\n width: 100%;\n height: 100%;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 0;\n pointer-events: none;\n}\n\n.card-lightbox__card-content,\n.card-lightbox__expanded-content {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 100%;\n border-radius: 20px;\n margin: 0 auto;\n background: hsl(var(--background));\n pointer-events: auto;\n user-select: none;\n}\n\n.card-lightbox__expanded-content {\n overflow: hidden;\n width: unset;\n max-width: 700px;\n height: 70dvh;\n overflow-y: auto;\n pointer-events: auto;\n}\n\n.card-lightbox__card-image-container,\n.card-lightbox__expanded-image-container {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 420px;\n}\n\n.card-lightbox__card-image,\n.card-lightbox__expanded-image {\n position: absolute;\n z-index: 1;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n pointer-events: none;\n transform: none;\n}\n\n.card-lightbox__card-title-container {\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n max-width: 300px;\n padding: 20px;\n text-align: left;\n}\n\n.card-lightbox__expanded-title-container {\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n padding: 20px;\n}\n\n.card-lightbox__expanded-close-button {\n position: absolute;\n z-index: 2;\n top: 0;\n right: 0;\n padding: 20px;\n cursor: pointer;\n}\n\n.card-lightbox__card-title,\n.card-lightbox__expanded-title {\n margin: 8px 0;\n color: hsl(0deg 0% 100%);\n font-size: 20px;\n font-weight: 600;\n}\n\n.card-lightbox__card-category,\n.card-lightbox__expanded-category {\n padding: 4px 8px;\n border-radius: 12px;\n backdrop-filter: blur(8px);\n background: hsl(0deg 0% 100% / 12%);\n color: hsl(0deg 0% 100%);\n font-size: 12px;\n text-transform: uppercase;\n}\n\n.theme-dark .card-lightbox__card-category,\n.theme-dark .card-lightbox__expanded-category {\n background: hsl(240deg 10% 3.9% / 20%);\n}\n\n.card-lightbox__expanded-overlay {\n position: fixed;\n z-index: 50;\n backdrop-filter: blur(12px);\n background: rgb(0 0 0 / 20%);\n inset: 0;\n will-change: opacity;\n}\n\n.card-lightbox__expanded-body {\n width: 100vw;\n max-width: 700px;\n padding: 35px;\n color: hsl(var(--primary));\n}\n\n.theme-dark .card-lightbox__card-category,\n.theme-dark .card-lightbox__card-title,\n.theme-dark .card-lightbox__expanded-title-container,\n.theme-dark .card-lightbox__expanded-title,\n.theme-dark .card-lightbox__expanded-category {\n color: hsl(240deg 10% 3.9% / 90%);\n}\n\n.theme-dark svg {\n stroke: hsl(240deg 10% 3.9% / 90%);\n}\n\n.theme-light svg {\n stroke: hsl(0deg 0% 100%);\n}\n\n@media only screen and (width <= 990px) {\n .card-lightbox__expanded-container {\n padding: 0;\n }\n\n .card-lightbox__expanded-content {\n overflow: hidden;\n width: 100vw;\n max-width: 100vw;\n height: 100dvh;\n border-radius: 0;\n overflow-y: auto;\n pointer-events: auto;\n }\n\n .card-lightbox__card-image-container,\n .card-lightbox__expanded-image-container {\n height: 280px;\n }\n}\n\n@container (max-width: 600px) {\n #sandbox {\n align-items: stretch;\n }\n\n .card-lightbox {\n padding: 60px 20px;\n padding-right: 10px;\n padding-left: 10px;\n }\n\n .card-lightbox__grid {\n gap: 10px;\n grid-template-columns: 1fr;\n }\n\n .card-lightbox__card {\n width: 100%;\n height: 280px;\n grid-column: auto / auto;\n }\n\n .card-lightbox__card:nth-child(4n + 1),\n .card-lightbox__card:nth-child(4n + 4) {\n grid-column: auto / auto;\n }\n\n .card-lightbox__card-image {\n position: absolute;\n width: 100%;\n height: 100%;\n inset: 0;\n object-fit: cover;\n }\n}\n</style>\n"
11
11
  },
12
12
  {
13
13
  "name": "index.ts",
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "name": "Checkbox.vue",
8
- "content": "<script setup lang=\"ts\">\nimport type { CheckboxRootEmits, CheckboxRootProps } from 'reka-ui';\nimport { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'reka-ui';\nimport { CheckIcon } from 'lucide-vue-next';\n\ninterface Props extends CheckboxRootProps {\n label?: string;\n description?: string;\n id?: string;\n}\n\nconst props = defineProps<Props>();\nconst emits = defineEmits<CheckboxRootEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <div\n class=\"sigma-ui-checkbox-wrapper\"\n :class=\"[{ 'sigma-ui-checkbox-wrapper--flex-start': props.description }]\"\n >\n <CheckboxRoot\n v-bind=\"forwarded\"\n :id=\"(props.label && props.id) || forwarded.id\"\n class=\"sigma-ui-checkbox\"\n >\n <transition name=\"fade-slide-top\">\n <CheckboxIndicator class=\"sigma-ui-checkbox__indicator\">\n <slot>\n <CheckIcon class=\"sigma-ui-checkbox__icon\" />\n </slot>\n </CheckboxIndicator>\n </transition>\n </CheckboxRoot>\n <div\n v-if=\"props.label\"\n class=\"sigma-ui-checkbox__content\"\n >\n <label\n v-if=\"props.label\"\n class=\"sigma-ui-checkbox__label\"\n :for=\"props.id\"\n >{{ props.label }}\n </label>\n <p\n v-if=\"props.description\"\n class=\"sigma-ui-checkbox__description\"\n >\n {{ props.description }}\n </p>\n </div>\n </div>\n</template>\n\n<style>\n.sigma-ui-checkbox-wrapper {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.sigma-ui-checkbox-wrapper--flex-start {\n align-items: flex-start;\n}\n\n.sigma-ui-checkbox {\n overflow: hidden;\n width: 1rem;\n height: 1rem;\n flex-shrink: 0;\n border: 1px solid hsl(var(--primary));\n border-radius: var(--radius-xs);\n background-color: hsl(var(--background));\n}\n\n.sigma-ui-checkbox:focus-visible {\n box-shadow:\n 0 0 0 2px hsl(var(--background)),\n 0 0 0 4px hsl(var(--ring));\n outline: none;\n}\n\n.sigma-ui-checkbox:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-checkbox[data-state=\"checked\"] {\n background-color: hsl(var(--primary));\n color: hsl(var(--primary-foreground));\n}\n\n.sigma-ui-checkbox__indicator {\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n justify-content: center;\n color: currentcolor;\n}\n\n.sigma-ui-checkbox__content {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n line-height: 1;\n}\n\n.sigma-ui-checkbox__label {\n font-size: 0.875rem;\n font-weight: 500;\n line-height: 1;\n user-select: none;\n}\n\n.sigma-ui-checkbox:disabled + .sigma-ui-checkbox__content .sigma-ui-checkbox__label,\n.sigma-ui-checkbox:disabled + .sigma-ui-checkbox__content .sigma-ui-checkbox__description {\n opacity: 0.7;\n}\n\n.sigma-ui-checkbox__description {\n color: hsl(var(--muted-foreground));\n font-size: 0.875rem;\n line-height: 1.25rem;\n user-select: none;\n}\n</style>\n"
8
+ "content": "<script setup lang=\"ts\">\nimport type { CheckboxRootEmits, CheckboxRootProps } from 'reka-ui';\nimport { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'reka-ui';\nimport { CheckIcon } from 'lucide-vue-next';\n\ninterface Props extends CheckboxRootProps {\n label?: string;\n description?: string;\n id?: string;\n}\n\nconst props = defineProps<Props>();\nconst emits = defineEmits<CheckboxRootEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <div\n class=\"sigma-ui-checkbox-wrapper\"\n :class=\"[{ 'sigma-ui-checkbox-wrapper--flex-start': props.description }]\"\n >\n <CheckboxRoot\n v-bind=\"forwarded\"\n :id=\"(props.label && props.id) || forwarded.id\"\n class=\"sigma-ui-checkbox\"\n >\n <transition name=\"fade-slide-top\">\n <CheckboxIndicator class=\"sigma-ui-checkbox__indicator\">\n <slot>\n <CheckIcon class=\"sigma-ui-checkbox__icon\" />\n </slot>\n </CheckboxIndicator>\n </transition>\n </CheckboxRoot>\n <div\n v-if=\"props.label\"\n class=\"sigma-ui-checkbox__content\"\n >\n <label\n v-if=\"props.label\"\n class=\"sigma-ui-checkbox__label\"\n :for=\"props.id\"\n >{{ props.label }}\n </label>\n <p\n v-if=\"props.description\"\n class=\"sigma-ui-checkbox__description\"\n >\n {{ props.description }}\n </p>\n </div>\n </div>\n</template>\n\n<style>\n.sigma-ui-checkbox-wrapper {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.sigma-ui-checkbox-wrapper--flex-start {\n align-items: flex-start;\n}\n\n.sigma-ui-checkbox {\n overflow: hidden;\n width: 1rem;\n height: 1rem;\n flex-shrink: 0;\n border: 1px solid hsl(var(--primary));\n border-radius: var(--radius-xs);\n background-color: hsl(var(--background));\n}\n\n.sigma-ui-checkbox:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-checkbox:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-checkbox[data-state=\"checked\"] {\n background-color: hsl(var(--primary));\n color: hsl(var(--primary-foreground));\n}\n\n.sigma-ui-checkbox__indicator {\n display: flex;\n width: 100%;\n height: 100%;\n align-items: center;\n justify-content: center;\n color: currentcolor;\n}\n\n.sigma-ui-checkbox__content {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n line-height: 1;\n}\n\n.sigma-ui-checkbox__label {\n font-size: 0.875rem;\n font-weight: 500;\n line-height: 1;\n user-select: none;\n}\n\n.sigma-ui-checkbox:disabled + .sigma-ui-checkbox__content .sigma-ui-checkbox__label,\n.sigma-ui-checkbox:disabled + .sigma-ui-checkbox__content .sigma-ui-checkbox__description {\n opacity: 0.7;\n}\n\n.sigma-ui-checkbox__description {\n color: hsl(var(--muted-foreground));\n font-size: 0.875rem;\n line-height: 1.25rem;\n user-select: none;\n}\n</style>\n"
9
9
  },
10
10
  {
11
11
  "name": "index.ts",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  {
25
25
  "name": "ComboboxInput.vue",
26
- "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue';\nimport { reactiveOmit } from '@vueuse/core';\nimport { ComboboxInput, type ComboboxInputEmits, type ComboboxInputProps, useForwardPropsEmits } from 'reka-ui';\n\nconst props = defineProps<ComboboxInputProps & {\n class?: HTMLAttributes['class'];\n}>();\n\nconst emits = defineEmits<ComboboxInputEmits>();\n\nconst delegatedProps = reactiveOmit(props, 'class');\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits);\n</script>\n\n<template>\n <ComboboxInput\n v-bind=\"forwarded\"\n :class=\"['sigma-ui-combobox-input', props.class]\"\n >\n <slot />\n </ComboboxInput>\n</template>\n\n<style>\n.sigma-ui-combobox-input {\n display: flex;\n width: 100%;\n height: 2.25rem;\n padding: 0.25rem 0.75rem;\n border: 1px solid hsl(var(--border));\n border-radius: 0.375rem;\n background-color: transparent;\n font-size: 0.875rem;\n line-height: 1.25rem;\n transition-duration: 150ms;\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-combobox-input:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));\n outline: none;\n}\n\n.sigma-ui-combobox-input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-combobox-input::file-selector-button {\n border: 0;\n background-color: transparent;\n font-size: 0.875rem;\n font-weight: 500;\n}\n\n.sigma-ui-combobox-input::placeholder {\n color: hsl(var(--muted-foreground));\n}\n</style>\n"
26
+ "content": "<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue';\nimport { reactiveOmit } from '@vueuse/core';\nimport { ComboboxInput, type ComboboxInputEmits, type ComboboxInputProps, useForwardPropsEmits } from 'reka-ui';\n\nconst props = defineProps<ComboboxInputProps & {\n class?: HTMLAttributes['class'];\n}>();\n\nconst emits = defineEmits<ComboboxInputEmits>();\n\nconst delegatedProps = reactiveOmit(props, 'class');\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits);\n</script>\n\n<template>\n <ComboboxInput\n v-bind=\"forwarded\"\n :class=\"['sigma-ui-combobox-input', props.class]\"\n >\n <slot />\n </ComboboxInput>\n</template>\n\n<style>\n.sigma-ui-combobox-input {\n display: flex;\n width: 100%;\n height: 2.25rem;\n padding: 0.25rem 0.75rem;\n border: 1px solid hsl(var(--border));\n border-radius: 0.375rem;\n background-color: transparent;\n font-size: 0.875rem;\n line-height: 1.25rem;\n transition-duration: 150ms;\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-combobox-input:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-combobox-input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-combobox-input::file-selector-button {\n border: 0;\n background-color: transparent;\n font-size: 0.875rem;\n font-weight: 500;\n}\n\n.sigma-ui-combobox-input::placeholder {\n color: hsl(var(--muted-foreground));\n}\n</style>\n"
27
27
  },
28
28
  {
29
29
  "name": "ComboboxItem.vue",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  {
15
15
  "name": "DialogContent.vue",
16
- "content": "<script setup lang=\"ts\">\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui';\nimport { XIcon } from 'lucide-vue-next';\n\nconst props = defineProps<DialogContentProps>();\nconst emits = defineEmits<DialogContentEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay class=\"sigma-ui-dialog-overlay\" />\n <DialogContent\n v-bind=\"forwarded\"\n class=\"sigma-ui-dialog-content\"\n :class=\"[$attrs.class]\"\n >\n <slot />\n\n <DialogClose class=\"sigma-ui-dialog-close\">\n <XIcon class=\"sigma-ui-dialog-close__icon\" />\n <span class=\"sigma-ui-dialog-close__label\">Close</span>\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n\n<style>\n.sigma-ui-dialog-overlay {\n position: fixed;\n z-index: 50;\n animation: sigma-ui-fade-in 0.2s ease-out;\n background-color: rgb(0 0 0 / 80%);\n inset: 0;\n}\n\n.sigma-ui-dialog-overlay[data-state=\"open\"] {\n animation: sigma-ui-fade-in 0.2s ease-out;\n}\n\n.sigma-ui-dialog-overlay[data-state=\"closed\"] {\n animation: sigma-ui-fade-out 0.2s ease-in;\n}\n\n.sigma-ui-dialog-content {\n position: fixed;\n z-index: 50;\n top: 50%;\n left: 50%;\n display: grid;\n width: 100%;\n max-width: 32rem;\n padding: 1.5rem;\n border: 1px solid hsl(var(--border));\n background-color: hsl(var(--background));\n box-shadow: var(--shadow-lg);\n gap: 1rem;\n transform: translate(-50%, -50%);\n transition-duration: 200ms;\n}\n\n.sigma-ui-dialog-content[data-state=\"open\"] {\n animation: sigma-ui-dialog-show 0.2s ease-out;\n}\n\n.sigma-ui-dialog-content[data-state=\"closed\"] {\n animation: sigma-ui-dialog-hide 0.2s ease-in;\n}\n\n.sigma-ui-dialog-close {\n position: absolute;\n top: 1rem;\n right: 1rem;\n border-radius: var(--radius-sm);\n opacity: 0.7;\n transition-duration: 150ms;\n transition-property: opacity;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-dialog-close:hover {\n opacity: 1;\n}\n\n.sigma-ui-dialog-close:focus {\n box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));\n outline: none;\n}\n\n.sigma-ui-dialog-close[data-state=\"open\"] {\n background-color: hsl(var(--secondary));\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-dialog-close:disabled {\n pointer-events: none;\n}\n\n.sigma-ui-dialog-close__icon {\n width: 1rem;\n height: 1rem;\n}\n\n.sigma-ui-dialog-close__label {\n position: absolute;\n overflow: hidden;\n width: 1px;\n height: 1px;\n padding: 0;\n border-width: 0;\n margin: -1px;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n}\n\n@keyframes sigma-ui-dialog-show {\n from {\n opacity: 0;\n transform: translate(-50%, -48%) scale(0.95);\n }\n\n to {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n }\n}\n\n@keyframes sigma-ui-dialog-hide {\n from {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n }\n\n to {\n opacity: 0;\n transform: translate(-50%, -48%) scale(0.95);\n }\n}\n\n@media (width >= 640px) {\n .sigma-ui-dialog-content {\n border-radius: var(--radius-lg);\n }\n}\n</style>\n"
16
+ "content": "<script setup lang=\"ts\">\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui';\nimport { XIcon } from 'lucide-vue-next';\n\nconst props = defineProps<DialogContentProps>();\nconst emits = defineEmits<DialogContentEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay class=\"sigma-ui-dialog-overlay\" />\n <DialogContent\n v-bind=\"forwarded\"\n class=\"sigma-ui-dialog-content\"\n :class=\"[$attrs.class]\"\n >\n <slot />\n\n <DialogClose class=\"sigma-ui-dialog-close\">\n <XIcon class=\"sigma-ui-dialog-close__icon\" />\n <span class=\"sigma-ui-dialog-close__label\">Close</span>\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n\n<style>\n.sigma-ui-dialog-overlay {\n position: fixed;\n z-index: 50;\n animation: sigma-ui-fade-in 0.2s ease-out;\n background-color: rgb(0 0 0 / 80%);\n inset: 0;\n}\n\n.sigma-ui-dialog-overlay[data-state=\"open\"] {\n animation: sigma-ui-fade-in 0.2s ease-out;\n}\n\n.sigma-ui-dialog-overlay[data-state=\"closed\"] {\n animation: sigma-ui-fade-out 0.2s ease-in;\n}\n\n.sigma-ui-dialog-content {\n position: fixed;\n z-index: 50;\n top: 50%;\n left: 50%;\n display: grid;\n width: 100%;\n max-width: 32rem;\n padding: 1.5rem;\n border: 1px solid hsl(var(--border));\n background-color: hsl(var(--background));\n box-shadow: var(--shadow-lg);\n gap: 1rem;\n transform: translate(-50%, -50%);\n transition-duration: 200ms;\n}\n\n.sigma-ui-dialog-content[data-state=\"open\"] {\n animation: sigma-ui-dialog-show 0.2s ease-out;\n}\n\n.sigma-ui-dialog-content[data-state=\"closed\"] {\n animation: sigma-ui-dialog-hide 0.2s ease-in;\n}\n\n.sigma-ui-dialog-close {\n position: absolute;\n top: 1rem;\n right: 1rem;\n border-radius: var(--radius-sm);\n opacity: 0.7;\n transition-duration: 150ms;\n transition-property: opacity;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-dialog-close:hover {\n opacity: 1;\n}\n\n.sigma-ui-dialog-close:focus {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-dialog-close[data-state=\"open\"] {\n background-color: hsl(var(--secondary));\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-dialog-close:disabled {\n pointer-events: none;\n}\n\n.sigma-ui-dialog-close__icon {\n width: 1rem;\n height: 1rem;\n}\n\n.sigma-ui-dialog-close__label {\n position: absolute;\n overflow: hidden;\n width: 1px;\n height: 1px;\n padding: 0;\n border-width: 0;\n margin: -1px;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n}\n\n@keyframes sigma-ui-dialog-show {\n from {\n opacity: 0;\n transform: translate(-50%, -48%) scale(0.95);\n }\n\n to {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n }\n}\n\n@keyframes sigma-ui-dialog-hide {\n from {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n }\n\n to {\n opacity: 0;\n transform: translate(-50%, -48%) scale(0.95);\n }\n}\n\n@media (width >= 640px) {\n .sigma-ui-dialog-content {\n border-radius: var(--radius-lg);\n }\n}\n</style>\n"
17
17
  },
18
18
  {
19
19
  "name": "DialogDescription.vue",
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "faceted-filter",
3
+ "dependencies": [],
4
+ "registryDependencies": [],
5
+ "files": [
6
+ {
7
+ "name": "FacetedFilter.vue",
8
+ "content": "<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport { CheckIcon, CirclePlusIcon } from 'lucide-vue-next';\nimport { Button } from '@ui/registry/css/ui/button';\nimport { Popover, PopoverContent, PopoverTrigger } from '@ui/registry/css/ui/popover';\nimport { Separator } from '@ui/registry/css/ui/separator';\nimport {\n Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator,\n} from '@ui/registry/css/ui/command';\n\nconst props = withDefaults(defineProps<{\n title: string;\n options: string[];\n modelValue: string[];\n maxBadges?: number;\n allowCreate?: boolean;\n minWidth?: number;\n}>(), {\n maxBadges: 2,\n allowCreate: false,\n minWidth: 200,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string[]];\n 'create': [value: string];\n}>();\n\nconst searchQuery = ref('');\nconst commandKey = ref(0);\n\nconst trimmedSearchQuery = computed(() => searchQuery.value.trim());\nconst selectedValues = computed(() => new Set(props.modelValue));\nconst filteredOptions = computed(() => {\n const normalizedSearch = searchQuery.value.trim().toLowerCase();\n if (!normalizedSearch) return props.options;\n return props.options.filter(option => option.toLowerCase().includes(normalizedSearch));\n});\n\nconst canCreate = computed(() => {\n if (!props.allowCreate) return false;\n const value = trimmedSearchQuery.value;\n if (value.length === 0) return false;\n const normalizedValue = value.toLowerCase();\n return !props.options.some(option => option.toLowerCase() === normalizedValue);\n});\n\nconst selectedBadges = computed(() => {\n return props.options.filter(option => selectedValues.value.has(option)).slice(0, props.maxBadges);\n});\n\nconst contentStyle = computed(() => props.minWidth ? ({ minWidth: `${props.minWidth}px` }) : undefined);\n\nfunction toggleValue(value: string) {\n const next = new Set(props.modelValue);\n if (next.has(value)) next.delete(value);\n else next.add(value);\n emit('update:modelValue', Array.from(next));\n}\n\nfunction createFromSearchQuery() {\n const value = trimmedSearchQuery.value;\n if (!value) return;\n emit('create', value);\n clearSearch();\n commandKey.value += 1;\n}\n\nfunction clearSearch() {\n searchQuery.value = '';\n}\n</script>\n\n<template>\n <Popover>\n <PopoverTrigger as-child>\n <Button\n variant=\"outline\"\n size=\"xs\"\n class=\"sigma-ui-faceted-filter__trigger\"\n >\n <CirclePlusIcon class=\"sigma-ui-faceted-filter__trigger-icon\" />\n {{ props.title }}\n <template v-if=\"selectedValues.size > 0\">\n <Separator\n orientation=\"vertical\"\n class=\"sigma-ui-faceted-filter__separator\"\n />\n <span class=\"sigma-ui-faceted-filter__count\">\n {{ selectedValues.size }}\n </span>\n <div class=\"sigma-ui-faceted-filter__badges\">\n <span\n v-for=\"badge in selectedBadges\"\n :key=\"badge\"\n class=\"sigma-ui-faceted-filter__badge\"\n >\n {{ badge }}\n </span>\n <span\n v-if=\"selectedValues.size > props.maxBadges\"\n class=\"sigma-ui-faceted-filter__badge\"\n >\n +{{ selectedValues.size - props.maxBadges }}\n </span>\n </div>\n </template>\n </Button>\n </PopoverTrigger>\n\n <PopoverContent\n class=\"sigma-ui-faceted-filter__content\"\n align=\"start\"\n :style=\"contentStyle\"\n >\n <Command :key=\"commandKey\">\n <CommandInput\n v-model=\"searchQuery\"\n :placeholder=\"props.title\"\n @keydown.esc=\"clearSearch\"\n />\n <CommandList>\n <CommandEmpty v-if=\"filteredOptions.length === 0 && !canCreate\">\n No results found.\n </CommandEmpty>\n <div\n v-if=\"canCreate\"\n class=\"sigma-ui-faceted-filter__empty-create\"\n >\n <Button\n variant=\"outline\"\n size=\"sm\"\n class=\"sigma-ui-faceted-filter__empty-create-button\"\n @click=\"createFromSearchQuery\"\n >\n <CirclePlusIcon class=\"sigma-ui-faceted-filter__empty-create-icon\" />\n Add {{ trimmedSearchQuery }}\n </Button>\n </div>\n <CommandGroup>\n <CommandItem\n v-for=\"option in filteredOptions\"\n :key=\"option\"\n :value=\"option\"\n @select=\"() => toggleValue(option)\"\n >\n <div\n class=\"sigma-ui-faceted-filter__checkbox\"\n :data-selected=\"selectedValues.has(option) || undefined\"\n >\n <CheckIcon class=\"sigma-ui-faceted-filter__check\" />\n </div>\n <span class=\"sigma-ui-faceted-filter__option-text\">{{ option }}</span>\n </CommandItem>\n </CommandGroup>\n <CommandSeparator v-if=\"$slots.footer\" />\n <div\n v-if=\"$slots.footer\"\n class=\"sigma-ui-faceted-filter__footer\"\n >\n <slot name=\"footer\" />\n </div>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n</template>\n\n<style>\n.sigma-ui-faceted-filter__trigger {\n gap: 0.5rem;\n border-style: dashed;\n}\n\n.sigma-ui-faceted-filter__trigger-icon {\n width: 0.875rem;\n height: 0.875rem;\n}\n\n.sigma-ui-faceted-filter__separator {\n height: 0.875rem;\n margin: 0 0.375rem;\n}\n\n.sigma-ui-faceted-filter__count {\n display: inline-flex;\n height: 1rem;\n align-items: center;\n justify-content: center;\n padding: 0 0.375rem;\n border-radius: 0.375rem;\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n font-size: 0.6875rem;\n}\n\n.sigma-ui-faceted-filter__badges {\n display: none;\n gap: 0.375rem;\n}\n\n.sigma-ui-faceted-filter__badge {\n display: inline-flex;\n height: 1rem;\n align-items: center;\n justify-content: center;\n padding: 0 0.375rem;\n border-radius: 0.375rem;\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n font-size: 0.6875rem;\n}\n\n.sigma-ui-faceted-filter__content {\n width: 20rem;\n padding: 0;\n}\n\n.sigma-ui-faceted-filter__empty-create {\n padding: 0.625rem;\n}\n\n.sigma-ui-faceted-filter__empty-create-button {\n width: 100%;\n gap: 0.5rem;\n justify-content: flex-start;\n}\n\n.sigma-ui-faceted-filter__empty-create-icon {\n width: 1rem;\n height: 1rem;\n}\n\n.sigma-ui-faceted-filter__checkbox {\n display: flex;\n width: 1rem;\n height: 1rem;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n border: 1px solid hsl(var(--border));\n border-radius: 0.25rem;\n margin-right: 0.625rem;\n opacity: 0.6;\n}\n\n.sigma-ui-faceted-filter__checkbox:not([data-selected]) .sigma-ui-faceted-filter__check {\n visibility: hidden;\n}\n\n.sigma-ui-faceted-filter__checkbox[data-selected] {\n border-color: hsl(var(--primary) / 60%);\n background: hsl(var(--primary) / 15%);\n opacity: 1;\n}\n\n.sigma-ui-faceted-filter__check {\n width: 0.875rem;\n height: 0.875rem;\n color: hsl(var(--primary));\n}\n\n.sigma-ui-faceted-filter__option-text {\n overflow: hidden;\n text-overflow: ellipsis;\n user-select: text;\n white-space: nowrap;\n}\n\n.sigma-ui-faceted-filter__footer {\n padding: 0.625rem 0.625rem 0.75rem;\n}\n\n@media (width >= 1024px) {\n .sigma-ui-faceted-filter__badges {\n display: flex;\n }\n\n .sigma-ui-faceted-filter__count {\n display: none;\n }\n}\n</style>\n"
9
+ },
10
+ {
11
+ "name": "index.ts",
12
+ "content": "export { default as FacetedFilter } from './FacetedFilter.vue';\n"
13
+ }
14
+ ],
15
+ "type": "components:ui"
16
+ }
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "name": "Input.vue",
8
- "content": "<script setup lang=\"ts\">\n\nconst model = defineModel<string | number>();\n</script>\n\n<template>\n <input\n v-model=\"model\"\n class=\"sigma-ui-input\"\n :class=\"[$attrs.class]\"\n autocomplete=\"off\"\n >\n</template>\n\n<style>\n.sigma-ui-input {\n display: flex;\n width: 100%;\n height: 2.5rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-md);\n background-color: hsl(var(--input));\n font-size: 0.875rem;\n padding-block: 0.5rem;\n padding-inline: 0.75rem;\n}\n\n.sigma-ui-input::file-selector-button {\n border: 0;\n background-color: transparent;\n font-size: 0.875rem;\n font-weight: 500;\n}\n\n.sigma-ui-input::placeholder {\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-input:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--background)),\n 0 0 0 4px hsl(var(--ring));\n outline: none;\n}\n\n.sigma-ui-input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n</style>\n"
8
+ "content": "<script setup lang=\"ts\">\n\nconst model = defineModel<string | number>();\n</script>\n\n<template>\n <input\n v-model=\"model\"\n class=\"sigma-ui-input\"\n :class=\"[$attrs.class]\"\n autocomplete=\"off\"\n >\n</template>\n\n<style>\n.sigma-ui-input {\n display: flex;\n width: 100%;\n height: 2.5rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-md);\n background-color: hsl(var(--input));\n font-size: 0.875rem;\n padding-block: 0.5rem;\n padding-inline: 0.75rem;\n}\n\n.sigma-ui-input::file-selector-button {\n border: 0;\n background-color: transparent;\n font-size: 0.875rem;\n font-weight: 500;\n}\n\n.sigma-ui-input::placeholder {\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-input:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n</style>\n"
9
9
  },
10
10
  {
11
11
  "name": "index.ts",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  {
23
23
  "name": "NumberFieldInput.vue",
24
- "content": "<script setup lang=\"ts\">\nimport { NumberFieldInput } from 'reka-ui';\n</script>\n\n<template>\n <NumberFieldInput\n data-slot=\"input\"\n class=\"sigma-ui-number-field-input\"\n />\n</template>\n\n<style>\n.sigma-ui-number-field-input {\n display: flex;\n width: 100%;\n height: 2.5rem;\n padding: 0.5rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius);\n background-color: transparent;\n font-size: 0.875rem;\n text-align: center;\n}\n\n.sigma-ui-number-field-input::placeholder {\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-number-field-input:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));\n outline: none;\n}\n\n.sigma-ui-number-field-input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n</style>\n"
24
+ "content": "<script setup lang=\"ts\">\nimport { NumberFieldInput } from 'reka-ui';\n</script>\n\n<template>\n <NumberFieldInput\n data-slot=\"input\"\n class=\"sigma-ui-number-field-input\"\n />\n</template>\n\n<style>\n.sigma-ui-number-field-input {\n display: flex;\n width: 100%;\n height: 2.5rem;\n padding: 0.5rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius);\n background-color: transparent;\n font-size: 0.875rem;\n text-align: center;\n}\n\n.sigma-ui-number-field-input::placeholder {\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-number-field-input:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-number-field-input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n</style>\n"
25
25
  },
26
26
  {
27
27
  "name": "index.ts",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  {
15
15
  "name": "PinInputInput.vue",
16
- "content": "<script setup lang=\"ts\">\nimport { PinInputInput, type PinInputInputProps, useForwardProps } from 'reka-ui';\n\nconst props = defineProps<PinInputInputProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <PinInputInput\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-pin-input-input\"\n />\n</template>\n\n<style>\n.sigma-ui-pin-input-input {\n position: relative;\n display: flex;\n width: 2.5rem;\n height: 2.5rem;\n align-items: center;\n justify-content: center;\n border: 1px solid hsl(var(--input));\n border-left: none;\n font-size: 0.875rem;\n text-align: center;\n transition: all 150ms;\n}\n\n.sigma-ui-pin-input-input:first-child {\n border-left: 1px solid hsl(var(--input));\n border-bottom-left-radius: 0.375rem;\n border-top-left-radius: 0.375rem;\n}\n\n.sigma-ui-pin-input-input:last-child {\n border-bottom-right-radius: 0.375rem;\n border-top-right-radius: 0.375rem;\n}\n\n.sigma-ui-pin-input-input:focus {\n position: relative;\n z-index: 10;\n box-shadow: 0 0 0 2px hsl(var(--ring));\n outline: none;\n}\n</style>\n"
16
+ "content": "<script setup lang=\"ts\">\nimport { PinInputInput, type PinInputInputProps, useForwardProps } from 'reka-ui';\n\nconst props = defineProps<PinInputInputProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <PinInputInput\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-pin-input-input\"\n />\n</template>\n\n<style>\n.sigma-ui-pin-input-input {\n position: relative;\n display: flex;\n width: 2.5rem;\n height: 2.5rem;\n align-items: center;\n justify-content: center;\n border: 1px solid hsl(var(--input));\n border-left: none;\n font-size: 0.875rem;\n text-align: center;\n transition: all 150ms;\n}\n\n.sigma-ui-pin-input-input:first-child {\n border-left: 1px solid hsl(var(--input));\n border-bottom-left-radius: 0.375rem;\n border-top-left-radius: 0.375rem;\n}\n\n.sigma-ui-pin-input-input:last-child {\n border-bottom-right-radius: 0.375rem;\n border-top-right-radius: 0.375rem;\n}\n\n.sigma-ui-pin-input-input:focus {\n position: relative;\n z-index: 10;\n outline: 2px solid hsl(var(--ring));\n outline-offset: -1px;\n}\n</style>\n"
17
17
  },
18
18
  {
19
19
  "name": "PinInputSeparator.vue",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "name": "RadioGroupItem.vue",
12
- "content": "<script setup lang=\"ts\">\nimport {\n RadioGroupIndicator,\n RadioGroupItem,\n type RadioGroupItemProps,\n useForwardProps,\n} from 'reka-ui';\nimport { CircleIcon } from 'lucide-vue-next';\n\nconst props = defineProps<RadioGroupItemProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <RadioGroupItem\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-radio-group-item\"\n >\n <RadioGroupIndicator\n class=\"sigma-ui-radio-group-item__indicator\"\n >\n <CircleIcon class=\"sigma-ui-radio-group-item__icon\" />\n </RadioGroupIndicator>\n </RadioGroupItem>\n</template>\n\n<style>\n.sigma-ui-radio-group-item {\n width: 1rem;\n height: 1rem;\n border: 1px solid hsl(var(--primary));\n border-radius: var(--radius-full);\n aspect-ratio: 1;\n background-color: transparent;\n color: hsl(var(--primary));\n transition: all 150ms ease-out;\n}\n\n.sigma-ui-radio-group-item:focus {\n outline: none;\n}\n\n.sigma-ui-radio-group-item:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--background)),\n 0 0 0 4px hsl(var(--ring));\n}\n\n.sigma-ui-radio-group-item:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-radio-group-item__indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sigma-ui-radio-group-item__icon {\n width: 0.625rem;\n height: 0.625rem;\n color: currentcolor;\n fill: currentcolor;\n}\n\n.sigma-ui-radio-group-item[data-state=\"checked\"] .sigma-ui-radio-group-item__icon {\n animation: sigma-ui-radio-check 150ms ease-out;\n}\n\n.sigma-ui-radio-group-item[data-state=\"unchecked\"] .sigma-ui-radio-group-item__icon {\n animation: sigma-ui-radio-uncheck 150ms ease-in;\n}\n\n@keyframes sigma-ui-radio-check {\n from {\n filter: blur(4px);\n opacity: 0;\n transform: scale(0.8);\n }\n\n to {\n filter: blur(0);\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes sigma-ui-radio-uncheck {\n from {\n filter: blur(0);\n opacity: 1;\n transform: scale(1);\n }\n\n to {\n filter: blur(4px);\n opacity: 0;\n transform: scale(0.8);\n }\n}\n</style>\n"
12
+ "content": "<script setup lang=\"ts\">\nimport {\n RadioGroupIndicator,\n RadioGroupItem,\n type RadioGroupItemProps,\n useForwardProps,\n} from 'reka-ui';\nimport { CircleIcon } from 'lucide-vue-next';\n\nconst props = defineProps<RadioGroupItemProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <RadioGroupItem\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-radio-group-item\"\n >\n <RadioGroupIndicator\n class=\"sigma-ui-radio-group-item__indicator\"\n >\n <CircleIcon class=\"sigma-ui-radio-group-item__icon\" />\n </RadioGroupIndicator>\n </RadioGroupItem>\n</template>\n\n<style>\n.sigma-ui-radio-group-item {\n width: 1rem;\n height: 1rem;\n border: 1px solid hsl(var(--primary));\n border-radius: var(--radius-full);\n aspect-ratio: 1;\n background-color: transparent;\n color: hsl(var(--primary));\n transition: all 150ms ease-out;\n}\n\n.sigma-ui-radio-group-item:focus {\n outline: none;\n}\n\n.sigma-ui-radio-group-item:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-radio-group-item:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-radio-group-item__indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sigma-ui-radio-group-item__icon {\n width: 0.625rem;\n height: 0.625rem;\n color: currentcolor;\n fill: currentcolor;\n}\n\n.sigma-ui-radio-group-item[data-state=\"checked\"] .sigma-ui-radio-group-item__icon {\n animation: sigma-ui-radio-check 150ms ease-out;\n}\n\n.sigma-ui-radio-group-item[data-state=\"unchecked\"] .sigma-ui-radio-group-item__icon {\n animation: sigma-ui-radio-uncheck 150ms ease-in;\n}\n\n@keyframes sigma-ui-radio-check {\n from {\n filter: blur(4px);\n opacity: 0;\n transform: scale(0.8);\n }\n\n to {\n filter: blur(0);\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes sigma-ui-radio-uncheck {\n from {\n filter: blur(0);\n opacity: 1;\n transform: scale(1);\n }\n\n to {\n filter: blur(4px);\n opacity: 0;\n transform: scale(0.8);\n }\n}\n</style>\n"
13
13
  },
14
14
  {
15
15
  "name": "index.ts",
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "name": "ResizableHandle.vue",
8
- "content": "<script setup lang=\"ts\">\nimport { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'reka-ui';\nimport { GripVerticalIcon } from 'lucide-vue-next';\n\nconst props = defineProps<SplitterResizeHandleProps & { withHandle?: boolean }>();\nconst emits = defineEmits<SplitterResizeHandleEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <SplitterResizeHandle\n v-bind=\"forwarded\"\n class=\"sigma-ui-resizable-handle\"\n >\n <template v-if=\"props.withHandle\">\n <div class=\"sigma-ui-resizable-handle__grip\">\n <GripVerticalIcon class=\"sigma-ui-resizable-handle__grip-icon\" />\n </div>\n </template>\n </SplitterResizeHandle>\n</template>\n\n<style>\n.sigma-ui-resizable-handle {\n position: relative;\n display: flex;\n width: 1px;\n align-items: center;\n justify-content: center;\n background-color: hsl(var(--border));\n}\n\n.sigma-ui-resizable-handle::after {\n position: absolute;\n left: 50%;\n width: 4px;\n content: '';\n inset-block: 0;\n transform: translateX(-50%);\n}\n\n.sigma-ui-resizable-handle:focus-visible {\n box-shadow: 0 0 0 1px hsl(var(--ring)), 0 0 0 2px hsl(var(--background));\n outline: none;\n}\n\n.sigma-ui-resizable-handle[data-orientation=\"vertical\"] {\n width: 100%;\n height: 1px;\n}\n\n.sigma-ui-resizable-handle[data-orientation=\"vertical\"]::after {\n left: 0;\n width: 100%;\n height: 4px;\n transform: translateY(-50%);\n}\n\n.sigma-ui-resizable-handle[data-orientation=\"vertical\"] > div {\n transform: rotate(90deg);\n}\n\n.sigma-ui-resizable-handle__grip {\n z-index: 10;\n display: flex;\n width: 0.75rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-sm);\n background-color: hsl(var(--border));\n}\n\n.sigma-ui-resizable-handle__grip-icon {\n width: 0.625rem;\n height: 0.625rem;\n}\n</style>\n"
8
+ "content": "<script setup lang=\"ts\">\nimport { SplitterResizeHandle, type SplitterResizeHandleEmits, type SplitterResizeHandleProps, useForwardPropsEmits } from 'reka-ui';\nimport { GripVerticalIcon } from 'lucide-vue-next';\n\nconst props = defineProps<SplitterResizeHandleProps & { withHandle?: boolean }>();\nconst emits = defineEmits<SplitterResizeHandleEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <SplitterResizeHandle\n v-bind=\"forwarded\"\n class=\"sigma-ui-resizable-handle\"\n >\n <template v-if=\"props.withHandle\">\n <div class=\"sigma-ui-resizable-handle__grip\">\n <GripVerticalIcon class=\"sigma-ui-resizable-handle__grip-icon\" />\n </div>\n </template>\n </SplitterResizeHandle>\n</template>\n\n<style>\n.sigma-ui-resizable-handle {\n position: relative;\n display: flex;\n width: 1px;\n align-items: center;\n justify-content: center;\n background-color: hsl(var(--border));\n}\n\n.sigma-ui-resizable-handle::after {\n position: absolute;\n left: 50%;\n width: 4px;\n content: '';\n inset-block: 0;\n transform: translateX(-50%);\n}\n\n.sigma-ui-resizable-handle:focus-visible {\n outline: 1px solid hsl(var(--ring));\n outline-offset: 1px;\n}\n\n.sigma-ui-resizable-handle[data-orientation=\"vertical\"] {\n width: 100%;\n height: 1px;\n}\n\n.sigma-ui-resizable-handle[data-orientation=\"vertical\"]::after {\n left: 0;\n width: 100%;\n height: 4px;\n transform: translateY(-50%);\n}\n\n.sigma-ui-resizable-handle[data-orientation=\"vertical\"] > div {\n transform: rotate(90deg);\n}\n\n.sigma-ui-resizable-handle__grip {\n z-index: 10;\n display: flex;\n width: 0.75rem;\n height: 1rem;\n align-items: center;\n justify-content: center;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-sm);\n background-color: hsl(var(--border));\n}\n\n.sigma-ui-resizable-handle__grip-icon {\n width: 0.625rem;\n height: 0.625rem;\n}\n</style>\n"
9
9
  },
10
10
  {
11
11
  "name": "ResizablePanelGroup.vue",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  {
43
43
  "name": "SelectTrigger.vue",
44
- "content": "<script setup lang=\"ts\">\nimport { SelectIcon, SelectTrigger, type SelectTriggerProps, useForwardProps } from 'reka-ui';\nimport { ChevronDownIcon } from 'lucide-vue-next';\n\nconst props = defineProps<SelectTriggerProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <SelectTrigger\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-select-trigger\"\n >\n <slot />\n <SelectIcon as-child>\n <ChevronDownIcon class=\"sigma-ui-select-trigger__icon\" />\n </SelectIcon>\n </SelectTrigger>\n</template>\n\n<style>\n.sigma-ui-select-trigger {\n display: flex;\n width: 100%;\n height: 2.5rem;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 0.75rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-md);\n background-color: hsl(var(--input));\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n\n.sigma-ui-select-trigger:focus {\n box-shadow: 0 0 0 2px hsl(var(--ring)), 0 0 0 4px hsl(var(--background));\n outline: none;\n}\n\n.sigma-ui-select-trigger:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-select-trigger > span {\n display: -webkit-box;\n overflow: hidden;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 1;\n}\n\n.sigma-ui-select-trigger__icon {\n width: 1rem;\n height: 1rem;\n opacity: 0.5;\n}\n</style>\n"
44
+ "content": "<script setup lang=\"ts\">\nimport { SelectIcon, SelectTrigger, type SelectTriggerProps, useForwardProps } from 'reka-ui';\nimport { ChevronDownIcon } from 'lucide-vue-next';\n\nconst props = defineProps<SelectTriggerProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <SelectTrigger\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-select-trigger\"\n >\n <slot />\n <SelectIcon as-child>\n <ChevronDownIcon class=\"sigma-ui-select-trigger__icon\" />\n </SelectIcon>\n </SelectTrigger>\n</template>\n\n<style>\n.sigma-ui-select-trigger {\n display: flex;\n width: 100%;\n height: 2.5rem;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 0.75rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-md);\n background-color: hsl(var(--input));\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n\n.sigma-ui-select-trigger:focus {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-select-trigger:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-select-trigger > span {\n display: -webkit-box;\n overflow: hidden;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 1;\n}\n\n.sigma-ui-select-trigger__icon {\n width: 1rem;\n height: 1rem;\n opacity: 0.5;\n}\n</style>\n"
45
45
  },
46
46
  {
47
47
  "name": "SelectValue.vue",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  {
15
15
  "name": "SheetContent.vue",
16
- "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui';\nimport { XIcon } from 'lucide-vue-next';\nimport { type SheetVariants, sheetVariants } from '.';\n\ninterface SheetContentProps extends DialogContentProps {\n side?: SheetVariants['side'];\n}\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = defineProps<SheetContentProps>();\nconst emits = defineEmits<DialogContentEmits>();\n\nconst delegatedProps = computed(() => ({ ...props, side: undefined }));\nconst forwarded = useForwardPropsEmits(delegatedProps, emits);\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay class=\"sigma-ui-sheet-overlay\" />\n <DialogContent\n :class=\"[sheetVariants({ side }), $attrs.class]\"\n v-bind=\"{ ...forwarded, ...$attrs }\"\n >\n <slot />\n\n <DialogClose class=\"sigma-ui-sheet-close\">\n <XIcon class=\"sigma-ui-sheet-close__icon\" />\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n\n<style>\n.sigma-ui-sheet-overlay {\n position: fixed;\n z-index: 50;\n background-color: rgb(0 0 0 / 80%);\n inset: 0;\n}\n\n.sigma-ui-sheet-overlay[data-state=\"open\"] {\n animation: sigma-ui-fade-in 150ms ease-out;\n}\n\n.sigma-ui-sheet-overlay[data-state=\"closed\"] {\n animation: sigma-ui-fade-out 150ms ease-in forwards;\n}\n\n.sigma-ui-sheet-content__base {\n position: fixed;\n z-index: 50;\n padding: 1.5rem;\n background-color: hsl(var(--background));\n box-shadow: 0 2px 10px rgb(0 0 0 / 10%);\n transition: all 0.3s ease-in-out;\n}\n\n.sigma-ui-sheet-content__base[data-state=\"open\"] {\n animation-duration: 500ms;\n animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-sheet-content__base[data-state=\"closed\"] {\n animation-duration: 300ms;\n animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-sheet-content--top {\n top: 0;\n border-bottom: 1px solid hsl(var(--border));\n inset-inline: 0;\n}\n\n.sigma-ui-sheet-content--top[data-state=\"closed\"] {\n animation-name: sigma-ui-slide-out-to-top;\n}\n\n.sigma-ui-sheet-content--top[data-state=\"open\"] {\n animation-name: sigma-ui-slide-in-from-top;\n}\n\n.sigma-ui-sheet-content--bottom {\n bottom: 0;\n border-top: 1px solid hsl(var(--border));\n inset-inline: 0;\n}\n\n.sigma-ui-sheet-content--bottom[data-state=\"closed\"] {\n animation-name: sigma-ui-slide-out-to-bottom;\n}\n\n.sigma-ui-sheet-content--bottom[data-state=\"open\"] {\n animation-name: sigma-ui-slide-in-from-bottom;\n}\n\n.sigma-ui-sheet-content--left {\n left: 0;\n width: 75%;\n height: 100%;\n border-right: 1px solid hsl(var(--border));\n inset-block: 0;\n}\n\n.sigma-ui-sheet-content--left[data-state=\"closed\"] {\n animation-name: sigma-ui-slide-out-to-left;\n}\n\n.sigma-ui-sheet-content--left[data-state=\"open\"] {\n animation-name: sigma-ui-slide-in-from-left;\n}\n\n@media (width >= 640px) {\n .sigma-ui-sheet-content--left {\n max-width: 24rem;\n }\n}\n\n.sigma-ui-sheet-content--right {\n right: 0;\n width: 75%;\n height: 100%;\n border-left: 1px solid hsl(var(--border));\n inset-block: 0;\n}\n\n.sigma-ui-sheet-content--right[data-state=\"closed\"] {\n animation-name: sigma-ui-slide-out-to-right;\n}\n\n.sigma-ui-sheet-content--right[data-state=\"open\"] {\n animation-name: sigma-ui-slide-in-from-right;\n}\n\n@media (width >= 640px) {\n .sigma-ui-sheet-content--right {\n max-width: 24rem;\n }\n}\n\n.sigma-ui-sheet-close {\n position: absolute;\n top: 1rem;\n right: 1rem;\n border-radius: var(--radius-sm);\n opacity: 0.7;\n transition: opacity 0.2s;\n}\n\n.sigma-ui-sheet-close:hover {\n opacity: 1;\n}\n\n.sigma-ui-sheet-close:focus {\n box-shadow: 0 0 0 2px hsl(var(--ring)), 0 0 0 4px hsl(var(--background));\n outline: none;\n}\n\n.sigma-ui-sheet-close:disabled {\n pointer-events: none;\n}\n\n.sigma-ui-sheet-close[data-state=\"open\"] {\n background-color: hsl(var(--secondary));\n}\n\n.sigma-ui-sheet-close__icon {\n width: 1rem;\n height: 1rem;\n color: hsl(var(--muted-foreground));\n}\n\n@keyframes sigma-ui-slide-in-from-top {\n from {\n transform: translateY(-100%);\n }\n\n to {\n transform: translateY(0);\n }\n}\n\n@keyframes sigma-ui-slide-out-to-top {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(-100%);\n }\n}\n\n@keyframes sigma-ui-slide-in-from-bottom {\n from {\n transform: translateY(100%);\n }\n\n to {\n transform: translateY(0);\n }\n}\n\n@keyframes sigma-ui-slide-out-to-bottom {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(100%);\n }\n}\n\n@keyframes sigma-ui-slide-in-from-left {\n from {\n transform: translateX(-100%);\n }\n\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes sigma-ui-slide-out-to-left {\n from {\n transform: translateX(0);\n }\n\n to {\n transform: translateX(-100%);\n }\n}\n\n@keyframes sigma-ui-slide-in-from-right {\n from {\n transform: translateX(100%);\n }\n\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes sigma-ui-slide-out-to-right {\n from {\n transform: translateX(0);\n }\n\n to {\n transform: translateX(100%);\n }\n}\n</style>\n"
16
+ "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport {\n DialogClose,\n DialogContent,\n type DialogContentEmits,\n type DialogContentProps,\n DialogOverlay,\n DialogPortal,\n useForwardPropsEmits,\n} from 'reka-ui';\nimport { XIcon } from 'lucide-vue-next';\nimport { type SheetVariants, sheetVariants } from '.';\n\ninterface SheetContentProps extends DialogContentProps {\n side?: SheetVariants['side'];\n}\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = defineProps<SheetContentProps>();\nconst emits = defineEmits<DialogContentEmits>();\n\nconst delegatedProps = computed(() => ({ ...props, side: undefined }));\nconst forwarded = useForwardPropsEmits(delegatedProps, emits);\n</script>\n\n<template>\n <DialogPortal>\n <DialogOverlay class=\"sigma-ui-sheet-overlay\" />\n <DialogContent\n :class=\"[sheetVariants({ side }), $attrs.class]\"\n v-bind=\"{ ...forwarded, ...$attrs }\"\n >\n <slot />\n\n <DialogClose class=\"sigma-ui-sheet-close\">\n <XIcon class=\"sigma-ui-sheet-close__icon\" />\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n</template>\n\n<style>\n.sigma-ui-sheet-overlay {\n position: fixed;\n z-index: 50;\n background-color: rgb(0 0 0 / 80%);\n inset: 0;\n}\n\n.sigma-ui-sheet-overlay[data-state=\"open\"] {\n animation: sigma-ui-fade-in 150ms ease-out;\n}\n\n.sigma-ui-sheet-overlay[data-state=\"closed\"] {\n animation: sigma-ui-fade-out 150ms ease-in forwards;\n}\n\n.sigma-ui-sheet-content__base {\n position: fixed;\n z-index: 50;\n padding: 1.5rem;\n background-color: hsl(var(--background));\n box-shadow: 0 2px 10px rgb(0 0 0 / 10%);\n transition: all 0.3s ease-in-out;\n}\n\n.sigma-ui-sheet-content__base[data-state=\"open\"] {\n animation-duration: 500ms;\n animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-sheet-content__base[data-state=\"closed\"] {\n animation-duration: 300ms;\n animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-sheet-content--top {\n top: 0;\n border-bottom: 1px solid hsl(var(--border));\n inset-inline: 0;\n}\n\n.sigma-ui-sheet-content--top[data-state=\"closed\"] {\n animation-name: sigma-ui-slide-out-to-top;\n}\n\n.sigma-ui-sheet-content--top[data-state=\"open\"] {\n animation-name: sigma-ui-slide-in-from-top;\n}\n\n.sigma-ui-sheet-content--bottom {\n bottom: 0;\n border-top: 1px solid hsl(var(--border));\n inset-inline: 0;\n}\n\n.sigma-ui-sheet-content--bottom[data-state=\"closed\"] {\n animation-name: sigma-ui-slide-out-to-bottom;\n}\n\n.sigma-ui-sheet-content--bottom[data-state=\"open\"] {\n animation-name: sigma-ui-slide-in-from-bottom;\n}\n\n.sigma-ui-sheet-content--left {\n left: 0;\n width: 75%;\n height: 100%;\n border-right: 1px solid hsl(var(--border));\n inset-block: 0;\n}\n\n.sigma-ui-sheet-content--left[data-state=\"closed\"] {\n animation-name: sigma-ui-slide-out-to-left;\n}\n\n.sigma-ui-sheet-content--left[data-state=\"open\"] {\n animation-name: sigma-ui-slide-in-from-left;\n}\n\n@media (width >= 640px) {\n .sigma-ui-sheet-content--left {\n max-width: 24rem;\n }\n}\n\n.sigma-ui-sheet-content--right {\n right: 0;\n width: 75%;\n height: 100%;\n border-left: 1px solid hsl(var(--border));\n inset-block: 0;\n}\n\n.sigma-ui-sheet-content--right[data-state=\"closed\"] {\n animation-name: sigma-ui-slide-out-to-right;\n}\n\n.sigma-ui-sheet-content--right[data-state=\"open\"] {\n animation-name: sigma-ui-slide-in-from-right;\n}\n\n@media (width >= 640px) {\n .sigma-ui-sheet-content--right {\n max-width: 24rem;\n }\n}\n\n.sigma-ui-sheet-close {\n position: absolute;\n top: 1rem;\n right: 1rem;\n border-radius: var(--radius-sm);\n opacity: 0.7;\n transition: opacity 0.2s;\n}\n\n.sigma-ui-sheet-close:hover {\n opacity: 1;\n}\n\n.sigma-ui-sheet-close:focus {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-sheet-close:disabled {\n pointer-events: none;\n}\n\n.sigma-ui-sheet-close[data-state=\"open\"] {\n background-color: hsl(var(--secondary));\n}\n\n.sigma-ui-sheet-close__icon {\n width: 1rem;\n height: 1rem;\n color: hsl(var(--muted-foreground));\n}\n\n@keyframes sigma-ui-slide-in-from-top {\n from {\n transform: translateY(-100%);\n }\n\n to {\n transform: translateY(0);\n }\n}\n\n@keyframes sigma-ui-slide-out-to-top {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(-100%);\n }\n}\n\n@keyframes sigma-ui-slide-in-from-bottom {\n from {\n transform: translateY(100%);\n }\n\n to {\n transform: translateY(0);\n }\n}\n\n@keyframes sigma-ui-slide-out-to-bottom {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(100%);\n }\n}\n\n@keyframes sigma-ui-slide-in-from-left {\n from {\n transform: translateX(-100%);\n }\n\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes sigma-ui-slide-out-to-left {\n from {\n transform: translateX(0);\n }\n\n to {\n transform: translateX(-100%);\n }\n}\n\n@keyframes sigma-ui-slide-in-from-right {\n from {\n transform: translateX(100%);\n }\n\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes sigma-ui-slide-out-to-right {\n from {\n transform: translateX(0);\n }\n\n to {\n transform: translateX(100%);\n }\n}\n</style>\n"
17
17
  },
18
18
  {
19
19
  "name": "SheetDescription.vue",
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "name": "Slider.vue",
8
- "content": "<script setup lang=\"ts\">\nimport type { SliderRootEmits, SliderRootProps } from 'reka-ui';\nimport { SliderRange, SliderRoot, SliderThumb, SliderTrack, useForwardPropsEmits } from 'reka-ui';\n\nconst props = defineProps<SliderRootProps>();\nconst emits = defineEmits<SliderRootEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <SliderRoot\n class=\"sigma-ui-slider\"\n v-bind=\"forwarded\"\n >\n <SliderTrack class=\"sigma-ui-slider__track\">\n <SliderRange class=\"sigma-ui-slider__range\" />\n </SliderTrack>\n <SliderThumb\n v-for=\"(_, key) in modelValue\"\n :key=\"key\"\n class=\"sigma-ui-slider__thumb\"\n />\n </SliderRoot>\n</template>\n\n<style>\n.sigma-ui-slider {\n position: relative;\n display: flex;\n width: 100%;\n min-width: 50px;\n align-items: center;\n touch-action: none;\n user-select: none;\n}\n\n.sigma-ui-slider__track {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 0.5rem;\n flex-grow: 1;\n border-radius: var(--radius-full);\n background-color: hsl(var(--secondary));\n}\n\n.sigma-ui-slider__range {\n position: absolute;\n height: 100%;\n background-color: hsl(var(--primary));\n}\n\n.sigma-ui-slider__thumb {\n display: block;\n width: 1.25rem;\n height: 1.25rem;\n border: 2px solid hsl(var(--primary));\n border-radius: var(--radius-full);\n background-color: hsl(var(--background));\n transition-duration: 150ms;\n transition-property: color, background-color, border-color;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-slider__thumb:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--ring)), 0 0 0 4px hsl(var(--background));\n outline: none;\n}\n\n.sigma-ui-slider__thumb:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n</style>\n"
8
+ "content": "<script setup lang=\"ts\">\nimport type { SliderRootEmits, SliderRootProps } from 'reka-ui';\nimport { SliderRange, SliderRoot, SliderThumb, SliderTrack, useForwardPropsEmits } from 'reka-ui';\n\nconst props = defineProps<SliderRootProps>();\nconst emits = defineEmits<SliderRootEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <SliderRoot\n class=\"sigma-ui-slider\"\n v-bind=\"forwarded\"\n >\n <SliderTrack class=\"sigma-ui-slider__track\">\n <SliderRange class=\"sigma-ui-slider__range\" />\n </SliderTrack>\n <SliderThumb\n v-for=\"(_, key) in modelValue\"\n :key=\"key\"\n class=\"sigma-ui-slider__thumb\"\n />\n </SliderRoot>\n</template>\n\n<style>\n.sigma-ui-slider {\n position: relative;\n display: flex;\n width: 100%;\n min-width: 50px;\n align-items: center;\n touch-action: none;\n user-select: none;\n}\n\n.sigma-ui-slider__track {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 0.5rem;\n flex-grow: 1;\n border-radius: var(--radius-full);\n background-color: hsl(var(--secondary));\n}\n\n.sigma-ui-slider__range {\n position: absolute;\n height: 100%;\n background-color: hsl(var(--primary));\n}\n\n.sigma-ui-slider__thumb {\n display: block;\n width: 1.25rem;\n height: 1.25rem;\n border: 2px solid hsl(var(--primary));\n border-radius: var(--radius-full);\n background-color: hsl(var(--background));\n transition-duration: 150ms;\n transition-property: color, background-color, border-color;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-slider__thumb:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-slider__thumb:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n</style>\n"
9
9
  },
10
10
  {
11
11
  "name": "index.ts",
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "name": "Switch.vue",
8
- "content": "<script setup lang=\"ts\">\nimport {\n SwitchRoot,\n type SwitchRootEmits,\n type SwitchRootProps,\n SwitchThumb,\n useForwardPropsEmits,\n\n} from 'reka-ui';\n\nconst props = defineProps<SwitchRootProps>();\n\nconst emits = defineEmits<SwitchRootEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <SwitchRoot\n v-bind=\"forwarded\"\n class=\"sigma-ui-switch\"\n >\n <SwitchThumb class=\"sigma-ui-switch__thumb\" />\n </SwitchRoot>\n</template>\n\n<style>\n.sigma-ui-switch {\n display: inline-flex;\n width: 2.75rem;\n height: 1.5rem;\n flex-shrink: 0;\n align-items: center;\n border: 2px solid transparent;\n border-radius: var(--radius-full);\n cursor: pointer;\n transition-duration: 150ms;\n transition-property: color, background-color, border-color;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-switch:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--ring)), 0 0 0 4px hsl(var(--background));\n outline: none;\n}\n\n.sigma-ui-switch:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-switch[data-state=\"checked\"] {\n background-color: hsl(var(--primary));\n}\n\n.sigma-ui-switch[data-state=\"unchecked\"] {\n background-color: hsl(218deg 14% 84% / 70%);\n}\n\n.sigma-ui-switch__thumb {\n display: block;\n width: 1.25rem;\n height: 1.25rem;\n border-radius: var(--radius-full);\n animation: none;\n background-color: hsl(var(--background));\n box-shadow: 0 2px 4px rgb(0 0 0 / 10%);\n pointer-events: none;\n transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-switch__thumb[data-state=\"checked\"] {\n animation: sigma-ui-switch-thumb-in 150ms cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(1.25rem);\n}\n\n.sigma-ui-switch__thumb[data-state=\"unchecked\"] {\n animation: sigma-ui-switch-thumb-out 150ms cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(0);\n}\n\n@keyframes sigma-ui-switch-thumb-in {\n 0% {\n filter: blur(0);\n }\n\n 50% {\n filter: blur(2px);\n }\n\n 100% {\n filter: blur(0);\n }\n}\n\n@keyframes sigma-ui-switch-thumb-out {\n 0% {\n filter: blur(0);\n }\n\n 50% {\n filter: blur(2px);\n }\n\n 100% {\n filter: blur(0);\n }\n}\n</style>\n"
8
+ "content": "<script setup lang=\"ts\">\nimport {\n SwitchRoot,\n type SwitchRootEmits,\n type SwitchRootProps,\n SwitchThumb,\n useForwardPropsEmits,\n\n} from 'reka-ui';\n\nconst props = defineProps<SwitchRootProps>();\n\nconst emits = defineEmits<SwitchRootEmits>();\n\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <SwitchRoot\n v-bind=\"forwarded\"\n class=\"sigma-ui-switch\"\n >\n <SwitchThumb class=\"sigma-ui-switch__thumb\" />\n </SwitchRoot>\n</template>\n\n<style>\n.sigma-ui-switch {\n display: inline-flex;\n width: 2.75rem;\n height: 1.5rem;\n flex-shrink: 0;\n align-items: center;\n border: 2px solid transparent;\n border-radius: var(--radius-full);\n cursor: pointer;\n transition-duration: 150ms;\n transition-property: color, background-color, border-color;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-switch:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-switch:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.sigma-ui-switch[data-state=\"checked\"] {\n background-color: hsl(var(--primary));\n}\n\n.sigma-ui-switch[data-state=\"unchecked\"] {\n background-color: hsl(218deg 14% 84% / 70%);\n}\n\n.sigma-ui-switch__thumb {\n display: block;\n width: 1.25rem;\n height: 1.25rem;\n border-radius: var(--radius-full);\n animation: none;\n background-color: hsl(var(--background));\n box-shadow: 0 2px 4px rgb(0 0 0 / 10%);\n pointer-events: none;\n transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-switch__thumb[data-state=\"checked\"] {\n animation: sigma-ui-switch-thumb-in 150ms cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(1.25rem);\n}\n\n.sigma-ui-switch__thumb[data-state=\"unchecked\"] {\n animation: sigma-ui-switch-thumb-out 150ms cubic-bezier(0.4, 0, 0.2, 1);\n transform: translateX(0);\n}\n\n@keyframes sigma-ui-switch-thumb-in {\n 0% {\n filter: blur(0);\n }\n\n 50% {\n filter: blur(2px);\n }\n\n 100% {\n filter: blur(0);\n }\n}\n\n@keyframes sigma-ui-switch-thumb-out {\n 0% {\n filter: blur(0);\n }\n\n 50% {\n filter: blur(2px);\n }\n\n 100% {\n filter: blur(0);\n }\n}\n</style>\n"
9
9
  },
10
10
  {
11
11
  "name": "index.ts",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "name": "TabsContent.vue",
12
- "content": "<script setup lang=\"ts\">\nimport { TabsContent, type TabsContentProps } from 'reka-ui';\n\nconst props = defineProps<TabsContentProps>();\n</script>\n\n<template>\n <TabsContent\n v-bind=\"props\"\n class=\"sigma-ui-tabs-content\"\n >\n <slot />\n </TabsContent>\n</template>\n\n<style>\n.sigma-ui-tabs-content {\n margin-top: 0.5rem;\n}\n\n.sigma-ui-tabs-content:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--ring)), 0 0 0 4px hsl(var(--background));\n outline: none;\n}\n</style>\n"
12
+ "content": "<script setup lang=\"ts\">\nimport { TabsContent, type TabsContentProps } from 'reka-ui';\n\nconst props = defineProps<TabsContentProps>();\n</script>\n\n<template>\n <TabsContent\n v-bind=\"props\"\n class=\"sigma-ui-tabs-content\"\n >\n <slot />\n </TabsContent>\n</template>\n\n<style>\n.sigma-ui-tabs-content {\n margin-top: 0.5rem;\n}\n\n.sigma-ui-tabs-content:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n</style>\n"
13
13
  },
14
14
  {
15
15
  "name": "TabsList.vue",
@@ -17,7 +17,7 @@
17
17
  },
18
18
  {
19
19
  "name": "TabsTrigger.vue",
20
- "content": "<script setup lang=\"ts\">\nimport { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'reka-ui';\n\nconst props = defineProps<TabsTriggerProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <TabsTrigger\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-tabs-trigger\"\n >\n <slot />\n </TabsTrigger>\n</template>\n\n<style>\n.sigma-ui-tabs-trigger {\n display: inline-flex;\n height: 100%;\n flex: 1;\n align-items: center;\n justify-content: center;\n border-radius: var(--radius-sm);\n font-size: 0.875rem;\n font-weight: 500;\n padding-inline: 0.75rem;\n transition-duration: 150ms;\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n}\n\n.sigma-ui-tabs-trigger:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--ring)), 0 0 0 4px hsl(var(--background));\n outline: none;\n}\n\n.sigma-ui-tabs-trigger:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.sigma-ui-tabs-trigger[data-state=\"active\"] {\n background-color: hsl(var(--input));\n box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);\n color: hsl(var(--foreground));\n}\n</style>\n"
20
+ "content": "<script setup lang=\"ts\">\nimport { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'reka-ui';\n\nconst props = defineProps<TabsTriggerProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <TabsTrigger\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-tabs-trigger\"\n >\n <slot />\n </TabsTrigger>\n</template>\n\n<style>\n.sigma-ui-tabs-trigger {\n display: inline-flex;\n height: 100%;\n flex: 1;\n align-items: center;\n justify-content: center;\n border-radius: var(--radius-sm);\n font-size: 0.875rem;\n font-weight: 500;\n padding-inline: 0.75rem;\n transition-duration: 150ms;\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n}\n\n.sigma-ui-tabs-trigger:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-tabs-trigger:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.sigma-ui-tabs-trigger[data-state=\"active\"] {\n background-color: hsl(var(--input));\n box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);\n color: hsl(var(--foreground));\n}\n</style>\n"
21
21
  },
22
22
  {
23
23
  "name": "index.ts",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  {
17
17
  "name": "TagsInputItem.vue",
18
- "content": "<script setup lang=\"ts\">\nimport { TagsInputItem, type TagsInputItemProps, useForwardProps } from 'reka-ui';\n\nconst props = defineProps<TagsInputItemProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <TagsInputItem\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-tags-input-item\"\n >\n <slot />\n </TagsInputItem>\n</template>\n\n<style>\n.sigma-ui-tags-input-item {\n display: flex;\n height: 1.5rem;\n align-items: center;\n border-radius: var(--radius-sm);\n background-color: hsl(var(--secondary));\n}\n\n.sigma-ui-tags-input-item[data-state=\"active\"] {\n box-shadow: 0 0 0 2px hsl(var(--ring)), 0 0 0 4px hsl(var(--background));\n}\n</style>\n"
18
+ "content": "<script setup lang=\"ts\">\nimport { TagsInputItem, type TagsInputItemProps, useForwardProps } from 'reka-ui';\n\nconst props = defineProps<TagsInputItemProps>();\n\nconst forwardedProps = useForwardProps(props);\n</script>\n\n<template>\n <TagsInputItem\n v-bind=\"forwardedProps\"\n class=\"sigma-ui-tags-input-item\"\n >\n <slot />\n </TagsInputItem>\n</template>\n\n<style>\n.sigma-ui-tags-input-item {\n display: flex;\n height: 1.5rem;\n align-items: center;\n border-radius: var(--radius-sm);\n background-color: hsl(var(--secondary));\n}\n\n.sigma-ui-tags-input-item[data-state=\"active\"] {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n</style>\n"
19
19
  },
20
20
  {
21
21
  "name": "TagsInputItemDelete.vue",
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "name": "Textarea.vue",
8
- "content": "<script setup lang=\"ts\">\n\nconst props = defineProps<{\n modelValue?: string | number;\n}>();\n\nconst model = defineModel<string | number>();\n</script>\n\n<template>\n <textarea\n v-model=\"model\"\n class=\"sigma-ui-textarea\"\n :class=\"[$attrs.class]\"\n autocomplete=\"off\"\n />\n</template>\n\n<style>\n.sigma-ui-textarea {\n display: flex;\n width: 100%;\n min-height: 5rem;\n padding: 0.5rem 0.75rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-md);\n background-color: hsl(var(--input));\n font-size: 0.875rem;\n}\n\n.sigma-ui-textarea::placeholder {\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-textarea:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));\n outline: none;\n}\n\n.sigma-ui-textarea:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n</style>\n"
8
+ "content": "<script setup lang=\"ts\">\n\nconst props = defineProps<{\n modelValue?: string | number;\n}>();\n\nconst model = defineModel<string | number>();\n</script>\n\n<template>\n <textarea\n v-model=\"model\"\n class=\"sigma-ui-textarea\"\n :class=\"[$attrs.class]\"\n autocomplete=\"off\"\n />\n</template>\n\n<style>\n.sigma-ui-textarea {\n display: flex;\n width: 100%;\n min-height: 5rem;\n padding: 0.5rem 0.75rem;\n border: 1px solid hsl(var(--border));\n border-radius: var(--radius-md);\n background-color: hsl(var(--input));\n font-size: 0.875rem;\n}\n\n.sigma-ui-textarea::placeholder {\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-textarea:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-textarea:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n</style>\n"
9
9
  },
10
10
  {
11
11
  "name": "index.ts",
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "name": "Toggle.vue",
8
- "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { Toggle, type ToggleEmits, type ToggleProps, useForwardPropsEmits } from 'reka-ui';\nimport { type ToggleVariants, toggleVariants } from '.';\n\nconst props = withDefaults(defineProps<ToggleProps & {\n variant?: ToggleVariants['variant'];\n size?: ToggleVariants['size'];\n}>(), {\n variant: 'default',\n size: 'default',\n disabled: false,\n});\n\nconst emits = defineEmits<ToggleEmits>();\n\nconst delegatedProps = computed(() => ({ ...props, size: undefined, variant: undefined }));\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits);\n</script>\n\n<template>\n <Toggle\n v-bind=\"forwarded\"\n :class=\"[toggleVariants({ variant, size })]\"\n >\n <slot />\n </Toggle>\n</template>\n\n<style>\n.sigma-ui-toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--radius-md);\n font-size: 0.875rem;\n font-weight: 500;\n transition-duration: 150ms;\n transition-property: color, background-color;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-toggle:hover {\n background-color: hsl(var(--muted));\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-toggle:focus-visible {\n box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));\n outline: none;\n}\n\n.sigma-ui-toggle:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.sigma-ui-toggle[data-state=\"on\"] {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-toggle--default {\n background-color: transparent;\n}\n\n.sigma-ui-toggle--outline {\n border: 1px solid hsl(var(--input));\n background-color: transparent;\n}\n\n.sigma-ui-toggle--outline:hover {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-toggle--size-default {\n height: 2.5rem;\n padding-inline: 0.75rem;\n}\n\n.sigma-ui-toggle--size-sm {\n height: 2.25rem;\n padding-inline: 0.625rem;\n}\n\n.sigma-ui-toggle--size-lg {\n height: 2.75rem;\n padding-inline: 1.25rem;\n}\n</style>\n"
8
+ "content": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { Toggle, type ToggleEmits, type ToggleProps, useForwardPropsEmits } from 'reka-ui';\nimport { type ToggleVariants, toggleVariants } from '.';\n\nconst props = withDefaults(defineProps<ToggleProps & {\n variant?: ToggleVariants['variant'];\n size?: ToggleVariants['size'];\n}>(), {\n variant: 'default',\n size: 'default',\n disabled: false,\n});\n\nconst emits = defineEmits<ToggleEmits>();\n\nconst delegatedProps = computed(() => ({ ...props, size: undefined, variant: undefined }));\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits);\n</script>\n\n<template>\n <Toggle\n v-bind=\"forwarded\"\n :class=\"[toggleVariants({ variant, size })]\"\n >\n <slot />\n </Toggle>\n</template>\n\n<style>\n.sigma-ui-toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--radius-md);\n font-size: 0.875rem;\n font-weight: 500;\n transition-duration: 150ms;\n transition-property: color, background-color;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sigma-ui-toggle:hover {\n background-color: hsl(var(--muted));\n color: hsl(var(--muted-foreground));\n}\n\n.sigma-ui-toggle:focus-visible {\n outline: 2px solid hsl(var(--ring));\n outline-offset: 2px;\n}\n\n.sigma-ui-toggle:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n.sigma-ui-toggle[data-state=\"on\"] {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-toggle--default {\n background-color: transparent;\n}\n\n.sigma-ui-toggle--outline {\n border: 1px solid hsl(var(--input));\n background-color: transparent;\n}\n\n.sigma-ui-toggle--outline:hover {\n background-color: hsl(var(--secondary));\n color: hsl(var(--secondary-foreground));\n}\n\n.sigma-ui-toggle--size-default {\n height: 2.5rem;\n padding-inline: 0.75rem;\n}\n\n.sigma-ui-toggle--size-sm {\n height: 2.25rem;\n padding-inline: 0.625rem;\n}\n\n.sigma-ui-toggle--size-lg {\n height: 2.75rem;\n padding-inline: 1.25rem;\n}\n</style>\n"
9
9
  },
10
10
  {
11
11
  "name": "index.ts",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "name": "index.ts",
12
- "content": "import { type VariantProps, cva } from 'class-variance-authority';\n\nexport { default as Badge } from './Badge.vue';\n\nexport const badgeVariants = cva(\n 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2',\n {\n variants: {\n variant: {\n default:\n 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',\n secondary:\n 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',\n destructive:\n 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',\n outline: 'text-foreground',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nexport type BadgeVariants = VariantProps<typeof badgeVariants>;\n"
12
+ "content": "import { type VariantProps, cva } from 'class-variance-authority';\n\nexport { default as Badge } from './Badge.vue';\n\nexport const badgeVariants = cva(\n 'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-2 focus:outline-ring focus:outline-offset-2',\n {\n variants: {\n variant: {\n default:\n 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',\n secondary:\n 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',\n destructive:\n 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',\n outline: 'text-foreground',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nexport type BadgeVariants = VariantProps<typeof badgeVariants>;\n"
13
13
  }
14
14
  ],
15
15
  "type": "components:ui"
@@ -7,9 +7,13 @@
7
7
  "name": "Button.vue",
8
8
  "content": "<script setup lang=\"ts\">\n;\nimport { Primitive, type PrimitiveProps } from 'reka-ui';\nimport { Loader2Icon } from 'lucide-vue-next';\nimport { cn } from '@ui/utils';\nimport { type ButtonVariants, buttonVariants } from '.';\n\ninterface Props extends PrimitiveProps {\n variant?: ButtonVariants['variant'];\n size?: ButtonVariants['size'];\n isLoading?: boolean;\n loadingText?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n as: 'button',\n variant: 'default',\n size: 'default',\n isLoading: false,\n loadingText: '',\n});\n</script>\n\n<template>\n <Primitive\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn(buttonVariants({ variant, size }), $attrs.class ?? '')\"\n :disabled=\"isLoading || $attrs.disabled\"\n >\n <Loader2Icon\n v-if=\"isLoading\"\n class=\"w-4 h-4 mr-2 animate-spin\"\n />\n <template v-if=\"!isLoading || (isLoading && !loadingText)\">\n <slot />\n </template>\n <template v-else>\n {{ loadingText }}\n </template>\n </Primitive>\n</template>\n"
9
9
  },
10
+ {
11
+ "name": "ConfirmButton.vue",
12
+ "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { CheckIcon } from 'lucide-vue-next';\nimport { cn } from '@ui/utils';\nimport { Button } from '.';\nimport { type ButtonVariants } from '.';\n\ninterface Props {\n variant?: ButtonVariants['variant'];\n size?: ButtonVariants['size'];\n confirmDuration?: number;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'outline',\n size: 'default',\n confirmDuration: 1000,\n});\n\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n}>();\n\nconst isConfirmed = ref(false);\nlet confirmTimeout: ReturnType<typeof setTimeout> | null = null;\n\nasync function handleClick(event: MouseEvent) {\n if (isConfirmed.value) {\n return;\n }\n\n emit('click', event);\n\n isConfirmed.value = true;\n\n if (confirmTimeout) {\n clearTimeout(confirmTimeout);\n }\n\n confirmTimeout = setTimeout(() => {\n isConfirmed.value = false;\n confirmTimeout = null;\n }, props.confirmDuration);\n}\n</script>\n\n<template>\n <Button\n :variant=\"variant\"\n :size=\"size\"\n :class=\"cn(\n 'relative overflow-hidden gap-2',\n isConfirmed && 'border-green-500/50',\n )\"\n @click=\"handleClick\"\n >\n <span\n :class=\"cn(\n 'inline-flex items-center gap-2 transition-opacity duration-150',\n isConfirmed && 'opacity-0',\n )\"\n >\n <slot />\n </span>\n <Transition\n enter-active-class=\"transition-all duration-150 ease-out\"\n leave-active-class=\"transition-all duration-150 ease-in\"\n enter-from-class=\"opacity-0 scale-50\"\n leave-to-class=\"opacity-0 scale-50\"\n >\n <span\n v-if=\"isConfirmed\"\n class=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 inline-flex items-center justify-center\"\n >\n <CheckIcon\n :size=\"14\"\n class=\"text-green-500\"\n />\n </span>\n </Transition>\n </Button>\n</template>\n"
13
+ },
10
14
  {
11
15
  "name": "index.ts",
12
- "content": "import { type VariantProps, cva } from 'class-variance-authority';\n\nexport { default as Button } from './Button.vue';\n\nexport const buttonVariants = cva(\n 'w-[fit-content] inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 select-none',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline:\n 'border border-border bg-transparent hover:bg-secondary hover:text-secondary-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'hover:bg-secondary hover:text-secondary-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 px-4 py-2',\n xs: 'h-7 px-2',\n sm: 'h-9 px-3',\n lg: 'h-11 px-8',\n icon: 'h-10 w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n"
16
+ "content": "import { type VariantProps, cva } from 'class-variance-authority';\n\nexport { default as Button } from './Button.vue';\nexport { default as ConfirmButton } from './ConfirmButton.vue';\n\nexport const buttonVariants = cva(\n 'w-[fit-content] inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-50 select-none',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline:\n 'border border-border bg-transparent hover:bg-secondary hover:text-secondary-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'hover:bg-secondary hover:text-secondary-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 px-4 py-2',\n xs: 'h-7 px-2',\n sm: 'h-9 px-3',\n lg: 'h-11 px-8',\n icon: 'h-10 w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n"
13
17
  }
14
18
  ],
15
19
  "type": "components:ui"
@@ -7,7 +7,7 @@
7
7
  "files": [
8
8
  {
9
9
  "name": "CardLightbox.vue",
10
- "content": "<script setup lang=\"ts\">\nimport { onMounted, onUnmounted, ref } from 'vue';\nimport { AnimatePresence, motion } from 'motion-v';\nimport type { Item } from './types';\nimport { XIcon } from 'lucide-vue-next';\n\ntype Props = {\n items: Item[];\n};\n\nconst props = defineProps<Props>();\n\nconst openId = ref<string | null>(null);\n\nonMounted(() => {\n document.addEventListener('keydown', handleEscKeydown);\n});\n\nonUnmounted(() => {\n document.removeEventListener('keydown', handleEscKeydown);\n});\n\nfunction open(id: string) {\n openId.value = id;\n}\n\nfunction close() {\n openId.value = null;\n}\n\nfunction handleEscKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n close();\n }\n}\n</script>\n\n<template>\n <div class=\"mx-auto w-full max-w-[990px] flex flex-col @container/card-lightbox\">\n <ul class=\"grid grid-cols-1 gap-2.5 p-0 m-0 list-none @lg/card-lightbox:grid-cols-10 @lg/card-lightbox:gap-5\">\n <motion.button\n v-for=\"card in props.items\"\n :key=\"card.id\"\n :data-open=\"openId === card.id\"\n :class=\"[\n 'relative p-0 overflow-hidden focus-visible:rounded-[20px] focus-visible:shadow-[0_0_0_2px_hsl(var(--background)),_0_0_0_4px_hsl(var(--ring))] focus-visible:outline-none',\n 'h-[280px] w-full col-span-1',\n '@lg/card-lightbox:h-[420px]',\n card.theme === 'dark' ? 'group theme-dark' : '',\n (props.items.findIndex(item => item.id === card.id) + 1) % 4 === 1 || (props.items.findIndex(item => item.id === card.id) + 1) % 4 === 0\n ? '@lg/card-lightbox:col-span-6'\n : '@lg/card-lightbox:col-span-4',\n ]\"\n @click=\"() => open(card.id)\"\n >\n <motion.div\n class=\"relative pointer-events-auto select-none rounded-[20px] bg-card overflow-hidden w-full h-full m-auto animate-fade-in\"\n :layout-id=\"`card-container-${card.id}`\"\n >\n <motion.div\n class=\"relative overflow-hidden h-full w-full\"\n :layout-id=\"`card-image-container-${card.id}`\"\n >\n <motion.img\n class=\"absolute inset-0 z-10 w-full h-full object-cover pointer-events-none\"\n :src=\"card.image\"\n alt=\"\"\n />\n <div\n :class=\"[\n 'absolute inset-0 z-10 pointer-events-none',\n card.theme === 'dark'\n ? 'bg-linear-[160deg,rgba(255,255,255,0.95)_-8%,rgba(255,255,255,0)_30%]'\n : 'bg-linear-[160deg,rgba(0,0,0,0.95)_-8%,rgba(0,0,0,0)_30%]'\n ]\"\n />\n </motion.div>\n <motion.div\n class=\"absolute top-0 left-0 z-20 max-w-[300px] p-5 text-left\"\n :layout-id=\"`title-container-${card.id}`\"\n layout=\"position\"\n >\n <span\n :class=\"[\n 'px-2 py-1 rounded-[12px] text-[12px] uppercase backdrop-blur-[8px]',\n 'text-white bg-white/10 group-[.theme-dark]:text-black/90 group-[.theme-dark]:bg-black/10'\n ]\"\n >\n {{ card.category }}\n </span>\n <h2\n :class=\"[\n 'my-2 text-[20px] font-semibold',\n 'text-white group-[.theme-dark]:text-black/90'\n ]\"\n >\n {{ card.title }}\n </h2>\n </motion.div>\n </motion.div>\n </motion.button>\n </ul>\n <AnimatePresence>\n <motion.div\n v-if=\"openId\"\n :initial=\"{ opacity: 0 }\"\n :animate=\"{ opacity: 1 }\"\n :exit=\"{ opacity: 0 }\"\n :transition=\"{ duration: 0.2 }\"\n style=\"pointer-events: auto\"\n class=\"fixed inset-0 z-50 backdrop-blur-[12px] bg-black/20 [will-change:opacity]\"\n @click=\"close\"\n />\n </AnimatePresence>\n <AnimatePresence>\n <div\n v-if=\"openId\"\n :class=\"[\n 'fixed inset-0 z-[51] w-full h-full pointer-events-none flex flex-col justify-center items-center p-0 lg:p-[40px_0]',\n props.items.find(item => item.id === openId)?.theme === 'dark' ? 'group theme-dark' : '',\n ]\"\n >\n <motion.div\n class=\"relative pointer-events-auto select-none bg-background overflow-hidden m-auto overflow-y-auto w-screen max-w-full h-screen rounded-none lg:w-auto lg:max-w-[700px] lg:h-[70dvh] lg:rounded-[20px]\"\n :layout-id=\"`card-container-${openId}`\"\n >\n <motion.div\n class=\"relative overflow-hidden w-full h-[280px] lg:h-[420px]\"\n :layout-id=\"`card-image-container-${openId}`\"\n >\n <motion.img\n class=\"absolute inset-0 z-10 w-full h-full object-cover pointer-events-none\"\n :src=\"props.items.find(item => item.id === openId)?.image\"\n alt=\"\"\n :layout-id=\"`card-image-${openId}`\"\n :initial=\"{ opacity: 0, filter: 'blur(12px)' }\"\n :animate=\"{ opacity: 1, filter: 'blur(0px)' }\"\n :exit=\"{ opacity: 0, filter: 'blur(12px)' }\"\n :transition=\"{ duration: 0.5 }\"\n />\n <div\n :class=\"[\n 'absolute inset-0 z-10 pointer-events-none',\n props.items.find(item => item.id === openId)?.theme === 'dark'\n ? 'bg-linear-[160deg,rgba(255,255,255,0.95)_-8%,rgba(255,255,255,0)_30%]'\n : 'bg-linear-[160deg,rgba(0,0,0,0.95)_-8%,rgba(0,0,0,0)_30%]'\n ]\"\n />\n <motion.div\n class=\"absolute top-0 left-0 z-20 p-5\"\n :layout-id=\"`title-container-${openId}`\"\n layout=\"position\"\n >\n <span\n :class=\"[\n 'px-2 py-1 rounded-[12px] text-[12px] uppercase backdrop-blur-[8px]',\n 'text-white bg-white/10 group-[.theme-dark]:text-black/90 group-[.theme-dark]:bg-black/10'\n ]\"\n >\n {{ props.items.find(item => item.id === openId)?.category }}\n </span>\n <h2\n :class=\"[\n 'my-2 text-[20px] font-semibold',\n 'text-white group-[.theme-dark]:text-black/90'\n ]\"\n >\n {{ props.items.find(item => item.id === openId)?.title }}\n </h2>\n </motion.div>\n <motion.div\n class=\"absolute top-0 right-0 z-20 p-5 cursor-pointer\"\n @click=\"close\"\n >\n <XIcon class=\"stroke-white group-[.theme-dark]:stroke-black/90\" />\n </motion.div>\n </motion.div>\n <motion.div\n class=\"p-[35px] max-w-[700px] w-screen text-primary\"\n >\n <div v-html=\"props.items.find(item => item.id === openId)?.content\" />\n </motion.div>\n </motion.div>\n </div>\n </AnimatePresence>\n </div>\n</template>\n"
10
+ "content": "<script setup lang=\"ts\">\nimport { onMounted, onUnmounted, ref } from 'vue';\nimport { AnimatePresence, motion } from 'motion-v';\nimport type { Item } from './types';\nimport { XIcon } from 'lucide-vue-next';\n\ntype Props = {\n items: Item[];\n};\n\nconst props = defineProps<Props>();\n\nconst openId = ref<string | null>(null);\n\nonMounted(() => {\n document.addEventListener('keydown', handleEscKeydown);\n});\n\nonUnmounted(() => {\n document.removeEventListener('keydown', handleEscKeydown);\n});\n\nfunction open(id: string) {\n openId.value = id;\n}\n\nfunction close() {\n openId.value = null;\n}\n\nfunction handleEscKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n close();\n }\n}\n</script>\n\n<template>\n <div class=\"mx-auto w-full max-w-[990px] flex flex-col @container/card-lightbox\">\n <ul class=\"grid grid-cols-1 gap-2.5 p-0 m-0 list-none @lg/card-lightbox:grid-cols-10 @lg/card-lightbox:gap-5\">\n <motion.button\n v-for=\"card in props.items\"\n :key=\"card.id\"\n :data-open=\"openId === card.id\"\n :class=\"[\n 'relative p-0 overflow-hidden focus-visible:rounded-[20px] focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2',\n 'h-[280px] w-full col-span-1',\n '@lg/card-lightbox:h-[420px]',\n card.theme === 'dark' ? 'group theme-dark' : '',\n (props.items.findIndex(item => item.id === card.id) + 1) % 4 === 1 || (props.items.findIndex(item => item.id === card.id) + 1) % 4 === 0\n ? '@lg/card-lightbox:col-span-6'\n : '@lg/card-lightbox:col-span-4',\n ]\"\n @click=\"() => open(card.id)\"\n >\n <motion.div\n class=\"relative pointer-events-auto select-none rounded-[20px] bg-card overflow-hidden w-full h-full m-auto animate-fade-in\"\n :layout-id=\"`card-container-${card.id}`\"\n >\n <motion.div\n class=\"relative overflow-hidden h-full w-full\"\n :layout-id=\"`card-image-container-${card.id}`\"\n >\n <motion.img\n class=\"absolute inset-0 z-10 w-full h-full object-cover pointer-events-none\"\n :src=\"card.image\"\n alt=\"\"\n />\n <div\n :class=\"[\n 'absolute inset-0 z-10 pointer-events-none',\n card.theme === 'dark'\n ? 'bg-linear-[160deg,rgba(255,255,255,0.95)_-8%,rgba(255,255,255,0)_30%]'\n : 'bg-linear-[160deg,rgba(0,0,0,0.95)_-8%,rgba(0,0,0,0)_30%]'\n ]\"\n />\n </motion.div>\n <motion.div\n class=\"absolute top-0 left-0 z-20 max-w-[300px] p-5 text-left\"\n :layout-id=\"`title-container-${card.id}`\"\n layout=\"position\"\n >\n <span\n :class=\"[\n 'px-2 py-1 rounded-[12px] text-[12px] uppercase backdrop-blur-[8px]',\n 'text-white bg-white/10 group-[.theme-dark]:text-black/90 group-[.theme-dark]:bg-black/10'\n ]\"\n >\n {{ card.category }}\n </span>\n <h2\n :class=\"[\n 'my-2 text-[20px] font-semibold',\n 'text-white group-[.theme-dark]:text-black/90'\n ]\"\n >\n {{ card.title }}\n </h2>\n </motion.div>\n </motion.div>\n </motion.button>\n </ul>\n <AnimatePresence>\n <motion.div\n v-if=\"openId\"\n :initial=\"{ opacity: 0 }\"\n :animate=\"{ opacity: 1 }\"\n :exit=\"{ opacity: 0 }\"\n :transition=\"{ duration: 0.2 }\"\n style=\"pointer-events: auto\"\n class=\"fixed inset-0 z-50 backdrop-blur-[12px] bg-black/20 [will-change:opacity]\"\n @click=\"close\"\n />\n </AnimatePresence>\n <AnimatePresence>\n <div\n v-if=\"openId\"\n :class=\"[\n 'fixed inset-0 z-[51] w-full h-full pointer-events-none flex flex-col justify-center items-center p-0 lg:p-[40px_0]',\n props.items.find(item => item.id === openId)?.theme === 'dark' ? 'group theme-dark' : '',\n ]\"\n >\n <motion.div\n class=\"relative pointer-events-auto select-none bg-background overflow-hidden m-auto overflow-y-auto w-screen max-w-full h-screen rounded-none lg:w-auto lg:max-w-[700px] lg:h-[70dvh] lg:rounded-[20px]\"\n :layout-id=\"`card-container-${openId}`\"\n >\n <motion.div\n class=\"relative overflow-hidden w-full h-[280px] lg:h-[420px]\"\n :layout-id=\"`card-image-container-${openId}`\"\n >\n <motion.img\n class=\"absolute inset-0 z-10 w-full h-full object-cover pointer-events-none\"\n :src=\"props.items.find(item => item.id === openId)?.image\"\n alt=\"\"\n :layout-id=\"`card-image-${openId}`\"\n :initial=\"{ opacity: 0, filter: 'blur(12px)' }\"\n :animate=\"{ opacity: 1, filter: 'blur(0px)' }\"\n :exit=\"{ opacity: 0, filter: 'blur(12px)' }\"\n :transition=\"{ duration: 0.5 }\"\n />\n <div\n :class=\"[\n 'absolute inset-0 z-10 pointer-events-none',\n props.items.find(item => item.id === openId)?.theme === 'dark'\n ? 'bg-linear-[160deg,rgba(255,255,255,0.95)_-8%,rgba(255,255,255,0)_30%]'\n : 'bg-linear-[160deg,rgba(0,0,0,0.95)_-8%,rgba(0,0,0,0)_30%]'\n ]\"\n />\n <motion.div\n class=\"absolute top-0 left-0 z-20 p-5\"\n :layout-id=\"`title-container-${openId}`\"\n layout=\"position\"\n >\n <span\n :class=\"[\n 'px-2 py-1 rounded-[12px] text-[12px] uppercase backdrop-blur-[8px]',\n 'text-white bg-white/10 group-[.theme-dark]:text-black/90 group-[.theme-dark]:bg-black/10'\n ]\"\n >\n {{ props.items.find(item => item.id === openId)?.category }}\n </span>\n <h2\n :class=\"[\n 'my-2 text-[20px] font-semibold',\n 'text-white group-[.theme-dark]:text-black/90'\n ]\"\n >\n {{ props.items.find(item => item.id === openId)?.title }}\n </h2>\n </motion.div>\n <motion.div\n class=\"absolute top-0 right-0 z-20 p-5 cursor-pointer\"\n @click=\"close\"\n >\n <XIcon class=\"stroke-white group-[.theme-dark]:stroke-black/90\" />\n </motion.div>\n </motion.div>\n <motion.div\n class=\"p-[35px] max-w-[700px] w-screen text-primary\"\n >\n <div v-html=\"props.items.find(item => item.id === openId)?.content\" />\n </motion.div>\n </motion.div>\n </div>\n </AnimatePresence>\n </div>\n</template>\n"
11
11
  },
12
12
  {
13
13
  "name": "index.ts",