@humain/ui 2.2.7 → 2.2.9

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 (159) hide show
  1. package/dist/index101.js +2 -2
  2. package/dist/index101.js.map +1 -1
  3. package/dist/index103.js +3 -3
  4. package/dist/index103.js.map +1 -1
  5. package/dist/index108.js +1 -1
  6. package/dist/index108.js.map +1 -1
  7. package/dist/index117.js +1 -1
  8. package/dist/index117.js.map +1 -1
  9. package/dist/index122.js +6 -6
  10. package/dist/index122.js.map +1 -1
  11. package/dist/index126.js +1 -1
  12. package/dist/index126.js.map +1 -1
  13. package/dist/index130.js +2 -2
  14. package/dist/index130.js.map +1 -1
  15. package/dist/index146.js +4 -4
  16. package/dist/index146.js.map +1 -1
  17. package/dist/index152.js +1 -1
  18. package/dist/index152.js.map +1 -1
  19. package/dist/index154.js +2 -2
  20. package/dist/index154.js.map +1 -1
  21. package/dist/index166.js +1 -1
  22. package/dist/index166.js.map +1 -1
  23. package/dist/index168.js +1 -1
  24. package/dist/index168.js.map +1 -1
  25. package/dist/index169.js +1 -1
  26. package/dist/index169.js.map +1 -1
  27. package/dist/index173.js +2 -2
  28. package/dist/index173.js.map +1 -1
  29. package/dist/index175.js +4 -4
  30. package/dist/index175.js.map +1 -1
  31. package/dist/index176.js +2 -2
  32. package/dist/index176.js.map +1 -1
  33. package/dist/index177.js +2 -2
  34. package/dist/index177.js.map +1 -1
  35. package/dist/index184.js +1 -1
  36. package/dist/index184.js.map +1 -1
  37. package/dist/index191.js +3 -3
  38. package/dist/index191.js.map +1 -1
  39. package/dist/index192.js +2 -2
  40. package/dist/index192.js.map +1 -1
  41. package/dist/index201.js +2 -2
  42. package/dist/index201.js.map +1 -1
  43. package/dist/index204.js +4 -4
  44. package/dist/index204.js.map +1 -1
  45. package/dist/index228.js +1 -1
  46. package/dist/index228.js.map +1 -1
  47. package/dist/index229.js +1 -1
  48. package/dist/index229.js.map +1 -1
  49. package/dist/index24.js +2 -2
  50. package/dist/index24.js.map +1 -1
  51. package/dist/index5.js +1 -1
  52. package/dist/index5.js.map +1 -1
  53. package/dist/styles.css +1 -1
  54. package/dist/wc/AICodeBlock.js +41 -41
  55. package/dist/wc/AICodeBlock.js.map +1 -1
  56. package/dist/wc/AIMermaidDiagram.js +7 -7
  57. package/dist/wc/AIMermaidDiagram.js.map +1 -1
  58. package/dist/wc/AIMessage.js +6 -6
  59. package/dist/wc/AIMessage.js.map +1 -1
  60. package/dist/wc/AISource.js +2 -2
  61. package/dist/wc/AISource.js.map +1 -1
  62. package/dist/wc/AIToolCall.js +1 -1
  63. package/dist/wc/AIToolCall.js.map +1 -1
  64. package/dist/wc/Breadcrumb.js +43 -43
  65. package/dist/wc/Breadcrumb.js.map +1 -1
  66. package/dist/wc/DropdownMenu.js +9 -9
  67. package/dist/wc/DropdownMenu.js.map +1 -1
  68. package/dist/wc/Kbd.js +22 -22
  69. package/dist/wc/Kbd.js.map +1 -1
  70. package/dist/wc/button.js +7 -7
  71. package/dist/wc/button.js.map +1 -1
  72. package/dist/wc/close-button.js +19 -19
  73. package/dist/wc/close-button.js.map +1 -1
  74. package/dist/wc/hf-ai-prompt-suggestion.js +14 -14
  75. package/dist/wc/hf-ai-prompt-suggestion.js.map +1 -1
  76. package/dist/wc/hf-ai-reasoning-block.js +13 -13
  77. package/dist/wc/hf-ai-reasoning-block.js.map +1 -1
  78. package/dist/wc/hf-ai-steps.js +53 -53
  79. package/dist/wc/hf-ai-steps.js.map +1 -1
  80. package/dist/wc/hf-ai-system-message.js +26 -26
  81. package/dist/wc/hf-ai-system-message.js.map +1 -1
  82. package/dist/wc/hf-code-snippet.js +35 -35
  83. package/dist/wc/hf-code-snippet.js.map +1 -1
  84. package/dist/wc/hf-command-menu.js +39 -39
  85. package/dist/wc/hf-command-menu.js.map +1 -1
  86. package/dist/wc/hf-data-table.js +3 -3
  87. package/dist/wc/hf-data-table.js.map +1 -1
  88. package/dist/wc/hf-display-value.js +50 -50
  89. package/dist/wc/hf-display-value.js.map +1 -1
  90. package/dist/wc/hf-nav-account-menu.js +5 -5
  91. package/dist/wc/hf-nav-account-menu.js.map +1 -1
  92. package/dist/wc/hf-rich-textarea.js +1 -1
  93. package/dist/wc/hf-rich-textarea.js.map +1 -1
  94. package/dist/wc/hf-steps.js +8 -8
  95. package/dist/wc/hf-steps.js.map +1 -1
  96. package/dist/wc/markdown-renderer.js +1 -1
  97. package/dist/wc/markdown-renderer.js.map +1 -1
  98. package/dist/wc/selection-group.js +26 -26
  99. package/dist/wc/selection-group.js.map +1 -1
  100. package/dist/wc/syntax-highlight.js +4 -4
  101. package/dist/wc/syntax-highlight.js.map +1 -1
  102. package/dist/wc/workflow-step-renderer.js +51 -51
  103. package/dist/wc/workflow-step-renderer.js.map +1 -1
  104. package/dist/wc-react/AICodeBlock.js +17 -17
  105. package/dist/wc-react/AICodeBlock.js.map +1 -1
  106. package/dist/wc-react/AIMermaidDiagram.js +16 -16
  107. package/dist/wc-react/AIMermaidDiagram.js.map +1 -1
  108. package/dist/wc-react/AIMessage.js +7 -7
  109. package/dist/wc-react/AIMessage.js.map +1 -1
  110. package/dist/wc-react/AISource.js +41 -41
  111. package/dist/wc-react/AISource.js.map +1 -1
  112. package/dist/wc-react/AIToolCall.js +6 -6
  113. package/dist/wc-react/AIToolCall.js.map +1 -1
  114. package/dist/wc-react/Breadcrumb.js +18 -18
  115. package/dist/wc-react/Breadcrumb.js.map +1 -1
  116. package/dist/wc-react/DropdownMenu.js +27 -27
  117. package/dist/wc-react/DropdownMenu.js.map +1 -1
  118. package/dist/wc-react/Kbd.js +17 -17
  119. package/dist/wc-react/Kbd.js.map +1 -1
  120. package/dist/wc-react/button.js +12 -12
  121. package/dist/wc-react/button.js.map +1 -1
  122. package/dist/wc-react/close-button.js +19 -19
  123. package/dist/wc-react/close-button.js.map +1 -1
  124. package/dist/wc-react/hf-ai-prompt-suggestion.js +1 -1
  125. package/dist/wc-react/hf-ai-prompt-suggestion.js.map +1 -1
  126. package/dist/wc-react/hf-ai-reasoning-block.js +1 -1
  127. package/dist/wc-react/hf-ai-reasoning-block.js.map +1 -1
  128. package/dist/wc-react/hf-ai-steps.js +33 -33
  129. package/dist/wc-react/hf-ai-steps.js.map +1 -1
  130. package/dist/wc-react/hf-ai-system-message.js +9 -9
  131. package/dist/wc-react/hf-ai-system-message.js.map +1 -1
  132. package/dist/wc-react/hf-code-snippet.js +3 -3
  133. package/dist/wc-react/hf-code-snippet.js.map +1 -1
  134. package/dist/wc-react/hf-command-menu.js +56 -56
  135. package/dist/wc-react/hf-command-menu.js.map +1 -1
  136. package/dist/wc-react/hf-data-table.js +3 -3
  137. package/dist/wc-react/hf-data-table.js.map +1 -1
  138. package/dist/wc-react/hf-display-value.js +58 -58
  139. package/dist/wc-react/hf-display-value.js.map +1 -1
  140. package/dist/wc-react/hf-nav-account-menu.js +7 -7
  141. package/dist/wc-react/hf-nav-account-menu.js.map +1 -1
  142. package/dist/wc-react/hf-rich-textarea.js +5 -5
  143. package/dist/wc-react/hf-rich-textarea.js.map +1 -1
  144. package/dist/wc-react/hf-steps.js +2 -2
  145. package/dist/wc-react/hf-steps.js.map +1 -1
  146. package/dist/wc-react/markdown-renderer.js +1 -1
  147. package/dist/wc-react/markdown-renderer.js.map +1 -1
  148. package/dist/wc-react/selection-group.js +7 -7
  149. package/dist/wc-react/selection-group.js.map +1 -1
  150. package/dist/wc-react/syntax-highlight.js +4 -4
  151. package/dist/wc-react/syntax-highlight.js.map +1 -1
  152. package/dist/wc-react/workflow-step-renderer.js +44 -44
  153. package/dist/wc-react/workflow-step-renderer.js.map +1 -1
  154. package/package.json +1 -1
  155. package/skills/humain-ui/SKILL.md +1 -1
  156. package/skills/humain-ui-wc/SKILL.md +1 -1
  157. package/skills/humain-ui-wc.skill +0 -0
  158. package/skills/humain-ui.skill +0 -0
  159. package/src/tokens.css +4 -0
package/dist/index101.js CHANGED
@@ -2,13 +2,13 @@
2
2
  var SUGAR_HIGH_STYLE = {
3
3
  "--sh-class": "var(--blue-700)",
4
4
  "--sh-identifier": "var(--foreground)",
5
- "--sh-sign": "var(--muted-foreground)",
5
+ "--sh-sign": "var(--secondary-foreground)",
6
6
  "--sh-property": "var(--pink-600)",
7
7
  "--sh-entity": "var(--purple-700)",
8
8
  "--sh-jsxliterals": "var(--cyan-700)",
9
9
  "--sh-string": "var(--green-700)",
10
10
  "--sh-keyword": "var(--indigo-700)",
11
- "--sh-comment": "var(--text-quaternary)"
11
+ "--sh-comment": "var(--secondary-foreground)"
12
12
  };
13
13
  var INVERTED_SUGAR_HIGH_STYLE = {
14
14
  "--sh-class": "var(--blue-200)",
@@ -1 +1 @@
1
- {"version":3,"file":"index101.js","names":[],"sources":["../src/lib/syntax-highlight.ts"],"sourcesContent":["import type * as React from 'react';\n\nexport const SUGAR_HIGH_STYLE = {\n '--sh-class': 'var(--blue-700)',\n '--sh-identifier': 'var(--foreground)',\n '--sh-sign': 'var(--muted-foreground)',\n '--sh-property': 'var(--pink-600)',\n '--sh-entity': 'var(--purple-700)',\n '--sh-jsxliterals': 'var(--cyan-700)',\n '--sh-string': 'var(--green-700)',\n '--sh-keyword': 'var(--indigo-700)',\n '--sh-comment': 'var(--text-quaternary)',\n} as React.CSSProperties;\n\nexport const INVERTED_SUGAR_HIGH_STYLE = {\n '--sh-class': 'var(--blue-200)',\n '--sh-identifier': 'var(--primary-foreground)',\n '--sh-sign': 'var(--primary-foreground)',\n '--sh-property': 'var(--pink-300)',\n '--sh-entity': 'var(--purple-300)',\n '--sh-jsxliterals': 'var(--cyan-300)',\n '--sh-string': 'var(--green-300)',\n '--sh-keyword': 'var(--indigo-300)',\n '--sh-comment': 'var(--primary-foreground)',\n} as React.CSSProperties;\n"],"mappings":";AAEA,IAAa,mBAAmB;CAC9B,cAAc;CACd,mBAAmB;CACnB,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;AAClB;AAEA,IAAa,4BAA4B;CACvC,cAAc;CACd,mBAAmB;CACnB,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;AAClB"}
1
+ {"version":3,"file":"index101.js","names":[],"sources":["../src/lib/syntax-highlight.ts"],"sourcesContent":["import type * as React from 'react';\n\nexport const SUGAR_HIGH_STYLE = {\n '--sh-class': 'var(--blue-700)',\n '--sh-identifier': 'var(--foreground)',\n '--sh-sign': 'var(--secondary-foreground)',\n '--sh-property': 'var(--pink-600)',\n '--sh-entity': 'var(--purple-700)',\n '--sh-jsxliterals': 'var(--cyan-700)',\n '--sh-string': 'var(--green-700)',\n '--sh-keyword': 'var(--indigo-700)',\n '--sh-comment': 'var(--secondary-foreground)',\n} as React.CSSProperties;\n\nexport const INVERTED_SUGAR_HIGH_STYLE = {\n '--sh-class': 'var(--blue-200)',\n '--sh-identifier': 'var(--primary-foreground)',\n '--sh-sign': 'var(--primary-foreground)',\n '--sh-property': 'var(--pink-300)',\n '--sh-entity': 'var(--purple-300)',\n '--sh-jsxliterals': 'var(--cyan-300)',\n '--sh-string': 'var(--green-300)',\n '--sh-keyword': 'var(--indigo-300)',\n '--sh-comment': 'var(--primary-foreground)',\n} as React.CSSProperties;\n"],"mappings":";AAEA,IAAa,mBAAmB;CAC9B,cAAc;CACd,mBAAmB;CACnB,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;AAClB;AAEA,IAAa,4BAA4B;CACvC,cAAc;CACd,mBAAmB;CACnB,aAAa;CACb,iBAAiB;CACjB,eAAe;CACf,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;AAClB"}
package/dist/index103.js CHANGED
@@ -16,7 +16,7 @@ var codeSnippetVariants = cva("overflow-hidden rounded-xl bg-background", {
16
16
  } },
17
17
  defaultVariants: { size: "md" }
18
18
  });
