@hyddenlabs/hydn-ui 0.3.4 → 0.3.6

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 (27) hide show
  1. package/dist/components/data-display/data-grid/data-grid.d.ts.map +1 -1
  2. package/dist/components/data-display/data-grid/data-grid.js +2 -14
  3. package/dist/components/data-display/data-grid/data-grid.js.map +1 -1
  4. package/dist/components/data-display/status-indicator/index.d.ts +3 -0
  5. package/dist/components/data-display/status-indicator/index.d.ts.map +1 -0
  6. package/dist/components/data-display/status-indicator/status-indicator.d.ts +23 -0
  7. package/dist/components/data-display/status-indicator/status-indicator.d.ts.map +1 -0
  8. package/dist/components/data-display/status-indicator/status-indicator.js +31 -0
  9. package/dist/components/data-display/status-indicator/status-indicator.js.map +1 -0
  10. package/dist/components/index.d.ts +2 -0
  11. package/dist/components/index.d.ts.map +1 -1
  12. package/dist/components/navigation/dropdown/dropdown.js +1 -1
  13. package/dist/components/navigation/dropdown/dropdown.js.map +1 -1
  14. package/dist/components/navigation/navbar/navbar.js +1 -1
  15. package/dist/components/navigation/navbar/navbar.js.map +1 -1
  16. package/dist/components/typography/code/code.d.ts +5 -1
  17. package/dist/components/typography/code/code.d.ts.map +1 -1
  18. package/dist/components/typography/code/code.js +67 -4
  19. package/dist/components/typography/code/code.js.map +1 -1
  20. package/dist/components/typography/text/text.d.ts +6 -1
  21. package/dist/components/typography/text/text.d.ts.map +1 -1
  22. package/dist/components/typography/text/text.js +48 -3
  23. package/dist/components/typography/text/text.js.map +1 -1
  24. package/dist/index.js +26 -24
  25. package/dist/index.js.map +1 -1
  26. package/dist/style.css +1 -1
  27. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"navbar.js","sources":["../../../../src/components/navigation/navbar/navbar.tsx"],"sourcesContent":["import { ReactNode } from 'react';\n\nexport type NavbarProps = {\n /** Brand logo or text to display on the left side */\n brand?: ReactNode;\n /** Navigation links or items to display in the center */\n children: ReactNode;\n /** Enable sticky positioning at the top of viewport */\n sticky?: boolean;\n /** Additional CSS classes for the navbar container */\n className?: string;\n /** Action buttons or elements to display on the right side */\n actions?: ReactNode;\n /** Visual style variant for the navbar background */\n appearance?: 'solid' | 'blur' | 'transparent';\n /** Border configuration for top and/or bottom edges */\n border?: 'none' | 'bottom' | 'top' | 'both';\n};\n\n/**\n * Navbar Component - Responsive navigation\n * - Sticky positioning option\n * - Brand logo section\n * - Action buttons area\n * - Fully responsive\n * - Configurable container size\n * - Appearance modes: solid, blur (frosted glass), transparent\n * - Configurable borders: none, bottom, top, or both\n */\nfunction Navbar({\n brand,\n children,\n sticky = true,\n className = '',\n actions,\n appearance = 'solid',\n border = 'none'\n}: Readonly<NavbarProps>) {\n // Appearance styles\n const appearanceClasses = {\n solid: 'bg-background shadow-sm',\n blur: 'bg-background/70 backdrop-blur-md supports-[backdrop-filter]:bg-background/60 border border-border/60',\n transparent: 'bg-transparent'\n } as const;\n\n const borderClasses = {\n none: '',\n bottom: 'border-b border-border',\n top: 'border-t border-border',\n both: 'border-y border-border'\n };\n\n return (\n <nav\n data-appearance={appearance}\n className={`${sticky ? 'sticky top-0 z-50' : ''} ${appearanceClasses[appearance]} ${borderClasses[border]} ${className}`}\n >\n <div className=\"w-auto max-w-full mx-3\">\n <div className=\"flex items-center justify-between h-14 md:h-16 px-3 md:px-0\">\n {/* Brand */}\n {brand && <div className=\"shrink-0\">{brand}</div>}\n\n {/* Navigation */}\n <div className=\"hidden md:flex md:items-center md:space-x-6 md:flex-1 md:ml-10\">{children}</div>\n\n {/* Actions */}\n {actions && <div className=\"flex items-center gap-1\">{actions}</div>}\n </div>\n </div>\n </nav>\n );\n}\n\nNavbar.displayName = 'Navbar';\n\nexport default Navbar;\n"],"names":[],"mappings":";AA6BA,SAAS,OAAO;AAAA,EACd;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,YAAY;AAAA,EACZ;AAAA,EACA,aAAa;AAAA,EACb,SAAS;AACX,GAA0B;AAExB,QAAM,oBAAoB;AAAA,IACxB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,EAAA;AAGf,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EAAA;AAGR,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,mBAAiB;AAAA,MACjB,WAAW,GAAG,SAAS,sBAAsB,EAAE,IAAI,kBAAkB,UAAU,CAAC,IAAI,cAAc,MAAM,CAAC,IAAI,SAAS;AAAA,MAEtH,8BAAC,OAAA,EAAI,WAAU,0BACb,UAAA,qBAAC,OAAA,EAAI,WAAU,+DAEZ,UAAA;AAAA,QAAA,SAAS,oBAAC,OAAA,EAAI,WAAU,YAAY,UAAA,OAAM;AAAA,QAG3C,oBAAC,OAAA,EAAI,WAAU,kEAAkE,SAAA,CAAS;AAAA,QAGzF,WAAW,oBAAC,OAAA,EAAI,WAAU,2BAA2B,UAAA,QAAA,CAAQ;AAAA,MAAA,EAAA,CAChE,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,OAAO,cAAc;"}
