@zentauri-ui/zentauri-components 1.5.22 → 1.5.31

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 (77) hide show
  1. package/README.md +59 -2
  2. package/cli/registry.json +2 -0
  3. package/dist/chunk-7OHC4ERB.mjs +60 -0
  4. package/dist/chunk-7OHC4ERB.mjs.map +1 -0
  5. package/dist/{chunk-2VQJ6OIL.js → chunk-HPN7H5ZM.js} +2 -2
  6. package/dist/{chunk-2VQJ6OIL.js.map → chunk-HPN7H5ZM.js.map} +1 -1
  7. package/dist/chunk-JJDANNNL.mjs +71 -0
  8. package/dist/chunk-JJDANNNL.mjs.map +1 -0
  9. package/dist/chunk-KXUG4WVW.js +62 -0
  10. package/dist/chunk-KXUG4WVW.js.map +1 -0
  11. package/dist/chunk-MEJMX4QI.js +73 -0
  12. package/dist/chunk-MEJMX4QI.js.map +1 -0
  13. package/dist/chunk-N6B35KWW.mjs +3 -0
  14. package/dist/chunk-N6B35KWW.mjs.map +1 -0
  15. package/dist/{chunk-73VCO5TE.mjs → chunk-NWOE2TZN.mjs} +2 -2
  16. package/dist/{chunk-73VCO5TE.mjs.map → chunk-NWOE2TZN.mjs.map} +1 -1
  17. package/dist/chunk-RGOMHX4G.js +4 -0
  18. package/dist/chunk-RGOMHX4G.js.map +1 -0
  19. package/dist/hooks/useControllableState.js +3 -2
  20. package/dist/hooks/useControllableState.mjs +2 -1
  21. package/dist/hooks/useDisclosure.js +3 -2
  22. package/dist/hooks/useDisclosure.js.map +1 -1
  23. package/dist/hooks/useDisclosure.mjs +2 -1
  24. package/dist/hooks/useDisclosure.mjs.map +1 -1
  25. package/dist/hooks/useDynamicStepper/index.d.ts +2 -0
  26. package/dist/hooks/useDynamicStepper/index.d.ts.map +1 -0
  27. package/dist/hooks/useDynamicStepper/useDynamicStepper.d.ts +9 -0
  28. package/dist/hooks/useDynamicStepper/useDynamicStepper.d.ts.map +1 -0
  29. package/dist/hooks/useDynamicStepper.js +14 -0
  30. package/dist/hooks/useDynamicStepper.js.map +1 -0
  31. package/dist/hooks/useDynamicStepper.mjs +5 -0
  32. package/dist/hooks/useDynamicStepper.mjs.map +1 -0
  33. package/dist/ui/buttons.js +7 -55
  34. package/dist/ui/buttons.js.map +1 -1
  35. package/dist/ui/buttons.mjs +2 -58
  36. package/dist/ui/buttons.mjs.map +1 -1
  37. package/dist/ui/dynamic-stepper/dynamic-stepper.d.ts +6 -0
  38. package/dist/ui/dynamic-stepper/dynamic-stepper.d.ts.map +1 -0
  39. package/dist/ui/dynamic-stepper/index.d.ts +5 -0
  40. package/dist/ui/dynamic-stepper/index.d.ts.map +1 -0
  41. package/dist/ui/dynamic-stepper/types.d.ts +61 -0
  42. package/dist/ui/dynamic-stepper/types.d.ts.map +1 -0
  43. package/dist/ui/dynamic-stepper/variants.d.ts +21 -0
  44. package/dist/ui/dynamic-stepper/variants.d.ts.map +1 -0
  45. package/dist/ui/dynamic-stepper.js +312 -0
  46. package/dist/ui/dynamic-stepper.js.map +1 -0
  47. package/dist/ui/dynamic-stepper.mjs +305 -0
  48. package/dist/ui/dynamic-stepper.mjs.map +1 -0
  49. package/dist/ui/pagination/pagination.d.ts +5 -16
  50. package/dist/ui/pagination/pagination.d.ts.map +1 -1
  51. package/dist/ui/pagination/types.d.ts +2 -2
  52. package/dist/ui/pagination/types.d.ts.map +1 -1
  53. package/dist/ui/pagination.js +171 -180
  54. package/dist/ui/pagination.js.map +1 -1
  55. package/dist/ui/pagination.mjs +172 -181
  56. package/dist/ui/pagination.mjs.map +1 -1
  57. package/dist/ui/typography/blockquote-base.d.ts.map +1 -1
  58. package/dist/ui/typography/code-block-base.d.ts.map +1 -1
  59. package/dist/ui/typography/heading-base.d.ts.map +1 -1
  60. package/dist/ui/typography/inline-code-base.d.ts.map +1 -1
  61. package/dist/ui/typography.js.map +1 -1
  62. package/dist/ui/typography.mjs.map +1 -1
  63. package/package.json +1 -1
  64. package/src/hooks/useDynamicStepper/index.ts +3 -0
  65. package/src/hooks/useDynamicStepper/useDynamicStepper.test.ts +107 -0
  66. package/src/hooks/useDynamicStepper/useDynamicStepper.ts +91 -0
  67. package/src/ui/dynamic-stepper/dynamic-stepper.test.tsx +109 -0
  68. package/src/ui/dynamic-stepper/dynamic-stepper.tsx +173 -0
  69. package/src/ui/dynamic-stepper/index.ts +24 -0
  70. package/src/ui/dynamic-stepper/types.ts +85 -0
  71. package/src/ui/dynamic-stepper/variants.ts +238 -0
  72. package/src/ui/pagination/pagination.tsx +186 -197
  73. package/src/ui/pagination/types.ts +2 -2
  74. package/src/ui/typography/blockquote-base.tsx +0 -2
  75. package/src/ui/typography/code-block-base.tsx +0 -2
  76. package/src/ui/typography/heading-base.tsx +0 -2
  77. package/src/ui/typography/inline-code-base.tsx +0 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ui/typography/variants.ts","../../src/ui/typography/heading-base.tsx","../../src/ui/typography/heading.tsx","../../src/ui/typography/text-base.tsx","../../src/ui/typography/text.tsx","../../src/ui/typography/list-base.tsx","../../src/ui/typography/list.tsx","../../src/ui/typography/blockquote-base.tsx","../../src/ui/typography/blockquote.tsx","../../src/ui/typography/inline-code-base.tsx","../../src/ui/typography/inline-code.tsx","../../src/ui/typography/code-block-base.tsx","../../src/ui/typography/code-block.tsx"],"names":["jsx","tone","className","children","ref","ordered","marker","rest"],"mappings":"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","file":"typography.mjs","sourcesContent":["import { cva } from \"class-variance-authority\";\n\n/** Semantic text colors aligned with slate/cyan/violet accents used across the kit (dark-first). */\nexport const typographyToneVariants = cva(\"\", {\n variants: {\n tone: {\n default: \"text-slate-50 border-white/15\",\n muted: \"text-slate-400 border-white/15\",\n primary: \"text-cyan-300 border-cyan-300/40\",\n secondary: \"text-slate-300 border-white/15\",\n accent: \"text-violet-300 border-violet-300/40\",\n destructive: \"text-rose-400 border-rose-300/40\",\n info: \"text-sky-300 border-sky-300/40\",\n success: \"text-emerald-300 border-emerald-300/40\",\n warning: \"text-amber-300 border-amber-300/40\",\n error: \"text-red-300 border-red-300/40\",\n \"gradient-pink-violet\":\n \"bg-linear-to-r from-pink-400 to-violet-400 bg-clip-text text-transparent\",\n \"gradient-cyan-violet\":\n \"bg-linear-to-r from-cyan-400 to-violet-400 bg-clip-text text-transparent\",\n \"gradient-cyan-blue\":\n \"bg-linear-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent\",\n \"gradient-cyan-green\":\n \"bg-linear-to-r from-cyan-400 to-green-400 bg-clip-text text-transparent\",\n \"gradient-cyan-orange\":\n \"bg-linear-to-r from-cyan-400 to-orange-400 bg-clip-text text-transparent\",\n \"gradient-cyan-red\":\n \"bg-linear-to-r from-cyan-400 to-red-400 bg-clip-text text-transparent\",\n \"gradient-cyan-purple\":\n \"bg-linear-to-r from-cyan-400 to-purple-400 bg-clip-text text-transparent\",\n \"gradient-cyan-pink\":\n \"bg-linear-to-r from-cyan-400 to-pink-400 bg-clip-text text-transparent\",\n },\n },\n defaultVariants: {\n tone: \"default\",\n },\n});\n\nexport const headingLevelVariants = cva(\"scroll-m-20\", {\n variants: {\n level: {\n 1: \"text-4xl font-bold tracking-tight md:text-5xl\",\n 2: \"text-3xl font-semibold tracking-tight\",\n 3: \"text-2xl font-semibold tracking-tight\",\n 4: \"text-xl font-semibold tracking-tight\",\n 5: \"text-lg font-medium\",\n 6: \"text-base font-medium\",\n },\n },\n});\n\nexport const textSizeVariants = cva(\"\", {\n variants: {\n size: {\n sm: \"text-sm leading-relaxed\",\n base: \"text-base leading-relaxed\",\n lg: \"text-lg leading-relaxed\",\n },\n },\n defaultVariants: {\n size: \"base\",\n },\n});\n\n/** Marker style for unordered lists; ignored when `ordered` is true (decimal numbering). */\nexport const unorderedListMarkerVariants = cva(\"space-y-2 pl-5\", {\n variants: {\n marker: {\n disc: \"list-disc\",\n circle: \"[list-style-type:circle]\",\n none: \"list-none pl-0\",\n },\n },\n defaultVariants: {\n marker: \"disc\",\n },\n});\n\nexport const orderedListVariants = cva(\"list-decimal space-y-2 pl-5\");\n","import { forwardRef } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nimport type { HeadingProps } from \"./types\";\nimport { headingLevelVariants, typographyToneVariants } from \"./variants\";\n\nconst HEADING_TAGS = {\n 1: \"h1\",\n 2: \"h2\",\n 3: \"h3\",\n 4: \"h4\",\n 5: \"h5\",\n 6: \"h6\",\n} as const;\n\nexport const HeadingBase = (props: HeadingProps) => {\n const {\n level,\n displayLevel,\n tone,\n bold,\n italic,\n underline,\n strikethrough,\n ref,\n className,\n children,\n ...rest\n } = props;\n\n const Tag = HEADING_TAGS[level];\n const scale = displayLevel ?? level;\n\n return (\n <Tag\n ref={ref}\n data-slot=\"typography-heading\"\n data-level={level}\n className={cn(\n typographyToneVariants({ tone }),\n headingLevelVariants({ level: scale }),\n bold && \"font-bold\",\n italic && \"italic\",\n underline && \"underline underline-offset-4\",\n strikethrough && \"line-through\",\n className,\n )}\n {...rest}\n >\n {children}\n </Tag>\n );\n};\n\nHeadingBase.displayName = \"Heading\";\n","import { HeadingBase } from \"./heading-base\";\nimport type { HeadingProps } from \"./types\";\n\nexport const Heading = (props: HeadingProps) => {\n return <HeadingBase {...props} />;\n};\n\nHeading.displayName = \"Heading\";\n","import { cn } from \"../../lib/utils\";\n\nimport type { TextProps } from \"./types\";\nimport { textSizeVariants, typographyToneVariants } from \"./variants\";\n\nexport const TextBase = (props: TextProps) => {\n const {\n as = \"p\",\n size = \"base\",\n tone,\n bold,\n italic,\n underline,\n strikethrough,\n highlight,\n className,\n children,\n ...rest\n } = props;\n\n const Component = as;\n\n return (\n <Component\n data-slot=\"typography-text\"\n className={cn(\n typographyToneVariants({ tone }),\n textSizeVariants({ size }),\n bold && \"font-semibold\",\n italic && \"italic\",\n underline && \"underline underline-offset-2\",\n strikethrough && \"line-through\",\n highlight && \"rounded bg-amber-400/15 px-0.5\",\n className,\n )}\n {...rest}\n >\n {children}\n </Component>\n );\n};\n\nTextBase.displayName = \"Text\";\n","import { TextBase } from \"./text-base\";\nimport type { TextProps } from \"./types\";\n\nexport const Text = (props: TextProps) => {\n return <TextBase {...props} />;\n};\n\nText.displayName = \"Text\";\n","import { cn } from \"../../lib/utils\";\n\nimport type { ListProps, ListItemProps } from \"./types\";\nimport {\n orderedListVariants,\n typographyToneVariants,\n unorderedListMarkerVariants,\n} from \"./variants\";\n\nexport function ListBase(props: ListProps) {\n if (\"ordered\" in props && props.ordered === true) {\n const { tone, className, children, ref, ordered, marker, ...rest } = props;\n\n void ordered;\n void marker;\n\n return (\n <ol\n ref={ref}\n data-slot=\"typography-list\"\n data-list-type=\"ordered\"\n className={cn(\n typographyToneVariants({ tone }),\n orderedListVariants(),\n className,\n )}\n {...rest}\n >\n {children}\n </ol>\n );\n }\n\n const {\n marker = \"disc\",\n tone,\n className,\n children,\n ref,\n ordered,\n ...rest\n } = props;\n\n void ordered;\n\n return (\n <ul\n ref={ref}\n data-slot=\"typography-list\"\n data-list-type=\"unordered\"\n className={cn(\n typographyToneVariants({ tone }),\n unorderedListMarkerVariants({ marker }),\n className,\n )}\n {...rest}\n >\n {children}\n </ul>\n );\n}\n\nListBase.displayName = \"List\";\n\nexport function ListItemBase(props: ListItemProps) {\n const { className, children, ref, ...rest } = props;\n\n return (\n <li\n ref={ref}\n data-slot=\"typography-list-item\"\n className={cn(\"leading-relaxed\", className)}\n {...rest}\n >\n {children}\n </li>\n );\n}\n\nListItemBase.displayName = \"ListItem\";\n","import type { ListProps } from \"./types\";\n\nimport { ListBase, ListItemBase } from \"./list-base\";\n\nexport const ListItem = ListItemBase;\n\nfunction ListRoot(props: ListProps) {\n return <ListBase {...props} />;\n}\n\nexport const List = Object.assign(ListRoot, {\n Item: ListItem,\n});\n\nListRoot.displayName = \"List\";\n","import { forwardRef } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nimport type { BlockquoteProps } from \"./types\";\nimport { typographyToneVariants } from \"./variants\";\n\nexport const BlockquoteBase = (props: BlockquoteProps) => {\n const { tone, attribution, className, children, ref, ...rest } = props;\n\n return (\n <blockquote\n ref={ref}\n data-slot=\"typography-blockquote\"\n className={cn(\n typographyToneVariants({ tone }),\n \"border-l-4 py-1 pl-4 italic\",\n className,\n )}\n {...rest}\n >\n <div className=\"space-y-2 leading-relaxed\">{children}</div>\n {attribution ? (\n <footer className=\"mt-3 text-sm not-italic\">\n <cite>{attribution}</cite>\n </footer>\n ) : null}\n </blockquote>\n );\n};\n\nBlockquoteBase.displayName = \"Blockquote\";\n","import { BlockquoteBase } from \"./blockquote-base\";\nimport type { BlockquoteProps } from \"./types\";\n\nexport const Blockquote = (props: BlockquoteProps) => {\n return <BlockquoteBase {...props} />;\n};\n\nBlockquote.displayName = \"Blockquote\";\n","import { forwardRef } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nimport type { InlineCodeProps } from \"./types\";\nimport { typographyToneVariants } from \"./variants\";\n\nexport const InlineCodeBase = (props: InlineCodeProps) => {\n const { tone, className, children, ref, ...rest } = props;\n\n return (\n <code\n ref={ref}\n data-slot=\"typography-inline-code\"\n className={cn(\n typographyToneVariants({ tone }),\n \"rounded-md border border-white/10 bg-white/6 px-1.5 py-0.5 font-mono text-[0.925em] font-normal\",\n className,\n )}\n {...rest}\n >\n {children}\n </code>\n );\n};\n\nInlineCodeBase.displayName = \"InlineCode\";\n","import { InlineCodeBase } from \"./inline-code-base\";\nimport type { InlineCodeProps } from \"./types\";\n\nexport const InlineCode = (props: InlineCodeProps) => {\n return <InlineCodeBase {...props} />;\n};\n\nInlineCode.displayName = \"InlineCode\";\n","import { forwardRef } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\nimport type { CodeBlockProps } from \"./types\";\nimport { typographyToneVariants } from \"./variants\";\n\nexport const CodeBlockBase = (props: CodeBlockProps) => {\n const { tone, language, className, children, ref, ...rest } = props;\n\n const ariaLabel = language ? `Code sample (${language})` : \"Code sample\";\n\n return (\n <pre\n ref={ref}\n data-slot=\"typography-code-block\"\n aria-label={ariaLabel}\n className={cn(\n typographyToneVariants({ tone }),\n \"overflow-x-auto rounded-xl border border-white/10 bg-slate-950/80 p-4 text-sm leading-relaxed shadow-inner shadow-slate-950/40\",\n className,\n )}\n {...rest}\n >\n <code className=\"font-mono text-[0.95em] whitespace-pre-wrap wrap-break-word\">\n {children}\n </code>\n </pre>\n );\n};\n\nCodeBlockBase.displayName = \"CodeBlock\";\n","import { CodeBlockBase } from \"./code-block-base\";\nimport type { CodeBlockProps } from \"./types\";\n\nexport const CodeBlock = (props: CodeBlockProps) => {\n return <CodeBlockBase {...props} />;\n};\n\nCodeBlock.displayName = \"CodeBlock\";\n"]}
