@music-vine/cadence 1.1.2 → 2.1.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 (46) hide show
  1. package/dist/components/accordion.js +1 -1
  2. package/dist/components/accordion.js.map +2 -2
  3. package/dist/components/badge.d.ts +3 -3
  4. package/dist/components/badge.d.ts.map +1 -1
  5. package/dist/components/badge.js +7 -9
  6. package/dist/components/badge.js.map +2 -2
  7. package/dist/components/button.d.ts +4 -4
  8. package/dist/components/button.js +8 -8
  9. package/dist/components/button.js.map +2 -2
  10. package/dist/components/carousel-dots.js +1 -1
  11. package/dist/components/carousel-dots.js.map +2 -2
  12. package/dist/components/checkbox.js +2 -2
  13. package/dist/components/checkbox.js.map +1 -1
  14. package/dist/components/input.js +3 -3
  15. package/dist/components/input.js.map +1 -1
  16. package/dist/components/radio-group.js +2 -2
  17. package/dist/components/radio-group.js.map +1 -1
  18. package/dist/components/select.js +1 -1
  19. package/dist/components/select.js.map +1 -1
  20. package/dist/components/slider.js +2 -2
  21. package/dist/components/slider.js.map +1 -1
  22. package/dist/components/stacking-card.js +2 -2
  23. package/dist/components/stacking-card.js.map +2 -2
  24. package/dist/components/tabs.js +2 -2
  25. package/dist/components/tabs.js.map +1 -1
  26. package/dist/components/toast.d.ts +26 -6
  27. package/dist/components/toast.d.ts.map +1 -1
  28. package/dist/components/toast.js +16 -14
  29. package/dist/components/toast.js.map +2 -2
  30. package/dist/components/typography/prose.js +1 -1
  31. package/dist/components/typography/prose.js.map +1 -1
  32. package/dist/icons/custom/view-credit-note.d.ts +4 -0
  33. package/dist/icons/custom/view-credit-note.d.ts.map +1 -0
  34. package/dist/icons/custom/view-credit-note.js +27 -0
  35. package/dist/icons/custom/view-credit-note.js.map +7 -0
  36. package/dist/icons/index.d.ts +1 -0
  37. package/dist/icons/index.d.ts.map +1 -1
  38. package/dist/icons/index.js +1 -0
  39. package/dist/icons/index.js.map +2 -2
  40. package/dist/styles/index.css +32 -0
  41. package/dist/theme/index.d.ts +142 -0
  42. package/dist/theme/index.d.ts.map +1 -0
  43. package/dist/theme/index.js +112 -0
  44. package/dist/theme/index.js.map +7 -0
  45. package/package.json +9 -1
  46. package/tailwind.config.ts +12 -0