19
- var lineNumberVariants = cva("select-none font-mono font-bold leading-normal text-text-quaternary", {
19
+ var lineNumberVariants = cva("select-none font-mono font-bold leading-normal text-secondary-foreground", {
20
20
  variants: { size: {
21
21
  sm: "text-xs",
22
22
  md: "text-base",
@@ -88,7 +88,7 @@ var CodeSnippet = React$1.forwardRef(({ code, language, showLineNumbers = true,
88
88
  (language || showCopyButton) && /* @__PURE__ */ jsxs("div", {
89
89
  className: "absolute top-2 end-2 flex items-center gap-2 z-10",
90
90
  children: [language && /* @__PURE__ */ jsx("span", {
91
- className: "text-xs font-medium text-text-quaternary uppercase select-none",
91
+ className: "text-xs font-medium text-secondary-foreground uppercase select-none",
92
92
  children: language
93
93
  }), showCopyButton && /* @__PURE__ */ jsx(Button, {
94
94
  appearance: "ghost",
@@ -96,7 +96,7 @@ var CodeSnippet = React$1.forwardRef(({ code, language, showLineNumbers = true,
96
96
  size: "sm",
97
97
  onClick: handleCopy,
98
98
  "aria-label": copied ? "Copied to clipboard" : "Copy code to clipboard",
99
- className: "h-7 px-2 text-text-quaternary hover:text-secondary-foreground transition-colors duration-150 ease-out",
99
+ className: "h-7 px-2 text-secondary-foreground hover:text-foreground transition-colors duration-150 ease-out",
100
100
  children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-success" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3.5" })
101
101
  })]
102
102
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"index103.js","names":[],"sources":["../src/components/molecules/data/CodeSnippet/CodeSnippet.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, Copy } from 'lucide-react';\nimport * as React from 'react';\nimport { Button } from '@/components/atoms/buttons/Button';\nimport { SUGAR_HIGH_STYLE } from '@/lib/syntax-highlight';\nimport { renderHighlightedCode } from '@/lib/syntax-highlight-react';\nimport { cn } from '@/lib/utils';\n\nconst codeSnippetVariants = cva('overflow-hidden rounded-xl bg-background', {\n variants: {\n size: {\n sm: 'text-xs',\n md: 'text-base',\n lg: 'text-lg',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nconst lineNumberVariants = cva(\n 'select-none font-mono font-bold leading-normal text-text-quaternary',\n {\n variants: {\n size: {\n sm: 'text-xs',\n md: 'text-base',\n lg: 'text-lg',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\nexport interface CodeSnippetProps\n extends VariantProps<typeof codeSnippetVariants> {\n /** Code content to display */\n code: string;\n /** Programming language label shown in the top-right corner */\n language?: string;\n /** Whether to show line numbers */\n showLineNumbers?: boolean;\n /** Starting line number */\n startLineNumber?: number;\n /** Whether to show a copy-to-clipboard button */\n showCopyButton?: boolean;\n /** Additional class name */\n className?: string;\n /** Responsive breakpoint for compact mode */\n breakpoint?: 'desktop' | 'mobile';\n}\n\ninterface LineNumbersProps {\n count: number;\n startLine: number;\n size?: 'sm' | 'md' | 'lg' | null;\n}\n\ninterface CopyFeedbackState {\n copied: boolean;\n resetKey: number;\n}\n\nfunction copyFeedbackReducer(\n state: CopyFeedbackState,\n copied: boolean,\n): CopyFeedbackState {\n return copied\n ? { copied: true, resetKey: state.resetKey + 1 }\n : { ...state, copied: false };\n}\n\nfunction getStartLineNumber(startLineNumber: number): number {\n return Number.isFinite(startLineNumber) ? Math.floor(startLineNumber) : 1;\n}\n\nfunction LineNumbers({ count, startLine, size }: LineNumbersProps) {\n return (\n <div aria-hidden=\"true\" className={cn(lineNumberVariants({ size }))}>\n {Array.from({ length: count }, (_, i) => (\n <span key={i} className=\"block mb-px last:mb-0\">\n {startLine + i}\n </span>\n ))}\n </div>\n );\n}\n\nconst CodeSnippet = React.forwardRef<HTMLElement, CodeSnippetProps>(\n (\n {\n code,\n language,\n showLineNumbers = true,\n startLineNumber = 1,\n showCopyButton = false,\n size,\n className,\n breakpoint = 'desktop',\n },\n ref,\n ) => {\n const highlightedContent = React.useMemo(\n () => renderHighlightedCode(code),\n [code],\n );\n const lineCount = React.useMemo(() => code.split('\\n').length, [code]);\n const safeStartLineNumber = getStartLineNumber(startLineNumber);\n\n const [copyFeedback, setCopyFeedback] = React.useReducer(\n copyFeedbackReducer,\n { copied: false, resetKey: 0 },\n );\n const { copied } = copyFeedback;\n const rootRef = React.useRef<HTMLElement>(null);\n\n // Merge forwarded ref with local ref\n React.useImperativeHandle(ref, () => rootRef.current as HTMLElement);\n\n React.useEffect(() => {\n if (!copyFeedback.copied) return;\n\n const copyResetTimer = setTimeout(() => {\n setCopyFeedback(false);\n }, 2000);\n\n return () => {\n clearTimeout(copyResetTimer);\n };\n }, [copyFeedback]);\n\n const handleCopy = React.useCallback(async () => {\n try {\n const win = rootRef.current?.ownerDocument.defaultView;\n if (!win) return;\n await win.navigator.clipboard.writeText(code);\n setCopyFeedback(true);\n } catch (err) {\n console.error('Failed to copy code:', err);\n }\n }, [code]);\n\n const containerPadding = breakpoint === 'mobile' ? 'p-4' : 'p-6';\n const contentPadding =\n breakpoint === 'mobile' ? 'py-4 px-4 pb-6' : 'py-6 px-6 pb-8';\n\n return (\n <section\n ref={rootRef}\n data-slot=\"code-snippet\"\n aria-label=\"Code snippet\"\n className={cn(\n codeSnippetVariants({ size }),\n 'relative flex items-start justify-center',\n className,\n )}\n style={SUGAR_HIGH_STYLE}\n >\n {/* Language badge & copy button */}\n {(language || showCopyButton) && (\n <div className=\"absolute top-2 end-2 flex items-center gap-2 z-10\">\n {language && (\n <span className=\"text-xs font-medium text-text-quaternary uppercase select-none\">\n {language}\n </span>\n )}\n {showCopyButton && (\n <Button\n appearance=\"ghost\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={handleCopy}\n aria-label={\n copied ? 'Copied to clipboard' : 'Copy code to clipboard'\n }\n className=\"h-7 px-2 text-text-quaternary hover:text-secondary-foreground transition-colors duration-150 ease-out\"\n >\n {copied ? (\n <Check className=\"size-3.5 text-success\" />\n ) : (\n <Copy className=\"size-3.5\" />\n )}\n </Button>\n )}\n </div>\n )}\n\n {/* Line Numbers Sidebar */}\n {showLineNumbers && (\n <div\n className={cn(\n 'shrink-0 self-stretch bg-muted border-e border-border',\n containerPadding,\n )}\n >\n <LineNumbers\n count={lineCount}\n startLine={safeStartLineNumber}\n size={size}\n />\n </div>\n )}\n\n {/* Code Content */}\n <section\n className={cn(\n 'grow min-w-0 overflow-x-auto focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n contentPadding,\n )}\n // biome-ignore lint/a11y/noNoninteractiveTabindex: Focusable scroll region satisfies axe scrollable-region-focusable.\n tabIndex={0}\n aria-label=\"Code content\"\n >\n <pre\n className={cn(\n 'font-mono font-medium leading-normal !bg-transparent !p-0 !m-0 !border-0 !rounded-none',\n '[&_.sh__line]:block [&_.sh__line]:leading-normal [&_.sh__line]:mb-px [&_.sh__line:last-child]:mb-0',\n )}\n >\n {highlightedContent}\n </pre>\n </section>\n </section>\n );\n },\n);\n\nCodeSnippet.displayName = 'CodeSnippet';\n\nexport { CodeSnippet, codeSnippetVariants, lineNumberVariants };\n"],"mappings":";;;;;;;;;;AAUA,IAAM,sBAAsB,IAAI,4CAA4C;CAC1E,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CAAC;AAED,IAAM,qBAAqB,IACzB,uEACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AA+BA,SAAS,oBACP,OACA,QACmB;CACnB,OAAO,SACH;EAAE,QAAQ;EAAM,UAAU,MAAM,WAAW;CAAE,IAC7C;EAAE,GAAG;EAAO,QAAQ;CAAM;AAChC;AAEA,SAAS,mBAAmB,iBAAiC;CAC3D,OAAO,OAAO,SAAS,eAAe,IAAI,KAAK,MAAM,eAAe,IAAI;AAC1E;AAEA,SAAS,YAAY,EAAE,OAAO,WAAW,QAA0B;CACjE,OACE,oBAAC,OAAD;EAAK,eAAY;EAAO,WAAW,GAAG,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC/D,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,GAAG,MACjC,oBAAC,QAAD;GAAc,WAAU;aACrB,YAAY;EACT,GAFK,CAEL,CACP;CACE,CAAA;AAET;AAEA,IAAM,cAAc,QAAM,YAEtB,EACE,MACA,UACA,kBAAkB,MAClB,kBAAkB,GAClB,iBAAiB,OACjB,MACA,WACA,aAAa,aAEf,QACG;CACH,MAAM,qBAAqB,QAAM,cACzB,sBAAsB,IAAI,GAChC,CAAC,IAAI,CACP;CACA,MAAM,YAAY,QAAM,cAAc,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;CACrE,MAAM,sBAAsB,mBAAmB,eAAe;CAE9D,MAAM,CAAC,cAAc,mBAAmB,QAAM,WAC5C,qBACA;EAAE,QAAQ;EAAO,UAAU;CAAE,CAC/B;CACA,MAAM,EAAE,WAAW;CACnB,MAAM,UAAU,QAAM,OAAoB,IAAI;CAG9C,QAAM,oBAAoB,WAAW,QAAQ,OAAsB;CAEnE,QAAM,gBAAgB;EACpB,IAAI,CAAC,aAAa,QAAQ;EAE1B,MAAM,iBAAiB,iBAAiB;GACtC,gBAAgB,KAAK;EACvB,GAAG,GAAI;EAEP,aAAa;GACX,aAAa,cAAc;EAC7B;CACF,GAAG,CAAC,YAAY,CAAC;CAEjB,MAAM,aAAa,QAAM,YAAY,YAAY;EAC/C,IAAI;GACF,MAAM,MAAM,QAAQ,SAAS,cAAc;GAC3C,IAAI,CAAC,KAAK;GACV,MAAM,IAAI,UAAU,UAAU,UAAU,IAAI;GAC5C,gBAAgB,IAAI;EACtB,SAAS,KAAK;GACZ,QAAQ,MAAM,wBAAwB,GAAG;EAC3C;CACF,GAAG,CAAC,IAAI,CAAC;CAET,MAAM,mBAAmB,eAAe,WAAW,QAAQ;CAC3D,MAAM,iBACJ,eAAe,WAAW,mBAAmB;CAE/C,OACE,qBAAC,WAAD;EACE,KAAK;EACL,aAAU;EACV,cAAW;EACX,WAAW,GACT,oBAAoB,EAAE,KAAK,CAAC,GAC5B,4CACA,SACF;EACA,OAAO;YATT;IAYI,YAAY,mBACZ,qBAAC,OAAD;IAAK,WAAU;cAAf,CACG,YACC,oBAAC,QAAD;KAAM,WAAU;eACb;IACG,CAAA,GAEP,kBACC,oBAAC,QAAD;KACE,YAAW;KACX,SAAQ;KACR,MAAK;KACL,SAAS;KACT,cACE,SAAS,wBAAwB;KAEnC,WAAU;eAET,SACC,oBAAC,OAAD,EAAO,WAAU,wBAAyB,CAAA,IAE1C,oBAAC,MAAD,EAAM,WAAU,WAAY,CAAA;IAExB,CAAA,CAEP;;GAIN,mBACC,oBAAC,OAAD;IACE,WAAW,GACT,yDACA,gBACF;cAEA,oBAAC,aAAD;KACE,OAAO;KACP,WAAW;KACL;IACP,CAAA;GACE,CAAA;GAIP,oBAAC,WAAD;IACE,WAAW,GACT,kHACA,cACF;IAEA,UAAU;IACV,cAAW;cAEX,oBAAC,OAAD;KACE,WAAW,GACT,0FACA,oGACF;eAEC;IACE,CAAA;GACE,CAAA;EACF;;AAEb,CACF;AAEA,YAAY,cAAc"}
1
+ {"version":3,"file":"index103.js","names":[],"sources":["../src/components/molecules/data/CodeSnippet/CodeSnippet.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, Copy } from 'lucide-react';\nimport * as React from 'react';\nimport { Button } from '@/components/atoms/buttons/Button';\nimport { SUGAR_HIGH_STYLE } from '@/lib/syntax-highlight';\nimport { renderHighlightedCode } from '@/lib/syntax-highlight-react';\nimport { cn } from '@/lib/utils';\n\nconst codeSnippetVariants = cva('overflow-hidden rounded-xl bg-background', {\n variants: {\n size: {\n sm: 'text-xs',\n md: 'text-base',\n lg: 'text-lg',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nconst lineNumberVariants = cva(\n 'select-none font-mono font-bold leading-normal text-secondary-foreground',\n {\n variants: {\n size: {\n sm: 'text-xs',\n md: 'text-base',\n lg: 'text-lg',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\nexport interface CodeSnippetProps\n extends VariantProps<typeof codeSnippetVariants> {\n /** Code content to display */\n code: string;\n /** Programming language label shown in the top-right corner */\n language?: string;\n /** Whether to show line numbers */\n showLineNumbers?: boolean;\n /** Starting line number */\n startLineNumber?: number;\n /** Whether to show a copy-to-clipboard button */\n showCopyButton?: boolean;\n /** Additional class name */\n className?: string;\n /** Responsive breakpoint for compact mode */\n breakpoint?: 'desktop' | 'mobile';\n}\n\ninterface LineNumbersProps {\n count: number;\n startLine: number;\n size?: 'sm' | 'md' | 'lg' | null;\n}\n\ninterface CopyFeedbackState {\n copied: boolean;\n resetKey: number;\n}\n\nfunction copyFeedbackReducer(\n state: CopyFeedbackState,\n copied: boolean,\n): CopyFeedbackState {\n return copied\n ? { copied: true, resetKey: state.resetKey + 1 }\n : { ...state, copied: false };\n}\n\nfunction getStartLineNumber(startLineNumber: number): number {\n return Number.isFinite(startLineNumber) ? Math.floor(startLineNumber) : 1;\n}\n\nfunction LineNumbers({ count, startLine, size }: LineNumbersProps) {\n return (\n <div aria-hidden=\"true\" className={cn(lineNumberVariants({ size }))}>\n {Array.from({ length: count }, (_, i) => (\n <span key={i} className=\"block mb-px last:mb-0\">\n {startLine + i}\n </span>\n ))}\n </div>\n );\n}\n\nconst CodeSnippet = React.forwardRef<HTMLElement, CodeSnippetProps>(\n (\n {\n code,\n language,\n showLineNumbers = true,\n startLineNumber = 1,\n showCopyButton = false,\n size,\n className,\n breakpoint = 'desktop',\n },\n ref,\n ) => {\n const highlightedContent = React.useMemo(\n () => renderHighlightedCode(code),\n [code],\n );\n const lineCount = React.useMemo(() => code.split('\\n').length, [code]);\n const safeStartLineNumber = getStartLineNumber(startLineNumber);\n\n const [copyFeedback, setCopyFeedback] = React.useReducer(\n copyFeedbackReducer,\n { copied: false, resetKey: 0 },\n );\n const { copied } = copyFeedback;\n const rootRef = React.useRef<HTMLElement>(null);\n\n // Merge forwarded ref with local ref\n React.useImperativeHandle(ref, () => rootRef.current as HTMLElement);\n\n React.useEffect(() => {\n if (!copyFeedback.copied) return;\n\n const copyResetTimer = setTimeout(() => {\n setCopyFeedback(false);\n }, 2000);\n\n return () => {\n clearTimeout(copyResetTimer);\n };\n }, [copyFeedback]);\n\n const handleCopy = React.useCallback(async () => {\n try {\n const win = rootRef.current?.ownerDocument.defaultView;\n if (!win) return;\n await win.navigator.clipboard.writeText(code);\n setCopyFeedback(true);\n } catch (err) {\n console.error('Failed to copy code:', err);\n }\n }, [code]);\n\n const containerPadding = breakpoint === 'mobile' ? 'p-4' : 'p-6';\n const contentPadding =\n breakpoint === 'mobile' ? 'py-4 px-4 pb-6' : 'py-6 px-6 pb-8';\n\n return (\n <section\n ref={rootRef}\n data-slot=\"code-snippet\"\n aria-label=\"Code snippet\"\n className={cn(\n codeSnippetVariants({ size }),\n 'relative flex items-start justify-center',\n className,\n )}\n style={SUGAR_HIGH_STYLE}\n >\n {/* Language badge & copy button */}\n {(language || showCopyButton) && (\n <div className=\"absolute top-2 end-2 flex items-center gap-2 z-10\">\n {language && (\n <span className=\"text-xs font-medium text-secondary-foreground uppercase select-none\">\n {language}\n </span>\n )}\n {showCopyButton && (\n <Button\n appearance=\"ghost\"\n variant=\"secondary\"\n size=\"sm\"\n onClick={handleCopy}\n aria-label={\n copied ? 'Copied to clipboard' : 'Copy code to clipboard'\n }\n className=\"h-7 px-2 text-secondary-foreground hover:text-foreground transition-colors duration-150 ease-out\"\n >\n {copied ? (\n <Check className=\"size-3.5 text-success\" />\n ) : (\n <Copy className=\"size-3.5\" />\n )}\n </Button>\n )}\n </div>\n )}\n\n {/* Line Numbers Sidebar */}\n {showLineNumbers && (\n <div\n className={cn(\n 'shrink-0 self-stretch bg-muted border-e border-border',\n containerPadding,\n )}\n >\n <LineNumbers\n count={lineCount}\n startLine={safeStartLineNumber}\n size={size}\n />\n </div>\n )}\n\n {/* Code Content */}\n <section\n className={cn(\n 'grow min-w-0 overflow-x-auto focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n contentPadding,\n )}\n // biome-ignore lint/a11y/noNoninteractiveTabindex: Focusable scroll region satisfies axe scrollable-region-focusable.\n tabIndex={0}\n aria-label=\"Code content\"\n >\n <pre\n className={cn(\n 'font-mono font-medium leading-normal !bg-transparent !p-0 !m-0 !border-0 !rounded-none',\n '[&_.sh__line]:block [&_.sh__line]:leading-normal [&_.sh__line]:mb-px [&_.sh__line:last-child]:mb-0',\n )}\n >\n {highlightedContent}\n </pre>\n </section>\n </section>\n );\n },\n);\n\nCodeSnippet.displayName = 'CodeSnippet';\n\nexport { CodeSnippet, codeSnippetVariants, lineNumberVariants };\n"],"mappings":"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"}
package/dist/index108.js CHANGED
@@ -12,7 +12,7 @@ var kbdVariants = cva("pointer-events-none inline-flex items-center justify-cent
12
12
  outline: "bg-transparent border border-border text-muted-foreground rounded-sm shadow-[var(--shadow-kbd-outline)]",
13
13
  solid: "bg-card/60 border border-border text-muted-foreground rounded shadow-[var(--shadow-kbd-default)]",
14
14
  tooltip: "bg-background/20 text-background dark:bg-background/10 rounded-sm",
15
- footer: "bg-background border border-border text-text-quaternary rounded-md shadow-[var(--shadow-kbd-footer)]"
15
+ footer: "bg-background border border-border text-secondary-foreground rounded-md shadow-[var(--shadow-kbd-footer)]"
16
16
  },
17
17
  size: {
18
18
  xs: "h-4 min-w-4 px-0.5 text-[10px]",
@@ -1 +1 @@
1
- {"version":3,"file":"index108.js","names":[],"sources":["../src/components/molecules/data/Kbd/Kbd.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\n// ============================================\n// Variants\n// ============================================\n\nexport const kbdVariants = cva(\n 'pointer-events-none inline-flex items-center justify-center select-none font-sans font-medium',\n {\n variants: {\n variant: {\n default:\n 'bg-muted text-muted-foreground border border-border rounded-sm shadow-[var(--shadow-kbd-default)]',\n ghost: 'bg-transparent text-muted-foreground',\n outline:\n 'bg-transparent border border-border text-muted-foreground rounded-sm shadow-[var(--shadow-kbd-outline)]',\n solid:\n 'bg-card/60 border border-border text-muted-foreground rounded shadow-[var(--shadow-kbd-default)]',\n tooltip:\n 'bg-background/20 text-background dark:bg-background/10 rounded-sm',\n footer:\n 'bg-background border border-border text-text-quaternary rounded-md shadow-[var(--shadow-kbd-footer)]',\n },\n size: {\n xs: 'h-4 min-w-4 px-0.5 text-[10px]',\n sm: 'h-5 min-w-5 px-1 text-xs',\n md: 'h-6 min-w-6 px-1.5 text-sm',\n lg: 'h-7 min-w-7 px-2 text-sm',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'sm',\n },\n },\n);\n\nexport const kbdGroupVariants = cva('inline-flex items-center', {\n variants: {\n gap: {\n none: 'gap-0',\n xs: 'gap-0.5',\n sm: 'gap-1',\n md: 'gap-1.5',\n lg: 'gap-2',\n },\n },\n defaultVariants: {\n gap: 'sm',\n },\n});\n\n// ============================================\n// Types\n// ============================================\n\nexport interface KbdProps\n extends React.ComponentProps<'kbd'>,\n VariantProps<typeof kbdVariants> {\n /** Icon to display before the key */\n icon?: React.ReactNode;\n /** Icon to display after the key */\n iconAfter?: React.ReactNode;\n}\n\nexport interface KbdGroupProps\n extends React.ComponentProps<'span'>,\n VariantProps<typeof kbdGroupVariants> {}\n\n// ============================================\n// Kbd Component\n// ============================================\n\n/**\n * Keyboard key indicator component for displaying keyboard shortcuts.\n *\n * @example\n * // Basic usage\n * <Kbd>⌘K</Kbd>\n *\n * @example\n * // With variant and size\n * <Kbd variant=\"solid\" size=\"md\">⌘</Kbd>\n *\n * @example\n * // With icon\n * <Kbd icon={<ArrowUp />} />\n */\nconst Kbd = React.forwardRef<HTMLElement, KbdProps>(\n ({ className, variant, size, icon, iconAfter, children, ...props }, ref) => {\n return (\n <kbd\n ref={ref}\n data-slot=\"kbd\"\n className={cn(kbdVariants({ variant, size }), className)}\n {...props}\n >\n {icon && (\n <span\n aria-hidden=\"true\"\n className=\"shrink-0 [&_svg:not([class*='size-'])]:size-3\"\n >\n {icon}\n </span>\n )}\n {children}\n {iconAfter && (\n <span\n aria-hidden=\"true\"\n className=\"shrink-0 [&_svg:not([class*='size-'])]:size-3\"\n >\n {iconAfter}\n </span>\n )}\n </kbd>\n );\n },\n);\nKbd.displayName = 'Kbd';\n\n// ============================================\n// KbdGroup Component\n// ============================================\n\n/**\n * Group multiple Kbd components together with consistent spacing.\n *\n * @example\n * <KbdGroup>\n * <Kbd>⌘</Kbd>\n * <Kbd>K</Kbd>\n * </KbdGroup>\n */\nconst KbdGroup = React.forwardRef<HTMLSpanElement, KbdGroupProps>(\n ({ className, gap, ...props }, ref) => {\n return (\n <span\n ref={ref}\n data-slot=\"kbd-group\"\n className={cn(kbdGroupVariants({ gap }), className)}\n {...props}\n />\n );\n },\n);\nKbdGroup.displayName = 'KbdGroup';\n\n// ============================================\n// Shortcut Component (convenience wrapper)\n// ============================================\n\nexport interface ShortcutProps extends Omit<KbdProps, 'children'> {\n /** Array of keys to display (e.g., ['⌘', 'K']) */\n keys: (string | React.ReactNode)[];\n /** Separator between keys (defaults to none, keys are grouped) */\n separator?: React.ReactNode;\n}\n\nfunction getShortcutPartKey(\n key: string | React.ReactNode,\n position: number,\n): string {\n return `${position}:${typeof key === 'string' ? key : 'node'}`;\n}\n\n/**\n * Convenience component for displaying keyboard shortcuts with multiple keys.\n *\n * @example\n * // Simple shortcut\n * <Shortcut keys={['⌘', 'K']} />\n *\n * @example\n * // With separator\n * <Shortcut keys={['⌘', 'Shift', 'P']} separator=\"+\" />\n */\nconst Shortcut = React.forwardRef<HTMLSpanElement, ShortcutProps>(\n ({ keys, separator, className, variant, size, ...props }, ref) => {\n if (separator) {\n return (\n <KbdGroup ref={ref} gap=\"xs\" className={className}>\n {keys.map((key, position) => (\n <React.Fragment key={getShortcutPartKey(key, position)}>\n <Kbd variant={variant} size={size} {...props}>\n {key}\n </Kbd>\n {position < keys.length - 1 && (\n <span className=\"text-muted-foreground text-xs\">\n {separator}\n </span>\n )}\n </React.Fragment>\n ))}\n </KbdGroup>\n );\n }\n\n return (\n <KbdGroup ref={ref} gap=\"xs\" className={className}>\n {keys.map((key, position) => (\n <Kbd\n key={getShortcutPartKey(key, position)}\n variant={variant}\n size={size}\n {...props}\n >\n {key}\n </Kbd>\n ))}\n </KbdGroup>\n );\n },\n);\nShortcut.displayName = 'Shortcut';\n\n// ============================================\n// Platform-aware helpers\n// ============================================\n\n/**\n * Common keyboard key symbols for macOS\n */\nexport const MAC_KEYS = {\n cmd: '⌘',\n command: '⌘',\n ctrl: '⌃',\n control: '⌃',\n alt: '⌥',\n option: '⌥',\n shift: '⇧',\n enter: '↵',\n return: '↵',\n backspace: '⌫',\n delete: '⌦',\n tab: '⇥',\n esc: 'esc',\n escape: 'esc',\n up: '↑',\n down: '↓',\n left: '←',\n right: '→',\n space: '␣',\n} as const;\n\n/**\n * Common keyboard key symbols for Windows/Linux\n */\nexport const WIN_KEYS = {\n cmd: 'Ctrl',\n command: 'Ctrl',\n ctrl: 'Ctrl',\n control: 'Ctrl',\n alt: 'Alt',\n option: 'Alt',\n shift: 'Shift',\n enter: 'Enter',\n return: 'Enter',\n backspace: 'Backspace',\n delete: 'Delete',\n tab: 'Tab',\n esc: 'Esc',\n escape: 'Esc',\n up: '↑',\n down: '↓',\n left: '←',\n right: '→',\n space: 'Space',\n} as const;\n\n// ============================================\n// Exports\n// ============================================\n\nexport { Kbd, KbdGroup, Shortcut };\n"],"mappings":";;;;;;AAWA,IAAa,cAAc,IACzB,iGACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,OAAO;GACP,SACE;GACF,OACE;GACF,SACE;GACF,QACE;EACJ;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;AAEA,IAAa,mBAAmB,IAAI,4BAA4B;CAC9D,UAAU,EACR,KAAK;EACH,MAAM;EACN,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,KAAK,KACP;AACF,CAAC;;;;;;;;;;;;;;;;AAsCD,IAAM,MAAM,QAAM,YACf,EAAE,WAAW,SAAS,MAAM,MAAM,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1E,OACE,qBAAC,OAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,YAAY;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EACvD,GAAI;YAJN;GAMG,QACC,oBAAC,QAAD;IACE,eAAY;IACZ,WAAU;cAET;GACG,CAAA;GAEP;GACA,aACC,oBAAC,QAAD;IACE,eAAY;IACZ,WAAU;cAET;GACG,CAAA;EAEL;;AAET,CACF;AACA,IAAI,cAAc;;;;;;;;;;AAelB,IAAM,WAAW,QAAM,YACpB,EAAE,WAAW,KAAK,GAAG,SAAS,QAAQ;CACrC,OACE,oBAAC,QAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,iBAAiB,EAAE,IAAI,CAAC,GAAG,SAAS;EAClD,GAAI;CACL,CAAA;AAEL,CACF;AACA,SAAS,cAAc;AAavB,SAAS,mBACP,KACA,UACQ;CACR,OAAO,GAAG,SAAS,GAAG,OAAO,QAAQ,WAAW,MAAM;AACxD;;;;;;;;;;;;AAaA,IAAM,WAAW,QAAM,YACpB,EAAE,MAAM,WAAW,WAAW,SAAS,MAAM,GAAG,SAAS,QAAQ;CAChE,IAAI,WACF,OACE,oBAAC,UAAD;EAAe;EAAK,KAAI;EAAgB;YACrC,KAAK,KAAK,KAAK,aACd,qBAAC,QAAM,UAAP,EAAA,UAAA,CACE,oBAAC,KAAD;GAAc;GAAe;GAAM,GAAI;aACpC;EACE,CAAA,GACJ,WAAW,KAAK,SAAS,KACxB,oBAAC,QAAD;GAAM,WAAU;aACb;EACG,CAAA,CAEM,EAAA,GATK,mBAAmB,KAAK,QAAQ,CASrC,CACjB;CACO,CAAA;CAId,OACE,oBAAC,UAAD;EAAe;EAAK,KAAI;EAAgB;YACrC,KAAK,KAAK,KAAK,aACd,oBAAC,KAAD;GAEW;GACH;GACN,GAAI;aAEH;EACE,GANE,mBAAmB,KAAK,QAAQ,CAMlC,CACN;CACO,CAAA;AAEd,CACF;AACA,SAAS,cAAc;;;;AASvB,IAAa,WAAW;CACtB,KAAK;CACL,SAAS;CACT,MAAM;CACN,SAAS;CACT,KAAK;CACL,QAAQ;CACR,OAAO;CACP,OAAO;CACP,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,KAAK;CACL,KAAK;CACL,QAAQ;CACR,IAAI;CACJ,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;AACT;;;;AAKA,IAAa,WAAW;CACtB,KAAK;CACL,SAAS;CACT,MAAM;CACN,SAAS;CACT,KAAK;CACL,QAAQ;CACR,OAAO;CACP,OAAO;CACP,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,KAAK;CACL,KAAK;CACL,QAAQ;CACR,IAAI;CACJ,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;AACT"}
1
+ {"version":3,"file":"index108.js","names":[],"sources":["../src/components/molecules/data/Kbd/Kbd.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\n// ============================================\n// Variants\n// ============================================\n\nexport const kbdVariants = cva(\n 'pointer-events-none inline-flex items-center justify-center select-none font-sans font-medium',\n {\n variants: {\n variant: {\n default:\n 'bg-muted text-muted-foreground border border-border rounded-sm shadow-[var(--shadow-kbd-default)]',\n ghost: 'bg-transparent text-muted-foreground',\n outline:\n 'bg-transparent border border-border text-muted-foreground rounded-sm shadow-[var(--shadow-kbd-outline)]',\n solid:\n 'bg-card/60 border border-border text-muted-foreground rounded shadow-[var(--shadow-kbd-default)]',\n tooltip:\n 'bg-background/20 text-background dark:bg-background/10 rounded-sm',\n footer:\n 'bg-background border border-border text-secondary-foreground rounded-md shadow-[var(--shadow-kbd-footer)]',\n },\n size: {\n xs: 'h-4 min-w-4 px-0.5 text-[10px]',\n sm: 'h-5 min-w-5 px-1 text-xs',\n md: 'h-6 min-w-6 px-1.5 text-sm',\n lg: 'h-7 min-w-7 px-2 text-sm',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'sm',\n },\n },\n);\n\nexport const kbdGroupVariants = cva('inline-flex items-center', {\n variants: {\n gap: {\n none: 'gap-0',\n xs: 'gap-0.5',\n sm: 'gap-1',\n md: 'gap-1.5',\n lg: 'gap-2',\n },\n },\n defaultVariants: {\n gap: 'sm',\n },\n});\n\n// ============================================\n// Types\n// ============================================\n\nexport interface KbdProps\n extends React.ComponentProps<'kbd'>,\n VariantProps<typeof kbdVariants> {\n /** Icon to display before the key */\n icon?: React.ReactNode;\n /** Icon to display after the key */\n iconAfter?: React.ReactNode;\n}\n\nexport interface KbdGroupProps\n extends React.ComponentProps<'span'>,\n VariantProps<typeof kbdGroupVariants> {}\n\n// ============================================\n// Kbd Component\n// ============================================\n\n/**\n * Keyboard key indicator component for displaying keyboard shortcuts.\n *\n * @example\n * // Basic usage\n * <Kbd>⌘K</Kbd>\n *\n * @example\n * // With variant and size\n * <Kbd variant=\"solid\" size=\"md\">⌘</Kbd>\n *\n * @example\n * // With icon\n * <Kbd icon={<ArrowUp />} />\n */\nconst Kbd = React.forwardRef<HTMLElement, KbdProps>(\n ({ className, variant, size, icon, iconAfter, children, ...props }, ref) => {\n return (\n <kbd\n ref={ref}\n data-slot=\"kbd\"\n className={cn(kbdVariants({ variant, size }), className)}\n {...props}\n >\n {icon && (\n <span\n aria-hidden=\"true\"\n className=\"shrink-0 [&_svg:not([class*='size-'])]:size-3\"\n >\n {icon}\n </span>\n )}\n {children}\n {iconAfter && (\n <span\n aria-hidden=\"true\"\n className=\"shrink-0 [&_svg:not([class*='size-'])]:size-3\"\n >\n {iconAfter}\n </span>\n )}\n </kbd>\n );\n },\n);\nKbd.displayName = 'Kbd';\n\n// ============================================\n// KbdGroup Component\n// ============================================\n\n/**\n * Group multiple Kbd components together with consistent spacing.\n *\n * @example\n * <KbdGroup>\n * <Kbd>⌘</Kbd>\n * <Kbd>K</Kbd>\n * </KbdGroup>\n */\nconst KbdGroup = React.forwardRef<HTMLSpanElement, KbdGroupProps>(\n ({ className, gap, ...props }, ref) => {\n return (\n <span\n ref={ref}\n data-slot=\"kbd-group\"\n className={cn(kbdGroupVariants({ gap }), className)}\n {...props}\n />\n );\n },\n);\nKbdGroup.displayName = 'KbdGroup';\n\n// ============================================\n// Shortcut Component (convenience wrapper)\n// ============================================\n\nexport interface ShortcutProps extends Omit<KbdProps, 'children'> {\n /** Array of keys to display (e.g., ['⌘', 'K']) */\n keys: (string | React.ReactNode)[];\n /** Separator between keys (defaults to none, keys are grouped) */\n separator?: React.ReactNode;\n}\n\nfunction getShortcutPartKey(\n key: string | React.ReactNode,\n position: number,\n): string {\n return `${position}:${typeof key === 'string' ? key : 'node'}`;\n}\n\n/**\n * Convenience component for displaying keyboard shortcuts with multiple keys.\n *\n * @example\n * // Simple shortcut\n * <Shortcut keys={['⌘', 'K']} />\n *\n * @example\n * // With separator\n * <Shortcut keys={['⌘', 'Shift', 'P']} separator=\"+\" />\n */\nconst Shortcut = React.forwardRef<HTMLSpanElement, ShortcutProps>(\n ({ keys, separator, className, variant, size, ...props }, ref) => {\n if (separator) {\n return (\n <KbdGroup ref={ref} gap=\"xs\" className={className}>\n {keys.map((key, position) => (\n <React.Fragment key={getShortcutPartKey(key, position)}>\n <Kbd variant={variant} size={size} {...props}>\n {key}\n </Kbd>\n {position < keys.length - 1 && (\n <span className=\"text-muted-foreground text-xs\">\n {separator}\n </span>\n )}\n </React.Fragment>\n ))}\n </KbdGroup>\n );\n }\n\n return (\n <KbdGroup ref={ref} gap=\"xs\" className={className}>\n {keys.map((key, position) => (\n <Kbd\n key={getShortcutPartKey(key, position)}\n variant={variant}\n size={size}\n {...props}\n >\n {key}\n </Kbd>\n ))}\n </KbdGroup>\n );\n },\n);\nShortcut.displayName = 'Shortcut';\n\n// ============================================\n// Platform-aware helpers\n// ============================================\n\n/**\n * Common keyboard key symbols for macOS\n */\nexport const MAC_KEYS = {\n cmd: '⌘',\n command: '⌘',\n ctrl: '⌃',\n control: '⌃',\n alt: '⌥',\n option: '⌥',\n shift: '⇧',\n enter: '↵',\n return: '↵',\n backspace: '⌫',\n delete: '⌦',\n tab: '⇥',\n esc: 'esc',\n escape: 'esc',\n up: '↑',\n down: '↓',\n left: '←',\n right: '→',\n space: '␣',\n} as const;\n\n/**\n * Common keyboard key symbols for Windows/Linux\n */\nexport const WIN_KEYS = {\n cmd: 'Ctrl',\n command: 'Ctrl',\n ctrl: 'Ctrl',\n control: 'Ctrl',\n alt: 'Alt',\n option: 'Alt',\n shift: 'Shift',\n enter: 'Enter',\n return: 'Enter',\n backspace: 'Backspace',\n delete: 'Delete',\n tab: 'Tab',\n esc: 'Esc',\n escape: 'Esc',\n up: '↑',\n down: '↓',\n left: '←',\n right: '→',\n space: 'Space',\n} as const;\n\n// ============================================\n// Exports\n// ============================================\n\nexport { Kbd, KbdGroup, Shortcut };\n"],"mappings":";;;;;;AAWA,IAAa,cAAc,IACzB,iGACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,OAAO;GACP,SACE;GACF,OACE;GACF,SACE;GACF,QACE;EACJ;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;AAEA,IAAa,mBAAmB,IAAI,4BAA4B;CAC9D,UAAU,EACR,KAAK;EACH,MAAM;EACN,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,KAAK,KACP;AACF,CAAC;;;;;;;;;;;;;;;;AAsCD,IAAM,MAAM,QAAM,YACf,EAAE,WAAW,SAAS,MAAM,MAAM,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1E,OACE,qBAAC,OAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,YAAY;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EACvD,GAAI;YAJN;GAMG,QACC,oBAAC,QAAD;IACE,eAAY;IACZ,WAAU;cAET;GACG,CAAA;GAEP;GACA,aACC,oBAAC,QAAD;IACE,eAAY;IACZ,WAAU;cAET;GACG,CAAA;EAEL;;AAET,CACF;AACA,IAAI,cAAc;;;;;;;;;;AAelB,IAAM,WAAW,QAAM,YACpB,EAAE,WAAW,KAAK,GAAG,SAAS,QAAQ;CACrC,OACE,oBAAC,QAAD;EACO;EACL,aAAU;EACV,WAAW,GAAG,iBAAiB,EAAE,IAAI,CAAC,GAAG,SAAS;EAClD,GAAI;CACL,CAAA;AAEL,CACF;AACA,SAAS,cAAc;AAavB,SAAS,mBACP,KACA,UACQ;CACR,OAAO,GAAG,SAAS,GAAG,OAAO,QAAQ,WAAW,MAAM;AACxD;;;;;;;;;;;;AAaA,IAAM,WAAW,QAAM,YACpB,EAAE,MAAM,WAAW,WAAW,SAAS,MAAM,GAAG,SAAS,QAAQ;CAChE,IAAI,WACF,OACE,oBAAC,UAAD;EAAe;EAAK,KAAI;EAAgB;YACrC,KAAK,KAAK,KAAK,aACd,qBAAC,QAAM,UAAP,EAAA,UAAA,CACE,oBAAC,KAAD;GAAc;GAAe;GAAM,GAAI;aACpC;EACE,CAAA,GACJ,WAAW,KAAK,SAAS,KACxB,oBAAC,QAAD;GAAM,WAAU;aACb;EACG,CAAA,CAEM,EAAA,GATK,mBAAmB,KAAK,QAAQ,CASrC,CACjB;CACO,CAAA;CAId,OACE,oBAAC,UAAD;EAAe;EAAK,KAAI;EAAgB;YACrC,KAAK,KAAK,KAAK,aACd,oBAAC,KAAD;GAEW;GACH;GACN,GAAI;aAEH;EACE,GANE,mBAAmB,KAAK,QAAQ,CAMlC,CACN;CACO,CAAA;AAEd,CACF;AACA,SAAS,cAAc;;;;AASvB,IAAa,WAAW;CACtB,KAAK;CACL,SAAS;CACT,MAAM;CACN,SAAS;CACT,KAAK;CACL,QAAQ;CACR,OAAO;CACP,OAAO;CACP,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,KAAK;CACL,KAAK;CACL,QAAQ;CACR,IAAI;CACJ,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;AACT;;;;AAKA,IAAa,WAAW;CACtB,KAAK;CACL,SAAS;CACT,MAAM;CACN,SAAS;CACT,KAAK;CACL,QAAQ;CACR,OAAO;CACP,OAAO;CACP,QAAQ;CACR,WAAW;CACX,QAAQ;CACR,KAAK;CACL,KAAK;CACL,QAAQ;CACR,IAAI;CACJ,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;AACT"}
package/dist/index117.js CHANGED
@@ -43,7 +43,7 @@ CloseButton.displayName = "CloseButton";
43
43
  * RemoveButton - for inline remove buttons (tags, list items, chips)
44
44
  * Lightweight button with smaller footprint
45
45
  */
46
- var removeButtonVariants = cva("flex shrink-0 items-center justify-center rounded-[3px] p-0.5 text-muted-foreground hover:bg-surface-1 hover:text-muted-foreground dark:text-text-quaternary dark:hover:text-text-quaternary transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", {
46
+ var removeButtonVariants = cva("flex shrink-0 items-center justify-center rounded-[3px] p-0.5 text-muted-foreground hover:bg-surface-1 hover:text-secondary-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", {
47
47
  variants: { size: {
48
48
  sm: "[&>svg]:size-2.5",
49
49
  md: "[&>svg]:size-3",
@@ -1 +1 @@
1
- {"version":3,"file":"index117.js","names":[],"sources":["../src/components/ui/close-button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { X } from 'lucide-react';\nimport * as React from 'react';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\n/**\n * CloseButton - for modal/overlay close buttons (dialogs, sheets, drawers)\n * Uses Button component with ghost variant, positioned by consumer\n */\nconst closeButtonVariants = cva('', {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n },\n});\n\nconst buttonSizeMap = {\n sm: 'icon-sm',\n md: 'icon',\n lg: 'icon-lg',\n} as const;\n\nexport interface CloseButtonProps\n extends Omit<\n React.ComponentProps<typeof Button>,\n 'variant' | 'size' | 'children'\n >,\n VariantProps<typeof closeButtonVariants> {\n /** Accessible label for the close button */\n 'aria-label'?: string;\n}\n\nconst CloseButton = React.forwardRef<HTMLButtonElement, CloseButtonProps>(\n (\n { className, size = 'sm', 'aria-label': ariaLabel = 'Close', ...props },\n ref,\n ) => {\n return (\n <Button\n ref={ref}\n data-slot=\"close-button\"\n appearance=\"ghost\"\n variant=\"secondary\"\n size={buttonSizeMap[size ?? 'sm']}\n className={cn(closeButtonVariants({ size }), className)}\n aria-label={ariaLabel}\n {...props}\n >\n <X />\n <span className=\"sr-only\">{ariaLabel}</span>\n </Button>\n );\n },\n);\n\nCloseButton.displayName = 'CloseButton';\n\n/**\n * RemoveButton - for inline remove buttons (tags, list items, chips)\n * Lightweight button with smaller footprint\n */\nconst removeButtonVariants = cva(\n 'flex shrink-0 items-center justify-center rounded-[3px] p-0.5 text-muted-foreground hover:bg-surface-1 hover:text-muted-foreground dark:text-text-quaternary dark:hover:text-text-quaternary transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n {\n variants: {\n size: {\n sm: '[&>svg]:size-2.5',\n md: '[&>svg]:size-3',\n lg: '[&>svg]:size-3.5',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\nexport interface RemoveButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof removeButtonVariants> {\n /** Accessible label for the remove button */\n 'aria-label'?: string;\n}\n\nconst RemoveButton = React.forwardRef<HTMLButtonElement, RemoveButtonProps>(\n (\n { className, size = 'md', 'aria-label': ariaLabel = 'Remove', ...props },\n ref,\n ) => {\n return (\n <button\n ref={ref}\n type=\"button\"\n data-slot=\"remove-button\"\n className={cn(removeButtonVariants({ size }), className)}\n aria-label={ariaLabel}\n {...props}\n >\n <X />\n </button>\n );\n },\n);\n\nRemoveButton.displayName = 'RemoveButton';\n\nexport { CloseButton, closeButtonVariants, RemoveButton, removeButtonVariants };\n"],"mappings":";;;;;;;;;;;AAUA,IAAM,sBAAsB,IAAI,IAAI;CAClC,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CAAC;AAED,IAAM,gBAAgB;CACpB,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAYA,IAAM,cAAc,QAAM,YAEtB,EAAE,WAAW,OAAO,MAAM,cAAc,YAAY,SAAS,GAAG,SAChE,QACG;CACH,OACE,qBAAC,QAAD;EACO;EACL,aAAU;EACV,YAAW;EACX,SAAQ;EACR,MAAM,cAAc,QAAQ;EAC5B,WAAW,GAAG,oBAAoB,EAAE,KAAK,CAAC,GAAG,SAAS;EACtD,cAAY;EACZ,GAAI;YARN,CAUE,oBAAC,GAAD,CAAI,CAAA,GACJ,oBAAC,QAAD;GAAM,WAAU;aAAW;EAAgB,CAAA,CACrC;;AAEZ,CACF;AAEA,YAAY,cAAc;;;;;AAM1B,IAAM,uBAAuB,IAC3B,0RACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AASA,IAAM,eAAe,QAAM,YAEvB,EAAE,WAAW,OAAO,MAAM,cAAc,YAAY,UAAU,GAAG,SACjE,QACG;CACH,OACE,oBAAC,UAAD;EACO;EACL,MAAK;EACL,aAAU;EACV,WAAW,GAAG,qBAAqB,EAAE,KAAK,CAAC,GAAG,SAAS;EACvD,cAAY;EACZ,GAAI;YAEJ,oBAAC,GAAD,CAAI,CAAA;CACE,CAAA;AAEZ,CACF;AAEA,aAAa,cAAc"}
1
+ {"version":3,"file":"index117.js","names":[],"sources":["../src/components/ui/close-button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { X } from 'lucide-react';\nimport * as React from 'react';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\n/**\n * CloseButton - for modal/overlay close buttons (dialogs, sheets, drawers)\n * Uses Button component with ghost variant, positioned by consumer\n */\nconst closeButtonVariants = cva('', {\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n },\n});\n\nconst buttonSizeMap = {\n sm: 'icon-sm',\n md: 'icon',\n lg: 'icon-lg',\n} as const;\n\nexport interface CloseButtonProps\n extends Omit<\n React.ComponentProps<typeof Button>,\n 'variant' | 'size' | 'children'\n >,\n VariantProps<typeof closeButtonVariants> {\n /** Accessible label for the close button */\n 'aria-label'?: string;\n}\n\nconst CloseButton = React.forwardRef<HTMLButtonElement, CloseButtonProps>(\n (\n { className, size = 'sm', 'aria-label': ariaLabel = 'Close', ...props },\n ref,\n ) => {\n return (\n <Button\n ref={ref}\n data-slot=\"close-button\"\n appearance=\"ghost\"\n variant=\"secondary\"\n size={buttonSizeMap[size ?? 'sm']}\n className={cn(closeButtonVariants({ size }), className)}\n aria-label={ariaLabel}\n {...props}\n >\n <X />\n <span className=\"sr-only\">{ariaLabel}</span>\n </Button>\n );\n },\n);\n\nCloseButton.displayName = 'CloseButton';\n\n/**\n * RemoveButton - for inline remove buttons (tags, list items, chips)\n * Lightweight button with smaller footprint\n */\nconst removeButtonVariants = cva(\n 'flex shrink-0 items-center justify-center rounded-[3px] p-0.5 text-muted-foreground hover:bg-surface-1 hover:text-secondary-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n {\n variants: {\n size: {\n sm: '[&>svg]:size-2.5',\n md: '[&>svg]:size-3',\n lg: '[&>svg]:size-3.5',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\nexport interface RemoveButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof removeButtonVariants> {\n /** Accessible label for the remove button */\n 'aria-label'?: string;\n}\n\nconst RemoveButton = React.forwardRef<HTMLButtonElement, RemoveButtonProps>(\n (\n { className, size = 'md', 'aria-label': ariaLabel = 'Remove', ...props },\n ref,\n ) => {\n return (\n <button\n ref={ref}\n type=\"button\"\n data-slot=\"remove-button\"\n className={cn(removeButtonVariants({ size }), className)}\n aria-label={ariaLabel}\n {...props}\n >\n <X />\n </button>\n );\n },\n);\n\nRemoveButton.displayName = 'RemoveButton';\n\nexport { CloseButton, closeButtonVariants, RemoveButton, removeButtonVariants };\n"],"mappings":";;;;;;;;;;;AAUA,IAAM,sBAAsB,IAAI,IAAI;CAClC,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CAAC;AAED,IAAM,gBAAgB;CACpB,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAYA,IAAM,cAAc,QAAM,YAEtB,EAAE,WAAW,OAAO,MAAM,cAAc,YAAY,SAAS,GAAG,SAChE,QACG;CACH,OACE,qBAAC,QAAD;EACO;EACL,aAAU;EACV,YAAW;EACX,SAAQ;EACR,MAAM,cAAc,QAAQ;EAC5B,WAAW,GAAG,oBAAoB,EAAE,KAAK,CAAC,GAAG,SAAS;EACtD,cAAY;EACZ,GAAI;YARN,CAUE,oBAAC,GAAD,CAAI,CAAA,GACJ,oBAAC,QAAD;GAAM,WAAU;aAAW;EAAgB,CAAA,CACrC;;AAEZ,CACF;AAEA,YAAY,cAAc;;;;;AAM1B,IAAM,uBAAuB,IAC3B,oOACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AASA,IAAM,eAAe,QAAM,YAEvB,EAAE,WAAW,OAAO,MAAM,cAAc,YAAY,UAAU,GAAG,SACjE,QACG;CACH,OACE,oBAAC,UAAD;EACO;EACL,MAAK;EACL,aAAU;EACV,WAAW,GAAG,qBAAqB,EAAE,KAAK,CAAC,GAAG,SAAS;EACvD,cAAY;EACZ,GAAI;YAEJ,oBAAC,GAAD,CAAI,CAAA;CACE,CAAA;AAEZ,CACF;AAEA,aAAa,cAAc"}
package/dist/index122.js CHANGED
@@ -30,11 +30,11 @@ function DisplayValueLabel({ label, helpIcon, helpTooltip }) {
30
30
  return /* @__PURE__ */ jsxs("div", {
31
31
  className: "flex items-center gap-0.5",
32
32
  children: [/* @__PURE__ */ jsx("span", {
33
- className: "text-sm font-medium leading-5 text-secondary-foreground dark:text-text-quaternary",
33
+ className: "text-sm font-medium leading-5 text-secondary-foreground",
34
34
  children: label
35
35
  }), helpIcon && /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx("button", {
36
36
  type: "button",
37
- className: "text-muted-foreground hover:text-text-quaternary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full transition-colors duration-200 ease-smooth motion-reduce:transition-none",
37
+ className: "text-muted-foreground hover:text-secondary-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full transition-colors duration-200 ease-smooth motion-reduce:transition-none",
38
38
  "aria-label": helpTooltip || `Help for ${label}`,
39
39
  children: /* @__PURE__ */ jsx(HelpCircle, { className: "size-4" })
40
40
  }) }), /* @__PURE__ */ jsx(TooltipPopup, { children: helpTooltip || label })] })]
@@ -52,7 +52,7 @@ function DisplayValueContent({ type, icon, value, children, leadingText, trailin
52
52
  case "icon-leading": return /* @__PURE__ */ jsxs("div", {
53
53
  className: "flex items-center gap-2 flex-1 min-w-0",
54
54
  children: [icon && /* @__PURE__ */ jsx("span", {
55
- className: "shrink-0 text-text-quaternary [&>svg]:size-5",
55
+ className: "shrink-0 text-muted-foreground [&>svg]:size-5",
56
56
  children: icon
57
57
  }), /* @__PURE__ */ jsx("span", {
58
58
  className: "text-base font-normal leading-6 text-foreground dark:text-foreground truncate",
@@ -64,7 +64,7 @@ function DisplayValueContent({ type, icon, value, children, leadingText, trailin
64
64
  children: [leadingText && /* @__PURE__ */ jsx("div", {
65
65
  className: cn("flex items-center gap-1 overflow-hidden", displayPaddingY),
66
66
  children: /* @__PURE__ */ jsx("span", {
67
- className: "text-base font-normal leading-6 text-secondary-foreground dark:text-text-quaternary whitespace-nowrap",
67
+ className: "text-base font-normal leading-6 text-secondary-foreground whitespace-nowrap",
68
68
  children: leadingText
69
69
  })
70
70
  }), /* @__PURE__ */ jsx("div", {
@@ -86,7 +86,7 @@ function DisplayValueContent({ type, icon, value, children, leadingText, trailin
86
86
  }), trailingText && /* @__PURE__ */ jsx("div", {
87
87
  className: cn("flex items-center gap-1 overflow-hidden px-3", displayPaddingY),
88
88
  children: /* @__PURE__ */ jsx("span", {
89
- className: "text-base font-normal leading-6 text-secondary-foreground dark:text-text-quaternary whitespace-nowrap",
89
+ className: "text-base font-normal leading-6 text-secondary-foreground whitespace-nowrap",
90
90
  children: trailingText
91
91
  })
92
92
  })]
@@ -138,7 +138,7 @@ function DisplayValueContent({ type, icon, value, children, leadingText, trailin
138
138
  children: /* @__PURE__ */ jsx("span", {
139
139
  className: "text-base font-normal leading-6 text-foreground dark:text-foreground truncate",
140
140
  children: value ?? children ?? /* @__PURE__ */ jsx("span", {
141
- className: "text-muted-foreground dark:text-text-quaternary italic",
141
+ className: "text-secondary-foreground italic",
142
142
  children: "—"
143
143
  })
144
144
  })
@@ -1 +1 @@
1
- {"version":3,"file":"index122.js","names":[],"sources":["../src/components/molecules/forms/DisplayValue/DisplayValue.tsx"],"sourcesContent":["import { HelpCircle } from 'lucide-react';\nimport * as React from 'react';\nimport { Badge, type BadgeProps } from '@/components/atoms/display/Badge';\nimport { Avatar, type AvatarProps } from '@/components/molecules/data/Avatar';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\nexport type DisplayValueType =\n | 'default'\n | 'icon-leading'\n | 'trailing-text'\n | 'link'\n | 'tags'\n | 'leading-text'\n | 'avatar'\n | 'badge';\n\nexport interface DisplayValueTag\n extends Omit<BadgeProps, 'avatar' | 'children'> {\n label: string;\n avatar?: string;\n avatarAlt?: string;\n}\n\nexport interface DisplayValueProps\n extends React.HTMLAttributes<HTMLDivElement> {\n /** Label text displayed above the field */\n label?: string;\n /** The main value to display */\n value?: React.ReactNode;\n /** Hint text displayed below the field */\n hint?: string;\n /** Show help icon with tooltip */\n helpIcon?: boolean;\n /** Tooltip content for help icon */\n helpTooltip?: string;\n /** Leading icon for icon-leading type */\n icon?: React.ReactNode;\n /** Size variant */\n size?: 'sm' | 'md';\n /** Display type */\n type?: DisplayValueType;\n /** RTL layout support */\n rtl?: boolean;\n /** Leading text (for leading-text type) */\n leadingText?: string;\n /** Trailing text (for trailing-text type) */\n trailingText?: string;\n /** Link URL (for link type) */\n linkHref?: string;\n /** Avatar props (for avatar type) */\n avatarProps?: AvatarProps;\n /** Supporting text for avatar */\n avatarSupportingText?: string;\n /** Badge props (for badge type) */\n badgeProps?: Omit<BadgeProps, 'children'>;\n /** Badge label (for badge type) */\n badgeLabel?: string;\n /** Tags data (for tags type) */\n tags?: DisplayValueTag[];\n}\n\ntype DisplayTag = NonNullable<DisplayValueProps['tags']>[number];\n\nfunction getDisplayTagKey(tag: DisplayTag): React.Key {\n return tag.id ?? `${tag.label}:${tag.avatarAlt ?? 'no-avatar'}`;\n}\n\nfunction DisplayValueBadge({ label, avatar, avatarAlt, ...props }: DisplayTag) {\n return (\n <Badge\n variant=\"outline\"\n shape=\"rounded\"\n size=\"md\"\n avatar={\n avatar ? (\n <Avatar\n src={avatar}\n alt={avatarAlt ?? ''}\n fallback={label}\n size=\"sm\"\n shape=\"circle\"\n />\n ) : undefined\n }\n {...props}\n >\n {label}\n </Badge>\n );\n}\n\ninterface DisplayValueLabelProps {\n label?: string;\n helpIcon: boolean;\n helpTooltip?: string;\n}\n\nfunction DisplayValueLabel({\n label,\n helpIcon,\n helpTooltip,\n}: DisplayValueLabelProps) {\n if (!label) return null;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <span className=\"text-sm font-medium leading-5 text-secondary-foreground dark:text-text-quaternary\">\n {label}\n </span>\n {helpIcon && (\n <Tooltip>\n <TooltipTrigger\n render={\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-text-quaternary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full transition-colors duration-200 ease-smooth motion-reduce:transition-none\"\n aria-label={helpTooltip || `Help for ${label}`}\n >\n <HelpCircle className=\"size-4\" />\n </button>\n }\n />\n <TooltipPopup>{helpTooltip || label}</TooltipPopup>\n </Tooltip>\n )}\n </div>\n );\n}\n\nfunction DisplayValueHint({ hint }: { hint?: string }) {\n if (!hint) return null;\n\n return (\n <p className=\"text-sm font-normal leading-5 text-muted-foreground dark:text-muted-foreground w-full\">\n {hint}\n </p>\n );\n}\n\ninterface DisplayValueContentProps {\n type: DisplayValueType;\n icon?: React.ReactNode;\n value?: React.ReactNode;\n children?: React.ReactNode;\n leadingText?: string;\n trailingText?: string;\n displayPaddingY: string;\n linkHref?: string;\n tags?: DisplayValueProps['tags'];\n avatarProps?: AvatarProps;\n avatarSupportingText?: string;\n badgeProps?: Omit<BadgeProps, 'children'>;\n badgeLabel?: string;\n}\n\nfunction DisplayValueContent({\n type,\n icon,\n value,\n children,\n leadingText,\n trailingText,\n displayPaddingY,\n linkHref,\n tags,\n avatarProps,\n avatarSupportingText,\n badgeProps,\n badgeLabel,\n}: DisplayValueContentProps) {\n switch (type) {\n case 'icon-leading':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {icon && (\n <span className=\"shrink-0 text-text-quaternary [&>svg]:size-5\">\n {icon}\n </span>\n )}\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n );\n\n case 'leading-text':\n return (\n <div className=\"flex items-start w-full\">\n {leadingText && (\n <div\n className={cn(\n 'flex items-center gap-1 overflow-hidden',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-secondary-foreground dark:text-text-quaternary whitespace-nowrap\">\n {leadingText}\n </span>\n </div>\n )}\n <div\n className={cn(\n 'flex-1 flex items-center gap-2 min-w-0',\n displayPaddingY,\n 'ps-3',\n )}\n >\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n </div>\n );\n\n case 'trailing-text':\n return (\n <div className=\"flex items-start w-full\">\n <div\n className={cn(\n 'flex-1 flex items-center gap-2 min-w-0',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n {trailingText && (\n <div\n className={cn(\n 'flex items-center gap-1 overflow-hidden px-3',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-secondary-foreground dark:text-text-quaternary whitespace-nowrap\">\n {trailingText}\n </span>\n </div>\n )}\n </div>\n );\n\n case 'link':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {linkHref ? (\n <a\n href={linkHref}\n className=\"text-sm font-normal leading-5 text-primary hover:text-primary dark:text-primary dark:hover:text-primary truncate transition-colors duration-200 ease-smooth motion-reduce:transition-none hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {value ?? children ?? linkHref}\n </a>\n ) : (\n <span className=\"text-sm font-normal leading-5 text-primary dark:text-primary truncate\">\n {value ?? children}\n </span>\n )}\n </div>\n );\n\n case 'tags':\n return (\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n {tags?.map((tag) => (\n <DisplayValueBadge key={getDisplayTagKey(tag)} {...tag} />\n ))}\n {children}\n </div>\n );\n\n case 'avatar':\n return (\n <div className=\"flex items-center gap-2\">\n <Avatar size=\"lg\" {...avatarProps} />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-semibold leading-5 text-foreground dark:text-foreground\">\n {value ?? children ?? avatarProps?.fallback}\n </span>\n {avatarSupportingText && (\n <span className=\"text-sm font-normal leading-5 text-muted-foreground dark:text-muted-foreground\">\n {avatarSupportingText}\n </span>\n )}\n </div>\n </div>\n );\n\n case 'badge':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Badge variant=\"dot\" color=\"success\" {...badgeProps}>\n {badgeLabel ?? value ?? children}\n </Badge>\n </div>\n );\n\n default:\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children ?? (\n <span className=\"text-muted-foreground dark:text-text-quaternary italic\">\n —\n </span>\n )}\n </span>\n </div>\n );\n }\n}\n\nconst DisplayValue = React.forwardRef<HTMLDivElement, DisplayValueProps>(\n (\n {\n className,\n label,\n value,\n hint,\n helpIcon = false,\n helpTooltip,\n icon,\n size = 'sm',\n type = 'default',\n rtl = false,\n leadingText,\n trailingText,\n linkHref,\n avatarProps,\n avatarSupportingText,\n badgeProps,\n badgeLabel,\n tags,\n children,\n ...props\n },\n ref,\n ) => {\n const isRTL = rtl;\n\n // Size-based padding for display area\n const displayPaddingY = size === 'md' ? 'py-2.5' : 'py-2';\n\n // Determine container width based on type\n const containerWidth =\n type === 'tags' || type === 'avatar' || type === 'badge'\n ? 'w-[400px]'\n : 'w-[320px]';\n\n return (\n <div\n ref={ref}\n data-slot=\"display-value\"\n dir={isRTL ? 'rtl' : undefined}\n className={cn('flex flex-col gap-1.5', containerWidth, className)}\n {...props}\n >\n {/* Label section */}\n <DisplayValueLabel\n label={label}\n helpIcon={helpIcon}\n helpTooltip={helpTooltip}\n />\n\n {/* Display section */}\n <div\n data-slot=\"display-value-content\"\n className={cn(\n 'flex items-center gap-2 w-full rounded-md',\n // Only add vertical padding for non-special types\n type !== 'leading-text' &&\n type !== 'trailing-text' &&\n displayPaddingY,\n )}\n >\n <DisplayValueContent\n type={type}\n icon={icon}\n value={value}\n leadingText={leadingText}\n trailingText={trailingText}\n displayPaddingY={displayPaddingY}\n linkHref={linkHref}\n tags={tags}\n avatarProps={avatarProps}\n avatarSupportingText={avatarSupportingText}\n badgeProps={badgeProps}\n badgeLabel={badgeLabel}\n >\n {children}\n </DisplayValueContent>\n </div>\n\n {/* Hint section */}\n <DisplayValueHint hint={hint} />\n </div>\n );\n },\n);\n\nDisplayValue.displayName = 'DisplayValue';\n\nexport { DisplayValue };\n"],"mappings":"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"}
1
+ {"version":3,"file":"index122.js","names":[],"sources":["../src/components/molecules/forms/DisplayValue/DisplayValue.tsx"],"sourcesContent":["import { HelpCircle } from 'lucide-react';\nimport * as React from 'react';\nimport { Badge, type BadgeProps } from '@/components/atoms/display/Badge';\nimport { Avatar, type AvatarProps } from '@/components/molecules/data/Avatar';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\nexport type DisplayValueType =\n | 'default'\n | 'icon-leading'\n | 'trailing-text'\n | 'link'\n | 'tags'\n | 'leading-text'\n | 'avatar'\n | 'badge';\n\nexport interface DisplayValueTag\n extends Omit<BadgeProps, 'avatar' | 'children'> {\n label: string;\n avatar?: string;\n avatarAlt?: string;\n}\n\nexport interface DisplayValueProps\n extends React.HTMLAttributes<HTMLDivElement> {\n /** Label text displayed above the field */\n label?: string;\n /** The main value to display */\n value?: React.ReactNode;\n /** Hint text displayed below the field */\n hint?: string;\n /** Show help icon with tooltip */\n helpIcon?: boolean;\n /** Tooltip content for help icon */\n helpTooltip?: string;\n /** Leading icon for icon-leading type */\n icon?: React.ReactNode;\n /** Size variant */\n size?: 'sm' | 'md';\n /** Display type */\n type?: DisplayValueType;\n /** RTL layout support */\n rtl?: boolean;\n /** Leading text (for leading-text type) */\n leadingText?: string;\n /** Trailing text (for trailing-text type) */\n trailingText?: string;\n /** Link URL (for link type) */\n linkHref?: string;\n /** Avatar props (for avatar type) */\n avatarProps?: AvatarProps;\n /** Supporting text for avatar */\n avatarSupportingText?: string;\n /** Badge props (for badge type) */\n badgeProps?: Omit<BadgeProps, 'children'>;\n /** Badge label (for badge type) */\n badgeLabel?: string;\n /** Tags data (for tags type) */\n tags?: DisplayValueTag[];\n}\n\ntype DisplayTag = NonNullable<DisplayValueProps['tags']>[number];\n\nfunction getDisplayTagKey(tag: DisplayTag): React.Key {\n return tag.id ?? `${tag.label}:${tag.avatarAlt ?? 'no-avatar'}`;\n}\n\nfunction DisplayValueBadge({ label, avatar, avatarAlt, ...props }: DisplayTag) {\n return (\n <Badge\n variant=\"outline\"\n shape=\"rounded\"\n size=\"md\"\n avatar={\n avatar ? (\n <Avatar\n src={avatar}\n alt={avatarAlt ?? ''}\n fallback={label}\n size=\"sm\"\n shape=\"circle\"\n />\n ) : undefined\n }\n {...props}\n >\n {label}\n </Badge>\n );\n}\n\ninterface DisplayValueLabelProps {\n label?: string;\n helpIcon: boolean;\n helpTooltip?: string;\n}\n\nfunction DisplayValueLabel({\n label,\n helpIcon,\n helpTooltip,\n}: DisplayValueLabelProps) {\n if (!label) return null;\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <span className=\"text-sm font-medium leading-5 text-secondary-foreground\">\n {label}\n </span>\n {helpIcon && (\n <Tooltip>\n <TooltipTrigger\n render={\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-secondary-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full transition-colors duration-200 ease-smooth motion-reduce:transition-none\"\n aria-label={helpTooltip || `Help for ${label}`}\n >\n <HelpCircle className=\"size-4\" />\n </button>\n }\n />\n <TooltipPopup>{helpTooltip || label}</TooltipPopup>\n </Tooltip>\n )}\n </div>\n );\n}\n\nfunction DisplayValueHint({ hint }: { hint?: string }) {\n if (!hint) return null;\n\n return (\n <p className=\"text-sm font-normal leading-5 text-muted-foreground dark:text-muted-foreground w-full\">\n {hint}\n </p>\n );\n}\n\ninterface DisplayValueContentProps {\n type: DisplayValueType;\n icon?: React.ReactNode;\n value?: React.ReactNode;\n children?: React.ReactNode;\n leadingText?: string;\n trailingText?: string;\n displayPaddingY: string;\n linkHref?: string;\n tags?: DisplayValueProps['tags'];\n avatarProps?: AvatarProps;\n avatarSupportingText?: string;\n badgeProps?: Omit<BadgeProps, 'children'>;\n badgeLabel?: string;\n}\n\nfunction DisplayValueContent({\n type,\n icon,\n value,\n children,\n leadingText,\n trailingText,\n displayPaddingY,\n linkHref,\n tags,\n avatarProps,\n avatarSupportingText,\n badgeProps,\n badgeLabel,\n}: DisplayValueContentProps) {\n switch (type) {\n case 'icon-leading':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {icon && (\n <span className=\"shrink-0 text-muted-foreground [&>svg]:size-5\">\n {icon}\n </span>\n )}\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n );\n\n case 'leading-text':\n return (\n <div className=\"flex items-start w-full\">\n {leadingText && (\n <div\n className={cn(\n 'flex items-center gap-1 overflow-hidden',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-secondary-foreground whitespace-nowrap\">\n {leadingText}\n </span>\n </div>\n )}\n <div\n className={cn(\n 'flex-1 flex items-center gap-2 min-w-0',\n displayPaddingY,\n 'ps-3',\n )}\n >\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n </div>\n );\n\n case 'trailing-text':\n return (\n <div className=\"flex items-start w-full\">\n <div\n className={cn(\n 'flex-1 flex items-center gap-2 min-w-0',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children}\n </span>\n </div>\n {trailingText && (\n <div\n className={cn(\n 'flex items-center gap-1 overflow-hidden px-3',\n displayPaddingY,\n )}\n >\n <span className=\"text-base font-normal leading-6 text-secondary-foreground whitespace-nowrap\">\n {trailingText}\n </span>\n </div>\n )}\n </div>\n );\n\n case 'link':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {linkHref ? (\n <a\n href={linkHref}\n className=\"text-sm font-normal leading-5 text-primary hover:text-primary dark:text-primary dark:hover:text-primary truncate transition-colors duration-200 ease-smooth motion-reduce:transition-none hover:underline\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {value ?? children ?? linkHref}\n </a>\n ) : (\n <span className=\"text-sm font-normal leading-5 text-primary dark:text-primary truncate\">\n {value ?? children}\n </span>\n )}\n </div>\n );\n\n case 'tags':\n return (\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n {tags?.map((tag) => (\n <DisplayValueBadge key={getDisplayTagKey(tag)} {...tag} />\n ))}\n {children}\n </div>\n );\n\n case 'avatar':\n return (\n <div className=\"flex items-center gap-2\">\n <Avatar size=\"lg\" {...avatarProps} />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-semibold leading-5 text-foreground dark:text-foreground\">\n {value ?? children ?? avatarProps?.fallback}\n </span>\n {avatarSupportingText && (\n <span className=\"text-sm font-normal leading-5 text-muted-foreground dark:text-muted-foreground\">\n {avatarSupportingText}\n </span>\n )}\n </div>\n </div>\n );\n\n case 'badge':\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <Badge variant=\"dot\" color=\"success\" {...badgeProps}>\n {badgeLabel ?? value ?? children}\n </Badge>\n </div>\n );\n\n default:\n return (\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <span className=\"text-base font-normal leading-6 text-foreground dark:text-foreground truncate\">\n {value ?? children ?? (\n <span className=\"text-secondary-foreground italic\">—</span>\n )}\n </span>\n </div>\n );\n }\n}\n\nconst DisplayValue = React.forwardRef<HTMLDivElement, DisplayValueProps>(\n (\n {\n className,\n label,\n value,\n hint,\n helpIcon = false,\n helpTooltip,\n icon,\n size = 'sm',\n type = 'default',\n rtl = false,\n leadingText,\n trailingText,\n linkHref,\n avatarProps,\n avatarSupportingText,\n badgeProps,\n badgeLabel,\n tags,\n children,\n ...props\n },\n ref,\n ) => {\n const isRTL = rtl;\n\n // Size-based padding for display area\n const displayPaddingY = size === 'md' ? 'py-2.5' : 'py-2';\n\n // Determine container width based on type\n const containerWidth =\n type === 'tags' || type === 'avatar' || type === 'badge'\n ? 'w-[400px]'\n : 'w-[320px]';\n\n return (\n <div\n ref={ref}\n data-slot=\"display-value\"\n dir={isRTL ? 'rtl' : undefined}\n className={cn('flex flex-col gap-1.5', containerWidth, className)}\n {...props}\n >\n {/* Label section */}\n <DisplayValueLabel\n label={label}\n helpIcon={helpIcon}\n helpTooltip={helpTooltip}\n />\n\n {/* Display section */}\n <div\n data-slot=\"display-value-content\"\n className={cn(\n 'flex items-center gap-2 w-full rounded-md',\n // Only add vertical padding for non-special types\n type !== 'leading-text' &&\n type !== 'trailing-text' &&\n displayPaddingY,\n )}\n >\n <DisplayValueContent\n type={type}\n icon={icon}\n value={value}\n leadingText={leadingText}\n trailingText={trailingText}\n displayPaddingY={displayPaddingY}\n linkHref={linkHref}\n tags={tags}\n avatarProps={avatarProps}\n avatarSupportingText={avatarSupportingText}\n badgeProps={badgeProps}\n badgeLabel={badgeLabel}\n >\n {children}\n </DisplayValueContent>\n </div>\n\n {/* Hint section */}\n <DisplayValueHint hint={hint} />\n </div>\n );\n },\n);\n\nDisplayValue.displayName = 'DisplayValue';\n\nexport { DisplayValue };\n"],"mappings":"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"}
package/dist/index126.js CHANGED
@@ -193,7 +193,7 @@ var RichTextarea = React$1.forwardRef(({ label, hint, error, required, showHelpI
193
193
  showHelpIcon && /* @__PURE__ */ jsx("button", {
194
194
  type: "button",
195
195
  onClick: onHelpClick,
196
- className: "text-muted-foreground hover:text-text-quaternary transition-colors duration-200 ease-smooth motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full",
196
+ className: "text-muted-foreground hover:text-secondary-foreground transition-colors duration-200 ease-smooth motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full",
197
197
  "aria-label": "Help",
198
198
  children: /* @__PURE__ */ jsx(HelpCircle, { className: "size-4" })
199
199
  })
@@ -1 +1 @@
1
- {"version":3,"file":"index126.js","names":[],"sources":["../src/components/molecules/forms/RichTextarea/RichTextarea.tsx"],"sourcesContent":["import {\n Bold,\n ChevronDown,\n Expand,\n HelpCircle,\n Italic,\n Link,\n List,\n MoreHorizontal,\n Paperclip,\n Redo2,\n Sparkles,\n Table,\n Type,\n Underline,\n Undo2,\n} from 'lucide-react';\nimport * as React from 'react';\nimport { Label } from '@/components/ui/label';\nimport { Separator } from '@/components/ui/separator';\nimport { Textarea as TextareaBase } from '@/components/ui/textarea';\nimport { Toggle } from '@/components/ui/toggle';\nimport { cn } from '@/lib/utils';\n\nconst DEFAULT_MAX_LENGTH = 3000;\n\nfunction getMaxLength(maxLength: number): number {\n return Number.isFinite(maxLength) && maxLength >= 0\n ? Math.floor(maxLength)\n : DEFAULT_MAX_LENGTH;\n}\n\nfunction getCharCount(charCount: number | undefined, fallback: number): number {\n return typeof charCount === 'number' &&\n Number.isFinite(charCount) &&\n charCount >= 0\n ? Math.floor(charCount)\n : fallback;\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar Button\n// ---------------------------------------------------------------------------\n\ninterface ToolbarButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value'> {\n icon: React.ReactNode;\n pressed?: boolean;\n hasDropdown?: boolean;\n}\n\nconst ToolbarButton = React.forwardRef<HTMLButtonElement, ToolbarButtonProps>(\n ({ icon, pressed, hasDropdown, className, ...props }, ref) => {\n if (hasDropdown) {\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-haspopup=\"true\"\n className={cn(\n 'group/dropdown inline-flex h-8 items-center justify-center gap-1 rounded px-1.5 py-1 text-foreground transition-[color,background-color,transform] duration-200 ease-smooth motion-reduce:transition-none',\n 'hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n 'active:scale-95 motion-reduce:active:scale-100',\n 'disabled:pointer-events-none disabled:opacity-50',\n pressed && 'bg-muted',\n className,\n )}\n {...props}\n >\n <span className=\"[&>svg]:size-4\">{icon}</span>\n <ChevronDown className=\"size-4 text-muted-foreground transition-transform duration-200 ease-smooth motion-reduce:transition-none group-hover/dropdown:translate-y-0.5\" />\n </button>\n );\n }\n\n return (\n <Toggle\n ref={ref}\n pressed={pressed}\n size=\"sm\"\n className={className}\n disabled={props.disabled}\n onClick={props.onClick}\n aria-label={props['aria-label']}\n >\n <span className=\"[&>svg]:size-5\">{icon}</span>\n </Toggle>\n );\n },\n);\n\nToolbarButton.displayName = 'ToolbarButton';\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar Divider\n// ---------------------------------------------------------------------------\n\nfunction ToolbarDivider() {\n return (\n <Separator\n orientation=\"vertical\"\n className=\"mx-0.5 h-5 w-px bg-surface-2\"\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar\n// ---------------------------------------------------------------------------\n\nexport interface RichTextareaToolbarProps {\n className?: string;\n /** Called when AI assist button is clicked */\n onAiAssist?: () => void;\n /** Called when undo is clicked */\n onUndo?: () => void;\n /** Called when redo is clicked */\n onRedo?: () => void;\n /** Called when expand/fullscreen button is clicked */\n onExpand?: () => void;\n /** Show AI assist button */\n showAiAssist?: boolean;\n /** Show expand button */\n showExpand?: boolean;\n /** Disabled state */\n disabled?: boolean;\n /** RTL mode */\n rtl?: boolean;\n /** Formatting state */\n formatting?: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n };\n /** Formatting callbacks */\n onFormatChange?: (format: 'bold' | 'italic' | 'underline') => void;\n}\n\nfunction RichTextareaToolbar({\n className,\n onAiAssist,\n onUndo,\n onRedo,\n onExpand,\n showAiAssist = true,\n showExpand = true,\n disabled,\n rtl,\n formatting = {},\n onFormatChange,\n}: RichTextareaToolbarProps) {\n return (\n <div\n data-slot=\"rich-textarea-toolbar\"\n role=\"toolbar\"\n aria-label=\"Formatting toolbar\"\n className={cn(\n 'flex flex-wrap items-center gap-2 rounded-t-xl border border-input border-b-0 bg-muted/30 p-2 transition-[border-color] duration-200 ease-smooth motion-reduce:transition-none group-has-[:focus-visible]/editor:border-ring group-has-[[aria-invalid=true]]/editor:border-destructive',\n rtl && 'flex-row-reverse',\n className,\n )}\n dir={rtl ? 'rtl' : 'ltr'}\n >\n {/* AI Assist */}\n {showAiAssist && (\n <>\n <ToolbarButton\n icon={\n <Sparkles className=\"size-5 text-primary transition-transform duration-300 ease-smooth motion-reduce:transition-none group-hover/toggle:rotate-12\" />\n }\n onClick={onAiAssist}\n disabled={disabled}\n aria-label=\"AI Assist\"\n />\n <ToolbarDivider />\n </>\n )}\n\n {/* Undo/Redo */}\n <div className=\"flex items-center gap-2\">\n <ToolbarButton\n icon={<Undo2 />}\n onClick={onUndo}\n disabled={disabled}\n aria-label=\"Undo\"\n />\n <ToolbarButton\n icon={<Redo2 />}\n onClick={onRedo}\n disabled={disabled}\n aria-label=\"Redo\"\n />\n </div>\n\n <ToolbarDivider />\n\n {/* Text formatting dropdown */}\n <ToolbarButton\n icon={<Type />}\n hasDropdown\n disabled={disabled}\n aria-label=\"Text formatting\"\n />\n\n {/* Text color dropdown */}\n <ToolbarButton\n icon={\n <span className=\"relative\">\n <span className=\"text-sm font-bold\">A</span>\n <span className=\"absolute bottom-0 left-0 right-0 h-0.5 bg-foreground\" />\n </span>\n }\n hasDropdown\n disabled={disabled}\n aria-label=\"Text color\"\n />\n\n {/* Bold/Italic/Underline */}\n <ToolbarButton\n icon={<Bold />}\n pressed={formatting.bold}\n onClick={() => onFormatChange?.('bold')}\n disabled={disabled}\n aria-label=\"Bold\"\n />\n <ToolbarButton\n icon={<Italic />}\n pressed={formatting.italic}\n onClick={() => onFormatChange?.('italic')}\n disabled={disabled}\n aria-label=\"Italic\"\n />\n <ToolbarButton\n icon={<Underline />}\n pressed={formatting.underline}\n onClick={() => onFormatChange?.('underline')}\n disabled={disabled}\n aria-label=\"Underline\"\n />\n\n {/* List dropdown */}\n <ToolbarButton\n icon={<List />}\n hasDropdown\n disabled={disabled}\n aria-label=\"List options\"\n />\n\n <ToolbarDivider />\n\n {/* Link */}\n <ToolbarButton\n icon={<Link />}\n disabled={disabled}\n aria-label=\"Insert link\"\n />\n\n {/* Table dropdown */}\n <ToolbarButton\n icon={<Table />}\n hasDropdown\n disabled={disabled}\n aria-label=\"Table options\"\n />\n\n {/* Attachment */}\n <ToolbarButton\n icon={<Paperclip />}\n disabled={disabled}\n aria-label=\"Attach file\"\n />\n\n {/* More options */}\n <ToolbarButton\n icon={<MoreHorizontal />}\n disabled={disabled}\n aria-label=\"More options\"\n />\n\n {/* Expand */}\n {showExpand && (\n <ToolbarButton\n icon={\n <Expand className=\"transition-transform duration-200 ease-smooth motion-reduce:transition-none group-hover/toggle:scale-110\" />\n }\n onClick={onExpand}\n disabled={disabled}\n aria-label=\"Expand\"\n className=\"ms-auto\"\n />\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Component\n// ---------------------------------------------------------------------------\n\nexport interface RichTextareaProps\n extends Omit<React.ComponentProps<typeof TextareaBase>, 'children'> {\n /** Label text displayed above the editor */\n label?: string;\n /** Hint text displayed below the editor */\n hint?: string;\n /** Error message displayed below the editor */\n error?: string;\n /** Show required indicator */\n required?: boolean;\n /** Show help icon next to label */\n showHelpIcon?: boolean;\n /** Callback when help icon is clicked */\n onHelpClick?: () => void;\n /** Show character count */\n showCharCount?: boolean;\n /** Maximum character count */\n maxLength?: number;\n /** Current character count (controlled) */\n charCount?: number;\n /** Show resize handle */\n showResizeHandle?: boolean;\n /** Show AI assist button in toolbar */\n showAiAssist?: boolean;\n /** Show expand button in toolbar */\n showExpand?: boolean;\n /** Called when AI assist button is clicked */\n onAiAssist?: () => void;\n /** Called when undo is clicked */\n onUndo?: () => void;\n /** Called when redo is clicked */\n onRedo?: () => void;\n /** Called when expand button is clicked */\n onExpand?: () => void;\n /** RTL mode */\n rtl?: boolean;\n /** Formatting state */\n formatting?: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n };\n /** Formatting callbacks */\n onFormatChange?: (format: 'bold' | 'italic' | 'underline') => void;\n}\n\nconst RichTextarea = React.forwardRef<HTMLTextAreaElement, RichTextareaProps>(\n (\n {\n label,\n hint,\n error,\n required,\n showHelpIcon,\n onHelpClick,\n showCharCount,\n maxLength = DEFAULT_MAX_LENGTH,\n charCount,\n showResizeHandle = true,\n showAiAssist = true,\n showExpand = true,\n onAiAssist,\n onUndo,\n onRedo,\n onExpand,\n rtl,\n formatting,\n onFormatChange,\n className,\n disabled,\n id,\n value,\n defaultValue,\n onChange,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const textareaId = id || generatedId;\n const hintId = `${textareaId}-hint`;\n const errorId = `${textareaId}-error`;\n\n // Track character count internally if not controlled\n const [internalValue, setInternalValue] = React.useState(\n defaultValue?.toString() || '',\n );\n const currentValue = value !== undefined ? value.toString() : internalValue;\n const safeMaxLength = getMaxLength(maxLength);\n const currentCharCount = getCharCount(charCount, currentValue.length);\n const isNearLimit = currentCharCount >= safeMaxLength * 0.9;\n const isApproachingLimit = currentCharCount >= safeMaxLength * 0.75;\n let describedById: string | undefined;\n if (error) {\n describedById = errorId;\n } else if (hint) {\n describedById = hintId;\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (value === undefined) {\n setInternalValue(e.target.value);\n }\n onChange?.(e);\n };\n\n const isDestructive = !!error;\n\n return (\n <div\n data-slot=\"rich-textarea\"\n className={cn('flex flex-col gap-1.5 w-full', rtl && 'text-right')}\n dir={rtl ? 'rtl' : 'ltr'}\n >\n {/* Label */}\n {label && (\n <div\n className={cn(\n 'flex items-center gap-0.5',\n rtl && 'flex-row-reverse',\n )}\n >\n <Label\n htmlFor={textareaId}\n className=\"text-sm font-medium leading-5 text-secondary-foreground\"\n >\n {label}\n </Label>\n {required && (\n <span\n className=\"text-sm font-medium leading-5 text-destructive\"\n aria-hidden=\"true\"\n >\n *\n </span>\n )}\n {showHelpIcon && (\n <button\n type=\"button\"\n onClick={onHelpClick}\n className=\"text-muted-foreground hover:text-text-quaternary transition-colors duration-200 ease-smooth motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full\"\n aria-label=\"Help\"\n >\n <HelpCircle className=\"size-4\" />\n </button>\n )}\n </div>\n )}\n\n {/* Toolbar + Textarea (gapless for connected borders) */}\n <div data-slot=\"rich-textarea-control\" className=\"group/editor\">\n <RichTextareaToolbar\n onAiAssist={onAiAssist}\n onUndo={onUndo}\n onRedo={onRedo}\n onExpand={onExpand}\n showAiAssist={showAiAssist}\n showExpand={showExpand}\n disabled={disabled}\n rtl={rtl}\n formatting={formatting}\n onFormatChange={onFormatChange}\n />\n\n <TextareaBase\n ref={ref}\n data-slot=\"rich-textarea-editor\"\n id={textareaId}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n disabled={disabled}\n aria-invalid={isDestructive}\n aria-required={required || undefined}\n aria-describedby={describedById}\n maxLength={safeMaxLength}\n className={cn(\n 'min-h-30 rounded-t-none border-t-0',\n isDestructive &&\n 'border-destructive focus-visible:border-destructive focus-visible:ring-destructive/20',\n !showResizeHandle && 'resize-none',\n rtl && 'text-right',\n className,\n )}\n dir={rtl ? 'rtl' : 'ltr'}\n {...props}\n />\n </div>\n\n {/* Hint/Error and Character Count */}\n <div\n className={cn(\n 'flex items-start gap-4 text-sm leading-5',\n rtl ? 'flex-row-reverse' : 'justify-between',\n )}\n >\n {/* Hint or error */}\n <div className=\"flex-1\">\n {error ? (\n <p\n id={errorId}\n className=\"text-destructive animate-in fade-in-0 slide-in-from-top-1 duration-200 motion-reduce:animate-none\"\n >\n {error}\n </p>\n ) : hint ? (\n <p id={hintId} className=\"text-muted-foreground\">\n {hint}\n </p>\n ) : null}\n </div>\n\n {/* Character count — only announces via aria-live when near the limit (≥90%) */}\n {showCharCount && (\n <span\n role={isNearLimit ? 'status' : undefined}\n aria-live={isNearLimit ? 'polite' : 'off'}\n className={cn(\n 'whitespace-nowrap transition-colors duration-300 ease-out motion-reduce:transition-none',\n isNearLimit\n ? 'text-destructive font-medium'\n : isApproachingLimit\n ? 'text-secondary-foreground'\n : 'text-muted-foreground',\n rtl && 'text-start',\n )}\n >\n {currentCharCount}/{safeMaxLength}\n </span>\n )}\n </div>\n </div>\n );\n },\n);\n\nRichTextarea.displayName = 'RichTextarea';\n\nexport { RichTextarea, RichTextareaToolbar, ToolbarButton, ToolbarDivider };\n"],"mappings":"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"}
1
+ {"version":3,"file":"index126.js","names":[],"sources":["../src/components/molecules/forms/RichTextarea/RichTextarea.tsx"],"sourcesContent":["import {\n Bold,\n ChevronDown,\n Expand,\n HelpCircle,\n Italic,\n Link,\n List,\n MoreHorizontal,\n Paperclip,\n Redo2,\n Sparkles,\n Table,\n Type,\n Underline,\n Undo2,\n} from 'lucide-react';\nimport * as React from 'react';\nimport { Label } from '@/components/ui/label';\nimport { Separator } from '@/components/ui/separator';\nimport { Textarea as TextareaBase } from '@/components/ui/textarea';\nimport { Toggle } from '@/components/ui/toggle';\nimport { cn } from '@/lib/utils';\n\nconst DEFAULT_MAX_LENGTH = 3000;\n\nfunction getMaxLength(maxLength: number): number {\n return Number.isFinite(maxLength) && maxLength >= 0\n ? Math.floor(maxLength)\n : DEFAULT_MAX_LENGTH;\n}\n\nfunction getCharCount(charCount: number | undefined, fallback: number): number {\n return typeof charCount === 'number' &&\n Number.isFinite(charCount) &&\n charCount >= 0\n ? Math.floor(charCount)\n : fallback;\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar Button\n// ---------------------------------------------------------------------------\n\ninterface ToolbarButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value'> {\n icon: React.ReactNode;\n pressed?: boolean;\n hasDropdown?: boolean;\n}\n\nconst ToolbarButton = React.forwardRef<HTMLButtonElement, ToolbarButtonProps>(\n ({ icon, pressed, hasDropdown, className, ...props }, ref) => {\n if (hasDropdown) {\n return (\n <button\n ref={ref}\n type=\"button\"\n aria-haspopup=\"true\"\n className={cn(\n 'group/dropdown inline-flex h-8 items-center justify-center gap-1 rounded px-1.5 py-1 text-foreground transition-[color,background-color,transform] duration-200 ease-smooth motion-reduce:transition-none',\n 'hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n 'active:scale-95 motion-reduce:active:scale-100',\n 'disabled:pointer-events-none disabled:opacity-50',\n pressed && 'bg-muted',\n className,\n )}\n {...props}\n >\n <span className=\"[&>svg]:size-4\">{icon}</span>\n <ChevronDown className=\"size-4 text-muted-foreground transition-transform duration-200 ease-smooth motion-reduce:transition-none group-hover/dropdown:translate-y-0.5\" />\n </button>\n );\n }\n\n return (\n <Toggle\n ref={ref}\n pressed={pressed}\n size=\"sm\"\n className={className}\n disabled={props.disabled}\n onClick={props.onClick}\n aria-label={props['aria-label']}\n >\n <span className=\"[&>svg]:size-5\">{icon}</span>\n </Toggle>\n );\n },\n);\n\nToolbarButton.displayName = 'ToolbarButton';\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar Divider\n// ---------------------------------------------------------------------------\n\nfunction ToolbarDivider() {\n return (\n <Separator\n orientation=\"vertical\"\n className=\"mx-0.5 h-5 w-px bg-surface-2\"\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Toolbar\n// ---------------------------------------------------------------------------\n\nexport interface RichTextareaToolbarProps {\n className?: string;\n /** Called when AI assist button is clicked */\n onAiAssist?: () => void;\n /** Called when undo is clicked */\n onUndo?: () => void;\n /** Called when redo is clicked */\n onRedo?: () => void;\n /** Called when expand/fullscreen button is clicked */\n onExpand?: () => void;\n /** Show AI assist button */\n showAiAssist?: boolean;\n /** Show expand button */\n showExpand?: boolean;\n /** Disabled state */\n disabled?: boolean;\n /** RTL mode */\n rtl?: boolean;\n /** Formatting state */\n formatting?: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n };\n /** Formatting callbacks */\n onFormatChange?: (format: 'bold' | 'italic' | 'underline') => void;\n}\n\nfunction RichTextareaToolbar({\n className,\n onAiAssist,\n onUndo,\n onRedo,\n onExpand,\n showAiAssist = true,\n showExpand = true,\n disabled,\n rtl,\n formatting = {},\n onFormatChange,\n}: RichTextareaToolbarProps) {\n return (\n <div\n data-slot=\"rich-textarea-toolbar\"\n role=\"toolbar\"\n aria-label=\"Formatting toolbar\"\n className={cn(\n 'flex flex-wrap items-center gap-2 rounded-t-xl border border-input border-b-0 bg-muted/30 p-2 transition-[border-color] duration-200 ease-smooth motion-reduce:transition-none group-has-[:focus-visible]/editor:border-ring group-has-[[aria-invalid=true]]/editor:border-destructive',\n rtl && 'flex-row-reverse',\n className,\n )}\n dir={rtl ? 'rtl' : 'ltr'}\n >\n {/* AI Assist */}\n {showAiAssist && (\n <>\n <ToolbarButton\n icon={\n <Sparkles className=\"size-5 text-primary transition-transform duration-300 ease-smooth motion-reduce:transition-none group-hover/toggle:rotate-12\" />\n }\n onClick={onAiAssist}\n disabled={disabled}\n aria-label=\"AI Assist\"\n />\n <ToolbarDivider />\n </>\n )}\n\n {/* Undo/Redo */}\n <div className=\"flex items-center gap-2\">\n <ToolbarButton\n icon={<Undo2 />}\n onClick={onUndo}\n disabled={disabled}\n aria-label=\"Undo\"\n />\n <ToolbarButton\n icon={<Redo2 />}\n onClick={onRedo}\n disabled={disabled}\n aria-label=\"Redo\"\n />\n </div>\n\n <ToolbarDivider />\n\n {/* Text formatting dropdown */}\n <ToolbarButton\n icon={<Type />}\n hasDropdown\n disabled={disabled}\n aria-label=\"Text formatting\"\n />\n\n {/* Text color dropdown */}\n <ToolbarButton\n icon={\n <span className=\"relative\">\n <span className=\"text-sm font-bold\">A</span>\n <span className=\"absolute bottom-0 left-0 right-0 h-0.5 bg-foreground\" />\n </span>\n }\n hasDropdown\n disabled={disabled}\n aria-label=\"Text color\"\n />\n\n {/* Bold/Italic/Underline */}\n <ToolbarButton\n icon={<Bold />}\n pressed={formatting.bold}\n onClick={() => onFormatChange?.('bold')}\n disabled={disabled}\n aria-label=\"Bold\"\n />\n <ToolbarButton\n icon={<Italic />}\n pressed={formatting.italic}\n onClick={() => onFormatChange?.('italic')}\n disabled={disabled}\n aria-label=\"Italic\"\n />\n <ToolbarButton\n icon={<Underline />}\n pressed={formatting.underline}\n onClick={() => onFormatChange?.('underline')}\n disabled={disabled}\n aria-label=\"Underline\"\n />\n\n {/* List dropdown */}\n <ToolbarButton\n icon={<List />}\n hasDropdown\n disabled={disabled}\n aria-label=\"List options\"\n />\n\n <ToolbarDivider />\n\n {/* Link */}\n <ToolbarButton\n icon={<Link />}\n disabled={disabled}\n aria-label=\"Insert link\"\n />\n\n {/* Table dropdown */}\n <ToolbarButton\n icon={<Table />}\n hasDropdown\n disabled={disabled}\n aria-label=\"Table options\"\n />\n\n {/* Attachment */}\n <ToolbarButton\n icon={<Paperclip />}\n disabled={disabled}\n aria-label=\"Attach file\"\n />\n\n {/* More options */}\n <ToolbarButton\n icon={<MoreHorizontal />}\n disabled={disabled}\n aria-label=\"More options\"\n />\n\n {/* Expand */}\n {showExpand && (\n <ToolbarButton\n icon={\n <Expand className=\"transition-transform duration-200 ease-smooth motion-reduce:transition-none group-hover/toggle:scale-110\" />\n }\n onClick={onExpand}\n disabled={disabled}\n aria-label=\"Expand\"\n className=\"ms-auto\"\n />\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// RichTextarea Component\n// ---------------------------------------------------------------------------\n\nexport interface RichTextareaProps\n extends Omit<React.ComponentProps<typeof TextareaBase>, 'children'> {\n /** Label text displayed above the editor */\n label?: string;\n /** Hint text displayed below the editor */\n hint?: string;\n /** Error message displayed below the editor */\n error?: string;\n /** Show required indicator */\n required?: boolean;\n /** Show help icon next to label */\n showHelpIcon?: boolean;\n /** Callback when help icon is clicked */\n onHelpClick?: () => void;\n /** Show character count */\n showCharCount?: boolean;\n /** Maximum character count */\n maxLength?: number;\n /** Current character count (controlled) */\n charCount?: number;\n /** Show resize handle */\n showResizeHandle?: boolean;\n /** Show AI assist button in toolbar */\n showAiAssist?: boolean;\n /** Show expand button in toolbar */\n showExpand?: boolean;\n /** Called when AI assist button is clicked */\n onAiAssist?: () => void;\n /** Called when undo is clicked */\n onUndo?: () => void;\n /** Called when redo is clicked */\n onRedo?: () => void;\n /** Called when expand button is clicked */\n onExpand?: () => void;\n /** RTL mode */\n rtl?: boolean;\n /** Formatting state */\n formatting?: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n };\n /** Formatting callbacks */\n onFormatChange?: (format: 'bold' | 'italic' | 'underline') => void;\n}\n\nconst RichTextarea = React.forwardRef<HTMLTextAreaElement, RichTextareaProps>(\n (\n {\n label,\n hint,\n error,\n required,\n showHelpIcon,\n onHelpClick,\n showCharCount,\n maxLength = DEFAULT_MAX_LENGTH,\n charCount,\n showResizeHandle = true,\n showAiAssist = true,\n showExpand = true,\n onAiAssist,\n onUndo,\n onRedo,\n onExpand,\n rtl,\n formatting,\n onFormatChange,\n className,\n disabled,\n id,\n value,\n defaultValue,\n onChange,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const textareaId = id || generatedId;\n const hintId = `${textareaId}-hint`;\n const errorId = `${textareaId}-error`;\n\n // Track character count internally if not controlled\n const [internalValue, setInternalValue] = React.useState(\n defaultValue?.toString() || '',\n );\n const currentValue = value !== undefined ? value.toString() : internalValue;\n const safeMaxLength = getMaxLength(maxLength);\n const currentCharCount = getCharCount(charCount, currentValue.length);\n const isNearLimit = currentCharCount >= safeMaxLength * 0.9;\n const isApproachingLimit = currentCharCount >= safeMaxLength * 0.75;\n let describedById: string | undefined;\n if (error) {\n describedById = errorId;\n } else if (hint) {\n describedById = hintId;\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (value === undefined) {\n setInternalValue(e.target.value);\n }\n onChange?.(e);\n };\n\n const isDestructive = !!error;\n\n return (\n <div\n data-slot=\"rich-textarea\"\n className={cn('flex flex-col gap-1.5 w-full', rtl && 'text-right')}\n dir={rtl ? 'rtl' : 'ltr'}\n >\n {/* Label */}\n {label && (\n <div\n className={cn(\n 'flex items-center gap-0.5',\n rtl && 'flex-row-reverse',\n )}\n >\n <Label\n htmlFor={textareaId}\n className=\"text-sm font-medium leading-5 text-secondary-foreground\"\n >\n {label}\n </Label>\n {required && (\n <span\n className=\"text-sm font-medium leading-5 text-destructive\"\n aria-hidden=\"true\"\n >\n *\n </span>\n )}\n {showHelpIcon && (\n <button\n type=\"button\"\n onClick={onHelpClick}\n className=\"text-muted-foreground hover:text-secondary-foreground transition-colors duration-200 ease-smooth motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-full\"\n aria-label=\"Help\"\n >\n <HelpCircle className=\"size-4\" />\n </button>\n )}\n </div>\n )}\n\n {/* Toolbar + Textarea (gapless for connected borders) */}\n <div data-slot=\"rich-textarea-control\" className=\"group/editor\">\n <RichTextareaToolbar\n onAiAssist={onAiAssist}\n onUndo={onUndo}\n onRedo={onRedo}\n onExpand={onExpand}\n showAiAssist={showAiAssist}\n showExpand={showExpand}\n disabled={disabled}\n rtl={rtl}\n formatting={formatting}\n onFormatChange={onFormatChange}\n />\n\n <TextareaBase\n ref={ref}\n data-slot=\"rich-textarea-editor\"\n id={textareaId}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n disabled={disabled}\n aria-invalid={isDestructive}\n aria-required={required || undefined}\n aria-describedby={describedById}\n maxLength={safeMaxLength}\n className={cn(\n 'min-h-30 rounded-t-none border-t-0',\n isDestructive &&\n 'border-destructive focus-visible:border-destructive focus-visible:ring-destructive/20',\n !showResizeHandle && 'resize-none',\n rtl && 'text-right',\n className,\n )}\n dir={rtl ? 'rtl' : 'ltr'}\n {...props}\n />\n </div>\n\n {/* Hint/Error and Character Count */}\n <div\n className={cn(\n 'flex items-start gap-4 text-sm leading-5',\n rtl ? 'flex-row-reverse' : 'justify-between',\n )}\n >\n {/* Hint or error */}\n <div className=\"flex-1\">\n {error ? (\n <p\n id={errorId}\n className=\"text-destructive animate-in fade-in-0 slide-in-from-top-1 duration-200 motion-reduce:animate-none\"\n >\n {error}\n </p>\n ) : hint ? (\n <p id={hintId} className=\"text-muted-foreground\">\n {hint}\n </p>\n ) : null}\n </div>\n\n {/* Character count — only announces via aria-live when near the limit (≥90%) */}\n {showCharCount && (\n <span\n role={isNearLimit ? 'status' : undefined}\n aria-live={isNearLimit ? 'polite' : 'off'}\n className={cn(\n 'whitespace-nowrap transition-colors duration-300 ease-out motion-reduce:transition-none',\n isNearLimit\n ? 'text-destructive font-medium'\n : isApproachingLimit\n ? 'text-secondary-foreground'\n : 'text-muted-foreground',\n rtl && 'text-start',\n )}\n >\n {currentCharCount}/{safeMaxLength}\n </span>\n )}\n </div>\n </div>\n );\n },\n);\n\nRichTextarea.displayName = 'RichTextarea';\n\nexport { RichTextarea, RichTextareaToolbar, ToolbarButton, ToolbarDivider };\n"],"mappings":"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"}
package/dist/index130.js CHANGED
@@ -104,7 +104,7 @@ function BreadcrumbSeparator({ className, type, ...props }) {
104
104
  const { separator } = useBreadcrumbContext();
105
105
  const separatorType = type ?? separator;
106
106
  return /* @__PURE__ */ jsx(BreadcrumbSeparator$1, {
107
- className: cn("[&>svg]:size-3.5 text-text-quaternary transition-opacity duration-200 ease-out motion-reduce:transition-none", className),
107
+ className: cn("[&>svg]:size-3.5 text-muted-foreground transition-opacity duration-200 ease-out motion-reduce:transition-none", className),
108
108
  ...props,
109
109
  children: separatorType === "slash" ? /* @__PURE__ */ jsx(Slash, {}) : /* @__PURE__ */ jsx(ChevronRight, { className: "rtl:rotate-180" })
110
110
  });
@@ -124,7 +124,7 @@ function BreadcrumbEllipsis({ className, variant = "text", ...props }) {
124
124
  }
125
125
  function BreadcrumbHomeLink({ className, variant = "text", srLabel = "Home", ...props }) {
126
126
  return /* @__PURE__ */ jsxs(BreadcrumbLink$1, {
127
- className: cn(`group inline-flex items-center text-text-quaternary hover:text-secondary-foreground transition-colors duration-200 ease-out motion-reduce:transition-none ${FOCUS_RING}`, variant === "soft-badge" && "rounded-full px-1.5 py-0.5 bg-primary/10 text-primary", variant === "outline-badge" && "rounded-full px-1.5 py-0.5 border border-muted-foreground/50", className),
127
+ className: cn(`group inline-flex items-center text-muted-foreground hover:text-secondary-foreground transition-colors duration-200 ease-out motion-reduce:transition-none ${FOCUS_RING}`, variant === "soft-badge" && "rounded-full px-1.5 py-0.5 bg-primary/10 text-primary", variant === "outline-badge" && "rounded-full px-1.5 py-0.5 border border-muted-foreground/50", className),
128
128
  ...props,
129
129
  children: [/* @__PURE__ */ jsx(Home, { className: "size-3.5 transition-transform duration-200 ease-out group-hover:scale-110 motion-reduce:transition-none" }), /* @__PURE__ */ jsx("span", {
130
130
  className: "sr-only",
@@ -1 +1 @@
1
- {"version":3,"file":"index130.js","names":[],"sources":["../src/components/molecules/navigation/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["/** biome-ignore-all lint/a11y/useFocusableInteractive: BreadcrumbPage intentionally uses aria-disabled=\"true\" for current page, removing it from tab order */\n/** biome-ignore-all lint/a11y/useSemanticElements: BreadcrumbPage uses span with role=\"link\" for non-interactive current page indicator per WAI-ARIA breadcrumb pattern */\nimport { cva } from 'class-variance-authority';\nimport { ChevronRight, Home, Slash } from 'lucide-react';\nimport * as React from 'react';\nimport {\n Breadcrumb as BreadcrumbBase,\n BreadcrumbItem as BreadcrumbItemBase,\n BreadcrumbLink as BreadcrumbLinkBase,\n BreadcrumbList as BreadcrumbListBase,\n BreadcrumbPage as BreadcrumbPageBase,\n BreadcrumbSeparator as BreadcrumbSeparatorBase,\n} from '@/components/ui/breadcrumb';\nimport { cn } from '@/lib/utils';\n\nconst FOCUS_RING =\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring rounded-sm';\n\n/* -----------------------------------------------------------------------------\n * Breadcrumb Variants\n * -------------------------------------------------------------------------- */\n\nconst breadcrumbItemVariants = cva(\n 'inline-flex items-center transition-[color,opacity,background-color,border-color,text-decoration-color] duration-200 ease-out whitespace-nowrap relative before:absolute before:inset-x-0 before:top-1/2 before:-translate-y-1/2 before:min-h-11 before:content-[\"\"] sm:before:content-none motion-reduce:transition-none',\n {\n variants: {\n variant: {\n text: 'text-sm font-normal text-muted-foreground hover:text-foreground underline decoration-transparent underline-offset-4 hover:decoration-current/30',\n 'soft-badge':\n 'text-xs font-normal text-primary rounded-full px-2 py-0.5 bg-primary/10 hover:bg-primary/15',\n 'outline-badge':\n 'text-xs font-normal text-foreground rounded-full px-2 py-0.5 border border-muted-foreground/50 hover:border-muted-foreground',\n },\n isCurrent: {\n true: '',\n false: '',\n },\n },\n compoundVariants: [\n {\n variant: 'text',\n isCurrent: true,\n className: 'text-foreground no-underline',\n },\n {\n variant: 'text',\n isCurrent: false,\n className: 'text-muted-foreground',\n },\n {\n variant: 'soft-badge',\n isCurrent: true,\n className: 'bg-primary/10',\n },\n {\n variant: 'soft-badge',\n isCurrent: false,\n className: 'bg-primary/10 opacity-50',\n },\n {\n variant: 'outline-badge',\n isCurrent: true,\n className: 'border-primary text-foreground',\n },\n {\n variant: 'outline-badge',\n isCurrent: false,\n className: 'border-muted-foreground/50 opacity-50',\n },\n ],\n defaultVariants: {\n variant: 'text',\n isCurrent: false,\n },\n },\n);\n\n/* -----------------------------------------------------------------------------\n * Context for sharing separator type\n * -------------------------------------------------------------------------- */\n\ntype SeparatorType = 'chevron' | 'slash';\n\ntype BreadcrumbContextValue = {\n separator: SeparatorType;\n};\n\nconst BreadcrumbContext = React.createContext<BreadcrumbContextValue>({\n separator: 'chevron',\n});\n\nconst useBreadcrumbContext = () => React.useContext(BreadcrumbContext);\n\n/* -----------------------------------------------------------------------------\n * Breadcrumb Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbProps\n extends React.ComponentProps<typeof BreadcrumbBase> {\n separator?: SeparatorType;\n ring?: boolean;\n}\n\nfunction Breadcrumb({\n className,\n separator = 'chevron',\n ring = false,\n children,\n ...props\n}: BreadcrumbProps) {\n const contextValue = React.useMemo(() => ({ separator }), [separator]);\n\n return (\n <BreadcrumbContext.Provider value={contextValue}>\n <BreadcrumbBase\n className={cn(\n ring &&\n 'inline-flex border border-ring/50 rounded-full px-2.5 py-0.5',\n className,\n )}\n {...props}\n >\n {children}\n </BreadcrumbBase>\n </BreadcrumbContext.Provider>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbList Component\n * -------------------------------------------------------------------------- */\n\nexport type BreadcrumbListProps = React.ComponentProps<\n typeof BreadcrumbListBase\n>;\n\nfunction BreadcrumbList({ className, ...props }: BreadcrumbListProps) {\n return (\n <BreadcrumbListBase\n className={cn('flex-nowrap gap-1', className)}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbItem Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbItemProps\n extends Omit<React.ComponentProps<typeof BreadcrumbItemBase>, 'className'> {\n className?: string;\n}\n\nfunction BreadcrumbItem({ className, ...props }: BreadcrumbItemProps) {\n return <BreadcrumbItemBase className={cn('gap-1', className)} {...props} />;\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbLink Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbLinkProps\n extends React.ComponentProps<typeof BreadcrumbLinkBase> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n isCurrent?: boolean;\n}\n\nfunction BreadcrumbLink({\n className,\n variant = 'text',\n isCurrent = false,\n ...props\n}: BreadcrumbLinkProps) {\n return (\n <BreadcrumbLinkBase\n className={cn(breadcrumbItemVariants({ variant, isCurrent }), className)}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbPage Component (Current Page)\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbPageProps\n extends React.ComponentProps<typeof BreadcrumbPageBase> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n}\n\nfunction BreadcrumbPage({\n className,\n variant = 'text',\n ...props\n}: BreadcrumbPageProps) {\n return (\n <BreadcrumbPageBase\n className={cn(\n breadcrumbItemVariants({ variant, isCurrent: true }),\n className,\n )}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbSeparator Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbSeparatorProps\n extends Omit<\n React.ComponentProps<typeof BreadcrumbSeparatorBase>,\n 'children'\n > {\n type?: SeparatorType;\n}\n\nfunction BreadcrumbSeparator({\n className,\n type,\n ...props\n}: BreadcrumbSeparatorProps) {\n const { separator } = useBreadcrumbContext();\n const separatorType = type ?? separator;\n\n return (\n <BreadcrumbSeparatorBase\n className={cn(\n '[&>svg]:size-3.5 text-text-quaternary transition-opacity duration-200 ease-out motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {separatorType === 'slash' ? (\n <Slash />\n ) : (\n <ChevronRight className=\"rtl:rotate-180\" />\n )}\n </BreadcrumbSeparatorBase>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbEllipsis Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbEllipsisProps\n extends React.ComponentProps<'button'> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n}\n\nfunction BreadcrumbEllipsis({\n className,\n variant = 'text',\n ...props\n}: BreadcrumbEllipsisProps) {\n return (\n <button\n type=\"button\"\n data-slot=\"breadcrumb-ellipsis\"\n aria-label=\"Show more breadcrumb items\"\n className={cn(\n breadcrumbItemVariants({ variant, isCurrent: false }),\n `cursor-pointer hover:text-foreground ${FOCUS_RING}`,\n className,\n )}\n {...props}\n >\n &#8230;\n </button>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbHomeLink Component (Home Icon)\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbHomeLinkProps\n extends Omit<BreadcrumbLinkProps, 'children'> {\n srLabel?: string;\n}\n\nfunction BreadcrumbHomeLink({\n className,\n variant = 'text',\n srLabel = 'Home',\n ...props\n}: BreadcrumbHomeLinkProps) {\n return (\n <BreadcrumbLinkBase\n className={cn(\n `group inline-flex items-center text-text-quaternary hover:text-secondary-foreground transition-colors duration-200 ease-out motion-reduce:transition-none ${FOCUS_RING}`,\n variant === 'soft-badge' &&\n 'rounded-full px-1.5 py-0.5 bg-primary/10 text-primary',\n variant === 'outline-badge' &&\n 'rounded-full px-1.5 py-0.5 border border-muted-foreground/50',\n className,\n )}\n {...props}\n >\n <Home className=\"size-3.5 transition-transform duration-200 ease-out group-hover:scale-110 motion-reduce:transition-none\" />\n <span className=\"sr-only\">{srLabel}</span>\n </BreadcrumbLinkBase>\n );\n}\n\nBreadcrumb.displayName = 'Breadcrumb';\nBreadcrumbList.displayName = 'BreadcrumbList';\nBreadcrumbItem.displayName = 'BreadcrumbItem';\nBreadcrumbLink.displayName = 'BreadcrumbLink';\nBreadcrumbPage.displayName = 'BreadcrumbPage';\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator';\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';\nBreadcrumbHomeLink.displayName = 'BreadcrumbHomeLink';\n\n/**\n * Breadcrumb component with dot notation for compound parts.\n *\n * @example\n * ```tsx\n * <Breadcrumb>\n * <Breadcrumb.List>\n * <Breadcrumb.Item>\n * <Breadcrumb.Link href=\"/\">Home</Breadcrumb.Link>\n * </Breadcrumb.Item>\n * <Breadcrumb.Separator />\n * <Breadcrumb.Item>\n * <Breadcrumb.Page>Current</Breadcrumb.Page>\n * </Breadcrumb.Item>\n * </Breadcrumb.List>\n * </Breadcrumb>\n * ```\n */\nconst BreadcrumbCompound = Object.assign(Breadcrumb, {\n Root: Breadcrumb,\n List: BreadcrumbList,\n Item: BreadcrumbItem,\n Link: BreadcrumbLink,\n Page: BreadcrumbPage,\n Separator: BreadcrumbSeparator,\n Ellipsis: BreadcrumbEllipsis,\n HomeLink: BreadcrumbHomeLink,\n});\n\nexport {\n BreadcrumbCompound as Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbHomeLink,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n breadcrumbItemVariants,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index130.js","names":[],"sources":["../src/components/molecules/navigation/Breadcrumb/Breadcrumb.tsx"],"sourcesContent":["/** biome-ignore-all lint/a11y/useFocusableInteractive: BreadcrumbPage intentionally uses aria-disabled=\"true\" for current page, removing it from tab order */\n/** biome-ignore-all lint/a11y/useSemanticElements: BreadcrumbPage uses span with role=\"link\" for non-interactive current page indicator per WAI-ARIA breadcrumb pattern */\nimport { cva } from 'class-variance-authority';\nimport { ChevronRight, Home, Slash } from 'lucide-react';\nimport * as React from 'react';\nimport {\n Breadcrumb as BreadcrumbBase,\n BreadcrumbItem as BreadcrumbItemBase,\n BreadcrumbLink as BreadcrumbLinkBase,\n BreadcrumbList as BreadcrumbListBase,\n BreadcrumbPage as BreadcrumbPageBase,\n BreadcrumbSeparator as BreadcrumbSeparatorBase,\n} from '@/components/ui/breadcrumb';\nimport { cn } from '@/lib/utils';\n\nconst FOCUS_RING =\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring rounded-sm';\n\n/* -----------------------------------------------------------------------------\n * Breadcrumb Variants\n * -------------------------------------------------------------------------- */\n\nconst breadcrumbItemVariants = cva(\n 'inline-flex items-center transition-[color,opacity,background-color,border-color,text-decoration-color] duration-200 ease-out whitespace-nowrap relative before:absolute before:inset-x-0 before:top-1/2 before:-translate-y-1/2 before:min-h-11 before:content-[\"\"] sm:before:content-none motion-reduce:transition-none',\n {\n variants: {\n variant: {\n text: 'text-sm font-normal text-muted-foreground hover:text-foreground underline decoration-transparent underline-offset-4 hover:decoration-current/30',\n 'soft-badge':\n 'text-xs font-normal text-primary rounded-full px-2 py-0.5 bg-primary/10 hover:bg-primary/15',\n 'outline-badge':\n 'text-xs font-normal text-foreground rounded-full px-2 py-0.5 border border-muted-foreground/50 hover:border-muted-foreground',\n },\n isCurrent: {\n true: '',\n false: '',\n },\n },\n compoundVariants: [\n {\n variant: 'text',\n isCurrent: true,\n className: 'text-foreground no-underline',\n },\n {\n variant: 'text',\n isCurrent: false,\n className: 'text-muted-foreground',\n },\n {\n variant: 'soft-badge',\n isCurrent: true,\n className: 'bg-primary/10',\n },\n {\n variant: 'soft-badge',\n isCurrent: false,\n className: 'bg-primary/10 opacity-50',\n },\n {\n variant: 'outline-badge',\n isCurrent: true,\n className: 'border-primary text-foreground',\n },\n {\n variant: 'outline-badge',\n isCurrent: false,\n className: 'border-muted-foreground/50 opacity-50',\n },\n ],\n defaultVariants: {\n variant: 'text',\n isCurrent: false,\n },\n },\n);\n\n/* -----------------------------------------------------------------------------\n * Context for sharing separator type\n * -------------------------------------------------------------------------- */\n\ntype SeparatorType = 'chevron' | 'slash';\n\ntype BreadcrumbContextValue = {\n separator: SeparatorType;\n};\n\nconst BreadcrumbContext = React.createContext<BreadcrumbContextValue>({\n separator: 'chevron',\n});\n\nconst useBreadcrumbContext = () => React.useContext(BreadcrumbContext);\n\n/* -----------------------------------------------------------------------------\n * Breadcrumb Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbProps\n extends React.ComponentProps<typeof BreadcrumbBase> {\n separator?: SeparatorType;\n ring?: boolean;\n}\n\nfunction Breadcrumb({\n className,\n separator = 'chevron',\n ring = false,\n children,\n ...props\n}: BreadcrumbProps) {\n const contextValue = React.useMemo(() => ({ separator }), [separator]);\n\n return (\n <BreadcrumbContext.Provider value={contextValue}>\n <BreadcrumbBase\n className={cn(\n ring &&\n 'inline-flex border border-ring/50 rounded-full px-2.5 py-0.5',\n className,\n )}\n {...props}\n >\n {children}\n </BreadcrumbBase>\n </BreadcrumbContext.Provider>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbList Component\n * -------------------------------------------------------------------------- */\n\nexport type BreadcrumbListProps = React.ComponentProps<\n typeof BreadcrumbListBase\n>;\n\nfunction BreadcrumbList({ className, ...props }: BreadcrumbListProps) {\n return (\n <BreadcrumbListBase\n className={cn('flex-nowrap gap-1', className)}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbItem Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbItemProps\n extends Omit<React.ComponentProps<typeof BreadcrumbItemBase>, 'className'> {\n className?: string;\n}\n\nfunction BreadcrumbItem({ className, ...props }: BreadcrumbItemProps) {\n return <BreadcrumbItemBase className={cn('gap-1', className)} {...props} />;\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbLink Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbLinkProps\n extends React.ComponentProps<typeof BreadcrumbLinkBase> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n isCurrent?: boolean;\n}\n\nfunction BreadcrumbLink({\n className,\n variant = 'text',\n isCurrent = false,\n ...props\n}: BreadcrumbLinkProps) {\n return (\n <BreadcrumbLinkBase\n className={cn(breadcrumbItemVariants({ variant, isCurrent }), className)}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbPage Component (Current Page)\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbPageProps\n extends React.ComponentProps<typeof BreadcrumbPageBase> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n}\n\nfunction BreadcrumbPage({\n className,\n variant = 'text',\n ...props\n}: BreadcrumbPageProps) {\n return (\n <BreadcrumbPageBase\n className={cn(\n breadcrumbItemVariants({ variant, isCurrent: true }),\n className,\n )}\n {...props}\n />\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbSeparator Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbSeparatorProps\n extends Omit<\n React.ComponentProps<typeof BreadcrumbSeparatorBase>,\n 'children'\n > {\n type?: SeparatorType;\n}\n\nfunction BreadcrumbSeparator({\n className,\n type,\n ...props\n}: BreadcrumbSeparatorProps) {\n const { separator } = useBreadcrumbContext();\n const separatorType = type ?? separator;\n\n return (\n <BreadcrumbSeparatorBase\n className={cn(\n '[&>svg]:size-3.5 text-muted-foreground transition-opacity duration-200 ease-out motion-reduce:transition-none',\n className,\n )}\n {...props}\n >\n {separatorType === 'slash' ? (\n <Slash />\n ) : (\n <ChevronRight className=\"rtl:rotate-180\" />\n )}\n </BreadcrumbSeparatorBase>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbEllipsis Component\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbEllipsisProps\n extends React.ComponentProps<'button'> {\n variant?: 'text' | 'soft-badge' | 'outline-badge';\n}\n\nfunction BreadcrumbEllipsis({\n className,\n variant = 'text',\n ...props\n}: BreadcrumbEllipsisProps) {\n return (\n <button\n type=\"button\"\n data-slot=\"breadcrumb-ellipsis\"\n aria-label=\"Show more breadcrumb items\"\n className={cn(\n breadcrumbItemVariants({ variant, isCurrent: false }),\n `cursor-pointer hover:text-foreground ${FOCUS_RING}`,\n className,\n )}\n {...props}\n >\n &#8230;\n </button>\n );\n}\n\n/* -----------------------------------------------------------------------------\n * BreadcrumbHomeLink Component (Home Icon)\n * -------------------------------------------------------------------------- */\n\nexport interface BreadcrumbHomeLinkProps\n extends Omit<BreadcrumbLinkProps, 'children'> {\n srLabel?: string;\n}\n\nfunction BreadcrumbHomeLink({\n className,\n variant = 'text',\n srLabel = 'Home',\n ...props\n}: BreadcrumbHomeLinkProps) {\n return (\n <BreadcrumbLinkBase\n className={cn(\n `group inline-flex items-center text-muted-foreground hover:text-secondary-foreground transition-colors duration-200 ease-out motion-reduce:transition-none ${FOCUS_RING}`,\n variant === 'soft-badge' &&\n 'rounded-full px-1.5 py-0.5 bg-primary/10 text-primary',\n variant === 'outline-badge' &&\n 'rounded-full px-1.5 py-0.5 border border-muted-foreground/50',\n className,\n )}\n {...props}\n >\n <Home className=\"size-3.5 transition-transform duration-200 ease-out group-hover:scale-110 motion-reduce:transition-none\" />\n <span className=\"sr-only\">{srLabel}</span>\n </BreadcrumbLinkBase>\n );\n}\n\nBreadcrumb.displayName = 'Breadcrumb';\nBreadcrumbList.displayName = 'BreadcrumbList';\nBreadcrumbItem.displayName = 'BreadcrumbItem';\nBreadcrumbLink.displayName = 'BreadcrumbLink';\nBreadcrumbPage.displayName = 'BreadcrumbPage';\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator';\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';\nBreadcrumbHomeLink.displayName = 'BreadcrumbHomeLink';\n\n/**\n * Breadcrumb component with dot notation for compound parts.\n *\n * @example\n * ```tsx\n * <Breadcrumb>\n * <Breadcrumb.List>\n * <Breadcrumb.Item>\n * <Breadcrumb.Link href=\"/\">Home</Breadcrumb.Link>\n * </Breadcrumb.Item>\n * <Breadcrumb.Separator />\n * <Breadcrumb.Item>\n * <Breadcrumb.Page>Current</Breadcrumb.Page>\n * </Breadcrumb.Item>\n * </Breadcrumb.List>\n * </Breadcrumb>\n * ```\n */\nconst BreadcrumbCompound = Object.assign(Breadcrumb, {\n Root: Breadcrumb,\n List: BreadcrumbList,\n Item: BreadcrumbItem,\n Link: BreadcrumbLink,\n Page: BreadcrumbPage,\n Separator: BreadcrumbSeparator,\n Ellipsis: BreadcrumbEllipsis,\n HomeLink: BreadcrumbHomeLink,\n});\n\nexport {\n BreadcrumbCompound as Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbHomeLink,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n breadcrumbItemVariants,\n};\n"],"mappings":"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"}
package/dist/index146.js CHANGED
@@ -34,7 +34,7 @@ function AICodeBlockHeader({ language, fileName, showCopyButton = true, onCopy,
34
34
  className: "text-sm font-medium text-secondary-foreground",
35
35
  children: fileName
36
36
  }), language && !fileName && /* @__PURE__ */ jsx("span", {
37
- className: "text-xs font-medium text-text-quaternary uppercase",
37
+ className: "text-xs font-medium text-secondary-foreground uppercase",
38
38
  children: language
39
39
  })]
40
40
  }), /* @__PURE__ */ jsxs("div", {
@@ -45,7 +45,7 @@ function AICodeBlockHeader({ language, fileName, showCopyButton = true, onCopy,
45
45
  size: "sm",
46
46
  onClick: onCopy,
47
47
  "aria-label": copied ? "Copied to clipboard" : "Copy code to clipboard",
48
- className: "h-7 px-2 text-text-quaternary hover:text-secondary-foreground transition-colors duration-150 ease-out",
48
+ className: "h-7 px-2 text-secondary-foreground hover:text-foreground transition-colors duration-150 ease-out",
49
49
  children: [copied ? /* @__PURE__ */ jsx(Check, { className: "size-4 text-success delight-bounce-in motion-reduce:animate-none" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" }), /* @__PURE__ */ jsx("span", {
50
50
  className: "ms-1.5 text-xs",
51
51
  children: copied ? "Copied!" : "Copy"
@@ -61,7 +61,7 @@ function AICodeBlockContentBody({ children, showLineNumbers, startLineNumber })
61
61
  children: [/* @__PURE__ */ jsx("div", {
62
62
  className: "flex flex-col items-end pe-4 select-none border-e border-border me-4",
63
63
  children: children.split("\n").map((_, index) => /* @__PURE__ */ jsx("span", {
64
- className: "text-muted-foreground leading-relaxed",
64
+ className: "text-secondary-foreground leading-relaxed",
65
65
  children: startLineNumber + index
66
66
  }, index))
67
67
  }), /* @__PURE__ */ jsx("section", {
@@ -136,7 +136,7 @@ function AICodeBlock({ code, language = "plaintext", fileName, showHeader = true
136
136
  copied,
137
137
  actions: headerActions
138
138
  }), /* @__PURE__ */ jsx("section", {
139
- className: cn("p-4 overflow-x-auto font-mono leading-relaxed [overflow-wrap:normal] !bg-transparent !m-0 !border-0 !rounded-none", "[&_.sh__line]:block [&_.sh__line]:leading-relaxed", showLineNumbers && ["[&_.sh__line]:[counter-increment:sh-line]", "[&_.sh__line]:before:[content:counter(sh-line)] [&_.sh__line]:before:inline-block [&_.sh__line]:before:w-8 [&_.sh__line]:before:me-4 [&_.sh__line]:before:text-end [&_.sh__line]:before:text-muted-foreground [&_.sh__line]:before:select-none"]),
139
+ className: cn("p-4 overflow-x-auto font-mono leading-relaxed [overflow-wrap:normal] !bg-transparent !m-0 !border-0 !rounded-none", "[&_.sh__line]:block [&_.sh__line]:leading-relaxed", showLineNumbers && ["[&_.sh__line]:[counter-increment:sh-line]", "[&_.sh__line]:before:[content:counter(sh-line)] [&_.sh__line]:before:inline-block [&_.sh__line]:before:w-8 [&_.sh__line]:before:me-4 [&_.sh__line]:before:text-end [&_.sh__line]:before:text-secondary-foreground [&_.sh__line]:before:select-none"]),
140
140
  style: showLineNumbers ? { counterReset: `sh-line ${startLineNumber - 1}` } : void 0,
141
141
  "aria-label": "Code content",
142
142
  tabIndex: 0,