1
+ {"version":3,"file":"navbar.js","sources":["../../../../src/components/navigation/navbar/navbar.tsx"],"sourcesContent":["import { ReactNode } from 'react';\n\nexport type NavbarProps = {\n /** Brand logo or text to display on the left side */\n brand?: ReactNode;\n /** Navigation links or items to display in the center */\n children: ReactNode;\n /** Enable sticky positioning at the top of viewport */\n sticky?: boolean;\n /** Additional CSS classes for the navbar container */\n className?: string;\n /** Action buttons or elements to display on the right side */\n actions?: ReactNode;\n /** Visual style variant for the navbar background */\n appearance?: 'solid' | 'blur' | 'transparent';\n /** Border configuration for top and/or bottom edges */\n border?: 'none' | 'bottom' | 'top' | 'both';\n};\n\n/**\n * Navbar Component - Responsive navigation\n * - Sticky positioning option\n * - Brand logo section\n * - Action buttons area\n * - Fully responsive\n * - Configurable container size\n * - Appearance modes: solid, blur (frosted glass), transparent\n * - Configurable borders: none, bottom, top, or both\n */\nfunction Navbar({\n brand,\n children,\n sticky = true,\n className = '',\n actions,\n appearance = 'solid',\n border = 'none'\n}: Readonly<NavbarProps>) {\n // Appearance styles\n const appearanceClasses = {\n solid: 'bg-background shadow-sm',\n blur: 'bg-background/70 backdrop-blur-md supports-[backdrop-filter]:bg-background/60 border border-border/60',\n transparent: 'bg-transparent'\n } as const;\n\n const borderClasses = {\n none: '',\n bottom: 'border-b border-border',\n top: 'border-t border-border',\n both: 'border-y border-border'\n };\n\n return (\n <nav\n data-appearance={appearance}\n className={`${sticky ? 'sticky top-0 z-50' : ''} ${appearanceClasses[appearance]} ${borderClasses[border]} ${className}`}\n >\n <div className=\"w-auto max-w-full mx-4\">\n <div className=\"flex items-center justify-between h-14 md:h-16 px-3 md:px-0\">\n {/* Brand */}\n {brand && <div className=\"shrink-0\">{brand}</div>}\n\n {/* Navigation */}\n <div className=\"hidden md:flex md:items-center md:space-x-6 md:flex-1 md:ml-10\">{children}</div>\n\n {/* Actions */}\n {actions && <div className=\"flex items-center gap-1\">{actions}</div>}\n </div>\n </div>\n </nav>\n );\n}\n\nNavbar.displayName = 'Navbar';\n\nexport default Navbar;\n"],"names":[],"mappings":";AA6BA,SAAS,OAAO;AAAA,EACd;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,YAAY;AAAA,EACZ;AAAA,EACA,aAAa;AAAA,EACb,SAAS;AACX,GAA0B;AAExB,QAAM,oBAAoB;AAAA,IACxB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,EAAA;AAGf,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,MAAM;AAAA,EAAA;AAGR,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,mBAAiB;AAAA,MACjB,WAAW,GAAG,SAAS,sBAAsB,EAAE,IAAI,kBAAkB,UAAU,CAAC,IAAI,cAAc,MAAM,CAAC,IAAI,SAAS;AAAA,MAEtH,8BAAC,OAAA,EAAI,WAAU,0BACb,UAAA,qBAAC,OAAA,EAAI,WAAU,+DAEZ,UAAA;AAAA,QAAA,SAAS,oBAAC,OAAA,EAAI,WAAU,YAAY,UAAA,OAAM;AAAA,QAG3C,oBAAC,OAAA,EAAI,WAAU,kEAAkE,SAAA,CAAS;AAAA,QAGzF,WAAW,oBAAC,OAAA,EAAI,WAAU,2BAA2B,UAAA,QAAA,CAAQ;AAAA,MAAA,EAAA,CAChE,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,OAAO,cAAc;"}
@@ -10,13 +10,17 @@ export type CodeProps = {
10
10
  * @default 'default'
11
11
  */
12
12
  variant?: 'default' | 'primary' | 'muted';
13
+ /** Show copy-to-clipboard button
14
+ * @default false
15
+ */
16
+ copy?: boolean;
13
17
  /** Additional CSS classes for custom styling */
14
18
  className?: string;
15
19
  };
16
20
  /**
17
21
  * Code - Styled code snippets (inline or block)
18
22
  */