@@ -21,7 +21,7 @@ function AccordionItem({
21
21
  AccordionPrimitive.Item,
22
22
  {
23
23
  className: cn(
24
- variant === "default" ? "border-0 border-gray-150 border-b-1 border-solid bg-transparent transition-colors md:mb-1 dark:border-gray-800 [&:has(:focus-visible)]:ring-2 [&:has(:focus-visible)]:ring-pink-500 [&:has(:focus-visible)]:ring-offset-8 dark:[&:has(:focus-visible)]:ring-offset-gray-950" : "border-0 border-gray-800 border-b-1 border-solid bg-transparent transition-colors [&:has(:focus-visible)]:ring-2 [&:has(:focus-visible)]:ring-pink-500 [&:has(:focus-visible)]:ring-offset-8 [&:has(:focus-visible)]:ring-offset-gray-950 [&:has([data-state='open'])]:border-transparent",
24
+ variant === "default" ? "border-0 border-gray-150 border-b-1 border-solid bg-transparent transition-colors md:mb-1 dark:border-gray-800 [&:has(:focus-visible)]:ring-2 [&:has(:focus-visible)]:ring-[var(--focus-ring)] [&:has(:focus-visible)]:ring-offset-8 dark:[&:has(:focus-visible)]:ring-offset-gray-950" : "border-0 border-gray-800 border-b-1 border-solid bg-transparent transition-colors [&:has(:focus-visible)]:ring-2 [&:has(:focus-visible)]:ring-[var(--focus-ring)] [&:has(:focus-visible)]:ring-offset-8 [&:has(:focus-visible)]:ring-offset-gray-950 [&:has([data-state='open'])]:border-transparent",
25
25
  "last-of-type:border-b-0",
26
26
  className
27
27
  ),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/accordion.tsx"],
4
- "sourcesContent": ["/**\n * @module Accordion\n *\n * A vertically stacked set of interactive headings that reveal/hide associated content.\n * Built on Radix UI Accordion primitive with custom styling variants.\n *\n * @see {@link https://ui.shadcn.com/docs/components/accordion Shadcn Accordion}\n * @see {@link https://www.radix-ui.com/primitives/docs/components/accordion Radix Accordion}\n *\n * @example\n * // Basic single-select accordion\n * <Accordion type=\"single\" collapsible>\n * <AccordionItem value=\"item-1\">\n * <AccordionTrigger>Section 1</AccordionTrigger>\n * <AccordionContent>Content for section 1</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n *\n * @example\n * // Multi-select accordion with HC variant (dark theme)\n * <Accordion type=\"multiple\" variant=\"hc\">\n * <AccordionItem value=\"faq-1\" variant=\"hc\">\n * <AccordionTrigger variant=\"hc\">What is Uppbeat?</AccordionTrigger>\n * <AccordionContent variant=\"hc\">Royalty-free music platform</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n */\nimport { ChevronDown } from \"lucide-react\";\nimport { Accordion as AccordionPrimitive } from \"radix-ui\";\nimport type { Ref } from \"react\";\nimport type * as React from \"react\";\nimport { cn } from \"../lib/utils\";\n\n/**\n * Visual style variants for the accordion.\n * - `default`: Light theme with subtle borders\n * - `hc`: High contrast dark theme variant\n */\ntype AccordionVariant = \"default\" | \"hc\";\n\ntype AccordionItemProps = React.ComponentPropsWithoutRef<\n typeof AccordionPrimitive.Item\n> & {\n variant?: AccordionVariant;\n};\n\ntype AccordionProps = React.ComponentPropsWithoutRef<\n typeof AccordionPrimitive.Root\n> & {\n variant?: AccordionVariant;\n};\n\n/**\n * Root container for accordion items. Controls single or multiple expansion.\n *\n * @param type - `\"single\"` allows one item open at a time, `\"multiple\"` allows many\n * @param collapsible - When `type=\"single\"`, allows closing all items (default: false)\n * @param variant - Visual style: `\"default\"` or `\"hc\"` (high contrast)\n */\nfunction Accordion({ variant = \"default\", ...props }: AccordionProps) {\n return (\n <AccordionPrimitive.Root\n className={cn(variant === \"hc\" && \"hc-accordion\")}\n {...props}\n />\n );\n}\n\nAccordion.displayName = \"Accordion\";\n\n/**\n * Wrapper for each accordion section. Must have a unique `value` prop.\n *\n * @param value - Unique identifier for this item (required)\n * @param variant - Visual style matching parent Accordion\n * @param disabled - Prevents interaction when true\n */\nfunction AccordionItem({\n className,\n variant = \"default\",\n ...props\n}: AccordionItemProps) {\n return (\n <AccordionPrimitive.Item\n className={cn(\n variant === \"default\"\n ? \"border-0 border-gray-150 border-b-1 border-solid bg-transparent transition-colors md:mb-1 dark:border-gray-800 [&:has(:focus-visible)]:ring-2 [&:has(:focus-visible)]:ring-pink-500 [&:has(:focus-visible)]:ring-offset-8 dark:[&:has(:focus-visible)]:ring-offset-gray-950\"\n : \"border-0 border-gray-800 border-b-1 border-solid bg-transparent transition-colors [&:has(:focus-visible)]:ring-2 [&:has(:focus-visible)]:ring-pink-500 [&:has(:focus-visible)]:ring-offset-8 [&:has(:focus-visible)]:ring-offset-gray-950 [&:has([data-state='open'])]:border-transparent\",\n \"last-of-type:border-b-0\",\n className\n )}\n data-variant={variant}\n {...props}\n />\n );\n}\n\nAccordionItem.displayName = \"AccordionItem\";\n\n/** Props for AccordionTrigger component */\ninterface AccordionTriggerProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> {\n variant?: AccordionVariant;\n headerClassName?: string;\n triggerChildrenClassName?: string;\n}\n\n/**\n * Clickable heading that toggles the associated AccordionContent.\n * Includes an animated chevron indicator.\n *\n * @param variant - Visual style: `\"default\"` or `\"hc\"`\n * @param headerClassName - Additional classes for the header wrapper\n * @param triggerChildrenClassName - Additional classes for the inner content wrapper\n */\nfunction AccordionTrigger({\n className,\n children,\n variant = \"default\",\n headerClassName,\n triggerChildrenClassName,\n ...props\n}: AccordionTriggerProps) {\n return (\n <AccordionPrimitive.Header className={cn(\"flex\", headerClassName)}>\n <AccordionPrimitive.Trigger\n className={cn(\n variant === \"default\"\n ? \"group my-4 flex flex-1 items-center justify-between text-left font-sans font-semibold text-base text-gray-950 transition-all md:my-3 2xl:my-2 2xl:text-lg dark:text-white [&>[data-icon='closed']]:data-[state=closed]:block [&>[data-icon='open']]:data-[state=open]:block [&>[data-icon]]:hidden\"\n : \"group my-3 flex flex-1 items-center justify-between text-left font-sans font-semibold text-base text-white transition-all 2xl:text-lg [&>[data-icon='closed']]:data-[state=closed]:block [&>[data-icon='open']]:data-[state=open]:block [&>[data-icon]]:hidden\",\n className\n )}\n data-variant={variant}\n style={{ WebkitTapHighlightColor: \"transparent\" }}\n {...props}\n >\n <div\n className={cn(\n \"flex flex-1 items-center justify-between gap-1 rounded-sm py-2 font-semibold text-base transition-colors 2xl:text-lg\",\n variant === \"default\"\n ? \"md:px-2 md:hover:bg-gray-50 dark:md:hover:bg-gray-900\"\n : \"-my-1 px-2 hover:bg-gray-900\",\n triggerChildrenClassName\n )}\n >\n {children}\n <ChevronDown className=\"w-5 transition-transform duration-150 group-data-[state=open]:rotate-180\" />\n </div>\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nAccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;\n\n/** Props for AccordionContent component */\ninterface AccordionContentProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content> {\n variant?: AccordionVariant;\n}\n\n/**\n * Collapsible content panel with smooth expand/collapse animation.\n * Automatically hidden when parent AccordionItem is closed.\n *\n * @param variant - Visual style: `\"default\"` or `\"hc\"`\n * @param forceMount - Keep content in DOM even when closed (useful for SEO/forms)\n */\nfunction AccordionContent({\n className,\n children,\n variant = \"default\",\n ...props\n}: AccordionContentProps) {\n return (\n <AccordionPrimitive.Content\n className={cn(\n variant === \"default\"\n ? \"overflow-hidden text-left font-sans text-gray-700 text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down md:px-2 2xl:text-base dark:text-gray-200\"\n : \"-mx-6 ~px-6/12 overflow-hidden bg-gray-900 pt-6 text-left font-sans text-gray-400 text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down 2xl:text-base\"\n )}\n data-variant={variant}\n {...props}\n >\n <div className={cn(\"pb-8\", className)}>{children}</div>\n </AccordionPrimitive.Content>\n );\n}\n\nAccordionContent.displayName = AccordionPrimitive.Content.displayName;\n\nexport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n type AccordionContentProps,\n type AccordionItemProps,\n type AccordionProps,\n type AccordionTriggerProps,\n type AccordionVariant,\n};\n"],
5
- "mappings": "AA6DI,cA2EI,YA3EJ;AAlCJ,SAAS,mBAAmB;AAC5B,SAAS,aAAa,0BAA0B;AAGhD,SAAS,UAAU;AA4BnB,SAAS,UAAU,EAAE,UAAU,WAAW,GAAG,MAAM,GAAmB;AACpE,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,WAAW,GAAG,YAAY,QAAQ,cAAc;AAAA,MAC/C,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,UAAU,cAAc;AASxB,SAAS,cAAc;AAAA,EACrB;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAAuB;AACrB,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,WAAW;AAAA,QACT,YAAY,YACR,gRACA;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,MACA,gBAAc;AAAA,MACb,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,cAAc,cAAc;AAkB5B,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,SACE,oBAAC,mBAAmB,QAAnB,EAA0B,WAAW,GAAG,QAAQ,eAAe,GAC9D;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,WAAW;AAAA,QACT,YAAY,YACR,uSACA;AAAA,QACJ;AAAA,MACF;AAAA,MACA,gBAAc;AAAA,MACd,OAAO,EAAE,yBAAyB,cAAc;AAAA,MAC/C,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,YAAY,YACR,0DACA;AAAA,YACJ;AAAA,UACF;AAAA,UAEC;AAAA;AAAA,YACD,oBAAC,eAAY,WAAU,4EAA2E;AAAA;AAAA;AAAA,MACpG;AAAA;AAAA,EACF,GACF;AAEJ;AAEA,iBAAiB,cAAc,mBAAmB,QAAQ;AAe1D,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAA0B;AACxB,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,WAAW;AAAA,QACT,YAAY,YACR,wMACA;AAAA,MACN;AAAA,MACA,gBAAc;AAAA,MACb,GAAG;AAAA,MAEJ,8BAAC,SAAI,WAAW,GAAG,QAAQ,SAAS,GAAI,UAAS;AAAA;AAAA,EACnD;AAEJ;AAEA,iBAAiB,cAAc,mBAAmB,QAAQ;",
4
+ "sourcesContent": ["/**\n * @module Accordion\n *\n * A vertically stacked set of interactive headings that reveal/hide associated content.\n * Built on Radix UI Accordion primitive with custom styling variants.\n *\n * @see {@link https://ui.shadcn.com/docs/components/accordion Shadcn Accordion}\n * @see {@link https://www.radix-ui.com/primitives/docs/components/accordion Radix Accordion}\n *\n * @example\n * // Basic single-select accordion\n * <Accordion type=\"single\" collapsible>\n * <AccordionItem value=\"item-1\">\n * <AccordionTrigger>Section 1</AccordionTrigger>\n * <AccordionContent>Content for section 1</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n *\n * @example\n * // Multi-select accordion with HC variant (dark theme)\n * <Accordion type=\"multiple\" variant=\"hc\">\n * <AccordionItem value=\"faq-1\" variant=\"hc\">\n * <AccordionTrigger variant=\"hc\">What is Uppbeat?</AccordionTrigger>\n * <AccordionContent variant=\"hc\">Royalty-free music platform</AccordionContent>\n * </AccordionItem>\n * </Accordion>\n */\nimport { ChevronDown } from \"lucide-react\";\nimport { Accordion as AccordionPrimitive } from \"radix-ui\";\nimport type { Ref } from \"react\";\nimport type * as React from \"react\";\nimport { cn } from \"../lib/utils\";\n\n/**\n * Visual style variants for the accordion.\n * - `default`: Light theme with subtle borders\n * - `hc`: High contrast dark theme variant\n */\ntype AccordionVariant = \"default\" | \"hc\";\n\ntype AccordionItemProps = React.ComponentPropsWithoutRef<\n typeof AccordionPrimitive.Item\n> & {\n variant?: AccordionVariant;\n};\n\ntype AccordionProps = React.ComponentPropsWithoutRef<\n typeof AccordionPrimitive.Root\n> & {\n variant?: AccordionVariant;\n};\n\n/**\n * Root container for accordion items. Controls single or multiple expansion.\n *\n * @param type - `\"single\"` allows one item open at a time, `\"multiple\"` allows many\n * @param collapsible - When `type=\"single\"`, allows closing all items (default: false)\n * @param variant - Visual style: `\"default\"` or `\"hc\"` (high contrast)\n */\nfunction Accordion({ variant = \"default\", ...props }: AccordionProps) {\n return (\n <AccordionPrimitive.Root\n className={cn(variant === \"hc\" && \"hc-accordion\")}\n {...props}\n />\n );\n}\n\nAccordion.displayName = \"Accordion\";\n\n/**\n * Wrapper for each accordion section. Must have a unique `value` prop.\n *\n * @param value - Unique identifier for this item (required)\n * @param variant - Visual style matching parent Accordion\n * @param disabled - Prevents interaction when true\n */\nfunction AccordionItem({\n className,\n variant = \"default\",\n ...props\n}: AccordionItemProps) {\n return (\n <AccordionPrimitive.Item\n className={cn(\n variant === \"default\"\n ? \"border-0 border-gray-150 border-b-1 border-solid bg-transparent transition-colors md:mb-1 dark:border-gray-800 [&:has(:focus-visible)]:ring-2 [&:has(:focus-visible)]:ring-[var(--focus-ring)] [&:has(:focus-visible)]:ring-offset-8 dark:[&:has(:focus-visible)]:ring-offset-gray-950\"\n : \"border-0 border-gray-800 border-b-1 border-solid bg-transparent transition-colors [&:has(:focus-visible)]:ring-2 [&:has(:focus-visible)]:ring-[var(--focus-ring)] [&:has(:focus-visible)]:ring-offset-8 [&:has(:focus-visible)]:ring-offset-gray-950 [&:has([data-state='open'])]:border-transparent\",\n \"last-of-type:border-b-0\",\n className\n )}\n data-variant={variant}\n {...props}\n />\n );\n}\n\nAccordionItem.displayName = \"AccordionItem\";\n\n/** Props for AccordionTrigger component */\ninterface AccordionTriggerProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> {\n variant?: AccordionVariant;\n headerClassName?: string;\n triggerChildrenClassName?: string;\n}\n\n/**\n * Clickable heading that toggles the associated AccordionContent.\n * Includes an animated chevron indicator.\n *\n * @param variant - Visual style: `\"default\"` or `\"hc\"`\n * @param headerClassName - Additional classes for the header wrapper\n * @param triggerChildrenClassName - Additional classes for the inner content wrapper\n */\nfunction AccordionTrigger({\n className,\n children,\n variant = \"default\",\n headerClassName,\n triggerChildrenClassName,\n ...props\n}: AccordionTriggerProps) {\n return (\n <AccordionPrimitive.Header className={cn(\"flex\", headerClassName)}>\n <AccordionPrimitive.Trigger\n className={cn(\n variant === \"default\"\n ? \"group my-4 flex flex-1 items-center justify-between text-left font-sans font-semibold text-base text-gray-950 transition-all md:my-3 2xl:my-2 2xl:text-lg dark:text-white [&>[data-icon='closed']]:data-[state=closed]:block [&>[data-icon='open']]:data-[state=open]:block [&>[data-icon]]:hidden\"\n : \"group my-3 flex flex-1 items-center justify-between text-left font-sans font-semibold text-base text-white transition-all 2xl:text-lg [&>[data-icon='closed']]:data-[state=closed]:block [&>[data-icon='open']]:data-[state=open]:block [&>[data-icon]]:hidden\",\n className\n )}\n data-variant={variant}\n style={{ WebkitTapHighlightColor: \"transparent\" }}\n {...props}\n >\n <div\n className={cn(\n \"flex flex-1 items-center justify-between gap-1 rounded-sm py-2 font-semibold text-base transition-colors 2xl:text-lg\",\n variant === \"default\"\n ? \"md:px-2 md:hover:bg-gray-50 dark:md:hover:bg-gray-900\"\n : \"-my-1 px-2 hover:bg-gray-900\",\n triggerChildrenClassName\n )}\n >\n {children}\n <ChevronDown className=\"w-5 transition-transform duration-150 group-data-[state=open]:rotate-180\" />\n </div>\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nAccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;\n\n/** Props for AccordionContent component */\ninterface AccordionContentProps\n extends React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content> {\n variant?: AccordionVariant;\n}\n\n/**\n * Collapsible content panel with smooth expand/collapse animation.\n * Automatically hidden when parent AccordionItem is closed.\n *\n * @param variant - Visual style: `\"default\"` or `\"hc\"`\n * @param forceMount - Keep content in DOM even when closed (useful for SEO/forms)\n */\nfunction AccordionContent({\n className,\n children,\n variant = \"default\",\n ...props\n}: AccordionContentProps) {\n return (\n <AccordionPrimitive.Content\n className={cn(\n variant === \"default\"\n ? \"overflow-hidden text-left font-sans text-gray-700 text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down md:px-2 2xl:text-base dark:text-gray-200\"\n : \"-mx-6 ~px-6/12 overflow-hidden bg-gray-900 pt-6 text-left font-sans text-gray-400 text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down 2xl:text-base\"\n )}\n data-variant={variant}\n {...props}\n >\n <div className={cn(\"pb-8\", className)}>{children}</div>\n </AccordionPrimitive.Content>\n );\n}\n\nAccordionContent.displayName = AccordionPrimitive.Content.displayName;\n\nexport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n type AccordionContentProps,\n type AccordionItemProps,\n type AccordionProps,\n type AccordionTriggerProps,\n type AccordionVariant,\n};\n"],
5
+ "mappings": "AA6DI,cA2EI,YA3EJ;AAlCJ,SAAS,mBAAmB;AAC5B,SAAS,aAAa,0BAA0B;AAGhD,SAAS,UAAU;AA4BnB,SAAS,UAAU,EAAE,UAAU,WAAW,GAAG,MAAM,GAAmB;AACpE,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,WAAW,GAAG,YAAY,QAAQ,cAAc;AAAA,MAC/C,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,UAAU,cAAc;AASxB,SAAS,cAAc;AAAA,EACrB;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAAuB;AACrB,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,WAAW;AAAA,QACT,YAAY,YACR,2RACA;AAAA,QACJ;AAAA,QACA;AAAA,MACF;AAAA,MACA,gBAAc;AAAA,MACb,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,cAAc,cAAc;AAkB5B,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,SACE,oBAAC,mBAAmB,QAAnB,EAA0B,WAAW,GAAG,QAAQ,eAAe,GAC9D;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,WAAW;AAAA,QACT,YAAY,YACR,uSACA;AAAA,QACJ;AAAA,MACF;AAAA,MACA,gBAAc;AAAA,MACd,OAAO,EAAE,yBAAyB,cAAc;AAAA,MAC/C,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,YAAY,YACR,0DACA;AAAA,YACJ;AAAA,UACF;AAAA,UAEC;AAAA;AAAA,YACD,oBAAC,eAAY,WAAU,4EAA2E;AAAA;AAAA;AAAA,MACpG;AAAA;AAAA,EACF,GACF;AAEJ;AAEA,iBAAiB,cAAc,mBAAmB,QAAQ;AAe1D,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAA0B;AACxB,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,WAAW;AAAA,QACT,YAAY,YACR,wMACA;AAAA,MACN;AAAA,MACA,gBAAc;AAAA,MACb,GAAG;AAAA,MAEJ,8BAAC,SAAI,WAAW,GAAG,QAAQ,SAAS,GAAI,UAAS;AAAA;AAAA,EACnD;AAEJ;AAEA,iBAAiB,cAAc,mBAAmB,QAAQ;",
6
6
  "names": []
7
7
  }
@@ -12,7 +12,7 @@
12
12
  *
13
13
  * @example
14
14
  * // Badge variants
15
- * <Badge variant="pink">Premium</Badge>
15
+ * <Badge variant="brand">Premium</Badge>
16
16
  * <Badge variant="success">Active</Badge>
17
17
  * <Badge variant="error">Expired</Badge>
18
18
  *
@@ -29,7 +29,7 @@ import type * as React from "react";
29
29
  * Includes color variants matching Button component for consistency.
30
30
  */
31
31
  declare const badgeVariants: (props?: ({
32
- variant?: "contrast" | "bold" | "pink" | "white" | "transparent" | "light" | "subtle" | "pinkSecondary" | "success" | "error" | "primary" | "secondary" | "destructive" | "lightPink" | "outline" | "free" | "pink-200" | null | undefined;
32
+ variant?: "contrast" | "bold" | "white" | "transparent" | "light" | "subtle" | "brand" | "brandSecondary" | "success" | "error" | "primary" | "secondary" | "destructive" | "brandLight" | "outline" | null | undefined;
33
33
  size?: "xs" | "sm" | "lg" | "default" | "icon" | null | undefined;
34
34
  shadow?: boolean | null | undefined;
35
35
  strong?: boolean | null | undefined;
@@ -37,7 +37,7 @@ declare const badgeVariants: (props?: ({
37
37
  /**
38
38
  * Props for the Badge component.
39
39
  *
40
- * @property variant - Color scheme: `pink`, `success`, `error`, `subtle`, `bold`, etc.
40
+ * @property variant - Color scheme: `brand`, `brandSecondary`, `success`, `error`, `subtle`, `bold`, etc.
41
41
  * @property size - Size variant: `xs`, `sm`, `default`, `lg`, `icon`
42
42
  * @property shadow - Add drop shadow when true
43
43
  * @property strong - Use semibold font weight when true
@@ -1 +1 @@
1
- {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../src/components/badge.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAIpC;;;GAGG;AACH,QAAA,MAAM,aAAa;;;;;8EAwDlB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,WAAW,UACf,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAC1C,YAAY,CAAC,OAAO,aAAa,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,QAAA,MAAM,KAAK,GAAI,sEASZ,UAAU,4CAaZ,CAAC;AAEF,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../src/components/badge.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAIpC;;;GAGG;AACH,QAAA,MAAM,aAAa;;;;;8EAsDlB,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,WAAW,UACf,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAC1C,YAAY,CAAC,OAAO,aAAa,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,QAAA,MAAM,KAAK,GAAI,sEASZ,UAAU,4CAaZ,CAAC;AAEF,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC"}
@@ -9,22 +9,20 @@ const badgeVariants = cva(
9
9
  variant: {
10
10
  // Matching button variants (without hover/disabled states)
11
11
  subtle: "border-1 border-gray-150 border-solid bg-white text-gray-950 dark:border-gray-800 dark:bg-gray-950 dark:text-white",
12
- pink: "border-1 border-pink-500 border-solid bg-pink-500 text-white",
13
- pinkSecondary: "border-1 border-pink-50 border-solid bg-pink-50 text-pink-600 dark:border-gray-900 dark:bg-gray-900 dark:text-white",
14
- bold: "border-gray-950 bg-gray-950 text-white dark:border-white dark:bg-white dark:text-gray-950",
12
+ brand: "border-1 border-brand-primary border-solid bg-brand-primary text-white",
13
+ brandSecondary: "border-1 border-brand-secondary border-solid bg-brand-secondary text-brand-primary-hover dark:border-gray-900 dark:bg-gray-900 dark:text-white",
14
+ bold: "border-gray-950 bg-gray-950 text-white dark:border-white dark:bg-white dark:text-gray-950",
15
15
  light: "border-gray-150 bg-gray-100 text-gray-950 dark:border-gray-800 dark:bg-gray-800 dark:text-white",
16
16
  transparent: "border-transparent bg-transparent text-gray-950 dark:text-white",
17
17
  contrast: "border-white bg-white text-gray-950",
18
- success: "border-green-500 bg-green-500 text-white dark:border-green-400 dark:bg-green-400",
18
+ success: "border-green-600 bg-green-600 text-white dark:border-green-500 dark:bg-green-500",
19
19
  error: "border-red-600 bg-red-600 text-white dark:border-red-500 dark:bg-red-500",
20
20
  primary: "border-gray-900 bg-gray-900 text-white dark:border-gray-50 dark:bg-gray-50 dark:text-gray-950",
21
21
  secondary: "border-gray-150 bg-gray-100 text-gray-950 dark:border-gray-800 dark:bg-gray-800 dark:text-white",
22
22
  destructive: "border-red bg-red text-white",
23
- white: "border-neutral-200 bg-white text-pink-500",
24
- lightPink: "border-pink-100 bg-pink-50 text-pink-600",
25
- outline: "border border-gray-200 border-solid bg-transparent text-gray-800 focus-visible:ring-gray-500 dark:border-gray-800 dark:bg-transparent dark:text-white dark:focus-visible:ring-gray-400",
26
- free: "border-free bg-free text-gray-950",
27
- "pink-200": "border-pink-100 bg-pink-200 text-pink-500"
23
+ white: "border-neutral-200 bg-white text-brand-primary",
24
+ brandLight: "border-brand-secondary bg-brand-secondary text-brand-primary-hover",
25
+ outline: "border border-gray-200 border-solid bg-transparent text-gray-800 focus-visible:ring-gray-500 dark:border-gray-800 dark:bg-transparent dark:text-white dark:focus-visible:ring-gray-400"
28
26
  },
29
27
  size: {
30
28
  default: "h-8 px-4 py-2 leading-8",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/badge.tsx"],
4
- "sourcesContent": ["/**\n * @module Badge\n *\n * Small status indicators and labels for highlighting information.\n * Supports multiple color variants and sizes for different contexts.\n *\n * @see {@link https://ui.shadcn.com/docs/components/badge Shadcn Badge}\n *\n * @example\n * // Basic badge\n * <Badge>New</Badge>\n *\n * @example\n * // Badge variants\n * <Badge variant=\"pink\">Premium</Badge>\n * <Badge variant=\"success\">Active</Badge>\n * <Badge variant=\"error\">Expired</Badge>\n *\n * @example\n * // As a child element (e.g., wrapping a link)\n * <Badge asChild variant=\"outline\">\n * <a href=\"/pricing\">View Plans</a>\n * </Badge>\n */\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot as SlotPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\n/**\n * CVA variants for Badge styling.\n * Includes color variants matching Button component for consistency.\n */\nconst badgeVariants = cva(\n \"inline-flex items-center rounded-full border transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 dark:focus-visible:ring-neutral-300\",\n {\n variants: {\n variant: {\n // Matching button variants (without hover/disabled states)\n subtle:\n \"border-1 border-gray-150 border-solid bg-white text-gray-950 dark:border-gray-800 dark:bg-gray-950 dark:text-white\",\n pink: \"border-1 border-pink-500 border-solid bg-pink-500 text-white\",\n pinkSecondary:\n \"border-1 border-pink-50 border-solid bg-pink-50 text-pink-600 dark:border-gray-900 dark:bg-gray-900 dark:text-white\",\n bold: \"border-gray-950 bg-gray-950 text-white dark:border-white dark:bg-white dark:text-gray-950\",\n light:\n \"border-gray-150 bg-gray-100 text-gray-950 dark:border-gray-800 dark:bg-gray-800 dark:text-white\",\n transparent:\n \"border-transparent bg-transparent text-gray-950 dark:text-white\",\n contrast: \"border-white bg-white text-gray-950\",\n success:\n \"border-green-500 bg-green-500 text-white dark:border-green-400 dark:bg-green-400\",\n error:\n \"border-red-600 bg-red-600 text-white dark:border-red-500 dark:bg-red-500\",\n primary:\n \"border-gray-900 bg-gray-900 text-white dark:border-gray-50 dark:bg-gray-50 dark:text-gray-950\",\n secondary:\n \"border-gray-150 bg-gray-100 text-gray-950 dark:border-gray-800 dark:bg-gray-800 dark:text-white\",\n destructive: \"border-red bg-red text-white\",\n white: \"border-neutral-200 bg-white text-pink-500\",\n lightPink: \"border-pink-100 bg-pink-50 text-pink-600\",\n outline:\n \"border border-gray-200 border-solid bg-transparent text-gray-800 focus-visible:ring-gray-500 dark:border-gray-800 dark:bg-transparent dark:text-white dark:focus-visible:ring-gray-400\",\n free: \"border-free bg-free text-gray-950\",\n \"pink-200\": \"border-pink-100 bg-pink-200 text-pink-500\",\n },\n size: {\n default: \"h-8 px-4 py-2 leading-8\",\n xs: \"h-5 gap-1.5 px-2 text-xs leading-5\",\n sm: \"h-6 px-2.5 text-xs leading-6 2xl:text-sm\",\n lg: \"h-10 gap-4 px-8 text-lg leading-10\",\n icon: \"h-8 w-8 leading-8\",\n },\n shadow: {\n true: \"shadow\",\n false: \"\",\n },\n strong: {\n true: \"font-semibold\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"bold\",\n size: \"default\",\n shadow: false,\n strong: false,\n },\n }\n);\n\n/**\n * Props for the Badge component.\n *\n * @property variant - Color scheme: `pink`, `success`, `error`, `subtle`, `bold`, etc.\n * @property size - Size variant: `xs`, `sm`, `default`, `lg`, `icon`\n * @property shadow - Add drop shadow when true\n * @property strong - Use semibold font weight when true\n * @property asChild - Render as child element (uses Radix Slot)\n * @property ref - Ref to the underlying div element\n */\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n asChild?: boolean;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Displays a small label or status indicator.\n *\n * Common use cases:\n * - Subscription status (Free, Premium)\n * - Item counts\n * - Status indicators (New, Sale, Popular)\n * - Tags and categories\n */\nconst Badge = ({\n className,\n variant,\n size,\n shadow,\n strong,\n asChild = false,\n ref,\n ...props\n}: BadgeProps) => {\n const Comp = asChild ? SlotPrimitive.Slot : \"div\";\n\n return (\n <Comp\n className={cn(\n badgeVariants({ variant, size, shadow, strong }),\n className\n )}\n ref={ref}\n {...props}\n />\n );\n};\n\nexport { Badge, badgeVariants };\n"],
5
- "mappings": "AAmII;AA3GJ,SAAS,WAA8B;AACvC,SAAS,QAAQ,qBAAqB;AAGtC,SAAS,UAAU;AAMnB,MAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA;AAAA,QAEP,QACE;AAAA,QACF,MAAM;AAAA,QACN,eACE;AAAA,QACF,MAAM;AAAA,QACN,OACE;AAAA,QACF,aACE;AAAA,QACF,UAAU;AAAA,QACV,SACE;AAAA,QACF,OACE;AAAA,QACF,SACE;AAAA,QACF,WACE;AAAA,QACF,aAAa;AAAA,QACb,OAAO;AAAA,QACP,WAAW;AAAA,QACX,SACE;AAAA,QACF,MAAM;AAAA,QACN,YAAY;AAAA,MACd;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AA4BA,MAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA,GAAG;AACL,MAAkB;AAChB,QAAM,OAAO,UAAU,cAAc,OAAO;AAE5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT,cAAc,EAAE,SAAS,MAAM,QAAQ,OAAO,CAAC;AAAA,QAC/C;AAAA,MACF;AAAA,MACA;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;",
4
+ "sourcesContent": ["/**\n * @module Badge\n *\n * Small status indicators and labels for highlighting information.\n * Supports multiple color variants and sizes for different contexts.\n *\n * @see {@link https://ui.shadcn.com/docs/components/badge Shadcn Badge}\n *\n * @example\n * // Basic badge\n * <Badge>New</Badge>\n *\n * @example\n * // Badge variants\n * <Badge variant=\"brand\">Premium</Badge>\n * <Badge variant=\"success\">Active</Badge>\n * <Badge variant=\"error\">Expired</Badge>\n *\n * @example\n * // As a child element (e.g., wrapping a link)\n * <Badge asChild variant=\"outline\">\n * <a href=\"/pricing\">View Plans</a>\n * </Badge>\n */\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot as SlotPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\n/**\n * CVA variants for Badge styling.\n * Includes color variants matching Button component for consistency.\n */\nconst badgeVariants = cva(\n \"inline-flex items-center rounded-full border transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 dark:focus-visible:ring-neutral-300\",\n {\n variants: {\n variant: {\n // Matching button variants (without hover/disabled states)\n subtle:\n \"border-1 border-gray-150 border-solid bg-white text-gray-950 dark:border-gray-800 dark:bg-gray-950 dark:text-white\",\n brand: \"border-1 border-brand-primary border-solid bg-brand-primary text-white\",\n brandSecondary:\n \"border-1 border-brand-secondary border-solid bg-brand-secondary text-brand-primary-hover dark:border-gray-900 dark:bg-gray-900 dark:text-white\",\n bold: \"border-gray-950 bg-gray-950 text-white dark:border-white dark:bg-white dark:text-gray-950\",\n light:\n \"border-gray-150 bg-gray-100 text-gray-950 dark:border-gray-800 dark:bg-gray-800 dark:text-white\",\n transparent:\n \"border-transparent bg-transparent text-gray-950 dark:text-white\",\n contrast: \"border-white bg-white text-gray-950\",\n success:\n \"border-green-600 bg-green-600 text-white dark:border-green-500 dark:bg-green-500\",\n error:\n \"border-red-600 bg-red-600 text-white dark:border-red-500 dark:bg-red-500\",\n primary:\n \"border-gray-900 bg-gray-900 text-white dark:border-gray-50 dark:bg-gray-50 dark:text-gray-950\",\n secondary:\n \"border-gray-150 bg-gray-100 text-gray-950 dark:border-gray-800 dark:bg-gray-800 dark:text-white\",\n destructive: \"border-red bg-red text-white\",\n white: \"border-neutral-200 bg-white text-brand-primary\",\n brandLight: \"border-brand-secondary bg-brand-secondary text-brand-primary-hover\",\n outline:\n \"border border-gray-200 border-solid bg-transparent text-gray-800 focus-visible:ring-gray-500 dark:border-gray-800 dark:bg-transparent dark:text-white dark:focus-visible:ring-gray-400\",\n },\n size: {\n default: \"h-8 px-4 py-2 leading-8\",\n xs: \"h-5 gap-1.5 px-2 text-xs leading-5\",\n sm: \"h-6 px-2.5 text-xs leading-6 2xl:text-sm\",\n lg: \"h-10 gap-4 px-8 text-lg leading-10\",\n icon: \"h-8 w-8 leading-8\",\n },\n shadow: {\n true: \"shadow\",\n false: \"\",\n },\n strong: {\n true: \"font-semibold\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"bold\",\n size: \"default\",\n shadow: false,\n strong: false,\n },\n }\n);\n\n/**\n * Props for the Badge component.\n *\n * @property variant - Color scheme: `brand`, `brandSecondary`, `success`, `error`, `subtle`, `bold`, etc.\n * @property size - Size variant: `xs`, `sm`, `default`, `lg`, `icon`\n * @property shadow - Add drop shadow when true\n * @property strong - Use semibold font weight when true\n * @property asChild - Render as child element (uses Radix Slot)\n * @property ref - Ref to the underlying div element\n */\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n asChild?: boolean;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Displays a small label or status indicator.\n *\n * Common use cases:\n * - Subscription status (Free, Premium)\n * - Item counts\n * - Status indicators (New, Sale, Popular)\n * - Tags and categories\n */\nconst Badge = ({\n className,\n variant,\n size,\n shadow,\n strong,\n asChild = false,\n ref,\n ...props\n}: BadgeProps) => {\n const Comp = asChild ? SlotPrimitive.Slot : \"div\";\n\n return (\n <Comp\n className={cn(\n badgeVariants({ variant, size, shadow, strong }),\n className\n )}\n ref={ref}\n {...props}\n />\n );\n};\n\nexport { Badge, badgeVariants };\n"],
5
+ "mappings": "AAiII;AAzGJ,SAAS,WAA8B;AACvC,SAAS,QAAQ,qBAAqB;AAGtC,SAAS,UAAU;AAMnB,MAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA;AAAA,QAEP,QACE;AAAA,QACF,OAAO;AAAA,QACP,gBACE;AAAA,QACF,MAAM;AAAA,QACN,OACE;AAAA,QACF,aACE;AAAA,QACF,UAAU;AAAA,QACV,SACE;AAAA,QACF,OACE;AAAA,QACF,SACE;AAAA,QACF,WACE;AAAA,QACF,aAAa;AAAA,QACb,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,SACE;AAAA,MACJ;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AA4BA,MAAM,QAAQ,CAAC;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA,GAAG;AACL,MAAkB;AAChB,QAAM,OAAO,UAAU,cAAc,OAAO;AAE5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT,cAAc,EAAE,SAAS,MAAM,QAAQ,OAAO,CAAC;AAAA,QAC/C;AAAA,MACF;AAAA,MACA;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -9,7 +9,7 @@
9
9
  * @example
10
10
  * // Basic buttons
11
11
  * <Button>Default</Button>
12
- * <Button variant="pink">Primary Action</Button>
12
+ * <Button variant="brand">Primary Action</Button>
13
13
  * <Button variant="subtle">Secondary</Button>
14
14
  *
15
15
  * @example
@@ -31,7 +31,7 @@
31
31
  *
32
32
  * @example
33
33
  * // As link (using asChild)
34
- * <Button asChild variant="pink">
34
+ * <Button asChild variant="brand">
35
35
  * <a href="/signup">Sign Up</a>
36
36
  * </Button>
37
37
  *
@@ -47,7 +47,7 @@ import type { ButtonHTMLAttributes, Ref } from "react";
47
47
  type ButtonSize = "default" | "xs" | "sm" | "lg" | "icon" | "xl";
48
48
  type ButtonFontSize = "xxs" | "xs" | "sm" | "base" | "lg" | "xl" | null;
49
49
  declare const buttonVariants: (props?: ({
50
- variant?: "contrast" | "bold" | "pink" | "transparent" | "light" | "subtle" | "pinkSecondary" | "success" | "error" | null | undefined;
50
+ variant?: "contrast" | "bold" | "transparent" | "light" | "subtle" | "brand" | "brandSecondary" | "success" | "error" | null | undefined;
51
51
  size?: "xs" | "sm" | "lg" | "xl" | "default" | "icon" | null | undefined;
52
52
  fontSize?: "xs" | "sm" | "base" | "lg" | "xl" | "xxs" | "null" | null | undefined;
53
53
  borderRadius?: "rounded" | "sm" | "default" | "full" | null | undefined;
@@ -77,7 +77,7 @@ type ResponsiveButtonFontSize = Exclude<ButtonFontSize, null> | {
77
77
  /**
78
78
  * Props for the Button component.
79
79
  *
80
- * @property variant - Color/style: `pink`, `subtle`, `bold`, `light`, `transparent`, `contrast`, `success`, `error`
80
+ * @property variant - Color/style: `brand`, `brandSecondary`, `subtle`, `bold`, `light`, `transparent`, `contrast`, `success`, `error`
81
81
  * @property size - Size or responsive size object: `xs`, `sm`, `default`, `lg`, `xl`, `icon`
82
82
  * @property fontSize - Override font size or responsive font size object
83
83
  * @property borderRadius - Corner style: `default`, `sm`, `full`, `rounded`
@@ -28,19 +28,19 @@ const defaultFontSizeForSize = {
28
28
  xl: "lg"
29
29
  };
30
30
  const buttonVariants = cva(
31
- "inline-flex items-center justify-center gap-2 whitespace-nowrap font-normal font-sans text-base transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-pink-500 focus-visible:ring-offset-2 enabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-50 dark:focus-visible:ring-offset-gray-950",
31
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap font-normal font-sans text-base transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--focus-ring-offset)] enabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-50",
32
32
  {
33
33
  variants: {
34
34
  variant: {
35
- // NEW BRANDING VARIANTS
36
- subtle: "border-1 border-gray-150 border-solid bg-white text-gray-950 hover:bg-gray-50 active:border-pink-600 active:bg-pink-50 active:text-pink-600 disabled:bg-gray-50 active:disabled:border-gray-150 active:disabled:bg-gray-50 active:disabled:text-gray-950 dark:border-gray-800 dark:bg-gray-950 dark:text-white dark:disabled:border-gray-900 dark:disabled:bg-gray-950 dark:disabled:text-white dark:active:border-white dark:active:text-white dark:disabled:active:border-gray-900 dark:disabled:active:bg-gray-950 dark:disabled:active:text-white dark:hover:bg-gray-900",
37
- pink: "border-1 border-pink-500 border-solid bg-pink-500 font-semibold text-white hover:border-pink-600 hover:bg-pink-600 disabled:hover:bg-pink-600 dark:hover:border-pink-600 dark:hover:bg-pink-600",
38
- pinkSecondary: "border-1 border-pink-50 border-solid bg-pink-50 font-semibold text-pink-600 hover:border-pink-100 hover:bg-pink-100 disabled:hover:bg-pink-100 dark:border-gray-900 dark:bg-gray-900 dark:text-white hover:dark:border-gray-800 hover:dark:bg-gray-800 dark:disabled:hover:border-gray-900 dark:disabled:hover:bg-gray-900",
35
+ // BRANDING VARIANTS (use CSS variables for themeability)
36
+ subtle: "border-1 border-gray-150 border-solid bg-white text-gray-950 hover:bg-gray-50 active:border-brand-primary-hover active:bg-brand-secondary active:text-brand-primary-hover disabled:bg-gray-50 active:disabled:border-gray-150 active:disabled:bg-gray-50 active:disabled:text-gray-950 dark:border-gray-800 dark:bg-gray-950 dark:text-white dark:disabled:border-gray-900 dark:disabled:bg-gray-950 dark:disabled:text-white dark:active:border-white dark:active:text-white dark:disabled:active:border-gray-900 dark:disabled:active:bg-gray-950 dark:disabled:active:text-white dark:hover:bg-gray-900",
37
+ brand: "border-1 border-brand-primary border-solid bg-brand-primary font-semibold text-white hover:border-brand-primary-hover hover:bg-brand-primary-hover disabled:hover:bg-brand-primary-hover",
38
+ brandSecondary: "border-1 border-brand-secondary border-solid bg-brand-secondary font-semibold text-brand-primary-hover hover:border-brand-secondary-hover hover:bg-brand-secondary-hover disabled:hover:bg-brand-secondary-hover dark:border-gray-900 dark:bg-gray-900 hover:dark:border-gray-800 hover:dark:bg-gray-800 dark:text-white dark:disabled:hover:border-gray-900 dark:disabled:hover:bg-gray-900",
39
39
  bold: "border-gray-950 bg-gray-950 font-semibold text-white dark:border-white dark:bg-white dark:text-gray-950",
40
- light: "border-gray-150 bg-gray-100 font-semibold text-gray-950 hover:border-gray-200 hover:bg-gray-200 disabled:hover:border-gray-150 disabled:hover:bg-gray-100 dark:border-gray-800 dark:bg-gray-800 dark:text-white dark:hover:border-gray-700 dark:hover:bg-gray-700 dark:hover:disabled:border-gray-800 dark:hover:disabled:bg-gray-800",
40
+ light: "border-gray-150 bg-gray-100 font-semibold text-gray-950 hover:border-gray-200 hover:bg-gray-200 disabled:hover:border-gray-150 disabled:hover:bg-gray-100 dark:border-gray-800 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700 dark:disabled:hover:bg-gray-800",
41
41
  transparent: "!border-transparent bg-transparent font-semibold text-gray-950 hover:border-gray-50 hover:bg-gray-50 disabled:hover:border-transparent disabled:hover:bg-transparent dark:text-white dark:hover:border-gray-900 dark:hover:bg-gray-900",
42
- contrast: "h border-white bg-white font-semibold text-gray-950 hover:bg-gray-50 hover:disabled:border-white hover:disabled:bg-white",
43
- success: "border-green-500 bg-green-500 font-semibold text-white hover:border-green-600 hover:bg-green-600 disabled:hover:border-green-500 disabled:hover:bg-green-500 dark:border-green-400 dark:bg-green-400 dark:hover:border-green-300 dark:hover:bg-green-300 dark:disabled:hover:border-green-400 dark:disabled:hover:bg-green-400",
42
+ contrast: "border-white bg-white font-semibold text-gray-950 hover:bg-gray-50 hover:disabled:border-white hover:disabled:bg-white",
43
+ success: "border-green-600 bg-green-600 font-semibold text-white hover:border-green-700 hover:bg-green-700 disabled:hover:border-green-600 disabled:hover:bg-green-600 dark:border-green-500 dark:bg-green-500 dark:hover:border-green-650 dark:hover:bg-green-650 dark:disabled:hover:border-green-500 dark:disabled:hover:bg-green-500",
44
44
  error: "border-red-600 bg-red-600 font-semibold text-white hover:bg-red-700 disabled:hover:border-red-700 disabled:hover:bg-red-700 dark:border-red-500 dark:bg-red-500 dark:hover:border-red-600 dark:hover:bg-red-600 dark:disabled:hover:border-red-600 dark:disabled:hover:bg-red-600"
45
45
  },
46
46
  size: sizeClasses,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/button.tsx"],
4
- "sourcesContent": ["/**\n * @module Button\n *\n * Versatile button component with multiple variants, sizes, and responsive options.\n * Supports all standard button interactions plus loading states and icon-only modes.\n *\n * @see {@link https://ui.shadcn.com/docs/components/button Shadcn Button}\n *\n * @example\n * // Basic buttons\n * <Button>Default</Button>\n * <Button variant=\"pink\">Primary Action</Button>\n * <Button variant=\"subtle\">Secondary</Button>\n *\n * @example\n * // Sizes\n * <Button size=\"xs\">Extra Small</Button>\n * <Button size=\"sm\">Small</Button>\n * <Button size=\"lg\">Large</Button>\n * <Button size=\"xl\">Extra Large</Button>\n *\n * @example\n * // Responsive size (changes at breakpoints)\n * <Button size={{ default: \"sm\", md: \"default\", lg: \"lg\" }}>\n * Responsive Button\n * </Button>\n *\n * @example\n * // Icon button\n * <Button icon size=\"default\"><PlayIcon /></Button>\n *\n * @example\n * // As link (using asChild)\n * <Button asChild variant=\"pink\">\n * <a href=\"/signup\">Sign Up</a>\n * </Button>\n *\n * @example\n * // With loading state\n * <Button disabled>\n * <Loading visible={isLoading} />\n * {isLoading ? \"Loading...\" : \"Submit\"}\n * </Button>\n */\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { LoaderCircle } from \"lucide-react\";\nimport { Slot as SlotPrimitive } from \"radix-ui\";\nimport type { ButtonHTMLAttributes, Ref } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\n/** Size classes for consistent button dimensions */\n// Define size classes once as a single source of truth (including leading but not font sizes)\nconst sizeClasses = {\n default: \"h-8 px-4 py-2 leading-8\",\n xs: \"h-5 gap-1.5 px-2 leading-5\",\n sm: \"h-7 px-3 py-2 leading-6\",\n lg: \"h-10 px-4 py-2 leading-8\",\n xl: \"h-12 px-8 py-3 leading-10\",\n icon: \"h-8 w-8 leading-8\",\n} as const;\n\nconst fontSizeClasses = {\n xxs: \"text-xxs\",\n xs: \"text-xs\",\n sm: \"text-sm\",\n base: \"text-base\",\n lg: \"text-lg\",\n xl: \"text-xl\",\n} as const;\n\n// Type definitions for responsive sizes\ntype ButtonSize = \"default\" | \"xs\" | \"sm\" | \"lg\" | \"icon\" | \"xl\";\n\ntype ButtonFontSize = \"xxs\" | \"xs\" | \"sm\" | \"base\" | \"lg\" | \"xl\" | null;\n\n// Default font size mapping based on button size (excludes null)\nconst defaultFontSizeForSize: Record<\n ButtonSize,\n Exclude<ButtonFontSize, null>\n> = {\n xs: \"xs\",\n sm: \"xs\",\n default: \"base\",\n lg: \"base\",\n icon: \"base\",\n xl: \"lg\",\n};\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap font-normal font-sans text-base transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-pink-500 focus-visible:ring-offset-2 enabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-50 dark:focus-visible:ring-offset-gray-950\",\n {\n variants: {\n variant: {\n // NEW BRANDING VARIANTS\n subtle:\n \"border-1 border-gray-150 border-solid bg-white text-gray-950 hover:bg-gray-50 active:border-pink-600 active:bg-pink-50 active:text-pink-600 disabled:bg-gray-50 active:disabled:border-gray-150 active:disabled:bg-gray-50 active:disabled:text-gray-950 dark:border-gray-800 dark:bg-gray-950 dark:text-white dark:disabled:border-gray-900 dark:disabled:bg-gray-950 dark:disabled:text-white dark:active:border-white dark:active:text-white dark:disabled:active:border-gray-900 dark:disabled:active:bg-gray-950 dark:disabled:active:text-white dark:hover:bg-gray-900\",\n pink: \"border-1 border-pink-500 border-solid bg-pink-500 font-semibold text-white hover:border-pink-600 hover:bg-pink-600 disabled:hover:bg-pink-600 dark:hover:border-pink-600 dark:hover:bg-pink-600\",\n pinkSecondary:\n \"border-1 border-pink-50 border-solid bg-pink-50 font-semibold text-pink-600 hover:border-pink-100 hover:bg-pink-100 disabled:hover:bg-pink-100 dark:border-gray-900 dark:bg-gray-900 dark:text-white hover:dark:border-gray-800 hover:dark:bg-gray-800 dark:disabled:hover:border-gray-900 dark:disabled:hover:bg-gray-900\",\n bold: \"border-gray-950 bg-gray-950 font-semibold text-white dark:border-white dark:bg-white dark:text-gray-950\",\n light:\n \"border-gray-150 bg-gray-100 font-semibold text-gray-950 hover:border-gray-200 hover:bg-gray-200 disabled:hover:border-gray-150 disabled:hover:bg-gray-100 dark:border-gray-800 dark:bg-gray-800 dark:text-white dark:hover:border-gray-700 dark:hover:bg-gray-700 dark:hover:disabled:border-gray-800 dark:hover:disabled:bg-gray-800\",\n transparent:\n \"!border-transparent bg-transparent font-semibold text-gray-950 hover:border-gray-50 hover:bg-gray-50 disabled:hover:border-transparent disabled:hover:bg-transparent dark:text-white dark:hover:border-gray-900 dark:hover:bg-gray-900\",\n contrast:\n \"h border-white bg-white font-semibold text-gray-950 hover:bg-gray-50 hover:disabled:border-white hover:disabled:bg-white\",\n success:\n \"border-green-500 bg-green-500 font-semibold text-white hover:border-green-600 hover:bg-green-600 disabled:hover:border-green-500 disabled:hover:bg-green-500 dark:border-green-400 dark:bg-green-400 dark:hover:border-green-300 dark:hover:bg-green-300 dark:disabled:hover:border-green-400 dark:disabled:hover:bg-green-400\",\n error:\n \"border-red-600 bg-red-600 font-semibold text-white hover:bg-red-700 disabled:hover:border-red-700 disabled:hover:bg-red-700 dark:border-red-500 dark:bg-red-500 dark:hover:border-red-600 dark:hover:bg-red-600 dark:disabled:hover:border-red-600 dark:disabled:hover:bg-red-600\",\n },\n\n size: sizeClasses,\n fontSize: {\n ...fontSizeClasses,\n null: \"\", // No font size class, relies on compound variants\n },\n borderRadius: {\n default: \"rounded-lg\",\n sm: \"rounded\",\n full: \"rounded-full\",\n rounded: \"rounded-[100px]\",\n },\n border: {\n true: \"border border-solid\",\n false: \"border-none\",\n },\n noFeedback: {\n true: \"\",\n false: \"transition-scale active:scale-[0.97] disabled:scale-100\",\n },\n },\n compoundVariants: [\n // Size + BorderRadius compounds\n {\n size: \"sm\",\n borderRadius: \"default\",\n className: \"rounded-lg\",\n },\n {\n size: \"xs\",\n borderRadius: \"default\",\n className: \"rounded-md\",\n },\n\n // Variant + Border compounds\n {\n variant: \"transparent\",\n border: true,\n className: \"border-gray-200 dark:border-gray-800\",\n },\n {\n variant: \"success\",\n border: true,\n className: \"border-green-dark\",\n },\n {\n variant: \"contrast\",\n border: true,\n className: \"border-white\",\n },\n // Size + fontSize compounds (default font size for each size when no explicit fontSize)\n { size: \"xs\", fontSize: null, className: \"text-xs\" },\n { size: \"sm\", fontSize: null, className: \"text-xs\" },\n { size: \"default\", fontSize: null, className: \"text-base\" },\n { size: \"lg\", fontSize: null, className: \"text-base\" },\n { size: \"icon\", fontSize: null, className: \"text-base\" },\n { size: \"xl\", fontSize: null, className: \"text-lg\" },\n ],\n defaultVariants: {\n variant: \"bold\",\n size: \"default\",\n fontSize: null,\n borderRadius: \"default\",\n border: false,\n noFeedback: false,\n },\n }\n);\n\ntype ResponsiveButtonSize =\n | ButtonSize\n | {\n default: ButtonSize;\n xxs?: ButtonSize;\n xs?: ButtonSize;\n sm?: ButtonSize;\n md?: ButtonSize;\n lg?: ButtonSize;\n xl?: ButtonSize;\n \"2xl\"?: ButtonSize;\n };\n\ntype ResponsiveButtonFontSize =\n | Exclude<ButtonFontSize, null>\n | {\n default?: Exclude<ButtonFontSize, null>;\n xxs?: Exclude<ButtonFontSize, null>;\n xs?: Exclude<ButtonFontSize, null>;\n sm?: Exclude<ButtonFontSize, null>;\n md?: Exclude<ButtonFontSize, null>;\n lg?: Exclude<ButtonFontSize, null>;\n xl?: Exclude<ButtonFontSize, null>;\n \"2xl\"?: Exclude<ButtonFontSize, null>;\n };\n\nconst getSizeClasses = (sizeKey: ButtonSize): string =>\n sizeClasses[sizeKey] || \"\";\n\nconst getFontSizeClasses = (\n fontSizeKey: Exclude<ButtonFontSize, null>\n): string => fontSizeClasses[fontSizeKey] || \"\";\n\n// Function to generate responsive Tailwind classes\nfunction generateResponsiveSizeClasses(size?: ResponsiveButtonSize): string {\n if (!size || typeof size === \"string\") {\n return \"\";\n }\n\n const classes: string[] = [];\n\n // Add responsive classes for each breakpoint\n const breakpoints = [\n { prefix: \"xxs\", value: size.xxs },\n { prefix: \"xs\", value: size.xs },\n { prefix: \"sm\", value: size.sm },\n { prefix: \"md\", value: size.md },\n { prefix: \"lg\", value: size.lg },\n { prefix: \"xl\", value: size.xl },\n { prefix: \"2xl\", value: size[\"2xl\"] },\n ];\n\n for (const breakpoint of breakpoints) {\n if (breakpoint.value) {\n const breakpointSizeClasses = getSizeClasses(breakpoint.value);\n const responsiveClasses = breakpointSizeClasses\n .split(\" \")\n .filter((cls) => cls.trim() !== \"\")\n .map((cls) => `${breakpoint.prefix}:${cls}`)\n .join(\" \");\n if (responsiveClasses) {\n classes.push(responsiveClasses);\n }\n }\n }\n\n return classes.join(\" \");\n}\n\nfunction generateResponsiveFontSizeClasses(\n fontSize?: ResponsiveButtonFontSize\n): string {\n if (!fontSize || typeof fontSize === \"string\") {\n return \"\";\n }\n\n const classes: string[] = [];\n\n // Add responsive classes for each breakpoint\n const breakpoints = [\n { prefix: \"xxs\", value: fontSize.xxs },\n { prefix: \"xs\", value: fontSize.xs },\n { prefix: \"sm\", value: fontSize.sm },\n { prefix: \"md\", value: fontSize.md },\n { prefix: \"lg\", value: fontSize.lg },\n { prefix: \"xl\", value: fontSize.xl },\n { prefix: \"2xl\", value: fontSize[\"2xl\"] },\n ];\n\n for (const breakpoint of breakpoints) {\n if (breakpoint.value) {\n const breakpointFontSizeClasses = getFontSizeClasses(breakpoint.value);\n const responsiveClasses = breakpointFontSizeClasses\n .split(\" \")\n .filter((cls) => cls.trim() !== \"\")\n .map((cls) => `${breakpoint.prefix}:${cls}`)\n .join(\" \");\n if (responsiveClasses) {\n classes.push(responsiveClasses);\n }\n }\n }\n\n return classes.join(\" \");\n}\n\n/**\n * Props for the Button component.\n *\n * @property variant - Color/style: `pink`, `subtle`, `bold`, `light`, `transparent`, `contrast`, `success`, `error`\n * @property size - Size or responsive size object: `xs`, `sm`, `default`, `lg`, `xl`, `icon`\n * @property fontSize - Override font size or responsive font size object\n * @property borderRadius - Corner style: `default`, `sm`, `full`, `rounded`\n * @property border - Show border when true\n * @property noFeedback - Disable scale animation on click\n * @property asChild - Render as child element (e.g., for links)\n * @property icon - Square aspect ratio with no padding (for icon-only buttons)\n */\nexport interface ButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>,\n Omit<VariantProps<typeof buttonVariants>, \"size\" | \"fontSize\"> {\n asChild?: boolean;\n size?: ResponsiveButtonSize;\n fontSize?: ResponsiveButtonFontSize;\n icon?: boolean;\n ref?: Ref<HTMLButtonElement>;\n}\n\nconst Button = ({\n className,\n variant,\n size,\n borderRadius,\n border,\n noFeedback,\n asChild = false,\n type,\n children,\n fontSize,\n icon = false,\n ref,\n ...props\n}: ButtonProps) => {\n const Comp = asChild ? SlotPrimitive.Slot : \"button\";\n const buttonType = asChild ? undefined : (type ?? \"button\");\n\n // Generate responsive classes or use the cva size variant\n const responsiveClasses =\n typeof size === \"object\"\n ? generateResponsiveSizeClasses(size)\n : undefined;\n\n // Generate responsive font size classes\n let responsiveFontSizeClasses: string | undefined;\n if (typeof fontSize === \"object\") {\n // User provided explicit responsive font sizes\n responsiveFontSizeClasses = generateResponsiveFontSizeClasses(fontSize);\n } else if (typeof size === \"object\" && fontSize === undefined) {\n // Auto-generate responsive font sizes based on responsive sizes\n const autoFontSize: ResponsiveButtonFontSize = {\n default: defaultFontSizeForSize[size.default] || \"base\",\n };\n\n // Map over the size object to create the auto font size object\n const breakpointMappings = [\n { sizeKey: \"xxs\" as const, fontKey: \"xxs\" as const },\n { sizeKey: \"xs\" as const, fontKey: \"xs\" as const },\n { sizeKey: \"sm\" as const, fontKey: \"sm\" as const },\n { sizeKey: \"md\" as const, fontKey: \"md\" as const },\n { sizeKey: \"lg\" as const, fontKey: \"lg\" as const },\n { sizeKey: \"xl\" as const, fontKey: \"xl\" as const },\n { sizeKey: \"2xl\" as const, fontKey: \"2xl\" as const },\n ];\n\n for (const { sizeKey, fontKey } of breakpointMappings) {\n const sizeValue = (size as Record<string, ButtonSize>)[sizeKey];\n if (sizeValue && sizeValue in defaultFontSizeForSize) {\n (autoFontSize as Record<string, Exclude<ButtonFontSize, null>>)[\n fontKey\n ] = defaultFontSizeForSize[sizeValue as ButtonSize];\n }\n }\n\n responsiveFontSizeClasses =\n generateResponsiveFontSizeClasses(autoFontSize);\n }\n\n // For object sizes, use the default size in the cva\n const cvaSize = typeof size === \"object\" ? size.default : size;\n\n // Determine font size for cva\n let cvaFontSize: ButtonFontSize = null;\n if (fontSize) {\n if (typeof fontSize === \"object\") {\n // If fontSize object has no default, let compound variants handle it (null)\n cvaFontSize = fontSize.default || null;\n } else {\n cvaFontSize = fontSize;\n }\n } // null triggers compound variants for default font sizes\n\n // Generate icon classes if icon prop is true\n let iconClasses = \"\";\n if (icon) {\n iconClasses = \"aspect-square p-0\";\n\n // If using responsive sizes, we need to override padding at each breakpoint\n if (typeof size === \"object\") {\n const iconResponsiveClasses: string[] = [];\n\n const breakpointMappings = [\n { sizeKey: \"xxs\" as const, prefix: \"xxs\" },\n { sizeKey: \"xs\" as const, prefix: \"xs\" },\n { sizeKey: \"sm\" as const, prefix: \"sm\" },\n { sizeKey: \"md\" as const, prefix: \"md\" },\n { sizeKey: \"lg\" as const, prefix: \"lg\" },\n { sizeKey: \"xl\" as const, prefix: \"xl\" },\n { sizeKey: \"2xl\" as const, prefix: \"2xl\" },\n ];\n\n for (const { sizeKey, prefix } of breakpointMappings) {\n const sizeValue = (size as Record<string, ButtonSize>)[sizeKey];\n if (sizeValue) {\n iconResponsiveClasses.push(`${prefix}:p-0`);\n }\n }\n\n if (iconResponsiveClasses.length > 0) {\n iconClasses += ` ${iconResponsiveClasses.join(\" \")}`;\n }\n }\n }\n\n return (\n <Comp\n className={cn(\n buttonVariants({\n variant,\n size: cvaSize,\n fontSize: cvaFontSize,\n borderRadius,\n border,\n noFeedback,\n }),\n responsiveClasses,\n responsiveFontSizeClasses,\n iconClasses,\n className\n )}\n ref={ref}\n type={buttonType}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n\n/** CVA variants for Loading spinner sizing */\nconst loadingVariants = cva(\"hidden w-4 animate-[spin_0.75s_linear_infinite] text-inherit\", {\n variants: {\n size: {\n default: \"w-4\",\n lg: \"w-5\",\n sm: \"w-3\",\n xs: \"w-3\",\n icon: \"w-4\",\n xl: \"w-5\",\n },\n visible: {\n true: \"block\",\n false: \"hidden\",\n },\n },\n defaultVariants: {\n size: \"default\",\n visible: false,\n },\n});\n\n/**\n * Animated loading spinner for use inside buttons.\n *\n * @param size - Match parent button size for proper scaling\n * @param visible - Show/hide the spinner\n *\n * @example\n * <Button disabled={isLoading}>\n * <Loading visible={isLoading} size=\"default\" />\n * Submit\n * </Button>\n */\nconst Loading = ({ size, visible }: VariantProps<typeof loadingVariants>) => (\n <LoaderCircle className={cn(loadingVariants({ size, visible }))} />\n);\n\nexport { Button, buttonVariants, Loading, loadingVariants };\nexport type {\n ResponsiveButtonSize,\n ButtonSize,\n ResponsiveButtonFontSize,\n ButtonFontSize,\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @module Button\n *\n * Versatile button component with multiple variants, sizes, and responsive options.\n * Supports all standard button interactions plus loading states and icon-only modes.\n *\n * @see {@link https://ui.shadcn.com/docs/components/button Shadcn Button}\n *\n * @example\n * // Basic buttons\n * <Button>Default</Button>\n * <Button variant=\"brand\">Primary Action</Button>\n * <Button variant=\"subtle\">Secondary</Button>\n *\n * @example\n * // Sizes\n * <Button size=\"xs\">Extra Small</Button>\n * <Button size=\"sm\">Small</Button>\n * <Button size=\"lg\">Large</Button>\n * <Button size=\"xl\">Extra Large</Button>\n *\n * @example\n * // Responsive size (changes at breakpoints)\n * <Button size={{ default: \"sm\", md: \"default\", lg: \"lg\" }}>\n * Responsive Button\n * </Button>\n *\n * @example\n * // Icon button\n * <Button icon size=\"default\"><PlayIcon /></Button>\n *\n * @example\n * // As link (using asChild)\n * <Button asChild variant=\"brand\">\n * <a href=\"/signup\">Sign Up</a>\n * </Button>\n *\n * @example\n * // With loading state\n * <Button disabled>\n * <Loading visible={isLoading} />\n * {isLoading ? \"Loading...\" : \"Submit\"}\n * </Button>\n */\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { LoaderCircle } from \"lucide-react\";\nimport { Slot as SlotPrimitive } from \"radix-ui\";\nimport type { ButtonHTMLAttributes, Ref } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\n/** Size classes for consistent button dimensions */\n// Define size classes once as a single source of truth (including leading but not font sizes)\nconst sizeClasses = {\n default: \"h-8 px-4 py-2 leading-8\",\n xs: \"h-5 gap-1.5 px-2 leading-5\",\n sm: \"h-7 px-3 py-2 leading-6\",\n lg: \"h-10 px-4 py-2 leading-8\",\n xl: \"h-12 px-8 py-3 leading-10\",\n icon: \"h-8 w-8 leading-8\",\n} as const;\n\nconst fontSizeClasses = {\n xxs: \"text-xxs\",\n xs: \"text-xs\",\n sm: \"text-sm\",\n base: \"text-base\",\n lg: \"text-lg\",\n xl: \"text-xl\",\n} as const;\n\n// Type definitions for responsive sizes\ntype ButtonSize = \"default\" | \"xs\" | \"sm\" | \"lg\" | \"icon\" | \"xl\";\n\ntype ButtonFontSize = \"xxs\" | \"xs\" | \"sm\" | \"base\" | \"lg\" | \"xl\" | null;\n\n// Default font size mapping based on button size (excludes null)\nconst defaultFontSizeForSize: Record<\n ButtonSize,\n Exclude<ButtonFontSize, null>\n> = {\n xs: \"xs\",\n sm: \"xs\",\n default: \"base\",\n lg: \"base\",\n icon: \"base\",\n xl: \"lg\",\n};\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap font-normal font-sans text-base transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--focus-ring-offset)] enabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-50\",\n {\n variants: {\n variant: {\n // BRANDING VARIANTS (use CSS variables for themeability)\n subtle:\n \"border-1 border-gray-150 border-solid bg-white text-gray-950 hover:bg-gray-50 active:border-brand-primary-hover active:bg-brand-secondary active:text-brand-primary-hover disabled:bg-gray-50 active:disabled:border-gray-150 active:disabled:bg-gray-50 active:disabled:text-gray-950 dark:border-gray-800 dark:bg-gray-950 dark:text-white dark:disabled:border-gray-900 dark:disabled:bg-gray-950 dark:disabled:text-white dark:active:border-white dark:active:text-white dark:disabled:active:border-gray-900 dark:disabled:active:bg-gray-950 dark:disabled:active:text-white dark:hover:bg-gray-900\",\n brand: \"border-1 border-brand-primary border-solid bg-brand-primary font-semibold text-white hover:border-brand-primary-hover hover:bg-brand-primary-hover disabled:hover:bg-brand-primary-hover\",\n brandSecondary:\n \"border-1 border-brand-secondary border-solid bg-brand-secondary font-semibold text-brand-primary-hover hover:border-brand-secondary-hover hover:bg-brand-secondary-hover disabled:hover:bg-brand-secondary-hover dark:border-gray-900 dark:bg-gray-900 hover:dark:border-gray-800 hover:dark:bg-gray-800 dark:text-white dark:disabled:hover:border-gray-900 dark:disabled:hover:bg-gray-900\",\n bold: \"border-gray-950 bg-gray-950 font-semibold text-white dark:border-white dark:bg-white dark:text-gray-950\",\n light:\n \"border-gray-150 bg-gray-100 font-semibold text-gray-950 hover:border-gray-200 hover:bg-gray-200 disabled:hover:border-gray-150 disabled:hover:bg-gray-100 dark:border-gray-800 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700 dark:disabled:hover:bg-gray-800\",\n transparent:\n \"!border-transparent bg-transparent font-semibold text-gray-950 hover:border-gray-50 hover:bg-gray-50 disabled:hover:border-transparent disabled:hover:bg-transparent dark:text-white dark:hover:border-gray-900 dark:hover:bg-gray-900\",\n contrast:\n \"border-white bg-white font-semibold text-gray-950 hover:bg-gray-50 hover:disabled:border-white hover:disabled:bg-white\",\n success:\n \"border-green-600 bg-green-600 font-semibold text-white hover:border-green-700 hover:bg-green-700 disabled:hover:border-green-600 disabled:hover:bg-green-600 dark:border-green-500 dark:bg-green-500 dark:hover:border-green-650 dark:hover:bg-green-650 dark:disabled:hover:border-green-500 dark:disabled:hover:bg-green-500\",\n error:\n \"border-red-600 bg-red-600 font-semibold text-white hover:bg-red-700 disabled:hover:border-red-700 disabled:hover:bg-red-700 dark:border-red-500 dark:bg-red-500 dark:hover:border-red-600 dark:hover:bg-red-600 dark:disabled:hover:border-red-600 dark:disabled:hover:bg-red-600\",\n },\n\n size: sizeClasses,\n fontSize: {\n ...fontSizeClasses,\n null: \"\", // No font size class, relies on compound variants\n },\n borderRadius: {\n default: \"rounded-lg\",\n sm: \"rounded\",\n full: \"rounded-full\",\n rounded: \"rounded-[100px]\",\n },\n border: {\n true: \"border border-solid\",\n false: \"border-none\",\n },\n noFeedback: {\n true: \"\",\n false: \"transition-scale active:scale-[0.97] disabled:scale-100\",\n },\n },\n compoundVariants: [\n // Size + BorderRadius compounds\n {\n size: \"sm\",\n borderRadius: \"default\",\n className: \"rounded-lg\",\n },\n {\n size: \"xs\",\n borderRadius: \"default\",\n className: \"rounded-md\",\n },\n\n // Variant + Border compounds\n {\n variant: \"transparent\",\n border: true,\n className: \"border-gray-200 dark:border-gray-800\",\n },\n {\n variant: \"success\",\n border: true,\n className: \"border-green-dark\",\n },\n {\n variant: \"contrast\",\n border: true,\n className: \"border-white\",\n },\n // Size + fontSize compounds (default font size for each size when no explicit fontSize)\n { size: \"xs\", fontSize: null, className: \"text-xs\" },\n { size: \"sm\", fontSize: null, className: \"text-xs\" },\n { size: \"default\", fontSize: null, className: \"text-base\" },\n { size: \"lg\", fontSize: null, className: \"text-base\" },\n { size: \"icon\", fontSize: null, className: \"text-base\" },\n { size: \"xl\", fontSize: null, className: \"text-lg\" },\n ],\n defaultVariants: {\n variant: \"bold\",\n size: \"default\",\n fontSize: null,\n borderRadius: \"default\",\n border: false,\n noFeedback: false,\n },\n }\n);\n\ntype ResponsiveButtonSize =\n | ButtonSize\n | {\n default: ButtonSize;\n xxs?: ButtonSize;\n xs?: ButtonSize;\n sm?: ButtonSize;\n md?: ButtonSize;\n lg?: ButtonSize;\n xl?: ButtonSize;\n \"2xl\"?: ButtonSize;\n };\n\ntype ResponsiveButtonFontSize =\n | Exclude<ButtonFontSize, null>\n | {\n default?: Exclude<ButtonFontSize, null>;\n xxs?: Exclude<ButtonFontSize, null>;\n xs?: Exclude<ButtonFontSize, null>;\n sm?: Exclude<ButtonFontSize, null>;\n md?: Exclude<ButtonFontSize, null>;\n lg?: Exclude<ButtonFontSize, null>;\n xl?: Exclude<ButtonFontSize, null>;\n \"2xl\"?: Exclude<ButtonFontSize, null>;\n };\n\nconst getSizeClasses = (sizeKey: ButtonSize): string =>\n sizeClasses[sizeKey] || \"\";\n\nconst getFontSizeClasses = (\n fontSizeKey: Exclude<ButtonFontSize, null>\n): string => fontSizeClasses[fontSizeKey] || \"\";\n\n// Function to generate responsive Tailwind classes\nfunction generateResponsiveSizeClasses(size?: ResponsiveButtonSize): string {\n if (!size || typeof size === \"string\") {\n return \"\";\n }\n\n const classes: string[] = [];\n\n // Add responsive classes for each breakpoint\n const breakpoints = [\n { prefix: \"xxs\", value: size.xxs },\n { prefix: \"xs\", value: size.xs },\n { prefix: \"sm\", value: size.sm },\n { prefix: \"md\", value: size.md },\n { prefix: \"lg\", value: size.lg },\n { prefix: \"xl\", value: size.xl },\n { prefix: \"2xl\", value: size[\"2xl\"] },\n ];\n\n for (const breakpoint of breakpoints) {\n if (breakpoint.value) {\n const breakpointSizeClasses = getSizeClasses(breakpoint.value);\n const responsiveClasses = breakpointSizeClasses\n .split(\" \")\n .filter((cls) => cls.trim() !== \"\")\n .map((cls) => `${breakpoint.prefix}:${cls}`)\n .join(\" \");\n if (responsiveClasses) {\n classes.push(responsiveClasses);\n }\n }\n }\n\n return classes.join(\" \");\n}\n\nfunction generateResponsiveFontSizeClasses(\n fontSize?: ResponsiveButtonFontSize\n): string {\n if (!fontSize || typeof fontSize === \"string\") {\n return \"\";\n }\n\n const classes: string[] = [];\n\n // Add responsive classes for each breakpoint\n const breakpoints = [\n { prefix: \"xxs\", value: fontSize.xxs },\n { prefix: \"xs\", value: fontSize.xs },\n { prefix: \"sm\", value: fontSize.sm },\n { prefix: \"md\", value: fontSize.md },\n { prefix: \"lg\", value: fontSize.lg },\n { prefix: \"xl\", value: fontSize.xl },\n { prefix: \"2xl\", value: fontSize[\"2xl\"] },\n ];\n\n for (const breakpoint of breakpoints) {\n if (breakpoint.value) {\n const breakpointFontSizeClasses = getFontSizeClasses(breakpoint.value);\n const responsiveClasses = breakpointFontSizeClasses\n .split(\" \")\n .filter((cls) => cls.trim() !== \"\")\n .map((cls) => `${breakpoint.prefix}:${cls}`)\n .join(\" \");\n if (responsiveClasses) {\n classes.push(responsiveClasses);\n }\n }\n }\n\n return classes.join(\" \");\n}\n\n/**\n * Props for the Button component.\n *\n * @property variant - Color/style: `brand`, `brandSecondary`, `subtle`, `bold`, `light`, `transparent`, `contrast`, `success`, `error`\n * @property size - Size or responsive size object: `xs`, `sm`, `default`, `lg`, `xl`, `icon`\n * @property fontSize - Override font size or responsive font size object\n * @property borderRadius - Corner style: `default`, `sm`, `full`, `rounded`\n * @property border - Show border when true\n * @property noFeedback - Disable scale animation on click\n * @property asChild - Render as child element (e.g., for links)\n * @property icon - Square aspect ratio with no padding (for icon-only buttons)\n */\nexport interface ButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>,\n Omit<VariantProps<typeof buttonVariants>, \"size\" | \"fontSize\"> {\n asChild?: boolean;\n size?: ResponsiveButtonSize;\n fontSize?: ResponsiveButtonFontSize;\n icon?: boolean;\n ref?: Ref<HTMLButtonElement>;\n}\n\nconst Button = ({\n className,\n variant,\n size,\n borderRadius,\n border,\n noFeedback,\n asChild = false,\n type,\n children,\n fontSize,\n icon = false,\n ref,\n ...props\n}: ButtonProps) => {\n const Comp = asChild ? SlotPrimitive.Slot : \"button\";\n const buttonType = asChild ? undefined : (type ?? \"button\");\n\n // Generate responsive classes or use the cva size variant\n const responsiveClasses =\n typeof size === \"object\"\n ? generateResponsiveSizeClasses(size)\n : undefined;\n\n // Generate responsive font size classes\n let responsiveFontSizeClasses: string | undefined;\n if (typeof fontSize === \"object\") {\n // User provided explicit responsive font sizes\n responsiveFontSizeClasses = generateResponsiveFontSizeClasses(fontSize);\n } else if (typeof size === \"object\" && fontSize === undefined) {\n // Auto-generate responsive font sizes based on responsive sizes\n const autoFontSize: ResponsiveButtonFontSize = {\n default: defaultFontSizeForSize[size.default] || \"base\",\n };\n\n // Map over the size object to create the auto font size object\n const breakpointMappings = [\n { sizeKey: \"xxs\" as const, fontKey: \"xxs\" as const },\n { sizeKey: \"xs\" as const, fontKey: \"xs\" as const },\n { sizeKey: \"sm\" as const, fontKey: \"sm\" as const },\n { sizeKey: \"md\" as const, fontKey: \"md\" as const },\n { sizeKey: \"lg\" as const, fontKey: \"lg\" as const },\n { sizeKey: \"xl\" as const, fontKey: \"xl\" as const },\n { sizeKey: \"2xl\" as const, fontKey: \"2xl\" as const },\n ];\n\n for (const { sizeKey, fontKey } of breakpointMappings) {\n const sizeValue = (size as Record<string, ButtonSize>)[sizeKey];\n if (sizeValue && sizeValue in defaultFontSizeForSize) {\n (autoFontSize as Record<string, Exclude<ButtonFontSize, null>>)[\n fontKey\n ] = defaultFontSizeForSize[sizeValue as ButtonSize];\n }\n }\n\n responsiveFontSizeClasses =\n generateResponsiveFontSizeClasses(autoFontSize);\n }\n\n // For object sizes, use the default size in the cva\n const cvaSize = typeof size === \"object\" ? size.default : size;\n\n // Determine font size for cva\n let cvaFontSize: ButtonFontSize = null;\n if (fontSize) {\n if (typeof fontSize === \"object\") {\n // If fontSize object has no default, let compound variants handle it (null)\n cvaFontSize = fontSize.default || null;\n } else {\n cvaFontSize = fontSize;\n }\n } // null triggers compound variants for default font sizes\n\n // Generate icon classes if icon prop is true\n let iconClasses = \"\";\n if (icon) {\n iconClasses = \"aspect-square p-0\";\n\n // If using responsive sizes, we need to override padding at each breakpoint\n if (typeof size === \"object\") {\n const iconResponsiveClasses: string[] = [];\n\n const breakpointMappings = [\n { sizeKey: \"xxs\" as const, prefix: \"xxs\" },\n { sizeKey: \"xs\" as const, prefix: \"xs\" },\n { sizeKey: \"sm\" as const, prefix: \"sm\" },\n { sizeKey: \"md\" as const, prefix: \"md\" },\n { sizeKey: \"lg\" as const, prefix: \"lg\" },\n { sizeKey: \"xl\" as const, prefix: \"xl\" },\n { sizeKey: \"2xl\" as const, prefix: \"2xl\" },\n ];\n\n for (const { sizeKey, prefix } of breakpointMappings) {\n const sizeValue = (size as Record<string, ButtonSize>)[sizeKey];\n if (sizeValue) {\n iconResponsiveClasses.push(`${prefix}:p-0`);\n }\n }\n\n if (iconResponsiveClasses.length > 0) {\n iconClasses += ` ${iconResponsiveClasses.join(\" \")}`;\n }\n }\n }\n\n return (\n <Comp\n className={cn(\n buttonVariants({\n variant,\n size: cvaSize,\n fontSize: cvaFontSize,\n borderRadius,\n border,\n noFeedback,\n }),\n responsiveClasses,\n responsiveFontSizeClasses,\n iconClasses,\n className\n )}\n ref={ref}\n type={buttonType}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n\n/** CVA variants for Loading spinner sizing */\nconst loadingVariants = cva(\"hidden w-4 animate-[spin_0.75s_linear_infinite] text-inherit\", {\n variants: {\n size: {\n default: \"w-4\",\n lg: \"w-5\",\n sm: \"w-3\",\n xs: \"w-3\",\n icon: \"w-4\",\n xl: \"w-5\",\n },\n visible: {\n true: \"block\",\n false: \"hidden\",\n },\n },\n defaultVariants: {\n size: \"default\",\n visible: false,\n },\n});\n\n/**\n * Animated loading spinner for use inside buttons.\n *\n * @param size - Match parent button size for proper scaling\n * @param visible - Show/hide the spinner\n *\n * @example\n * <Button disabled={isLoading}>\n * <Loading visible={isLoading} size=\"default\" />\n * Submit\n * </Button>\n */\nconst Loading = ({ size, visible }: VariantProps<typeof loadingVariants>) => (\n <LoaderCircle className={cn(loadingVariants({ size, visible }))} />\n);\n\nexport { Button, buttonVariants, Loading, loadingVariants };\nexport type {\n ResponsiveButtonSize,\n ButtonSize,\n ResponsiveButtonFontSize,\n ButtonFontSize,\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -39,7 +39,7 @@ const CarouselDots = ({ api, count, className }) => {
39
39
  borderRadius: "full",
40
40
  className: cn(
41
41
  "size-2 transition-all duration-300 2xl:size-3",
42
- selectedIndex === index ? "hover:!bg-pink-500 border-pink-500 bg-pink-500 hover:border-pink-500 dark:border-pink-500 dark:bg-pink-500 dark:hover:border-pink-500 dark:hover:bg-pink-500" : "hover:!bg-gray-300 dark:hover:!bg-gray-600 border-gray-300 bg-gray-300 dark:border-gray-600 dark:bg-gray-600 dark:hover:border-gray-600"
42
+ selectedIndex === index ? "hover:!bg-brand-primary border-brand-primary bg-brand-primary hover:border-brand-primary" : "hover:!bg-gray-300 dark:hover:!bg-gray-600 border-gray-300 bg-gray-300 dark:border-gray-600 dark:bg-gray-600 dark:hover:border-gray-600"
43
43
  ),
44
44
  icon: true,
45
45
  onClick: () => onClick(index),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/carousel-dots.tsx"],
4
- "sourcesContent": ["/**\n * @module CarouselDots\n *\n * Navigation dots for Carousel component. Shows current slide position and allows direct navigation.\n *\n * @example\n * // With Carousel\n * const [api, setApi] = useState<CarouselApi>();\n *\n * <Carousel setApi={setApi}>\n * <CarouselContent>\n * <CarouselItem>Slide 1</CarouselItem>\n * <CarouselItem>Slide 2</CarouselItem>\n * </CarouselContent>\n * </Carousel>\n * <CarouselDots api={api} count={2} />\n */\nimport * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\n\nimport type { CarouselApi } from \"./carousel\";\n\n/**\n * Props for CarouselDots component.\n * @property api - Embla Carousel API instance from useCarousel or setApi\n * @property count - Total number of slides\n */\ninterface CarouselDotsProps {\n api: CarouselApi | null;\n count: number;\n className?: string;\n}\n\n/**\n * Dot indicators for carousel navigation. Highlights current slide and allows direct jump.\n */\nexport const CarouselDots = ({ api, count, className }: CarouselDotsProps) => {\n const [selectedIndex, setSelectedIndex] = React.useState(0);\n const currentIndexRef = React.useRef(selectedIndex);\n\n React.useEffect(() => {\n if (!api) {\n return;\n }\n\n const updateIndex = () => {\n const newIndex = api.selectedScrollSnap();\n\n if (currentIndexRef.current !== newIndex) {\n currentIndexRef.current = newIndex;\n // Schedule state update outside of useEffect\n queueMicrotask(() => {\n setSelectedIndex(newIndex);\n });\n }\n };\n\n // Subscribe to select events\n api.on(\"select\", updateIndex);\n // Initial update\n updateIndex();\n\n // Cleanup\n return () => {\n api.off(\"select\", updateIndex);\n };\n }, [api]);\n\n const onClick = React.useCallback(\n (index: number) => {\n api?.scrollTo(index);\n },\n [api]\n );\n\n return (\n <div className={cn(\"flex items-center justify-center gap-2\", className)}>\n {Array.from({ length: count }).map((_, index) => (\n <Button\n aria-current={selectedIndex === index ? \"true\" : undefined}\n aria-label={`Go to slide ${index + 1}`}\n border\n borderRadius=\"full\"\n className={cn(\n \"size-2 transition-all duration-300 2xl:size-3\",\n selectedIndex === index\n ? \"hover:!bg-pink-500 border-pink-500 bg-pink-500 hover:border-pink-500 dark:border-pink-500 dark:bg-pink-500 dark:hover:border-pink-500 dark:hover:bg-pink-500\"\n : \"hover:!bg-gray-300 dark:hover:!bg-gray-600 border-gray-300 bg-gray-300 dark:border-gray-600 dark:bg-gray-600 dark:hover:border-gray-600\"\n )}\n icon\n key={index}\n onClick={() => onClick(index)}\n size=\"sm\"\n variant=\"bold\"\n />\n ))}\n </div>\n );\n};\n"],
5
- "mappings": "AAgFQ;AA/DR,YAAY,WAAW;AAEvB,SAAS,UAAU;AACnB,SAAS,cAAc;AAkBhB,MAAM,eAAe,CAAC,EAAE,KAAK,OAAO,UAAU,MAAyB;AAC5E,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,CAAC;AAC1D,QAAM,kBAAkB,MAAM,OAAO,aAAa;AAElD,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,KAAK;AACR;AAAA,IACF;AAEA,UAAM,cAAc,MAAM;AACxB,YAAM,WAAW,IAAI,mBAAmB;AAExC,UAAI,gBAAgB,YAAY,UAAU;AACxC,wBAAgB,UAAU;AAE1B,uBAAe,MAAM;AACnB,2BAAiB,QAAQ;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,GAAG,UAAU,WAAW;AAE5B,gBAAY;AAGZ,WAAO,MAAM;AACX,UAAI,IAAI,UAAU,WAAW;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,GAAG,CAAC;AAER,QAAM,UAAU,MAAM;AAAA,IACpB,CAAC,UAAkB;AACjB,WAAK,SAAS,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,GAAG;AAAA,EACN;AAEA,SACE,oBAAC,SAAI,WAAW,GAAG,0CAA0C,SAAS,GACnE,gBAAM,KAAK,EAAE,QAAQ,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,UACrC;AAAA,IAAC;AAAA;AAAA,MACC,gBAAc,kBAAkB,QAAQ,SAAS;AAAA,MACjD,cAAY,eAAe,QAAQ,CAAC;AAAA,MACpC,QAAM;AAAA,MACN,cAAa;AAAA,MACb,WAAW;AAAA,QACT;AAAA,QACA,kBAAkB,QACd,iKACA;AAAA,MACN;AAAA,MACA,MAAI;AAAA,MAEJ,SAAS,MAAM,QAAQ,KAAK;AAAA,MAC5B,MAAK;AAAA,MACL,SAAQ;AAAA;AAAA,IAHH;AAAA,EAIP,CACD,GACH;AAEJ;",
4
+ "sourcesContent": ["/**\n * @module CarouselDots\n *\n * Navigation dots for Carousel component. Shows current slide position and allows direct navigation.\n *\n * @example\n * // With Carousel\n * const [api, setApi] = useState<CarouselApi>();\n *\n * <Carousel setApi={setApi}>\n * <CarouselContent>\n * <CarouselItem>Slide 1</CarouselItem>\n * <CarouselItem>Slide 2</CarouselItem>\n * </CarouselContent>\n * </Carousel>\n * <CarouselDots api={api} count={2} />\n */\nimport * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\n\nimport type { CarouselApi } from \"./carousel\";\n\n/**\n * Props for CarouselDots component.\n * @property api - Embla Carousel API instance from useCarousel or setApi\n * @property count - Total number of slides\n */\ninterface CarouselDotsProps {\n api: CarouselApi | null;\n count: number;\n className?: string;\n}\n\n/**\n * Dot indicators for carousel navigation. Highlights current slide and allows direct jump.\n */\nexport const CarouselDots = ({ api, count, className }: CarouselDotsProps) => {\n const [selectedIndex, setSelectedIndex] = React.useState(0);\n const currentIndexRef = React.useRef(selectedIndex);\n\n React.useEffect(() => {\n if (!api) {\n return;\n }\n\n const updateIndex = () => {\n const newIndex = api.selectedScrollSnap();\n\n if (currentIndexRef.current !== newIndex) {\n currentIndexRef.current = newIndex;\n // Schedule state update outside of useEffect\n queueMicrotask(() => {\n setSelectedIndex(newIndex);\n });\n }\n };\n\n // Subscribe to select events\n api.on(\"select\", updateIndex);\n // Initial update\n updateIndex();\n\n // Cleanup\n return () => {\n api.off(\"select\", updateIndex);\n };\n }, [api]);\n\n const onClick = React.useCallback(\n (index: number) => {\n api?.scrollTo(index);\n },\n [api]\n );\n\n return (\n <div className={cn(\"flex items-center justify-center gap-2\", className)}>\n {Array.from({ length: count }).map((_, index) => (\n <Button\n aria-current={selectedIndex === index ? \"true\" : undefined}\n aria-label={`Go to slide ${index + 1}`}\n border\n borderRadius=\"full\"\n className={cn(\n \"size-2 transition-all duration-300 2xl:size-3\",\n selectedIndex === index\n ? \"hover:!bg-brand-primary border-brand-primary bg-brand-primary hover:border-brand-primary\"\n : \"hover:!bg-gray-300 dark:hover:!bg-gray-600 border-gray-300 bg-gray-300 dark:border-gray-600 dark:bg-gray-600 dark:hover:border-gray-600\"\n )}\n icon\n key={index}\n onClick={() => onClick(index)}\n size=\"sm\"\n variant=\"bold\"\n />\n ))}\n </div>\n );\n};\n"],
5
+ "mappings": "AAgFQ;AA/DR,YAAY,WAAW;AAEvB,SAAS,UAAU;AACnB,SAAS,cAAc;AAkBhB,MAAM,eAAe,CAAC,EAAE,KAAK,OAAO,UAAU,MAAyB;AAC5E,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,CAAC;AAC1D,QAAM,kBAAkB,MAAM,OAAO,aAAa;AAElD,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,KAAK;AACR;AAAA,IACF;AAEA,UAAM,cAAc,MAAM;AACxB,YAAM,WAAW,IAAI,mBAAmB;AAExC,UAAI,gBAAgB,YAAY,UAAU;AACxC,wBAAgB,UAAU;AAE1B,uBAAe,MAAM;AACnB,2BAAiB,QAAQ;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,GAAG,UAAU,WAAW;AAE5B,gBAAY;AAGZ,WAAO,MAAM;AACX,UAAI,IAAI,UAAU,WAAW;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,GAAG,CAAC;AAER,QAAM,UAAU,MAAM;AAAA,IACpB,CAAC,UAAkB;AACjB,WAAK,SAAS,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,GAAG;AAAA,EACN;AAEA,SACE,oBAAC,SAAI,WAAW,GAAG,0CAA0C,SAAS,GACnE,gBAAM,KAAK,EAAE,QAAQ,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,UACrC;AAAA,IAAC;AAAA;AAAA,MACC,gBAAc,kBAAkB,QAAQ,SAAS;AAAA,MACjD,cAAY,eAAe,QAAQ,CAAC;AAAA,MACpC,QAAM;AAAA,MACN,cAAa;AAAA,MACb,WAAW;AAAA,QACT;AAAA,QACA,kBAAkB,QACd,6FACA;AAAA,MACN;AAAA,MACA,MAAI;AAAA,MAEJ,SAAS,MAAM,QAAQ,KAAK;AAAA,MAC5B,MAAK;AAAA,MACL,SAAQ;AAAA;AAAA,IAHH;AAAA,EAIP,CACD,GACH;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -4,12 +4,12 @@ import { Check } from "lucide-react";
4
4
  import { Checkbox as CheckboxPrimitive } from "radix-ui";
5
5
  import { cn } from "../lib/utils";
6
6
  const checkboxVariants = cva(
7
- "peer h-4 w-4 shrink-0 rounded border border-gray-200 border-solid ring-offset-white hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-pink-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-pink-500 data-[state=checked]:text-white data-[state=checked]:hover:bg-pink-600 dark:border-gray-800 dark:ring-offset-gray-950 dark:data-[state=checked]:bg-pink-500 dark:data-[state=checked]:text-white dark:focus-visible:ring-pink-500 dark:hover:bg-gray-900 dark:data-[state=checked]:hover:bg-pink-600",
7
+ "peer h-4 w-4 shrink-0 rounded border border-gray-200 border-solid ring-offset-white hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-brand-primary data-[state=checked]:text-white data-[state=checked]:hover:bg-brand-primary-hover dark:border-gray-800 dark:ring-offset-gray-950 dark:data-[state=checked]:bg-brand-primary dark:data-[state=checked]:text-white dark:focus-visible:ring-[var(--focus-ring)] dark:hover:bg-gray-900 dark:data-[state=checked]:hover:bg-brand-primary-hover",
8
8
  {
9
9
  variants: {
10
10
  variant: {
11
11
  default: "",
12
- rounded: "rounded-full dark:border-gray-500 [&[data-state='checked']]:border-pink-500 [&[data-state='checked']]:bg-pink-500 dark:[&[data-state='checked']]:border-pink-500 dark:[&[data-state='checked']]:bg-pink-500"
12
+ rounded: "rounded-full dark:border-gray-500 [&[data-state='checked']]:border-brand-primary [&[data-state='checked']]:bg-brand-primary"
13
13
  }
14
14
  }
15
15
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/checkbox.tsx"],
4
- "sourcesContent": ["/**\n * @module Checkbox\n *\n * Toggle control for binary choices. Built on Radix UI Checkbox primitive.\n *\n * @see {@link https://ui.shadcn.com/docs/components/checkbox Shadcn Checkbox}\n * @see {@link https://www.radix-ui.com/primitives/docs/components/checkbox Radix Checkbox}\n *\n * @example\n * // Basic checkbox\n * <Checkbox id=\"terms\" />\n * <label htmlFor=\"terms\">Accept terms</label>\n *\n * @example\n * // Controlled checkbox\n * const [checked, setChecked] = useState(false);\n * <Checkbox checked={checked} onCheckedChange={setChecked} />\n *\n * @example\n * // Rounded variant\n * <Checkbox variant=\"rounded\" />\n */\nimport { cva } from \"class-variance-authority\";\nimport { Check } from \"lucide-react\";\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport type { Ref } from \"react\";\nimport * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\n/** CVA variants for checkbox styling */\nconst checkboxVariants = cva(\n \"peer h-4 w-4 shrink-0 rounded border border-gray-200 border-solid ring-offset-white hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-pink-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-pink-500 data-[state=checked]:text-white data-[state=checked]:hover:bg-pink-600 dark:border-gray-800 dark:ring-offset-gray-950 dark:data-[state=checked]:bg-pink-500 dark:data-[state=checked]:text-white dark:focus-visible:ring-pink-500 dark:hover:bg-gray-900 dark:data-[state=checked]:hover:bg-pink-600\",\n {\n variants: {\n variant: {\n default: \"\",\n rounded:\n \"rounded-full dark:border-gray-500 [&[data-state='checked']]:border-pink-500 [&[data-state='checked']]:bg-pink-500 dark:[&[data-state='checked']]:border-pink-500 dark:[&[data-state='checked']]:bg-pink-500\",\n },\n },\n }\n);\n\n/**\n * Props for the Checkbox component.\n * @property variant - Visual style: `\"default\"` (square) or `\"rounded\"` (circular)\n */\ninterface CheckboxProps\n extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> {\n variant?: \"default\" | \"rounded\";\n ref?: Ref<React.ElementRef<typeof CheckboxPrimitive.Root>>;\n}\n\n/**\n * Interactive checkbox with check indicator.\n * Supports checked, unchecked, and indeterminate states.\n */\nconst Checkbox = ({ className, variant = \"default\", ref, ...props }: CheckboxProps) => (\n <CheckboxPrimitive.Root\n className={cn(checkboxVariants({ variant }), className)}\n ref={ref}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n className={cn(\"flex items-center justify-center text-current\")}\n >\n <Check className=\"h-4 w-4\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n);\n\n/**\n * Props for the DummyCheckbox component.\n * @property variant - Visual style: `\"default\"` or `\"rounded\"`\n * @property checked - Whether to show the check indicator\n */\ninterface DummyCheckboxProps extends React.ComponentPropsWithoutRef<\"div\"> {\n variant?: \"default\" | \"rounded\";\n checked?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Non-interactive checkbox for display purposes only.\n * Visually identical to Checkbox but without click/keyboard handling.\n * Useful for list items where the parent handles selection.\n */\nconst DummyCheckbox = ({ className, variant = \"default\", checked, ref, ...props }: DummyCheckboxProps) => (\n <div\n className={cn(checkboxVariants({ variant }), className)}\n data-state={checked ? \"checked\" : \"unchecked\"}\n ref={ref}\n {...props}\n >\n <div\n className={cn(\n checked ? \"flex items-center justify-center text-current\" : \"hidden\"\n )}\n >\n <Check className=\"h-4 w-4\" />\n </div>\n </div>\n);\n\nexport { Checkbox, DummyCheckbox, type CheckboxProps };\n"],
4
+ "sourcesContent": ["/**\n * @module Checkbox\n *\n * Toggle control for binary choices. Built on Radix UI Checkbox primitive.\n *\n * @see {@link https://ui.shadcn.com/docs/components/checkbox Shadcn Checkbox}\n * @see {@link https://www.radix-ui.com/primitives/docs/components/checkbox Radix Checkbox}\n *\n * @example\n * // Basic checkbox\n * <Checkbox id=\"terms\" />\n * <label htmlFor=\"terms\">Accept terms</label>\n *\n * @example\n * // Controlled checkbox\n * const [checked, setChecked] = useState(false);\n * <Checkbox checked={checked} onCheckedChange={setChecked} />\n *\n * @example\n * // Rounded variant\n * <Checkbox variant=\"rounded\" />\n */\nimport { cva } from \"class-variance-authority\";\nimport { Check } from \"lucide-react\";\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport type { Ref } from \"react\";\nimport * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\n/** CVA variants for checkbox styling */\nconst checkboxVariants = cva(\n \"peer h-4 w-4 shrink-0 rounded border border-gray-200 border-solid ring-offset-white hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-brand-primary data-[state=checked]:text-white data-[state=checked]:hover:bg-brand-primary-hover dark:border-gray-800 dark:ring-offset-gray-950 dark:data-[state=checked]:bg-brand-primary dark:data-[state=checked]:text-white dark:focus-visible:ring-[var(--focus-ring)] dark:hover:bg-gray-900 dark:data-[state=checked]:hover:bg-brand-primary-hover\",\n {\n variants: {\n variant: {\n default: \"\",\n rounded:\n \"rounded-full dark:border-gray-500 [&[data-state='checked']]:border-brand-primary [&[data-state='checked']]:bg-brand-primary\",\n },\n },\n }\n);\n\n/**\n * Props for the Checkbox component.\n * @property variant - Visual style: `\"default\"` (square) or `\"rounded\"` (circular)\n */\ninterface CheckboxProps\n extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> {\n variant?: \"default\" | \"rounded\";\n ref?: Ref<React.ElementRef<typeof CheckboxPrimitive.Root>>;\n}\n\n/**\n * Interactive checkbox with check indicator.\n * Supports checked, unchecked, and indeterminate states.\n */\nconst Checkbox = ({ className, variant = \"default\", ref, ...props }: CheckboxProps) => (\n <CheckboxPrimitive.Root\n className={cn(checkboxVariants({ variant }), className)}\n ref={ref}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n className={cn(\"flex items-center justify-center text-current\")}\n >\n <Check className=\"h-4 w-4\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n);\n\n/**\n * Props for the DummyCheckbox component.\n * @property variant - Visual style: `\"default\"` or `\"rounded\"`\n * @property checked - Whether to show the check indicator\n */\ninterface DummyCheckboxProps extends React.ComponentPropsWithoutRef<\"div\"> {\n variant?: \"default\" | \"rounded\";\n checked?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Non-interactive checkbox for display purposes only.\n * Visually identical to Checkbox but without click/keyboard handling.\n * Useful for list items where the parent handles selection.\n */\nconst DummyCheckbox = ({ className, variant = \"default\", checked, ref, ...props }: DummyCheckboxProps) => (\n <div\n className={cn(checkboxVariants({ variant }), className)}\n data-state={checked ? \"checked\" : \"unchecked\"}\n ref={ref}\n {...props}\n >\n <div\n className={cn(\n checked ? \"flex items-center justify-center text-current\" : \"hidden\"\n )}\n >\n <Check className=\"h-4 w-4\" />\n </div>\n </div>\n);\n\nexport { Checkbox, DummyCheckbox, type CheckboxProps };\n"],
5
5
  "mappings": "AAmEM;AA7CN,SAAS,WAAW;AACpB,SAAS,aAAa;AACtB,SAAS,YAAY,yBAAyB;AAI9C,SAAS,UAAU;AAGnB,MAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,SACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;AAgBA,MAAM,WAAW,CAAC,EAAE,WAAW,UAAU,WAAW,KAAK,GAAG,MAAM,MAChE;AAAA,EAAC,kBAAkB;AAAA,EAAlB;AAAA,IACC,WAAW,GAAG,iBAAiB,EAAE,QAAQ,CAAC,GAAG,SAAS;AAAA,IACtD;AAAA,IACC,GAAG;AAAA,IAEJ;AAAA,MAAC,kBAAkB;AAAA,MAAlB;AAAA,QACC,WAAW,GAAG,+CAA+C;AAAA,QAE7D,8BAAC,SAAM,WAAU,WAAU;AAAA;AAAA,IAC7B;AAAA;AACF;AAmBF,MAAM,gBAAgB,CAAC,EAAE,WAAW,UAAU,WAAW,SAAS,KAAK,GAAG,MAAM,MAC9E;AAAA,EAAC;AAAA;AAAA,IACC,WAAW,GAAG,iBAAiB,EAAE,QAAQ,CAAC,GAAG,SAAS;AAAA,IACtD,cAAY,UAAU,YAAY;AAAA,IAClC;AAAA,IACC,GAAG;AAAA,IAEJ;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT,UAAU,kDAAkD;AAAA,QAC9D;AAAA,QAEA,8BAAC,SAAM,WAAU,WAAU;AAAA;AAAA,IAC7B;AAAA;AACF;",
6
6
  "names": []
7
7
  }
@@ -26,7 +26,7 @@ const inputVariants = cva(
26
26
  // background
27
27
  "bg-white focus:bg-white enabled:hover:bg-white disabled:bg-white/60 dark:bg-black dark:disabled:bg-black/60 dark:focus:bg-black dark:enabled:hover:bg-black",
28
28
  // borders (light)
29
- "rounded-lg border border-gray-150 border-solid invalid:border-red invalid:hover:border-red focus:border-pink-500 enabled:hover:border-gray-200 enabled:focus:hover:border-pink-500 disabled:border-gray-150/60",
29
+ "rounded-lg border border-gray-150 border-solid invalid:border-red invalid:hover:border-red focus:border-brand-primary enabled:hover:border-gray-200 enabled:focus:hover:border-brand-primary disabled:border-gray-150/60",
30
30
  // borders light
31
31
  // borders (dark)
32
32
  "dark:border-gray-800 dark:disabled:border-gray-900 dark:focus:border-white dark:enabled:hover:border-gray-700 dark:enabled:focus:hover:border-white dark:invalid:border-red dark:invalid:hover:border-red",
@@ -152,8 +152,8 @@ const ClearInputButton = ({ className, ref, ...props }) => /* @__PURE__ */ jsx(
152
152
  {
153
153
  className: cn(
154
154
  "absolute top-1/2 -translate-y-1/2 text-gray-950 dark:text-gray-300",
155
- "focus-visible:ring-2 focus-visible:ring-pink-500 focus-visible:ring-offset-2 focus-visible:ring-offset-gray-100",
156
- "rounded-full focus-visible:outline-none dark:focus-visible:ring-pink-500 dark:focus-visible:ring-offset-gray-800",
155
+ "focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-gray-100",
156
+ "rounded-full focus-visible:outline-none dark:focus-visible:ring-[var(--focus-ring)] dark:focus-visible:ring-offset-gray-800",
157
157
  className
158
158
  ),
159
159
  ref,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/components/input.tsx"],
4
- "sourcesContent": ["/**\n * @module Input\n *\n * Styled text input with support for icons, sizes, and clear button.\n * Includes focus state management and dark mode support.\n *\n * @example\n * // Basic input\n * <Input placeholder=\"Enter your email\" type=\"email\" />\n *\n * @example\n * // With icons\n * <Input\n * leftIcon={<Search />}\n * rightIcon={<ClearInputButton onClick={clearValue} />}\n * placeholder=\"Search...\"\n * />\n *\n * @example\n * // Small size\n * <Input size=\"sm\" placeholder=\"Compact input\" />\n *\n * @example\n * // With clear button\n * const [value, setValue] = useState('');\n *\n * <Input\n * value={value}\n * onChange={(e) => setValue(e.target.value)}\n * rightIcon={\n * value && <ClearInputButton onClick={() => setValue('')} />\n * }\n * />\n */\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\nimport { Slot as SlotPrimitive } from \"radix-ui\";\nimport type { Ref } from \"react\";\nimport { useState } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nconst inputWrapperVariants = cva(\"relative flex w-full items-center\", {\n variants: {\n size: {\n auto: \"h-auto w-auto\",\n default: \"h-10\",\n sm: \"h-7\",\n },\n },\n defaultVariants: {\n size: \"default\",\n },\n});\n\nconst inputVariants = cva(\n [\n \"w-full touch-manipulation self-stretch shadow-none outline-none outline-0 transition duration-200 ease-out disabled:cursor-not-allowed dark:disabled:cursor-not-allowed\",\n // text\n \"font-sans text-base text-black antialiased disabled:text-black/60 dark:text-white dark:disabled:text-white/60\",\n // placeholder\n \"placeholder-gray-700 placeholder:font-sans dark:placeholder-gray-200\",\n // background\n \"bg-white focus:bg-white enabled:hover:bg-white disabled:bg-white/60 dark:bg-black dark:disabled:bg-black/60 dark:focus:bg-black dark:enabled:hover:bg-black\",\n // borders (light)\n \"rounded-lg border border-gray-150 border-solid invalid:border-red invalid:hover:border-red focus:border-pink-500 enabled:hover:border-gray-200 enabled:focus:hover:border-pink-500 disabled:border-gray-150/60\", // borders light\n // borders (dark)\n \"dark:border-gray-800 dark:disabled:border-gray-900 dark:focus:border-white dark:enabled:hover:border-gray-700 dark:enabled:focus:hover:border-white dark:invalid:border-red dark:invalid:hover:border-red\", // borders dark\n // default clear button\n \"dark:[&::-webkit-search-cancel-button]:hidden\",\n ],\n {\n variants: {\n size: {\n default: \"px-4\",\n sm: \"px-3\",\n auto: \"px-4\",\n },\n hasLeftIcon: {\n true: \"\",\n false: \"\",\n },\n hasRightIcon: {\n true: \"\",\n false: \"\",\n },\n },\n compoundVariants: [\n {\n hasLeftIcon: true,\n size: \"default\",\n class: \"pl-10\",\n },\n {\n hasLeftIcon: true,\n size: \"sm\",\n class: \"pl-8\",\n },\n {\n hasRightIcon: true,\n size: \"default\",\n class: \"pr-10\",\n },\n {\n hasRightIcon: true,\n size: \"sm\",\n class: \"pr-8\",\n },\n ],\n defaultVariants: {\n size: \"default\",\n hasLeftIcon: false,\n hasRightIcon: false,\n },\n }\n);\n\ntype InputPropsWithoutSize = Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n>;\n\ntype InputVariantsProps = VariantProps<typeof inputVariants>;\n\n// Omit hasLeftIcon and hasRightIcon from the public API\ntype PublicInputVariantsProps = Omit<\n InputVariantsProps,\n \"hasLeftIcon\" | \"hasRightIcon\"\n>;\n\n/**\n * Props for the Input component.\n * @property size - Input size: `\"default\"`, `\"sm\"`, or `\"auto\"`\n * @property htmlSize - Native HTML size attribute for input width\n * @property leftIcon - Icon element displayed on the left side\n * @property rightIcon - Icon element displayed on the right side\n */\nexport interface InputProps\n extends InputPropsWithoutSize,\n PublicInputVariantsProps {\n htmlSize?: number;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n ref?: Ref<HTMLInputElement>;\n}\n\nconst Input = ({\n className,\n size,\n type = \"text\",\n htmlSize,\n leftIcon,\n rightIcon,\n placeholder,\n ref,\n ...props\n}: InputProps) => {\n const [isFocused, setIsFocused] = useState(false);\n\n return (\n <div\n className={cn(inputWrapperVariants({ size }))}\n onBlur={() => {\n setTimeout(() => {\n setIsFocused(false);\n }, 50);\n }}\n >\n {!!leftIcon && (\n <SlotPrimitive.Slot\n className={cn(\n \"absolute top-1/2 -translate-y-1/2 text-gray-950 dark:text-gray-300 [&:is(svg)]:pointer-events-none\",\n size === \"sm\" ? \"left-3 size-3\" : \"left-4 size-4\"\n )}\n >\n {leftIcon}\n </SlotPrimitive.Slot>\n )}\n <input\n className={cn(\n inputVariants({\n size,\n hasLeftIcon: !!leftIcon,\n hasRightIcon: !!rightIcon,\n className,\n })\n )}\n onFocus={(e) => {\n setIsFocused(true);\n props.onFocus?.(e);\n }}\n placeholder={isFocused ? \" \" : placeholder}\n ref={ref}\n size={htmlSize}\n type={type}\n {...props}\n />\n {!!rightIcon && (\n <SlotPrimitive.Slot\n className={cn(\n \"absolute top-1/2 -translate-y-1/2 text-gray-950 dark:text-gray-300 [&:is(svg)]:pointer-events-none\",\n size === \"sm\" ? \"right-3 size-3\" : \"right-4 size-4\"\n )}\n >\n {rightIcon}\n </SlotPrimitive.Slot>\n )}\n </div>\n );\n};\n\ninterface ClearInputButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n ref?: Ref<HTMLButtonElement>;\n}\n\n/**\n * Clear/reset button designed for use as Input's rightIcon.\n * Displays an X icon and handles focus states.\n */\nconst ClearInputButton = ({ className, ref, ...props }: ClearInputButtonProps) => (\n <button\n className={cn(\n \"absolute top-1/2 -translate-y-1/2 text-gray-950 dark:text-gray-300\",\n \"focus-visible:ring-2 focus-visible:ring-pink-500 focus-visible:ring-offset-2 focus-visible:ring-offset-gray-100\",\n \"rounded-full focus-visible:outline-none dark:focus-visible:ring-pink-500 dark:focus-visible:ring-offset-gray-800\",\n className\n )}\n ref={ref}\n type=\"button\"\n {...props}\n >\n <X className=\"absolute inset-0 size-full\" strokeWidth={3} />\n </button>\n);\n\nexport { ClearInputButton, Input, inputVariants };\n"],
4
+ "sourcesContent": ["/**\n * @module Input\n *\n * Styled text input with support for icons, sizes, and clear button.\n * Includes focus state management and dark mode support.\n *\n * @example\n * // Basic input\n * <Input placeholder=\"Enter your email\" type=\"email\" />\n *\n * @example\n * // With icons\n * <Input\n * leftIcon={<Search />}\n * rightIcon={<ClearInputButton onClick={clearValue} />}\n * placeholder=\"Search...\"\n * />\n *\n * @example\n * // Small size\n * <Input size=\"sm\" placeholder=\"Compact input\" />\n *\n * @example\n * // With clear button\n * const [value, setValue] = useState('');\n *\n * <Input\n * value={value}\n * onChange={(e) => setValue(e.target.value)}\n * rightIcon={\n * value && <ClearInputButton onClick={() => setValue('')} />\n * }\n * />\n */\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\nimport { Slot as SlotPrimitive } from \"radix-ui\";\nimport type { Ref } from \"react\";\nimport { useState } from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nconst inputWrapperVariants = cva(\"relative flex w-full items-center\", {\n variants: {\n size: {\n auto: \"h-auto w-auto\",\n default: \"h-10\",\n sm: \"h-7\",\n },\n },\n defaultVariants: {\n size: \"default\",\n },\n});\n\nconst inputVariants = cva(\n [\n \"w-full touch-manipulation self-stretch shadow-none outline-none outline-0 transition duration-200 ease-out disabled:cursor-not-allowed dark:disabled:cursor-not-allowed\",\n // text\n \"font-sans text-base text-black antialiased disabled:text-black/60 dark:text-white dark:disabled:text-white/60\",\n // placeholder\n \"placeholder-gray-700 placeholder:font-sans dark:placeholder-gray-200\",\n // background\n \"bg-white focus:bg-white enabled:hover:bg-white disabled:bg-white/60 dark:bg-black dark:disabled:bg-black/60 dark:focus:bg-black dark:enabled:hover:bg-black\",\n // borders (light)\n \"rounded-lg border border-gray-150 border-solid invalid:border-red invalid:hover:border-red focus:border-brand-primary enabled:hover:border-gray-200 enabled:focus:hover:border-brand-primary disabled:border-gray-150/60\", // borders light\n // borders (dark)\n \"dark:border-gray-800 dark:disabled:border-gray-900 dark:focus:border-white dark:enabled:hover:border-gray-700 dark:enabled:focus:hover:border-white dark:invalid:border-red dark:invalid:hover:border-red\", // borders dark\n // default clear button\n \"dark:[&::-webkit-search-cancel-button]:hidden\",\n ],\n {\n variants: {\n size: {\n default: \"px-4\",\n sm: \"px-3\",\n auto: \"px-4\",\n },\n hasLeftIcon: {\n true: \"\",\n false: \"\",\n },\n hasRightIcon: {\n true: \"\",\n false: \"\",\n },\n },\n compoundVariants: [\n {\n hasLeftIcon: true,\n size: \"default\",\n class: \"pl-10\",\n },\n {\n hasLeftIcon: true,\n size: \"sm\",\n class: \"pl-8\",\n },\n {\n hasRightIcon: true,\n size: \"default\",\n class: \"pr-10\",\n },\n {\n hasRightIcon: true,\n size: \"sm\",\n class: \"pr-8\",\n },\n ],\n defaultVariants: {\n size: \"default\",\n hasLeftIcon: false,\n hasRightIcon: false,\n },\n }\n);\n\ntype InputPropsWithoutSize = Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n>;\n\ntype InputVariantsProps = VariantProps<typeof inputVariants>;\n\n// Omit hasLeftIcon and hasRightIcon from the public API\ntype PublicInputVariantsProps = Omit<\n InputVariantsProps,\n \"hasLeftIcon\" | \"hasRightIcon\"\n>;\n\n/**\n * Props for the Input component.\n * @property size - Input size: `\"default\"`, `\"sm\"`, or `\"auto\"`\n * @property htmlSize - Native HTML size attribute for input width\n * @property leftIcon - Icon element displayed on the left side\n * @property rightIcon - Icon element displayed on the right side\n */\nexport interface InputProps\n extends InputPropsWithoutSize,\n PublicInputVariantsProps {\n htmlSize?: number;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n ref?: Ref<HTMLInputElement>;\n}\n\nconst Input = ({\n className,\n size,\n type = \"text\",\n htmlSize,\n leftIcon,\n rightIcon,\n placeholder,\n ref,\n ...props\n}: InputProps) => {\n const [isFocused, setIsFocused] = useState(false);\n\n return (\n <div\n className={cn(inputWrapperVariants({ size }))}\n onBlur={() => {\n setTimeout(() => {\n setIsFocused(false);\n }, 50);\n }}\n >\n {!!leftIcon && (\n <SlotPrimitive.Slot\n className={cn(\n \"absolute top-1/2 -translate-y-1/2 text-gray-950 dark:text-gray-300 [&:is(svg)]:pointer-events-none\",\n size === \"sm\" ? \"left-3 size-3\" : \"left-4 size-4\"\n )}\n >\n {leftIcon}\n </SlotPrimitive.Slot>\n )}\n <input\n className={cn(\n inputVariants({\n size,\n hasLeftIcon: !!leftIcon,\n hasRightIcon: !!rightIcon,\n className,\n })\n )}\n onFocus={(e) => {\n setIsFocused(true);\n props.onFocus?.(e);\n }}\n placeholder={isFocused ? \" \" : placeholder}\n ref={ref}\n size={htmlSize}\n type={type}\n {...props}\n />\n {!!rightIcon && (\n <SlotPrimitive.Slot\n className={cn(\n \"absolute top-1/2 -translate-y-1/2 text-gray-950 dark:text-gray-300 [&:is(svg)]:pointer-events-none\",\n size === \"sm\" ? \"right-3 size-3\" : \"right-4 size-4\"\n )}\n >\n {rightIcon}\n </SlotPrimitive.Slot>\n )}\n </div>\n );\n};\n\ninterface ClearInputButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n ref?: Ref<HTMLButtonElement>;\n}\n\n/**\n * Clear/reset button designed for use as Input's rightIcon.\n * Displays an X icon and handles focus states.\n */\nconst ClearInputButton = ({ className, ref, ...props }: ClearInputButtonProps) => (\n <button\n className={cn(\n \"absolute top-1/2 -translate-y-1/2 text-gray-950 dark:text-gray-300\",\n \"focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-gray-100\",\n \"rounded-full focus-visible:outline-none dark:focus-visible:ring-[var(--focus-ring)] dark:focus-visible:ring-offset-gray-800\",\n className\n )}\n ref={ref}\n type=\"button\"\n {...props}\n >\n <X className=\"absolute inset-0 size-full\" strokeWidth={3} />\n </button>\n);\n\nexport { ClearInputButton, Input, inputVariants };\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -46,7 +46,7 @@ const RadioGroupItem = ({ className, ref, ...props }) => {
46
46
  RadioGroupPrimitive.Item,
47
47
  {
48
48
  className: cn(
49
- "relative aspect-square size-4 h-4 w-4 rounded-full border border-gray-500 border-solid p-0.5 text-pink-500 ring-offset-pink-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset focus-visible:ring-pink-500 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-pink-500",
49
+ "relative aspect-square size-4 h-4 w-4 rounded-full border border-gray-500 border-solid p-0.5 text-brand-primary ring-offset-brand-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-offset focus-visible:ring-[var(--focus-ring)] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-brand-primary",
50
50
  className
51
51
  ),
52
52
  ref: setRefs,
@@ -56,7 +56,7 @@ const RadioGroupItem = ({ className, ref, ...props }) => {
56
56
  motion.div,
57
57
  {
58
58
  animate: { scale: 2, opacity: 0 },
59
- className: "absolute inset-0 z-0 rounded-full bg-pink-500",
59
+ className: "absolute inset-0 z-0 rounded-full bg-brand-primary",
60
60
  exit: { scale: 0, opacity: 0 },
61
61
  initial: { scale: 0, opacity: 0.5 },
62
62
  transition: { duration: 0.4 }