1
+ {"version":3,"sources":["../../src/ui/typography/variants.ts","../../src/ui/typography/heading-base.tsx","../../src/ui/typography/heading.tsx","../../src/ui/typography/text-base.tsx","../../src/ui/typography/text.tsx","../../src/ui/typography/list-base.tsx","../../src/ui/typography/list.tsx","../../src/ui/typography/blockquote-base.tsx","../../src/ui/typography/blockquote.tsx","../../src/ui/typography/inline-code-base.tsx","../../src/ui/typography/inline-code.tsx","../../src/ui/typography/code-block-base.tsx","../../src/ui/typography/code-block.tsx"],"names":["jsx","tone","className","children","ref","ordered","marker","rest"],"mappings":"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","file":"typography.mjs","sourcesContent":["import { cva } from \"class-variance-authority\";\n\n/** Semantic text colors aligned with slate/cyan/violet accents used across the kit (dark-first). */\nexport const typographyToneVariants = cva(\"\", {\n variants: {\n tone: {\n default: \"text-slate-50 border-white/15\",\n muted: \"text-slate-400 border-white/15\",\n primary: \"text-cyan-300 border-cyan-300/40\",\n secondary: \"text-slate-300 border-white/15\",\n accent: \"text-violet-300 border-violet-300/40\",\n destructive: \"text-rose-400 border-rose-300/40\",\n info: \"text-sky-300 border-sky-300/40\",\n success: \"text-emerald-300 border-emerald-300/40\",\n warning: \"text-amber-300 border-amber-300/40\",\n error: \"text-red-300 border-red-300/40\",\n \"gradient-pink-violet\":\n \"bg-linear-to-r from-pink-400 to-violet-400 bg-clip-text text-transparent\",\n \"gradient-cyan-violet\":\n \"bg-linear-to-r from-cyan-400 to-violet-400 bg-clip-text text-transparent\",\n \"gradient-cyan-blue\":\n \"bg-linear-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent\",\n \"gradient-cyan-green\":\n \"bg-linear-to-r from-cyan-400 to-green-400 bg-clip-text text-transparent\",\n \"gradient-cyan-orange\":\n \"bg-linear-to-r from-cyan-400 to-orange-400 bg-clip-text text-transparent\",\n \"gradient-cyan-red\":\n \"bg-linear-to-r from-cyan-400 to-red-400 bg-clip-text text-transparent\",\n \"gradient-cyan-purple\":\n \"bg-linear-to-r from-cyan-400 to-purple-400 bg-clip-text text-transparent\",\n \"gradient-cyan-pink\":\n \"bg-linear-to-r from-cyan-400 to-pink-400 bg-clip-text text-transparent\",\n },\n },\n defaultVariants: {\n tone: \"default\",\n },\n});\n\nexport const headingLevelVariants = cva(\"scroll-m-20\", {\n variants: {\n level: {\n 1: \"text-4xl font-bold tracking-tight md:text-5xl\",\n 2: \"text-3xl font-semibold tracking-tight\",\n 3: \"text-2xl font-semibold tracking-tight\",\n 4: \"text-xl font-semibold tracking-tight\",\n 5: \"text-lg font-medium\",\n 6: \"text-base font-medium\",\n },\n },\n});\n\nexport const textSizeVariants = cva(\"\", {\n variants: {\n size: {\n sm: \"text-sm leading-relaxed\",\n base: \"text-base leading-relaxed\",\n lg: \"text-lg leading-relaxed\",\n },\n },\n defaultVariants: {\n size: \"base\",\n },\n});\n\n/** Marker style for unordered lists; ignored when `ordered` is true (decimal numbering). */\nexport const unorderedListMarkerVariants = cva(\"space-y-2 pl-5\", {\n variants: {\n marker: {\n disc: \"list-disc\",\n circle: \"[list-style-type:circle]\",\n none: \"list-none pl-0\",\n },\n },\n defaultVariants: {\n marker: \"disc\",\n },\n});\n\nexport const orderedListVariants = cva(\"list-decimal space-y-2 pl-5\");\n","import { cn } from \"../../lib/utils\";\n\nimport type { HeadingProps } from \"./types\";\nimport { headingLevelVariants, typographyToneVariants } from \"./variants\";\n\nconst HEADING_TAGS = {\n 1: \"h1\",\n 2: \"h2\",\n 3: \"h3\",\n 4: \"h4\",\n 5: \"h5\",\n 6: \"h6\",\n} as const;\n\nexport const HeadingBase = (props: HeadingProps) => {\n const {\n level,\n displayLevel,\n tone,\n bold,\n italic,\n underline,\n strikethrough,\n ref,\n className,\n children,\n ...rest\n } = props;\n\n const Tag = HEADING_TAGS[level];\n const scale = displayLevel ?? level;\n\n return (\n <Tag\n ref={ref}\n data-slot=\"typography-heading\"\n data-level={level}\n className={cn(\n typographyToneVariants({ tone }),\n headingLevelVariants({ level: scale }),\n bold && \"font-bold\",\n italic && \"italic\",\n underline && \"underline underline-offset-4\",\n strikethrough && \"line-through\",\n className,\n )}\n {...rest}\n >\n {children}\n </Tag>\n );\n};\n\nHeadingBase.displayName = \"Heading\";\n","import { HeadingBase } from \"./heading-base\";\nimport type { HeadingProps } from \"./types\";\n\nexport const Heading = (props: HeadingProps) => {\n return <HeadingBase {...props} />;\n};\n\nHeading.displayName = \"Heading\";\n","import { cn } from \"../../lib/utils\";\n\nimport type { TextProps } from \"./types\";\nimport { textSizeVariants, typographyToneVariants } from \"./variants\";\n\nexport const TextBase = (props: TextProps) => {\n const {\n as = \"p\",\n size = \"base\",\n tone,\n bold,\n italic,\n underline,\n strikethrough,\n highlight,\n className,\n children,\n ...rest\n } = props;\n\n const Component = as;\n\n return (\n <Component\n data-slot=\"typography-text\"\n className={cn(\n typographyToneVariants({ tone }),\n textSizeVariants({ size }),\n bold && \"font-semibold\",\n italic && \"italic\",\n underline && \"underline underline-offset-2\",\n strikethrough && \"line-through\",\n highlight && \"rounded bg-amber-400/15 px-0.5\",\n className,\n )}\n {...rest}\n >\n {children}\n </Component>\n );\n};\n\nTextBase.displayName = \"Text\";\n","import { TextBase } from \"./text-base\";\nimport type { TextProps } from \"./types\";\n\nexport const Text = (props: TextProps) => {\n return <TextBase {...props} />;\n};\n\nText.displayName = \"Text\";\n","import { cn } from \"../../lib/utils\";\n\nimport type { ListProps, ListItemProps } from \"./types\";\nimport {\n orderedListVariants,\n typographyToneVariants,\n unorderedListMarkerVariants,\n} from \"./variants\";\n\nexport function ListBase(props: ListProps) {\n if (\"ordered\" in props && props.ordered === true) {\n const { tone, className, children, ref, ordered, marker, ...rest } = props;\n\n void ordered;\n void marker;\n\n return (\n <ol\n ref={ref}\n data-slot=\"typography-list\"\n data-list-type=\"ordered\"\n className={cn(\n typographyToneVariants({ tone }),\n orderedListVariants(),\n className,\n )}\n {...rest}\n >\n {children}\n </ol>\n );\n }\n\n const {\n marker = \"disc\",\n tone,\n className,\n children,\n ref,\n ordered,\n ...rest\n } = props;\n\n void ordered;\n\n return (\n <ul\n ref={ref}\n data-slot=\"typography-list\"\n data-list-type=\"unordered\"\n className={cn(\n typographyToneVariants({ tone }),\n unorderedListMarkerVariants({ marker }),\n className,\n )}\n {...rest}\n >\n {children}\n </ul>\n );\n}\n\nListBase.displayName = \"List\";\n\nexport function ListItemBase(props: ListItemProps) {\n const { className, children, ref, ...rest } = props;\n\n return (\n <li\n ref={ref}\n data-slot=\"typography-list-item\"\n className={cn(\"leading-relaxed\", className)}\n {...rest}\n >\n {children}\n </li>\n );\n}\n\nListItemBase.displayName = \"ListItem\";\n","import type { ListProps } from \"./types\";\n\nimport { ListBase, ListItemBase } from \"./list-base\";\n\nexport const ListItem = ListItemBase;\n\nfunction ListRoot(props: ListProps) {\n return <ListBase {...props} />;\n}\n\nexport const List = Object.assign(ListRoot, {\n Item: ListItem,\n});\n\nListRoot.displayName = \"List\";\n","import { cn } from \"../../lib/utils\";\n\nimport type { BlockquoteProps } from \"./types\";\nimport { typographyToneVariants } from \"./variants\";\n\nexport const BlockquoteBase = (props: BlockquoteProps) => {\n const { tone, attribution, className, children, ref, ...rest } = props;\n\n return (\n <blockquote\n ref={ref}\n data-slot=\"typography-blockquote\"\n className={cn(\n typographyToneVariants({ tone }),\n \"border-l-4 py-1 pl-4 italic\",\n className,\n )}\n {...rest}\n >\n <div className=\"space-y-2 leading-relaxed\">{children}</div>\n {attribution ? (\n <footer className=\"mt-3 text-sm not-italic\">\n <cite>{attribution}</cite>\n </footer>\n ) : null}\n </blockquote>\n );\n};\n\nBlockquoteBase.displayName = \"Blockquote\";\n","import { BlockquoteBase } from \"./blockquote-base\";\nimport type { BlockquoteProps } from \"./types\";\n\nexport const Blockquote = (props: BlockquoteProps) => {\n return <BlockquoteBase {...props} />;\n};\n\nBlockquote.displayName = \"Blockquote\";\n","import { cn } from \"../../lib/utils\";\n\nimport type { InlineCodeProps } from \"./types\";\nimport { typographyToneVariants } from \"./variants\";\n\nexport const InlineCodeBase = (props: InlineCodeProps) => {\n const { tone, className, children, ref, ...rest } = props;\n\n return (\n <code\n ref={ref}\n data-slot=\"typography-inline-code\"\n className={cn(\n typographyToneVariants({ tone }),\n \"rounded-md border border-white/10 bg-white/6 px-1.5 py-0.5 font-mono text-[0.925em] font-normal\",\n className,\n )}\n {...rest}\n >\n {children}\n </code>\n );\n};\n\nInlineCodeBase.displayName = \"InlineCode\";\n","import { InlineCodeBase } from \"./inline-code-base\";\nimport type { InlineCodeProps } from \"./types\";\n\nexport const InlineCode = (props: InlineCodeProps) => {\n return <InlineCodeBase {...props} />;\n};\n\nInlineCode.displayName = \"InlineCode\";\n","import { cn } from \"../../lib/utils\";\n\nimport type { CodeBlockProps } from \"./types\";\nimport { typographyToneVariants } from \"./variants\";\n\nexport const CodeBlockBase = (props: CodeBlockProps) => {\n const { tone, language, className, children, ref, ...rest } = props;\n\n const ariaLabel = language ? `Code sample (${language})` : \"Code sample\";\n\n return (\n <pre\n ref={ref}\n data-slot=\"typography-code-block\"\n aria-label={ariaLabel}\n className={cn(\n typographyToneVariants({ tone }),\n \"overflow-x-auto rounded-xl border border-white/10 bg-slate-950/80 p-4 text-sm leading-relaxed shadow-inner shadow-slate-950/40\",\n className,\n )}\n {...rest}\n >\n <code className=\"font-mono text-[0.95em] whitespace-pre-wrap wrap-break-word\">\n {children}\n </code>\n </pre>\n );\n};\n\nCodeBlockBase.displayName = \"CodeBlock\";\n","import { CodeBlockBase } from \"./code-block-base\";\nimport type { CodeBlockProps } from \"./types\";\n\nexport const CodeBlock = (props: CodeBlockProps) => {\n return <CodeBlockBase {...props} />;\n};\n\nCodeBlock.displayName = \"CodeBlock\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zentauri-ui/zentauri-components",
3
- "version": "1.5.22",
3
+ "version": "1.5.31",
4
4
  "description": "React + Tailwind UI kit with charts, ESM/CJS builds, per-entry exports, and a zentauri-components / zentauri-ui CLI to vendor UI or hook source into your app",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -0,0 +1,3 @@
1
+ export {
2
+ useDynamicStepper,
3
+ } from "./useDynamicStepper";
@@ -0,0 +1,107 @@
1
+ import { act, renderHook } from "@testing-library/react";
2
+ import { describe, expect, it, vi } from "vitest";
3
+
4
+ import { useDynamicStepper } from "./useDynamicStepper";
5
+
6
+ describe("useDynamicStepper", () => {
7
+ it("should use internal state when uncontrolled", () => {
8
+ const { result } = renderHook(() =>
9
+ useDynamicStepper({ stepCount: 3, defaultActiveStep: 1 }),
10
+ );
11
+ expect(result.current.activeStep).toBe(1);
12
+ expect(result.current.canGoPrevious).toBe(true);
13
+ expect(result.current.canGoNext).toBe(true);
14
+ act(() => {
15
+ result.current.goNext();
16
+ });
17
+ expect(result.current.activeStep).toBe(2);
18
+ act(() => {
19
+ result.current.goPrevious();
20
+ });
21
+ expect(result.current.activeStep).toBe(1);
22
+ });
23
+
24
+ it("should clamp defaultActiveStep when uncontrolled", () => {
25
+ const { result } = renderHook(() =>
26
+ useDynamicStepper({ stepCount: 2, defaultActiveStep: 99 }),
27
+ );
28
+ expect(result.current.activeStep).toBe(1);
29
+ });
30
+
31
+ it("should not navigate past bounds", () => {
32
+ const { result } = renderHook(() =>
33
+ useDynamicStepper({ stepCount: 2, defaultActiveStep: 0 }),
34
+ );
35
+ expect(result.current.canGoPrevious).toBe(false);
36
+ act(() => {
37
+ result.current.goPrevious();
38
+ });
39
+ expect(result.current.activeStep).toBe(0);
40
+ act(() => {
41
+ result.current.goNext();
42
+ });
43
+ act(() => {
44
+ result.current.goNext();
45
+ });
46
+ expect(result.current.activeStep).toBe(1);
47
+ expect(result.current.canGoNext).toBe(false);
48
+ });
49
+
50
+ it("should respect controlled activeStep", () => {
51
+ const { result, rerender } = renderHook(
52
+ ({ step }: { step: number }) =>
53
+ useDynamicStepper({ stepCount: 3, activeStep: step }),
54
+ { initialProps: { step: 0 } },
55
+ );
56
+ expect(result.current.activeStep).toBe(0);
57
+ rerender({ step: 2 });
58
+ expect(result.current.activeStep).toBe(2);
59
+ });
60
+
61
+ it("should call onActiveStepChange when navigating uncontrolled", () => {
62
+ const onActiveStepChange = vi.fn();
63
+ const onNext = vi.fn();
64
+ const { result } = renderHook(() =>
65
+ useDynamicStepper({
66
+ stepCount: 3,
67
+ defaultActiveStep: 0,
68
+ onActiveStepChange,
69
+ onNext,
70
+ }),
71
+ );
72
+ act(() => {
73
+ result.current.goNext();
74
+ });
75
+ expect(onActiveStepChange).toHaveBeenCalledWith(1);
76
+ expect(onNext).toHaveBeenCalledWith(1);
77
+ });
78
+
79
+ it("should call onPrevious when going back", () => {
80
+ const onPrevious = vi.fn();
81
+ const { result } = renderHook(() =>
82
+ useDynamicStepper({
83
+ stepCount: 3,
84
+ defaultActiveStep: 1,
85
+ onPrevious,
86
+ }),
87
+ );
88
+ act(() => {
89
+ result.current.goPrevious();
90
+ });
91
+ expect(onPrevious).toHaveBeenCalledWith(0);
92
+ });
93
+
94
+ it("should expose safe flags when stepCount is zero", () => {
95
+ const { result } = renderHook(() =>
96
+ useDynamicStepper({ stepCount: 0, defaultActiveStep: 0 }),
97
+ );
98
+ expect(result.current.activeStep).toBe(0);
99
+ expect(result.current.canGoPrevious).toBe(false);
100
+ expect(result.current.canGoNext).toBe(false);
101
+ act(() => {
102
+ result.current.goNext();
103
+ result.current.goPrevious();
104
+ });
105
+ expect(result.current.activeStep).toBe(0);
106
+ });
107
+ });
@@ -0,0 +1,91 @@
1
+ "use client";
2
+
3
+ import { useCallback, useMemo } from "react";
4
+
5
+ import { useControllableState } from "../useControllableState/useControllableState";
6
+
7
+ import type {
8
+ UseDynamicStepperParams,
9
+ UseDynamicStepperResult,
10
+ } from "../../ui/dynamic-stepper/types";
11
+
12
+ function clampDynamicStepperIndex(index: number, stepCount: number): number {
13
+ if (stepCount <= 0) {
14
+ return 0;
15
+ }
16
+ return Math.min(Math.max(index, 0), stepCount - 1);
17
+ }
18
+
19
+ /**
20
+ * Headless multi-step index with prev/next navigation.
21
+ *
22
+ * @param params.stepCount - Number of steps (0-based count semantics via indices).
23
+ * @returns Active step, setter, navigation helpers, and boundary flags.
24
+ */
25
+ export function useDynamicStepper({
26
+ stepCount,
27
+ activeStep: activeStepProp,
28
+ defaultActiveStep = 0,
29
+ onActiveStepChange,
30
+ onPrevious,
31
+ onNext,
32
+ }: UseDynamicStepperParams): UseDynamicStepperResult {
33
+ const [storedStep, setStoredStep] = useControllableState<number>({
34
+ value: activeStepProp,
35
+ defaultValue: clampDynamicStepperIndex(defaultActiveStep, stepCount),
36
+ onChange: onActiveStepChange,
37
+ });
38
+
39
+ const activeStep = useMemo(
40
+ () => clampDynamicStepperIndex(storedStep, stepCount),
41
+ [storedStep, stepCount],
42
+ );
43
+
44
+ const canGoPrevious = stepCount > 0 && activeStep > 0;
45
+ const canGoNext = stepCount > 0 && activeStep < stepCount - 1;
46
+
47
+ const setActiveStep = useCallback(
48
+ (next: number | ((prev: number) => number)) => {
49
+ const resolved =
50
+ typeof next === "function"
51
+ ? (next as (prev: number) => number)(activeStep)
52
+ : next;
53
+ setStoredStep(clampDynamicStepperIndex(resolved, stepCount));
54
+ },
55
+ [activeStep, setStoredStep, stepCount],
56
+ );
57
+
58
+ const goPrevious = useCallback(() => {
59
+ if (!canGoPrevious) {
60
+ return;
61
+ }
62
+ const nextStep = clampDynamicStepperIndex(activeStep - 1, stepCount);
63
+ setStoredStep(nextStep);
64
+ onPrevious?.(nextStep);
65
+ }, [
66
+ activeStep,
67
+ canGoPrevious,
68
+ onPrevious,
69
+ setStoredStep,
70
+ stepCount,
71
+ ]);
72
+
73
+ const goNext = useCallback(() => {
74
+ if (!canGoNext) {
75
+ return;
76
+ }
77
+ const nextStep = clampDynamicStepperIndex(activeStep + 1, stepCount);
78
+ setStoredStep(nextStep);
79
+ onNext?.(nextStep);
80
+ }, [activeStep, canGoNext, onNext, setStoredStep, stepCount]);
81
+
82
+ return {
83
+ activeStep,
84
+ setActiveStep,
85
+ goPrevious,
86
+ goNext,
87
+ canGoPrevious,
88
+ canGoNext,
89
+ stepCount,
90
+ };
91
+ }
@@ -0,0 +1,109 @@
1
+ import { createRef } from "react";
2
+ import { render, screen } from "@testing-library/react";
3
+ import userEvent from "@testing-library/user-event";
4
+ import { describe, expect, it, vi } from "vitest";
5
+
6
+ import { DynamicStepper } from "./dynamic-stepper";
7
+
8
+ const sampleSteps = [
9
+ { id: "a", title: "One", description: "First" },
10
+ { id: "b", title: "Two", description: "Second" },
11
+ { id: "c", title: "Three", description: "Third" },
12
+ ];
13
+
14
+ describe("DynamicStepper", () => {
15
+ it("should expose displayName", () => {
16
+ expect(DynamicStepper.displayName).toBe("DynamicStepper");
17
+ });
18
+
19
+ it("should render null when steps is empty", () => {
20
+ const { container } = render(<DynamicStepper steps={[]} />);
21
+ expect(container.firstChild).toBeNull();
22
+ });
23
+
24
+ it("should stamp mapper ol and button ids with suffixes", () => {
25
+ render(<DynamicStepper steps={sampleSteps} />);
26
+ const mapper = document.querySelector('[data-slot="dynamic-stepper-mapper"]');
27
+ expect(mapper?.tagName).toBe("OL");
28
+ expect(mapper?.id.endsWith("-mapper")).toBe(true);
29
+
30
+ const prev = document.querySelector('[data-slot="dynamic-stepper-previous"]');
31
+ const next = document.querySelector('[data-slot="dynamic-stepper-next"]');
32
+ expect(prev?.id.endsWith("-previous")).toBe(true);
33
+ expect(next?.id.endsWith("-next")).toBe(true);
34
+ });
35
+
36
+ it("should navigate uncontrolled with next and previous", async () => {
37
+ const user = userEvent.setup();
38
+ render(<DynamicStepper steps={sampleSteps} defaultActiveStep={0} />);
39
+
40
+ expect(screen.getByText("One")).toBeInTheDocument();
41
+ const indicators = document.querySelectorAll(
42
+ '[data-slot="dynamic-stepper-indicator"]',
43
+ );
44
+ expect(indicators[0]?.className).toMatch(/violet/);
45
+
46
+ await user.click(screen.getByRole("button", { name: "Next" }));
47
+ expect(indicators[1]?.className).toMatch(/violet/);
48
+
49
+ await user.click(screen.getByRole("button", { name: "Previous" }));
50
+ expect(indicators[0]?.className).toMatch(/violet/);
51
+ });
52
+
53
+ it("should disable previous on first step and next on last step", () => {
54
+ render(<DynamicStepper steps={sampleSteps} defaultActiveStep={0} />);
55
+ expect(screen.getByRole("button", { name: "Previous" })).toBeDisabled();
56
+ expect(screen.getByRole("button", { name: "Next" })).not.toBeDisabled();
57
+ });
58
+
59
+ it("should respect controlled activeStep", async () => {
60
+ const user = userEvent.setup();
61
+ const onActiveStepChange = vi.fn();
62
+ const { rerender } = render(
63
+ <DynamicStepper
64
+ steps={sampleSteps}
65
+ activeStep={0}
66
+ onActiveStepChange={onActiveStepChange}
67
+ />,
68
+ );
69
+
70
+ await user.click(screen.getByRole("button", { name: "Next" }));
71
+ expect(onActiveStepChange).toHaveBeenCalledWith(1);
72
+
73
+ rerender(
74
+ <DynamicStepper
75
+ steps={sampleSteps}
76
+ activeStep={1}
77
+ onActiveStepChange={onActiveStepChange}
78
+ />,
79
+ );
80
+ const indicators = document.querySelectorAll(
81
+ '[data-slot="dynamic-stepper-indicator"]',
82
+ );
83
+ expect(indicators[1]?.className).toMatch(/violet/);
84
+ });
85
+
86
+ it("should forward ref to root", () => {
87
+ const ref = createRef<HTMLDivElement>();
88
+ render(<DynamicStepper ref={ref} steps={sampleSteps} />);
89
+ expect(ref.current?.getAttribute("data-slot")).toBe("dynamic-stepper");
90
+ });
91
+
92
+ it("should apply indicator tone props to semantic states", () => {
93
+ const { container } = render(
94
+ <DynamicStepper
95
+ steps={sampleSteps}
96
+ defaultActiveStep={1}
97
+ indicatorCompleteAppearance="sky"
98
+ indicatorCurrentAppearance="rose"
99
+ indicatorUpcomingAppearance="amber"
100
+ />,
101
+ );
102
+ const indicators = container.querySelectorAll(
103
+ '[data-slot="dynamic-stepper-indicator"]',
104
+ );
105
+ expect(indicators[0]?.className).toMatch(/sky-/);
106
+ expect(indicators[1]?.className).toMatch(/rose-/);
107
+ expect(indicators[2]?.className).toMatch(/amber-/);
108
+ });
109
+ });
@@ -0,0 +1,173 @@
1
+ "use client";
2
+
3
+ import { useId } from "react";
4
+
5
+ import { useDynamicStepper } from "../../hooks/useDynamicStepper/useDynamicStepper";
6
+ import { cn } from "../../lib/utils";
7
+ import { Button } from "../buttons/button";
8
+
9
+ import type { DynamicStepperProps } from "./types";
10
+ import {
11
+ dynamicStepperIndicatorToneClass,
12
+ dynamicStepperIndicatorVariants,
13
+ dynamicStepperItemVariants,
14
+ dynamicStepperMapperVariants,
15
+ dynamicStepperRootVariants,
16
+ } from "./variants";
17
+
18
+ export const DynamicStepper = ({
19
+ steps,
20
+ orientation = "horizontal",
21
+ buttonAppearance = "outline",
22
+ buttonSize = "md",
23
+ indicatorSize = "md",
24
+ indicatorCompleteAppearance = "emerald",
25
+ indicatorCurrentAppearance = "violet",
26
+ indicatorUpcomingAppearance = "outline",
27
+ activeStep: activeStepProp,
28
+ defaultActiveStep,
29
+ onActiveStepChange,
30
+ onPrevious,
31
+ onNext,
32
+ prevLabel = "Previous",
33
+ nextLabel = "Next",
34
+ className,
35
+ ref,
36
+ ...rest
37
+ }: DynamicStepperProps) => {
38
+ const baseId = useId();
39
+ const previousId = `${baseId}-previous`;
40
+ const nextId = `${baseId}-next`;
41
+ const mapperId = `${baseId}-mapper`;
42
+
43
+ const { activeStep, goPrevious, goNext, canGoPrevious, canGoNext } =
44
+ useDynamicStepper({
45
+ stepCount: steps.length,
46
+ activeStep: activeStepProp,
47
+ defaultActiveStep,
48
+ onActiveStepChange,
49
+ onPrevious,
50
+ onNext,
51
+ });
52
+
53
+ if (steps.length === 0) {
54
+ return null;
55
+ }
56
+
57
+ const itemOrientation =
58
+ orientation === "vertical" ? "vertical" : "horizontal";
59
+
60
+ return (
61
+ <div
62
+ ref={ref}
63
+ role="navigation"
64
+ data-slot="dynamic-stepper"
65
+ className={cn(dynamicStepperRootVariants({ orientation }), className)}
66
+ {...rest}
67
+ >
68
+ <Button
69
+ id={previousId}
70
+ data-slot="dynamic-stepper-previous"
71
+ type="button"
72
+ appearance={buttonAppearance}
73
+ size={buttonSize}
74
+ disabled={!canGoPrevious}
75
+ onClick={goPrevious}
76
+ className={
77
+ orientation === "vertical" ? "shrink-0 self-start" : "shrink-0"
78
+ }
79
+ >
80
+ {prevLabel}
81
+ </Button>
82
+
83
+ <ol
84
+ id={mapperId}
85
+ aria-label="Steps"
86
+ data-slot="dynamic-stepper-mapper"
87
+ className={dynamicStepperMapperVariants({ orientation })}
88
+ >
89
+ {steps.map((step, index) => {
90
+ const key = step.id ?? `dynamic-stepper-step-${index}`;
91
+ const isCurrent = index === activeStep;
92
+ const semanticState =
93
+ index < activeStep
94
+ ? "complete"
95
+ : isCurrent
96
+ ? "current"
97
+ : "upcoming";
98
+ const indicatorTone =
99
+ semanticState === "complete"
100
+ ? indicatorCompleteAppearance
101
+ : semanticState === "current"
102
+ ? indicatorCurrentAppearance
103
+ : indicatorUpcomingAppearance;
104
+
105
+ const isVertical = orientation === "vertical";
106
+
107
+ return (
108
+ <li
109
+ key={key}
110
+ data-slot="dynamic-stepper-item"
111
+ aria-current={isCurrent ? "step" : undefined}
112
+ className={dynamicStepperItemVariants({
113
+ orientation: itemOrientation,
114
+ })}
115
+ >
116
+ <div
117
+ data-slot="dynamic-stepper-indicator"
118
+ className={cn(
119
+ dynamicStepperIndicatorVariants({ size: indicatorSize }),
120
+ dynamicStepperIndicatorToneClass(
121
+ semanticState,
122
+ indicatorTone,
123
+ ),
124
+ )}
125
+ >
126
+ {step.indicator ?? index + 1}
127
+ </div>
128
+ <div
129
+ className={cn(
130
+ "min-w-0",
131
+ !isVertical && "flex flex-col items-center",
132
+ )}
133
+ >
134
+ {step.title != null && (
135
+ <div
136
+ className={cn(
137
+ "text-sm font-semibold text-white",
138
+ !isVertical && "mt-3",
139
+ )}
140
+ >
141
+ {step.title}
142
+ </div>
143
+ )}
144
+ {step.description != null && (
145
+ <p className="mt-1 text-xs text-slate-400">
146
+ {step.description}
147
+ </p>
148
+ )}
149
+ </div>
150
+ </li>
151
+ );
152
+ })}
153
+ </ol>
154
+
155
+ <Button
156
+ id={nextId}
157
+ data-slot="dynamic-stepper-next"
158
+ type="button"
159
+ appearance={buttonAppearance}
160
+ size={buttonSize}
161
+ disabled={!canGoNext}
162
+ onClick={goNext}
163
+ className={
164
+ orientation === "vertical" ? "shrink-0 self-start" : "shrink-0"
165
+ }
166
+ >
167
+ {nextLabel}
168
+ </Button>
169
+ </div>
170
+ );
171
+ };
172
+
173
+ DynamicStepper.displayName = "DynamicStepper";
@@ -0,0 +1,24 @@
1
+ "use client";
2
+
3
+ export { DynamicStepper } from "./dynamic-stepper";
4
+ export type {
5
+ DynamicStepperButtonAppearance,
6
+ DynamicStepperButtonSize,
7
+ DynamicStepperIndicatorSize,
8
+ DynamicStepperIndicatorToneAppearance,
9
+ DynamicStepperOrientation,
10
+ DynamicStepperProps,
11
+ DynamicStepperStep,
12
+ UseDynamicStepperParams,
13
+ UseDynamicStepperResult,
14
+ } from "./types";
15
+ export {
16
+ dynamicStepperIndicatorToneClass,
17
+ dynamicStepperIndicatorVariants,
18
+ dynamicStepperItemVariants,
19
+ dynamicStepperMapperVariants,
20
+ dynamicStepperRootVariants,
21
+ } from "./variants";
22
+ export type {
23
+ DynamicStepperIndicatorSemanticState,
24
+ } from "./variants";