19
- declare function Code({ children, block, variant, className }: Readonly<CodeProps>): import("react/jsx-runtime").JSX.Element;
23
+ declare function Code({ children, block, variant, copy, className }: Readonly<CodeProps>): import("react/jsx-runtime").JSX.Element;
20
24
  declare namespace Code {
21
25
  var displayName: string;
22
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../../../src/components/typography/code/code.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,MAAM,MAAM,SAAS,GAAG;IACtB,mCAAmC;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1C,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAa,EAAE,OAAmB,EAAE,SAAc,EAAE,EAAE,QAAQ,CAAC,SAAS,CAAC,2CAkBlG;kBAlBQ,IAAI;;;AAsBb,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../../../src/components/typography/code/code.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAoB,MAAM,OAAO,CAAC;AAGpD,MAAM,MAAM,SAAS,GAAG;IACtB,mCAAmC;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1C;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAa,EAAE,OAAmB,EAAE,IAAY,EAAE,SAAc,EAAE,EAAE,QAAQ,CAAC,SAAS,CAAC,2CAqFhH;kBArFQ,IAAI;;;AAyFb,eAAe,IAAI,CAAC"}
@@ -1,5 +1,20 @@
1
- import { jsx } from "react/jsx-runtime";
2
- function Code({ children, block = false, variant = "default", className = "" }) {
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useRef, useState } from "react";
3
+ import { Icon } from "../../system/icon/icon.js";
4
+ function Code({ children, block = false, variant = "default", copy = false, className = "" }) {
5
+ const codeRef = useRef(null);
6
+ const [copied, setCopied] = useState(false);
7
+ const handleCopy = async () => {
8
+ if (!codeRef.current) return;
9
+ try {
10
+ const textContent = codeRef.current.textContent || "";
11
+ await navigator.clipboard.writeText(textContent);
12
+ setCopied(true);
13
+ setTimeout(() => setCopied(false), 2e3);
14
+ } catch (err) {
15
+ console.error("Failed to copy code:", err);
16
+ }
17
+ };
3
18
  const variantClasses = {
4
19
  default: "bg-muted text-foreground",
5
20
  primary: "text-primary",
@@ -7,9 +22,57 @@ function Code({ children, block = false, variant = "default", className = "" })
7
22
  };
8
23
  const baseClasses = `font-mono ${variantClasses[variant]}`;
9
24
  if (block) {
10
- return /* @__PURE__ */ jsx("pre", { className: `${baseClasses} p-4 rounded-lg overflow-x-auto border border-border ${className}`, children: /* @__PURE__ */ jsx("code", { children }) });
25
+ const blockElement = /* @__PURE__ */ jsx("pre", { className: `${baseClasses} p-4 rounded-lg overflow-x-auto border border-border ${className}`, ref: codeRef, children: /* @__PURE__ */ jsx("code", { children }) });
26
+ if (copy) {
27
+ return /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
28
+ blockElement,
29
+ /* @__PURE__ */ jsx(
30
+ "button",
31
+ {
32
+ type: "button",
33
+ onClick: handleCopy,
34
+ className: "absolute top-2 right-2 inline-flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity focus:opacity-100 cursor-pointer bg-background/80 backdrop-blur-sm p-1.5 rounded border border-border hover:bg-muted",
35
+ "aria-label": "Copy to clipboard",
36
+ children: /* @__PURE__ */ jsx(
37
+ Icon,
38
+ {
39
+ name: copied ? "check" : "copy",
40
+ size: "sm",
41
+ color: copied ? "success" : "currentColor",
42
+ className: "transition-all"
43
+ }
44
+ )
45
+ }
46
+ )
47
+ ] });
48
+ }
49
+ return blockElement;
50
+ }
51
+ const inlineElement = /* @__PURE__ */ jsx("code", { className: `${baseClasses} px-1.5 py-0.5 rounded text-sm ${className}`, ref: codeRef, children });
52
+ if (copy) {
53
+ return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2 group", children: [
54
+ inlineElement,
55
+ /* @__PURE__ */ jsx(
56
+ "button",
57
+ {
58
+ type: "button",
59
+ onClick: handleCopy,
60
+ className: "inline-flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity focus:opacity-100 cursor-pointer",
61
+ "aria-label": "Copy to clipboard",
62
+ children: /* @__PURE__ */ jsx(
63
+ Icon,
64
+ {
65
+ name: copied ? "check" : "copy",
66
+ size: "sm",
67
+ color: copied ? "success" : "currentColor",
68
+ className: "transition-all"
69
+ }
70
+ )
71
+ }
72
+ )
73
+ ] });
11
74
  }
12
- return /* @__PURE__ */ jsx("code", { className: `${baseClasses} px-1.5 py-0.5 rounded text-sm ${className}`, children });
75
+ return inlineElement;
13
76
  }
14
77
  Code.displayName = "Code";
15
78
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"code.js","sources":["../../../../src/components/typography/code/code.tsx"],"sourcesContent":["import { ReactNode } from 'react';\n\nexport type CodeProps = {\n /** Code content to be displayed */\n children: ReactNode;\n /** Whether to render as a code block (pre + code) or inline code\n * @default false\n */\n block?: boolean;\n /** Visual style variant\n * @default 'default'\n */\n variant?: 'default' | 'primary' | 'muted';\n /** Additional CSS classes for custom styling */\n className?: string;\n};\n\n/**\n * Code - Styled code snippets (inline or block)\n */\nfunction Code({ children, block = false, variant = 'default', className = '' }: Readonly<CodeProps>) {\n const variantClasses = {\n default: 'bg-muted text-foreground',\n primary: 'text-primary',\n muted: 'text-muted-foreground'\n };\n\n const baseClasses = `font-mono ${variantClasses[variant]}`;\n\n if (block) {\n return (\n <pre className={`${baseClasses} p-4 rounded-lg overflow-x-auto border border-border ${className}`}>\n <code>{children}</code>\n </pre>\n );\n }\n\n return <code className={`${baseClasses} px-1.5 py-0.5 rounded text-sm ${className}`}>{children}</code>;\n}\n\nCode.displayName = 'Code';\n\nexport default Code;\n"],"names":[],"mappings":";AAoBA,SAAS,KAAK,EAAE,UAAU,QAAQ,OAAO,UAAU,WAAW,YAAY,MAA2B;AACnG,QAAM,iBAAiB;AAAA,IACrB,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,EAAA;AAGT,QAAM,cAAc,aAAa,eAAe,OAAO,CAAC;AAExD,MAAI,OAAO;AACT,WACE,oBAAC,OAAA,EAAI,WAAW,GAAG,WAAW,wDAAwD,SAAS,IAC7F,UAAA,oBAAC,QAAA,EAAM,SAAA,CAAS,GAClB;AAAA,EAEJ;AAEA,SAAO,oBAAC,UAAK,WAAW,GAAG,WAAW,kCAAkC,SAAS,IAAK,UAAS;AACjG;AAEA,KAAK,cAAc;"}
1
+ {"version":3,"file":"code.js","sources":["../../../../src/components/typography/code/code.tsx"],"sourcesContent":["import { ReactNode, useRef, useState } from 'react';\nimport Icon from '../../system/icon/icon';\n\nexport type CodeProps = {\n /** Code content to be displayed */\n children: ReactNode;\n /** Whether to render as a code block (pre + code) or inline code\n * @default false\n */\n block?: boolean;\n /** Visual style variant\n * @default 'default'\n */\n variant?: 'default' | 'primary' | 'muted';\n /** Show copy-to-clipboard button\n * @default false\n */\n copy?: boolean;\n /** Additional CSS classes for custom styling */\n className?: string;\n};\n\n/**\n * Code - Styled code snippets (inline or block)\n */\nfunction Code({ children, block = false, variant = 'default', copy = false, className = '' }: Readonly<CodeProps>) {\n const codeRef = useRef<HTMLElement>(null);\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n if (!codeRef.current) return;\n\n try {\n const textContent = codeRef.current.textContent || '';\n await navigator.clipboard.writeText(textContent);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Failed to copy code:', err);\n }\n };\n\n const variantClasses = {\n default: 'bg-muted text-foreground',\n primary: 'text-primary',\n muted: 'text-muted-foreground'\n };\n\n const baseClasses = `font-mono ${variantClasses[variant]}`;\n\n if (block) {\n const blockElement = (\n <pre className={`${baseClasses} p-4 rounded-lg overflow-x-auto border border-border ${className}`} ref={codeRef}>\n <code>{children}</code>\n </pre>\n );\n\n if (copy) {\n return (\n <div className=\"relative group\">\n {blockElement}\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"absolute top-2 right-2 inline-flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity focus:opacity-100 cursor-pointer bg-background/80 backdrop-blur-sm p-1.5 rounded border border-border hover:bg-muted\"\n aria-label=\"Copy to clipboard\"\n >\n <Icon\n name={copied ? 'check' : 'copy'}\n size=\"sm\"\n color={copied ? 'success' : 'currentColor'}\n className=\"transition-all\"\n />\n </button>\n </div>\n );\n }\n\n return blockElement;\n }\n\n const inlineElement = (\n <code className={`${baseClasses} px-1.5 py-0.5 rounded text-sm ${className}`} ref={codeRef}>\n {children}\n </code>\n );\n\n if (copy) {\n return (\n <span className=\"inline-flex items-center gap-2 group\">\n {inlineElement}\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"inline-flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity focus:opacity-100 cursor-pointer\"\n aria-label=\"Copy to clipboard\"\n >\n <Icon\n name={copied ? 'check' : 'copy'}\n size=\"sm\"\n color={copied ? 'success' : 'currentColor'}\n className=\"transition-all\"\n />\n </button>\n </span>\n );\n }\n\n return inlineElement;\n}\n\nCode.displayName = 'Code';\n\nexport default Code;\n"],"names":[],"mappings":";;;AAyBA,SAAS,KAAK,EAAE,UAAU,QAAQ,OAAO,UAAU,WAAW,OAAO,OAAO,YAAY,GAAA,GAA2B;AACjH,QAAM,UAAU,OAAoB,IAAI;AACxC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,aAAa,YAAY;AAC7B,QAAI,CAAC,QAAQ,QAAS;AAEtB,QAAI;AACF,YAAM,cAAc,QAAQ,QAAQ,eAAe;AACnD,YAAM,UAAU,UAAU,UAAU,WAAW;AAC/C,gBAAU,IAAI;AACd,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC,SAAS,KAAK;AAEZ,cAAQ,MAAM,wBAAwB,GAAG;AAAA,IAC3C;AAAA,EACF;AAEA,QAAM,iBAAiB;AAAA,IACrB,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,EAAA;AAGT,QAAM,cAAc,aAAa,eAAe,OAAO,CAAC;AAExD,MAAI,OAAO;AACT,UAAM,eACJ,oBAAC,OAAA,EAAI,WAAW,GAAG,WAAW,wDAAwD,SAAS,IAAI,KAAK,SACtG,UAAA,oBAAC,QAAA,EAAM,UAAS,GAClB;AAGF,QAAI,MAAM;AACR,aACE,qBAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,QAAA;AAAA,QACD;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS;AAAA,YACT,WAAU;AAAA,YACV,cAAW;AAAA,YAEX,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAM,SAAS,UAAU;AAAA,gBACzB,MAAK;AAAA,gBACL,OAAO,SAAS,YAAY;AAAA,gBAC5B,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ;AAAA,QAAA;AAAA,MACF,GACF;AAAA,IAEJ;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,gBACJ,oBAAC,QAAA,EAAK,WAAW,GAAG,WAAW,kCAAkC,SAAS,IAAI,KAAK,SAChF,SAAA,CACH;AAGF,MAAI,MAAM;AACR,WACE,qBAAC,QAAA,EAAK,WAAU,wCACb,UAAA;AAAA,MAAA;AAAA,MACD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS;AAAA,UACT,WAAU;AAAA,UACV,cAAW;AAAA,UAEX,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM,SAAS,UAAU;AAAA,cACzB,MAAK;AAAA,cACL,OAAO,SAAS,YAAY;AAAA,cAC5B,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ;AAAA,MAAA;AAAA,IACF,GACF;AAAA,EAEJ;AAEA,SAAO;AACT;AAEA,KAAK,cAAc;"}
@@ -79,6 +79,11 @@ export type TextProps = {
79
79
  * Make text selectable or not
80
80
  */
81
81
  selectable?: boolean;
82
+ /**
83
+ * Show copy-to-clipboard button
84
+ * @default false
85
+ */
86
+ copy?: boolean;
82
87
  /**
83
88
  * Additional CSS classes (use as last resort)
84
89
  */
@@ -96,7 +101,7 @@ export type TextProps = {
96
101
  * Text - Versatile typography component for body text
97
102
  * Handles all common text styling needs through props
98
103
  */
99
- declare function Text({ children, as, variant, size, weight, align, leading, tracking, transform, decoration, italic, truncate, lineClamp, wrap, wordBreak, opacity, hasMargin, selectable, className, id, htmlFor }: Readonly<TextProps>): import('react').DetailedReactHTMLElement<Record<string, unknown>, HTMLElement>;
104
+ declare function Text({ children, as, variant, size, weight, align, leading, tracking, transform, decoration, italic, truncate, lineClamp, wrap, wordBreak, opacity, hasMargin, selectable, copy, className, id, htmlFor }: Readonly<TextProps>): import("react/jsx-runtime").JSX.Element;
100
105
  declare namespace Text {
101
106
  var displayName: string;
102
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../../src/components/typography/text/text.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAiB,MAAM,OAAO,CAAC;AACjD,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtE,MAAM,MAAM,SAAS,GAAG;IACtB,qDAAqD;IACrD,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;OAGG;IACH,EAAE,CAAC,EACC,GAAG,GACH,MAAM,GACN,OAAO,GACP,QAAQ,GACR,IAAI,GACJ,OAAO,GACP,MAAM,GACN,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,MAAM,GACN,GAAG,CAAC;IAER;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAE/F;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,WAAW,CAAC;IAE3E;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAEhD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;IAErE;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAExE;;OAEG;IACH,SAAS,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,QAAQ,CAAC;IAEhE;;OAEG;IACH,UAAU,CAAC,EAAE,WAAW,GAAG,cAAc,GAAG,MAAM,CAAC;IAEnD;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAElC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAEhD;;OAEG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IAEhD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAEjC;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,iBAAS,IAAI,CAAC,EACZ,QAAQ,EACR,EAAQ,EACR,OAAgB,EAChB,IAAI,EACJ,MAAiB,EACjB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,SAAS,EACT,UAAU,EACV,MAAc,EACd,QAAgB,EAChB,SAAS,EACT,IAAI,EACJ,SAAS,EACT,OAAO,EACP,SAAiB,EACjB,UAAU,EACV,SAAc,EACd,EAAE,EACF,OAAO,EACR,EAAE,QAAQ,CAAC,SAAS,CAAC,kFAwIrB;kBA9JQ,IAAI;;;AAkKb,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../../src/components/typography/text/text.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAmC,MAAM,OAAO,CAAC;AACnE,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAGtE,MAAM,MAAM,SAAS,GAAG;IACtB,qDAAqD;IACrD,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;OAGG;IACH,EAAE,CAAC,EACC,GAAG,GACH,MAAM,GACN,OAAO,GACP,QAAQ,GACR,IAAI,GACJ,OAAO,GACP,MAAM,GACN,KAAK,GACL,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,MAAM,GACN,GAAG,CAAC;IAER;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAE/F;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,WAAW,CAAC;IAE3E;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAEhD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;IAErE;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAExE;;OAEG;IACH,SAAS,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,QAAQ,CAAC;IAEhE;;OAEG;IACH,UAAU,CAAC,EAAE,WAAW,GAAG,cAAc,GAAG,MAAM,CAAC;IAEnD;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAElC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAEhD;;OAEG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IAEhD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAEjC;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;GAGG;AACH,iBAAS,IAAI,CAAC,EACZ,QAAQ,EACR,EAAQ,EACR,OAAgB,EAChB,IAAI,EACJ,MAAiB,EACjB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,SAAS,EACT,UAAU,EACV,MAAc,EACd,QAAgB,EAChB,SAAS,EACT,IAAI,EACJ,SAAS,EACT,OAAO,EACP,SAAiB,EACjB,UAAU,EACV,IAAY,EACZ,SAAc,EACd,EAAE,EACF,OAAO,EACR,EAAE,QAAQ,CAAC,SAAS,CAAC,2CA0LrB;kBAjNQ,IAAI;;;AAqNb,eAAe,IAAI,CAAC"}
@@ -1,5 +1,7 @@
1
- import { createElement } from "react";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useRef, useState, createElement } from "react";
2
3
  import { textSizes } from "../../../theme/size-tokens.js";
4
+ import { Icon } from "../../system/icon/icon.js";
3
5
  function Text({
4
6
  children,
5
7
  as = "p",
@@ -19,10 +21,28 @@ function Text({
19
21
  opacity,
20
22
  hasMargin = false,
21
23
  selectable,
24
+ copy = false,
22
25
  className = "",
23
26
  id,
24
27
  htmlFor
25
28
  }) {
29
+ const textRef = useRef(null);
30
+ const [copied, setCopied] = useState(false);
31
+ const handleCopy = async () => {
32
+ if (!textRef.current) return;
33
+ if (typeof navigator === "undefined" || !navigator.clipboard || typeof navigator.clipboard.writeText !== "function") {
34
+ console.error("Clipboard API is not available in this environment.");
35
+ return;
36
+ }
37
+ try {
38
+ const textContent = textRef.current.textContent || "";
39
+ await navigator.clipboard.writeText(textContent);
40
+ setCopied(true);
41
+ setTimeout(() => setCopied(false), 2e3);
42
+ } catch (err) {
43
+ console.error("Failed to copy text:", err);
44
+ }
45
+ };
26
46
  const variantClasses = {
27
47
  body: "text-foreground",
28
48
  muted: "text-muted-foreground",
@@ -137,9 +157,34 @@ function Text({
137
157
  const elementProps = {
138
158
  className: classes,
139
159
  ...id && { id },
140
- ...htmlFor && as === "label" && { htmlFor }
160
+ ...htmlFor && as === "label" && { htmlFor },
161
+ ref: textRef
141
162
  };
142
- return createElement(as, elementProps, children);
163
+ const textElement = createElement(as, elementProps, children);
164
+ if (copy) {
165
+ return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2 group", children: [
166
+ textElement,
167
+ /* @__PURE__ */ jsx(
168
+ "button",
169
+ {
170
+ type: "button",
171
+ onClick: handleCopy,
172
+ className: "inline-flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity focus:opacity-100 cursor-pointer",
173
+ "aria-label": "Copy to clipboard",
174
+ children: /* @__PURE__ */ jsx(
175
+ Icon,
176
+ {
177
+ name: copied ? "check" : "copy",
178
+ size: "sm",
179
+ color: copied ? "success" : "currentColor",
180
+ className: "transition-all"
181
+ }
182
+ )
183
+ }
184
+ )
185
+ ] });
186
+ }
187
+ return textElement;
143
188
  }
144
189
  Text.displayName = "Text";
145
190
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","sources":["../../../../src/components/typography/text/text.tsx"],"sourcesContent":["import { ReactNode, createElement } from 'react';\nimport { textSizes, type TextSize } from '../../../theme/size-tokens';\n\nexport type TextProps = {\n /** Content to be rendered within the text element */\n children: ReactNode;\n\n /**\n * Semantic HTML element to render\n * @default 'p'\n */\n as?:\n | 'p'\n | 'span'\n | 'label'\n | 'strong'\n | 'em'\n | 'small'\n | 'mark'\n | 'del'\n | 'ins'\n | 'sub'\n | 'sup'\n | 'abbr'\n | 'cite'\n | 'q';\n\n /**\n * Color variant\n * @default 'body'\n */\n variant?: 'body' | 'muted' | 'small' | 'primary' | 'success' | 'warning' | 'error' | 'inherit';\n\n /**\n * Text size - uses unified size system\n * @default based on variant\n */\n size?: TextSize;\n\n /**\n * Font weight\n * @default 'semibold'\n */\n weight?: 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold';\n\n /**\n * Text alignment\n * @default 'left'\n */\n align?: 'left' | 'center' | 'right' | 'justify';\n\n /**\n * Line height / leading\n * @default 'normal'\n */\n leading?: 'none' | 'tight' | 'snug' | 'normal' | 'relaxed' | 'loose';\n\n /**\n * Letter spacing / tracking\n * @default 'normal'\n */\n tracking?: 'tighter' | 'tight' | 'normal' | 'wide' | 'wider' | 'widest';\n\n /**\n * Text transform\n */\n transform?: 'uppercase' | 'lowercase' | 'capitalize' | 'normal';\n\n /**\n * Text decoration\n */\n decoration?: 'underline' | 'line-through' | 'none';\n\n /**\n * Font style\n */\n italic?: boolean;\n\n /**\n * Truncate text with ellipsis\n */\n truncate?: boolean;\n\n /**\n * Limit text to specified number of lines (uses line-clamp)\n */\n lineClamp?: 1 | 2 | 3 | 4 | 5 | 6;\n\n /**\n * Text wrapping behavior\n */\n wrap?: 'wrap' | 'nowrap' | 'balance' | 'pretty';\n\n /**\n * Word break behavior\n */\n wordBreak?: 'normal' | 'words' | 'all' | 'keep';\n\n /**\n * Text opacity (0-100)\n */\n opacity?: 0 | 25 | 50 | 75 | 100;\n\n /**\n * Add bottom margin\n * @default false\n */\n hasMargin?: boolean;\n\n /**\n * Make text selectable or not\n */\n selectable?: boolean;\n\n /**\n * Additional CSS classes (use as last resort)\n */\n className?: string;\n\n /**\n * ID for the element\n */\n id?: string;\n\n /**\n * HTML for attribute (useful when as=\"label\")\n */\n htmlFor?: string;\n};\n\n/**\n * Text - Versatile typography component for body text\n * Handles all common text styling needs through props\n */\nfunction Text({\n children,\n as = 'p',\n variant = 'body',\n size,\n weight = 'normal',\n align,\n leading,\n tracking,\n transform,\n decoration,\n italic = false,\n truncate = false,\n lineClamp,\n wrap,\n wordBreak,\n opacity,\n hasMargin = false,\n selectable,\n className = '',\n id,\n htmlFor\n}: Readonly<TextProps>) {\n const variantClasses = {\n body: 'text-foreground',\n muted: 'text-muted-foreground',\n small: 'text-muted-foreground',\n primary: 'text-primary',\n success: 'text-success',\n warning: 'text-warning',\n error: 'text-error',\n inherit: 'text-inherit'\n };\n\n const sizeClasses = textSizes;\n\n const weightClasses = {\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold'\n };\n\n const alignClasses = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n justify: 'text-justify'\n };\n\n const leadingClasses = {\n none: 'leading-none',\n tight: 'leading-tight',\n snug: 'leading-snug',\n normal: 'leading-normal',\n relaxed: 'leading-relaxed',\n loose: 'leading-loose'\n };\n\n const trackingClasses = {\n tighter: 'tracking-tighter',\n tight: 'tracking-tight',\n normal: 'tracking-normal',\n wide: 'tracking-wide',\n wider: 'tracking-wider',\n widest: 'tracking-widest'\n };\n\n const transformClasses = {\n uppercase: 'uppercase',\n lowercase: 'lowercase',\n capitalize: 'capitalize',\n normal: 'normal-case'\n };\n\n const decorationClasses = {\n underline: 'underline',\n 'line-through': 'line-through',\n none: 'no-underline'\n };\n\n const wrapClasses = {\n wrap: 'text-wrap',\n nowrap: 'text-nowrap',\n balance: 'text-balance',\n pretty: 'text-pretty'\n };\n\n const wordBreakClasses = {\n normal: 'break-normal',\n words: 'break-words',\n all: 'break-all',\n keep: 'break-keep'\n };\n\n const opacityClasses = {\n 0: 'opacity-0',\n 25: 'opacity-25',\n 50: 'opacity-50',\n 75: 'opacity-75',\n 100: 'opacity-100'\n };\n\n const lineClampClasses = {\n 1: 'line-clamp-1',\n 2: 'line-clamp-2',\n 3: 'line-clamp-3',\n 4: 'line-clamp-4',\n 5: 'line-clamp-5',\n 6: 'line-clamp-6'\n };\n\n const defaultSizes = {\n body: 'lg',\n muted: 'base',\n small: 'sm',\n primary: 'base',\n success: 'base',\n warning: 'base',\n error: 'base',\n inherit: 'base'\n } as const;\n\n const finalSize = size || defaultSizes[variant];\n const margin = hasMargin ? 'mb-3 sm:mb-4' : '';\n\n const classes = [\n variantClasses[variant],\n sizeClasses[finalSize],\n weightClasses[weight],\n margin,\n align && alignClasses[align],\n leading && leadingClasses[leading],\n tracking && trackingClasses[tracking],\n transform && transformClasses[transform],\n decoration && decorationClasses[decoration],\n italic && 'italic',\n truncate && 'truncate',\n lineClamp && lineClampClasses[lineClamp],\n wrap && wrapClasses[wrap],\n wordBreak && wordBreakClasses[wordBreak],\n opacity !== undefined && opacityClasses[opacity],\n selectable === true && 'select-all',\n selectable === false && 'select-none',\n className\n ]\n .filter(Boolean)\n .join(' ');\n\n const elementProps: Record<string, unknown> = {\n className: classes,\n ...(id && { id }),\n ...(htmlFor && as === 'label' && { htmlFor })\n };\n\n return createElement(as, elementProps, children);\n}\n\nText.displayName = 'Text';\n\nexport default Text;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"text.js","sources":["../../../../src/components/typography/text/text.tsx"],"sourcesContent":["import { ReactNode, createElement, useRef, useState } from 'react';\nimport { textSizes, type TextSize } from '../../../theme/size-tokens';\nimport Icon from '../../system/icon/icon';\n\nexport type TextProps = {\n /** Content to be rendered within the text element */\n children: ReactNode;\n\n /**\n * Semantic HTML element to render\n * @default 'p'\n */\n as?:\n | 'p'\n | 'span'\n | 'label'\n | 'strong'\n | 'em'\n | 'small'\n | 'mark'\n | 'del'\n | 'ins'\n | 'sub'\n | 'sup'\n | 'abbr'\n | 'cite'\n | 'q';\n\n /**\n * Color variant\n * @default 'body'\n */\n variant?: 'body' | 'muted' | 'small' | 'primary' | 'success' | 'warning' | 'error' | 'inherit';\n\n /**\n * Text size - uses unified size system\n * @default based on variant\n */\n size?: TextSize;\n\n /**\n * Font weight\n * @default 'semibold'\n */\n weight?: 'light' | 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold';\n\n /**\n * Text alignment\n * @default 'left'\n */\n align?: 'left' | 'center' | 'right' | 'justify';\n\n /**\n * Line height / leading\n * @default 'normal'\n */\n leading?: 'none' | 'tight' | 'snug' | 'normal' | 'relaxed' | 'loose';\n\n /**\n * Letter spacing / tracking\n * @default 'normal'\n */\n tracking?: 'tighter' | 'tight' | 'normal' | 'wide' | 'wider' | 'widest';\n\n /**\n * Text transform\n */\n transform?: 'uppercase' | 'lowercase' | 'capitalize' | 'normal';\n\n /**\n * Text decoration\n */\n decoration?: 'underline' | 'line-through' | 'none';\n\n /**\n * Font style\n */\n italic?: boolean;\n\n /**\n * Truncate text with ellipsis\n */\n truncate?: boolean;\n\n /**\n * Limit text to specified number of lines (uses line-clamp)\n */\n lineClamp?: 1 | 2 | 3 | 4 | 5 | 6;\n\n /**\n * Text wrapping behavior\n */\n wrap?: 'wrap' | 'nowrap' | 'balance' | 'pretty';\n\n /**\n * Word break behavior\n */\n wordBreak?: 'normal' | 'words' | 'all' | 'keep';\n\n /**\n * Text opacity (0-100)\n */\n opacity?: 0 | 25 | 50 | 75 | 100;\n\n /**\n * Add bottom margin\n * @default false\n */\n hasMargin?: boolean;\n\n /**\n * Make text selectable or not\n */\n selectable?: boolean;\n\n /**\n * Show copy-to-clipboard button\n * @default false\n */\n copy?: boolean;\n\n /**\n * Additional CSS classes (use as last resort)\n */\n className?: string;\n\n /**\n * ID for the element\n */\n id?: string;\n\n /**\n * HTML for attribute (useful when as=\"label\")\n */\n htmlFor?: string;\n};\n\n/**\n * Text - Versatile typography component for body text\n * Handles all common text styling needs through props\n */\nfunction Text({\n children,\n as = 'p',\n variant = 'body',\n size,\n weight = 'normal',\n align,\n leading,\n tracking,\n transform,\n decoration,\n italic = false,\n truncate = false,\n lineClamp,\n wrap,\n wordBreak,\n opacity,\n hasMargin = false,\n selectable,\n copy = false,\n className = '',\n id,\n htmlFor\n}: Readonly<TextProps>) {\n const textRef = useRef<HTMLElement>(null);\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n if (!textRef.current) return;\n\n // Guard against environments without the Clipboard API (SSR, unsupported browsers, tests)\n if (\n typeof navigator === 'undefined' ||\n !navigator.clipboard ||\n typeof navigator.clipboard.writeText !== 'function'\n ) {\n // eslint-disable-next-line no-console\n console.error('Clipboard API is not available in this environment.');\n return;\n }\n try {\n const textContent = textRef.current.textContent || '';\n await navigator.clipboard.writeText(textContent);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error('Failed to copy text:', err);\n }\n };\n const variantClasses = {\n body: 'text-foreground',\n muted: 'text-muted-foreground',\n small: 'text-muted-foreground',\n primary: 'text-primary',\n success: 'text-success',\n warning: 'text-warning',\n error: 'text-error',\n inherit: 'text-inherit'\n };\n\n const sizeClasses = textSizes;\n\n const weightClasses = {\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold'\n };\n\n const alignClasses = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n justify: 'text-justify'\n };\n\n const leadingClasses = {\n none: 'leading-none',\n tight: 'leading-tight',\n snug: 'leading-snug',\n normal: 'leading-normal',\n relaxed: 'leading-relaxed',\n loose: 'leading-loose'\n };\n\n const trackingClasses = {\n tighter: 'tracking-tighter',\n tight: 'tracking-tight',\n normal: 'tracking-normal',\n wide: 'tracking-wide',\n wider: 'tracking-wider',\n widest: 'tracking-widest'\n };\n\n const transformClasses = {\n uppercase: 'uppercase',\n lowercase: 'lowercase',\n capitalize: 'capitalize',\n normal: 'normal-case'\n };\n\n const decorationClasses = {\n underline: 'underline',\n 'line-through': 'line-through',\n none: 'no-underline'\n };\n\n const wrapClasses = {\n wrap: 'text-wrap',\n nowrap: 'text-nowrap',\n balance: 'text-balance',\n pretty: 'text-pretty'\n };\n\n const wordBreakClasses = {\n normal: 'break-normal',\n words: 'break-words',\n all: 'break-all',\n keep: 'break-keep'\n };\n\n const opacityClasses = {\n 0: 'opacity-0',\n 25: 'opacity-25',\n 50: 'opacity-50',\n 75: 'opacity-75',\n 100: 'opacity-100'\n };\n\n const lineClampClasses = {\n 1: 'line-clamp-1',\n 2: 'line-clamp-2',\n 3: 'line-clamp-3',\n 4: 'line-clamp-4',\n 5: 'line-clamp-5',\n 6: 'line-clamp-6'\n };\n\n const defaultSizes = {\n body: 'lg',\n muted: 'base',\n small: 'sm',\n primary: 'base',\n success: 'base',\n warning: 'base',\n error: 'base',\n inherit: 'base'\n } as const;\n\n const finalSize = size || defaultSizes[variant];\n const margin = hasMargin ? 'mb-3 sm:mb-4' : '';\n\n const classes = [\n variantClasses[variant],\n sizeClasses[finalSize],\n weightClasses[weight],\n margin,\n align && alignClasses[align],\n leading && leadingClasses[leading],\n tracking && trackingClasses[tracking],\n transform && transformClasses[transform],\n decoration && decorationClasses[decoration],\n italic && 'italic',\n truncate && 'truncate',\n lineClamp && lineClampClasses[lineClamp],\n wrap && wrapClasses[wrap],\n wordBreak && wordBreakClasses[wordBreak],\n opacity !== undefined && opacityClasses[opacity],\n selectable === true && 'select-all',\n selectable === false && 'select-none',\n className\n ]\n .filter(Boolean)\n .join(' ');\n\n const elementProps: Record<string, unknown> = {\n className: classes,\n ...(id && { id }),\n ...(htmlFor && as === 'label' && { htmlFor }),\n ref: textRef\n };\n\n const textElement = createElement(as, elementProps, children);\n\n if (copy) {\n return (\n <span className=\"inline-flex items-center gap-2 group\">\n {textElement}\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"inline-flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity focus:opacity-100 cursor-pointer\"\n aria-label=\"Copy to clipboard\"\n >\n <Icon\n name={copied ? 'check' : 'copy'}\n size=\"sm\"\n color={copied ? 'success' : 'currentColor'}\n className=\"transition-all\"\n />\n </button>\n </span>\n );\n }\n\n return textElement;\n}\n\nText.displayName = 'Text';\n\nexport default Text;\n"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -91,20 +91,21 @@ import { default as default87 } from "./components/forms/slider/slider.js";
91
91
  import { default as default88, useStaggeredTransition } from "./components/feedback/smooth-transition/smooth-transition.js";
92
92
  import { default as default89 } from "./components/feedback/spinner/spinner.js";
93
93
  import { default as default90 } from "./components/layout/stack/stack.js";
94
- import { default as default91 } from "./components/data-display/badge/status-label.js";
95
- import { default as default92 } from "./components/navigation/stepper/stepper.js";
96
- import { default as default93 } from "./components/forms/switch/switch.js";
94
+ import { default as default91 } from "./components/data-display/status-indicator/status-indicator.js";
95
+ import { default as default92 } from "./components/data-display/badge/status-label.js";
96
+ import { default as default93 } from "./components/navigation/stepper/stepper.js";
97
+ import { default as default94 } from "./components/forms/switch/switch.js";
97
98
  import { Table, TableBody, TableCell, TableFooter, TableHeadCell, TableHeader, TableRow } from "./components/data-display/table/table.js";
98
- import { default as default94 } from "./components/navigation/tabs/tabs.js";
99
- import { default as default95 } from "./components/typography/text/text.js";
100
- import { default as default96 } from "./components/forms/textarea/textarea.js";
99
+ import { default as default95 } from "./components/navigation/tabs/tabs.js";
100
+ import { default as default96 } from "./components/typography/text/text.js";
101
+ import { default as default97 } from "./components/forms/textarea/textarea.js";
101
102
  import { ThemeProvider, useTheme } from "./components/system/theme-provider/theme-provider.js";
102
- import { default as default97, TimelineItem } from "./components/data-display/timeline/timeline.js";
103
- import { default as default98 } from "./components/feedback/toast/toast.js";
104
- import { default as default99 } from "./components/feedback/tooltip/tooltip.js";
105
- import { default as default100 } from "./hooks/useDebounce.js";
106
- import { default as default101 } from "./hooks/useScrollReset.js";
107
- import { default as default102 } from "./components/data-display/data-table/use-table.js";
103
+ import { default as default98, TimelineItem } from "./components/data-display/timeline/timeline.js";
104
+ import { default as default99 } from "./components/feedback/toast/toast.js";
105
+ import { default as default100 } from "./components/feedback/tooltip/tooltip.js";
106
+ import { default as default101 } from "./hooks/useDebounce.js";
107
+ import { default as default102 } from "./hooks/useScrollReset.js";
108
+ import { default as default103 } from "./components/data-display/data-table/use-table.js";
108
109
  import { ActionCard } from "./components/layout/action-card/action-card.js";
109
110
  import { GoogleLogo } from "./components/branding/google-logo.js";
110
111
  import { HyddenLogo } from "./components/branding/hydden-logo.js";
@@ -217,9 +218,10 @@ export {
217
218
  default88 as SmoothTransition,
218
219
  default89 as Spinner,
219
220
  default90 as Stack,
220
- default91 as StatusLabel,
221
- default92 as Stepper,
222
- default93 as Switch,
221
+ default91 as StatusIndicator,
222
+ default92 as StatusLabel,
223
+ default93 as Stepper,
224
+ default94 as Switch,
223
225
  Table,
224
226
  TableBody,
225
227
  TableCell,
@@ -227,14 +229,14 @@ export {
227
229
  TableHeadCell,
228
230
  TableHeader,
229
231
  TableRow,
230
- default94 as Tabs,
231
- default95 as Text,
232
- default96 as Textarea,
232
+ default95 as Tabs,
233
+ default96 as Text,
234
+ default97 as Textarea,
233
235
  ThemeProvider,
234
- default97 as Timeline,
236
+ default98 as Timeline,
235
237
  TimelineItem,
236
- default98 as Toast,
237
- default99 as Tooltip,
238
+ default99 as Toast,
239
+ default100 as Tooltip,
238
240
  authFetch,
239
241
  avatarSizes,
240
242
  badgeSizes,
@@ -280,10 +282,10 @@ export {
280
282
  statusLabelSizes,
281
283
  textSizes,
282
284
  useAuth,
283
- default100 as useDebounce,
284
- default101 as useScrollReset,
285
+ default101 as useDebounce,
286
+ default102 as useScrollReset,
285
287
  useStaggeredTransition,
286
- default102 as useTable,
288
+ default103 as useTable,
287
289
  useTheme,
288
290
  validationBorderClasses,
289
291
  validationRingClasses,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}