@krizaka/ui 2.0.0-beta.1 → 2.0.0-beta.3

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 (210) hide show
  1. package/README.md +44 -3
  2. package/dist/alert.d.ts +2 -0
  3. package/dist/alert.js.map +1 -1
  4. package/dist/avatar.d.ts +5 -0
  5. package/dist/avatar.js.map +1 -1
  6. package/dist/badge.d.ts +12 -0
  7. package/dist/badge.js.map +1 -1
  8. package/dist/button-8La7l0V4.d.ts +83 -0
  9. package/dist/button.d.ts +19 -0
  10. package/dist/button.js.map +1 -1
  11. package/dist/card.d.ts +24 -1
  12. package/dist/card.js +1 -1
  13. package/dist/card.js.map +1 -1
  14. package/dist/checkbox.d.ts +52 -0
  15. package/dist/checkbox.js +42 -0
  16. package/dist/checkbox.js.map +1 -0
  17. package/dist/chip.d.ts +120 -0
  18. package/dist/chip.js +93 -0
  19. package/dist/chip.js.map +1 -0
  20. package/dist/chunk-3X5MVH54.js +121 -0
  21. package/dist/chunk-3X5MVH54.js.map +1 -0
  22. package/dist/{chunk-RLOXWF2G.js → chunk-5AXLA4LK.js} +1 -1
  23. package/dist/chunk-5AXLA4LK.js.map +1 -0
  24. package/dist/{chunk-CPMZS4XA.js → chunk-FJDSLNXK.js} +1 -1
  25. package/dist/chunk-FJDSLNXK.js.map +1 -0
  26. package/dist/{chunk-QRG5RYEI.js → chunk-ZUD4U22H.js} +1 -1
  27. package/dist/chunk-ZUD4U22H.js.map +1 -0
  28. package/dist/cn.d.ts +3 -0
  29. package/dist/cn.js +1 -1
  30. package/dist/command.d.ts +159 -0
  31. package/dist/command.js +111 -0
  32. package/dist/command.js.map +1 -0
  33. package/dist/confirm-button.d.ts +23 -0
  34. package/dist/confirm-button.js +85 -0
  35. package/dist/confirm-button.js.map +1 -0
  36. package/dist/countdown.d.ts +3 -0
  37. package/dist/countdown.js.map +1 -1
  38. package/dist/dialog-GQ4Nvuyf.d.ts +157 -0
  39. package/dist/dialog.d.ts +12 -131
  40. package/dist/dialog.js +27 -91
  41. package/dist/dialog.js.map +1 -1
  42. package/dist/dropdown-menu.d.ts +1 -0
  43. package/dist/dropdown-menu.js +1 -1
  44. package/dist/dropdown-menu.js.map +1 -1
  45. package/dist/empty-state.d.ts +2 -0
  46. package/dist/empty-state.js.map +1 -1
  47. package/dist/field.js +1 -1
  48. package/dist/kbd.d.ts +7 -1
  49. package/dist/kbd.js.map +1 -1
  50. package/dist/motion.css +7 -1
  51. package/dist/page-header.d.ts +2 -0
  52. package/dist/page-header.js.map +1 -1
  53. package/dist/popover.js +1 -1
  54. package/dist/progress.d.ts +92 -0
  55. package/dist/progress.js +85 -0
  56. package/dist/progress.js.map +1 -0
  57. package/dist/radio-group.d.ts +77 -0
  58. package/dist/radio-group.js +48 -0
  59. package/dist/radio-group.js.map +1 -0
  60. package/dist/skeleton.d.ts +7 -1
  61. package/dist/skeleton.js.map +1 -1
  62. package/dist/slider.d.ts +90 -0
  63. package/dist/slider.js +82 -0
  64. package/dist/slider.js.map +1 -0
  65. package/dist/spinner.d.ts +5 -0
  66. package/dist/spinner.js.map +1 -1
  67. package/dist/stat.d.ts +2 -0
  68. package/dist/stat.js.map +1 -1
  69. package/dist/switch.d.ts +76 -0
  70. package/dist/switch.js +38 -0
  71. package/dist/switch.js.map +1 -0
  72. package/dist/tabs.d.ts +86 -0
  73. package/dist/tabs.js +60 -0
  74. package/dist/tabs.js.map +1 -0
  75. package/dist/theme.d.ts +11 -60
  76. package/dist/theme.js +4 -2
  77. package/dist/theme.js.map +1 -1
  78. package/dist/toast.js +1 -1
  79. package/dist/tooltip.d.ts +3 -0
  80. package/dist/tooltip.js +1 -1
  81. package/dist/tooltip.js.map +1 -1
  82. package/package.json +146 -6
  83. package/registry/alert.json +59 -0
  84. package/registry/avatar.json +114 -0
  85. package/registry/badge.json +59 -0
  86. package/registry/button.json +115 -0
  87. package/registry/card.json +154 -0
  88. package/registry/checkbox.json +46 -0
  89. package/registry/chip.json +164 -0
  90. package/registry/cn.json +21 -0
  91. package/registry/command.json +162 -0
  92. package/registry/confirm-button.json +104 -0
  93. package/registry/countdown.json +84 -0
  94. package/registry/demos/alert.d.ts +5 -0
  95. package/registry/demos/alert.js +12 -0
  96. package/registry/demos/alert.tsx +15 -0
  97. package/registry/demos/avatar.d.ts +5 -0
  98. package/registry/demos/avatar.js +14 -0
  99. package/registry/demos/avatar.tsx +13 -0
  100. package/registry/demos/badge.d.ts +5 -0
  101. package/registry/demos/badge.js +11 -0
  102. package/registry/demos/badge.tsx +5 -0
  103. package/registry/demos/button.d.ts +5 -0
  104. package/registry/demos/button.js +11 -0
  105. package/registry/demos/button.tsx +5 -0
  106. package/registry/demos/card.d.ts +5 -0
  107. package/registry/demos/card.js +30 -0
  108. package/registry/demos/card.tsx +37 -0
  109. package/registry/demos/checkbox.d.ts +5 -0
  110. package/registry/demos/checkbox.js +11 -0
  111. package/registry/demos/checkbox.tsx +5 -0
  112. package/registry/demos/chip.d.ts +5 -0
  113. package/registry/demos/chip.js +15 -0
  114. package/registry/demos/chip.tsx +11 -0
  115. package/registry/demos/cn.d.ts +7 -0
  116. package/registry/demos/cn.js +17 -0
  117. package/registry/demos/cn.tsx +9 -0
  118. package/registry/demos/command.d.ts +5 -0
  119. package/registry/demos/command.js +32 -0
  120. package/registry/demos/command.tsx +28 -0
  121. package/registry/demos/confirm-button.d.ts +5 -0
  122. package/registry/demos/confirm-button.js +12 -0
  123. package/registry/demos/confirm-button.tsx +13 -0
  124. package/registry/demos/countdown.d.ts +5 -0
  125. package/registry/demos/countdown.js +13 -0
  126. package/registry/demos/countdown.tsx +10 -0
  127. package/registry/demos/dialog.d.ts +7 -0
  128. package/registry/demos/dialog.js +29 -0
  129. package/registry/demos/dialog.tsx +31 -0
  130. package/registry/demos/dropdown-menu.d.ts +7 -0
  131. package/registry/demos/dropdown-menu.js +36 -0
  132. package/registry/demos/dropdown-menu.tsx +27 -0
  133. package/registry/demos/empty-state.d.ts +5 -0
  134. package/registry/demos/empty-state.js +15 -0
  135. package/registry/demos/empty-state.tsx +12 -0
  136. package/registry/demos/field.d.ts +5 -0
  137. package/registry/demos/field.js +15 -0
  138. package/registry/demos/field.tsx +11 -0
  139. package/registry/demos/kbd.d.ts +5 -0
  140. package/registry/demos/kbd.js +11 -0
  141. package/registry/demos/kbd.tsx +5 -0
  142. package/registry/demos/page-header.d.ts +5 -0
  143. package/registry/demos/page-header.js +11 -0
  144. package/registry/demos/page-header.tsx +5 -0
  145. package/registry/demos/popover.d.ts +7 -0
  146. package/registry/demos/popover.js +25 -0
  147. package/registry/demos/popover.tsx +31 -0
  148. package/registry/demos/progress.d.ts +5 -0
  149. package/registry/demos/progress.js +11 -0
  150. package/registry/demos/progress.tsx +5 -0
  151. package/registry/demos/radio-group.d.ts +5 -0
  152. package/registry/demos/radio-group.js +16 -0
  153. package/registry/demos/radio-group.tsx +14 -0
  154. package/registry/demos/separator.d.ts +5 -0
  155. package/registry/demos/separator.js +15 -0
  156. package/registry/demos/separator.tsx +11 -0
  157. package/registry/demos/skeleton.d.ts +5 -0
  158. package/registry/demos/skeleton.js +20 -0
  159. package/registry/demos/skeleton.tsx +16 -0
  160. package/registry/demos/slider.d.ts +5 -0
  161. package/registry/demos/slider.js +11 -0
  162. package/registry/demos/slider.tsx +5 -0
  163. package/registry/demos/slot.d.ts +5 -0
  164. package/registry/demos/slot.js +14 -0
  165. package/registry/demos/slot.tsx +13 -0
  166. package/registry/demos/spinner.d.ts +5 -0
  167. package/registry/demos/spinner.js +11 -0
  168. package/registry/demos/spinner.tsx +5 -0
  169. package/registry/demos/stat.d.ts +5 -0
  170. package/registry/demos/stat.js +11 -0
  171. package/registry/demos/stat.tsx +5 -0
  172. package/registry/demos/switch.d.ts +5 -0
  173. package/registry/demos/switch.js +11 -0
  174. package/registry/demos/switch.tsx +5 -0
  175. package/registry/demos/tabs.d.ts +5 -0
  176. package/registry/demos/tabs.js +22 -0
  177. package/registry/demos/tabs.tsx +28 -0
  178. package/registry/demos/theme.d.ts +5 -0
  179. package/registry/demos/theme.js +11 -0
  180. package/registry/demos/theme.tsx +9 -0
  181. package/registry/demos/toast.d.ts +8 -0
  182. package/registry/demos/toast.js +29 -0
  183. package/registry/demos/toast.tsx +31 -0
  184. package/registry/demos/tooltip.d.ts +7 -0
  185. package/registry/demos/tooltip.js +15 -0
  186. package/registry/demos/tooltip.tsx +15 -0
  187. package/registry/dialog.json +218 -0
  188. package/registry/dropdown-menu.json +63 -0
  189. package/registry/empty-state.json +59 -0
  190. package/registry/field.json +66 -0
  191. package/registry/index.json +320 -0
  192. package/registry/kbd.json +38 -0
  193. package/registry/page-header.json +66 -0
  194. package/registry/popover.json +44 -0
  195. package/registry/progress.json +80 -0
  196. package/registry/radio-group.json +64 -0
  197. package/registry/separator.json +25 -0
  198. package/registry/skeleton.json +38 -0
  199. package/registry/slider.json +95 -0
  200. package/registry/slot.json +31 -0
  201. package/registry/spinner.json +45 -0
  202. package/registry/stat.json +66 -0
  203. package/registry/switch.json +53 -0
  204. package/registry/tabs.json +44 -0
  205. package/registry/theme.json +78 -0
  206. package/registry/toast.json +54 -0
  207. package/registry/tooltip.json +91 -0
  208. package/dist/chunk-CPMZS4XA.js.map +0 -1
  209. package/dist/chunk-QRG5RYEI.js.map +0 -1
  210. package/dist/chunk-RLOXWF2G.js.map +0 -1
@@ -0,0 +1,48 @@
1
+ "use client";
2
+
3
+ // src/radio-group/radio-group.tsx
4
+ import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
5
+ import { tv } from "tailwind-variants";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ var radioGroup = tv({
8
+ slots: {
9
+ root: "grid gap-2 data-[orientation=horizontal]:flex data-[orientation=horizontal]:flex-wrap",
10
+ item: "peer inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-border-strong bg-surface-1 transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 hover:border-accent disabled:cursor-not-allowed disabled:opacity-40 data-[state=checked]:border-accent aria-invalid:border-danger",
11
+ dot: "h-2.5 w-2.5 rounded-full bg-accent",
12
+ label: "flex cursor-pointer items-start gap-3 text-sm text-fg has-disabled:cursor-not-allowed has-disabled:opacity-60",
13
+ card: "relative flex min-w-0 flex-col items-start gap-1 rounded-xl border border-border-default bg-surface-1 p-3 text-left text-sm text-fg transition-colors hover:border-border-strong focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-40 data-[state=checked]:border-accent data-[state=checked]:bg-accent-soft data-[state=checked]:shadow-sm"
14
+ }
15
+ });
16
+ var s = radioGroup();
17
+ function RadioGroupRoot({ label, invalid, className, ...props }) {
18
+ return /* @__PURE__ */ jsx(
19
+ RadioGroupPrimitive.Root,
20
+ {
21
+ "aria-label": label,
22
+ "aria-invalid": invalid || void 0,
23
+ "data-invalid": invalid ? "" : void 0,
24
+ className: s.root({ className }),
25
+ ...props
26
+ }
27
+ );
28
+ }
29
+ function RadioGroupItem({ className, children, ...props }) {
30
+ const item = /* @__PURE__ */ jsx(RadioGroupPrimitive.Item, { className: s.item({ className: children ? "mt-0.5" : className }), ...props, children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: s.dot() }) });
31
+ if (!children) return item;
32
+ return /* @__PURE__ */ jsxs("label", { className: s.label({ className }), children: [
33
+ item,
34
+ /* @__PURE__ */ jsx("span", { className: "min-w-0", children })
35
+ ] });
36
+ }
37
+ function RadioGroupCard({ className, ...props }) {
38
+ return /* @__PURE__ */ jsx(RadioGroupPrimitive.Item, { className: s.card({ className }), ...props });
39
+ }
40
+ var RadioGroup = { Root: RadioGroupRoot, Item: RadioGroupItem, Card: RadioGroupCard };
41
+ export {
42
+ RadioGroup,
43
+ RadioGroupCard,
44
+ RadioGroupItem,
45
+ RadioGroupRoot,
46
+ radioGroup
47
+ };
48
+ //# sourceMappingURL=radio-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/radio-group/radio-group.tsx"],"sourcesContent":["// Client (a context). Radix RadioGroup: role=\"radiogroup\" / \"radio\", one tab stop, the arrows move and select, a\n// hidden input inside a form. Two looks: `RadioGroup.Item` (a dot and its words) and `RadioGroup.Card` (a whole card\n// is the radio: an amount, a pack, a payment method, a plan).\nimport { RadioGroup as RadioGroupPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const radioGroup = tv({\n slots: {\n root: \"grid gap-2 data-[orientation=horizontal]:flex data-[orientation=horizontal]:flex-wrap\",\n item:\n \"peer inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-border-strong bg-surface-1 transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"hover:border-accent disabled:cursor-not-allowed disabled:opacity-40 data-[state=checked]:border-accent aria-invalid:border-danger\",\n dot: \"h-2.5 w-2.5 rounded-full bg-accent\",\n label: \"flex cursor-pointer items-start gap-3 text-sm text-fg has-disabled:cursor-not-allowed has-disabled:opacity-60\",\n card:\n \"relative flex min-w-0 flex-col items-start gap-1 rounded-xl border border-border-default bg-surface-1 p-3 text-left text-sm text-fg transition-colors \" +\n \"hover:border-border-strong focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring \" +\n \"disabled:cursor-not-allowed disabled:opacity-40 data-[state=checked]:border-accent data-[state=checked]:bg-accent-soft \" +\n \"data-[state=checked]:shadow-sm\",\n },\n});\nconst s = radioGroup();\n\nexport type RadioGroupRootProps = React.ComponentProps<typeof RadioGroupPrimitive.Root> & {\n /** The group's accessible name — passed translated (or `aria-labelledby` a visible heading). */\n label?: string;\n /** Marks every radio invalid: aria-invalid (pair it with a `Field.Error`). */\n invalid?: boolean;\n};\n\n/** `value`/`defaultValue` + `onValueChange`, `orientation`, `required`, `name` for a form. */\nexport function RadioGroupRoot({ label, invalid, className, ...props }: RadioGroupRootProps) {\n return (\n <RadioGroupPrimitive.Root\n aria-label={label}\n aria-invalid={invalid || undefined}\n data-invalid={invalid ? \"\" : undefined}\n className={s.root({ className })}\n {...props}\n />\n );\n}\n\nexport type RadioGroupItemProps = Omit<React.ComponentProps<typeof RadioGroupPrimitive.Item>, \"children\"> & {\n /** The words next to the dot, clickable. Otherwise name it with `Field.Label htmlFor` or `aria-label`. */\n children?: React.ReactNode;\n};\n\n/** A radio: a dot, and its words when given. */\nexport function RadioGroupItem({ className, children, ...props }: RadioGroupItemProps) {\n const item = (\n <RadioGroupPrimitive.Item className={s.item({ className: children ? \"mt-0.5\" : className })} {...props}>\n <RadioGroupPrimitive.Indicator className={s.dot()} />\n </RadioGroupPrimitive.Item>\n );\n if (!children) return item;\n return (\n <label className={s.label({ className })}>\n {item}\n <span className=\"min-w-0\">{children}</span>\n </label>\n );\n}\n\n/** A whole card as the radio: its content is the radio's name. `data-state=\"checked\"` styles the chosen one. */\nexport function RadioGroupCard({ className, ...props }: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {\n return <RadioGroupPrimitive.Item className={s.card({ className })} {...props} />;\n}\n\n/** `RadioGroup.Root/Item/Card`. */\nexport const RadioGroup = { Root: RadioGroupRoot, Item: RadioGroupItem, Card: RadioGroupCard };\n"],"mappings":";;;AAGA,SAAS,cAAc,2BAA2B;AAElD,SAAS,UAAU;AA8Bf,cAwBA,YAxBA;AA5BG,IAAM,aAAa,GAAG;AAAA,EAC3B,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MACE;AAAA,IAGF,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MACE;AAAA,EAIJ;AACF,CAAC;AACD,IAAM,IAAI,WAAW;AAUd,SAAS,eAAe,EAAE,OAAO,SAAS,WAAW,GAAG,MAAM,GAAwB;AAC3F,SACE;AAAA,IAAC,oBAAoB;AAAA,IAApB;AAAA,MACC,cAAY;AAAA,MACZ,gBAAc,WAAW;AAAA,MACzB,gBAAc,UAAU,KAAK;AAAA,MAC7B,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC;AAAA,MAC9B,GAAG;AAAA;AAAA,EACN;AAEJ;AAQO,SAAS,eAAe,EAAE,WAAW,UAAU,GAAG,MAAM,GAAwB;AACrF,QAAM,OACJ,oBAAC,oBAAoB,MAApB,EAAyB,WAAW,EAAE,KAAK,EAAE,WAAW,WAAW,WAAW,UAAU,CAAC,GAAI,GAAG,OAC/F,8BAAC,oBAAoB,WAApB,EAA8B,WAAW,EAAE,IAAI,GAAG,GACrD;AAEF,MAAI,CAAC,SAAU,QAAO;AACtB,SACE,qBAAC,WAAM,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,GACpC;AAAA;AAAA,IACD,oBAAC,UAAK,WAAU,WAAW,UAAS;AAAA,KACtC;AAEJ;AAGO,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAA0D;AAC7G,SAAO,oBAAC,oBAAoB,MAApB,EAAyB,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO;AAChF;AAGO,IAAM,aAAa,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,MAAM,eAAe;","names":[]}
@@ -21,7 +21,13 @@ declare const skeletonVariants: tailwind_variants.TVReturnType<{
21
21
  rect: "h-24 w-full rounded-lg";
22
22
  };
23
23
  }, undefined>>;
24
- type SkeletonProps = React.ComponentProps<"span"> & VariantProps<typeof skeletonVariants>;
24
+ type SkeletonProps = React.ComponentProps<"span"> & {
25
+ /**
26
+ * text (a line) · circle (an avatar; give it a height) · rect (a media; give it a height).
27
+ * @default "text"
28
+ */
29
+ shape?: VariantProps<typeof skeletonVariants>["shape"];
30
+ };
25
31
  /** A pulsing shape the size of what is loading. Announce the wait elsewhere (aria-busy on the region, a Spinner). */
26
32
  declare function Skeleton({ shape, className, ...props }: SkeletonProps): React.JSX.Element;
27
33
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/skeleton/skeleton.tsx"],"sourcesContent":["// Server-safe. A placeholder for content on its way: decorative, so hidden from assistive technology.\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const skeletonVariants = tv({\n base: \"block bg-surface-3 motion-safe:animate-pulse\",\n variants: {\n shape: { text: \"h-3 w-full rounded-sm\", circle: \"aspect-square h-10 rounded-full\", rect: \"h-24 w-full rounded-lg\" },\n },\n defaultVariants: { shape: \"text\" },\n});\n\nexport type SkeletonProps = React.ComponentProps<\"span\"> & VariantProps<typeof skeletonVariants>;\n\n/** A pulsing shape the size of what is loading. Announce the wait elsewhere (aria-busy on the region, a Spinner). */\nexport function Skeleton({ shape, className, ...props }: SkeletonProps) {\n return <span aria-hidden data-shape={shape ?? \"text\"} className={skeletonVariants({ shape, className })} {...props} />;\n}\n"],"mappings":";AAEA,SAAS,UAA6B;AAc7B;AAZF,IAAM,mBAAmB,GAAG;AAAA,EACjC,MAAM;AAAA,EACN,UAAU;AAAA,IACR,OAAO,EAAE,MAAM,yBAAyB,QAAQ,mCAAmC,MAAM,yBAAyB;AAAA,EACpH;AAAA,EACA,iBAAiB,EAAE,OAAO,OAAO;AACnC,CAAC;AAKM,SAAS,SAAS,EAAE,OAAO,WAAW,GAAG,MAAM,GAAkB;AACtE,SAAO,oBAAC,UAAK,eAAW,MAAC,cAAY,SAAS,QAAQ,WAAW,iBAAiB,EAAE,OAAO,UAAU,CAAC,GAAI,GAAG,OAAO;AACtH;","names":[]}
1
+ {"version":3,"sources":["../src/skeleton/skeleton.tsx"],"sourcesContent":["// Server-safe. A placeholder for content on its way: decorative, so hidden from assistive technology.\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const skeletonVariants = tv({\n base: \"block bg-surface-3 motion-safe:animate-pulse\",\n variants: {\n shape: { text: \"h-3 w-full rounded-sm\", circle: \"aspect-square h-10 rounded-full\", rect: \"h-24 w-full rounded-lg\" },\n },\n defaultVariants: { shape: \"text\" },\n});\n\nexport type SkeletonProps = React.ComponentProps<\"span\"> & {\n /**\n * text (a line) · circle (an avatar; give it a height) · rect (a media; give it a height).\n * @default \"text\"\n */\n shape?: VariantProps<typeof skeletonVariants>[\"shape\"];\n};\n\n/** A pulsing shape the size of what is loading. Announce the wait elsewhere (aria-busy on the region, a Spinner). */\nexport function Skeleton({ shape, className, ...props }: SkeletonProps) {\n return <span aria-hidden data-shape={shape ?? \"text\"} className={skeletonVariants({ shape, className })} {...props} />;\n}\n"],"mappings":";AAEA,SAAS,UAA6B;AAoB7B;AAlBF,IAAM,mBAAmB,GAAG;AAAA,EACjC,MAAM;AAAA,EACN,UAAU;AAAA,IACR,OAAO,EAAE,MAAM,yBAAyB,QAAQ,mCAAmC,MAAM,yBAAyB;AAAA,EACpH;AAAA,EACA,iBAAiB,EAAE,OAAO,OAAO;AACnC,CAAC;AAWM,SAAS,SAAS,EAAE,OAAO,WAAW,GAAG,MAAM,GAAkB;AACtE,SAAO,oBAAC,UAAK,eAAW,MAAC,cAAY,SAAS,QAAQ,WAAW,iBAAiB,EAAE,OAAO,UAAU,CAAC,GAAI,GAAG,OAAO;AACtH;","names":[]}
@@ -0,0 +1,90 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import { Slider as Slider$1 } from 'radix-ui';
3
+ import * as React from 'react';
4
+
5
+ declare const slider: tailwind_variants.TVReturnType<{
6
+ [key: string]: {
7
+ [key: string]: tailwind_variants.ClassValue | {
8
+ root?: tailwind_variants.ClassValue;
9
+ header?: tailwind_variants.ClassValue;
10
+ value?: tailwind_variants.ClassValue;
11
+ control?: tailwind_variants.ClassValue;
12
+ track?: tailwind_variants.ClassValue;
13
+ range?: tailwind_variants.ClassValue;
14
+ thumb?: tailwind_variants.ClassValue;
15
+ };
16
+ };
17
+ } | {
18
+ [x: string]: {
19
+ [x: string]: tailwind_variants.ClassValue | {
20
+ root?: tailwind_variants.ClassValue;
21
+ header?: tailwind_variants.ClassValue;
22
+ value?: tailwind_variants.ClassValue;
23
+ control?: tailwind_variants.ClassValue;
24
+ track?: tailwind_variants.ClassValue;
25
+ range?: tailwind_variants.ClassValue;
26
+ thumb?: tailwind_variants.ClassValue;
27
+ };
28
+ };
29
+ } | {}, {
30
+ root: string;
31
+ header: string;
32
+ value: string;
33
+ control: string;
34
+ track: string;
35
+ range: string;
36
+ thumb: string;
37
+ }, undefined, {
38
+ [key: string]: {
39
+ [key: string]: tailwind_variants.ClassValue | {
40
+ root?: tailwind_variants.ClassValue;
41
+ header?: tailwind_variants.ClassValue;
42
+ value?: tailwind_variants.ClassValue;
43
+ control?: tailwind_variants.ClassValue;
44
+ track?: tailwind_variants.ClassValue;
45
+ range?: tailwind_variants.ClassValue;
46
+ thumb?: tailwind_variants.ClassValue;
47
+ };
48
+ };
49
+ } | {}, {
50
+ root: string;
51
+ header: string;
52
+ value: string;
53
+ control: string;
54
+ track: string;
55
+ range: string;
56
+ thumb: string;
57
+ }, tailwind_variants.TVReturnTypeLike<unknown, {
58
+ root: string;
59
+ header: string;
60
+ value: string;
61
+ control: string;
62
+ track: string;
63
+ range: string;
64
+ thumb: string;
65
+ }>>;
66
+ type SliderValue = number | [number, number];
67
+ type SliderProps<V extends SliderValue = number> = Omit<React.ComponentProps<typeof Slider$1.Root>, "value" | "defaultValue" | "onValueChange" | "onValueCommit" | "children"> & {
68
+ /** One number (a thumb) or two (a range). Controlled with `onValueChange`. */
69
+ value?: V;
70
+ /** The value at first, uncontrolled: one number, or two for a range. */
71
+ defaultValue?: V;
72
+ /** Called on every move, with one number or two. */
73
+ onValueChange?: (value: V) => void;
74
+ /** Called once the drag or the key press ends. */
75
+ onValueCommit?: (value: V) => void;
76
+ /** The accessible name — of the thumb, or of both thumbs of a range — passed translated. */
77
+ label: string;
78
+ /** For a range: each thumb's own name (["Minimum", "Maximum"]), passed translated. */
79
+ thumbLabels?: [string, string];
80
+ /** The value as words (aria-valuetext) and as shown: "1.5×", "−12 %", "3 min". */
81
+ formatValue?: (value: number) => string;
82
+ /** Shows the label and the value above the track. Without it, `label` only names the thumb. */
83
+ showLabel?: boolean;
84
+ /** Fills from this value instead of the minimum (a ±range from 0: brightness, balance). One thumb only. */
85
+ origin?: number;
86
+ };
87
+ /** A slider on one value or a range: `value`/`defaultValue` + `onValueChange`, `min`, `max`, `step`. */
88
+ declare function Slider<V extends SliderValue = number>({ value, defaultValue, onValueChange, onValueCommit, label, thumbLabels, formatValue, showLabel, origin, min, max, className, ...props }: SliderProps<V>): React.JSX.Element;
89
+
90
+ export { Slider, type SliderProps, type SliderValue, slider };
package/dist/slider.js ADDED
@@ -0,0 +1,82 @@
1
+ "use client";
2
+
3
+ // src/slider/slider.tsx
4
+ import { Slider as SliderPrimitive } from "radix-ui";
5
+ import * as React from "react";
6
+ import { tv } from "tailwind-variants";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ var slider = tv({
9
+ slots: {
10
+ root: "flex flex-col gap-2",
11
+ header: "flex items-baseline justify-between gap-3 text-xs font-semibold text-fg-secondary",
12
+ value: "font-mono text-[11px] tabular-nums text-fg-secondary",
13
+ control: "relative flex h-6 w-full touch-none select-none items-center data-disabled:cursor-not-allowed data-disabled:opacity-40",
14
+ track: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-surface-3",
15
+ range: "absolute h-full rounded-full bg-linear-to-r from-accent to-accent-2",
16
+ thumb: "block h-5 w-5 cursor-grab rounded-full border border-border-strong bg-fg-on-media shadow-md transition-[box-shadow] focus-visible:outline-hidden focus-visible:ring-4 focus-visible:ring-ring/50 active:cursor-grabbing"
17
+ }
18
+ });
19
+ var toArray = (v) => v === void 0 ? void 0 : typeof v === "number" ? [v] : v;
20
+ function Slider({
21
+ value,
22
+ defaultValue,
23
+ onValueChange,
24
+ onValueCommit,
25
+ label,
26
+ thumbLabels,
27
+ formatValue = String,
28
+ showLabel,
29
+ origin,
30
+ min = 0,
31
+ max = 100,
32
+ className,
33
+ ...props
34
+ }) {
35
+ const s = slider();
36
+ const range = Array.isArray(value ?? defaultValue);
37
+ const [inner, setInner] = React.useState(() => toArray(defaultValue) ?? [min]);
38
+ const current = toArray(value) ?? inner;
39
+ const out = (next) => range ? next : next[0];
40
+ const pct = (v) => (v - min) / (max - min || 1) * 100;
41
+ const fill = origin !== void 0 && !range ? { left: `${Math.min(pct(origin), pct(current[0]))}%`, right: `${100 - Math.max(pct(origin), pct(current[0]))}%` } : void 0;
42
+ const id = React.useId();
43
+ return /* @__PURE__ */ jsxs("div", { className: s.root({ className }), "data-range": range ? "" : void 0, children: [
44
+ showLabel && /* @__PURE__ */ jsxs("div", { className: s.header(), children: [
45
+ /* @__PURE__ */ jsx("span", { id: `${id}-label`, children: label }),
46
+ /* @__PURE__ */ jsx("span", { className: s.value(), "aria-hidden": true, children: current.map(formatValue).join(" \u2013 ") })
47
+ ] }),
48
+ /* @__PURE__ */ jsxs(
49
+ SliderPrimitive.Root,
50
+ {
51
+ min,
52
+ max,
53
+ value: current,
54
+ onValueChange: (next) => {
55
+ if (value === void 0) setInner(next);
56
+ onValueChange?.(out(next));
57
+ },
58
+ onValueCommit: onValueCommit && ((next) => onValueCommit(out(next))),
59
+ className: s.control(),
60
+ ...props,
61
+ children: [
62
+ /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: s.track(), children: fill ? /* @__PURE__ */ jsx("span", { "data-origin": "", className: s.range(), style: fill }) : /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: s.range() }) }),
63
+ current.map((v, i) => /* @__PURE__ */ jsx(
64
+ SliderPrimitive.Thumb,
65
+ {
66
+ "aria-label": range ? thumbLabels?.[i] ?? label : showLabel ? void 0 : label,
67
+ "aria-labelledby": !range && showLabel ? `${id}-label` : void 0,
68
+ "aria-valuetext": formatValue(v),
69
+ className: s.thumb()
70
+ },
71
+ i
72
+ ))
73
+ ]
74
+ }
75
+ )
76
+ ] });
77
+ }
78
+ export {
79
+ Slider,
80
+ slider
81
+ };
82
+ //# sourceMappingURL=slider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/slider/slider.tsx"],"sourcesContent":["// Client. Radix Slider: role=\"slider\" on each thumb, arrows / Page Up / Page Down / Home / End, a range with two\n// thumbs. The words arrive as props: `label` names the thumb(s), `formatValue` gives the aria-valuetext and the value\n// shown next to a visible label.\nimport { Slider as SliderPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const slider = tv({\n slots: {\n root: \"flex flex-col gap-2\",\n header: \"flex items-baseline justify-between gap-3 text-xs font-semibold text-fg-secondary\",\n value: \"font-mono text-[11px] tabular-nums text-fg-secondary\",\n control:\n \"relative flex h-6 w-full touch-none select-none items-center data-disabled:cursor-not-allowed data-disabled:opacity-40\",\n track: \"relative h-1.5 w-full grow overflow-hidden rounded-full bg-surface-3\",\n range: \"absolute h-full rounded-full bg-linear-to-r from-accent to-accent-2\",\n thumb:\n \"block h-5 w-5 cursor-grab rounded-full border border-border-strong bg-fg-on-media shadow-md transition-[box-shadow] \" +\n \"focus-visible:outline-hidden focus-visible:ring-4 focus-visible:ring-ring/50 active:cursor-grabbing\",\n },\n});\n\nexport type SliderValue = number | [number, number];\n\nexport type SliderProps<V extends SliderValue = number> = Omit<\n React.ComponentProps<typeof SliderPrimitive.Root>,\n \"value\" | \"defaultValue\" | \"onValueChange\" | \"onValueCommit\" | \"children\"\n> & {\n /** One number (a thumb) or two (a range). Controlled with `onValueChange`. */\n value?: V;\n /** The value at first, uncontrolled: one number, or two for a range. */\n defaultValue?: V;\n /** Called on every move, with one number or two. */\n onValueChange?: (value: V) => void;\n /** Called once the drag or the key press ends. */\n onValueCommit?: (value: V) => void;\n /** The accessible name — of the thumb, or of both thumbs of a range — passed translated. */\n label: string;\n /** For a range: each thumb's own name ([\"Minimum\", \"Maximum\"]), passed translated. */\n thumbLabels?: [string, string];\n /** The value as words (aria-valuetext) and as shown: \"1.5×\", \"−12 %\", \"3 min\". */\n formatValue?: (value: number) => string;\n /** Shows the label and the value above the track. Without it, `label` only names the thumb. */\n showLabel?: boolean;\n /** Fills from this value instead of the minimum (a ±range from 0: brightness, balance). One thumb only. */\n origin?: number;\n};\n\nconst toArray = (v: SliderValue | undefined) => (v === undefined ? undefined : typeof v === \"number\" ? [v] : v);\n\n/** A slider on one value or a range: `value`/`defaultValue` + `onValueChange`, `min`, `max`, `step`. */\nexport function Slider<V extends SliderValue = number>({\n value,\n defaultValue,\n onValueChange,\n onValueCommit,\n label,\n thumbLabels,\n formatValue = String,\n showLabel,\n origin,\n min = 0,\n max = 100,\n className,\n ...props\n}: SliderProps<V>) {\n const s = slider();\n const range = Array.isArray(value ?? defaultValue);\n const [inner, setInner] = React.useState(() => toArray(defaultValue) ?? [min]);\n const current = toArray(value) ?? inner;\n const out = (next: number[]) => (range ? next : next[0]) as V;\n const pct = (v: number) => ((v - min) / (max - min || 1)) * 100;\n const fill =\n origin !== undefined && !range\n ? { left: `${Math.min(pct(origin), pct(current[0]))}%`, right: `${100 - Math.max(pct(origin), pct(current[0]))}%` }\n : undefined;\n const id = React.useId();\n return (\n <div className={s.root({ className })} data-range={range ? \"\" : undefined}>\n {showLabel && (\n <div className={s.header()}>\n <span id={`${id}-label`}>{label}</span>\n <span className={s.value()} aria-hidden>\n {current.map(formatValue).join(\" – \")}\n </span>\n </div>\n )}\n <SliderPrimitive.Root\n min={min}\n max={max}\n value={current}\n onValueChange={(next) => {\n if (value === undefined) setInner(next);\n onValueChange?.(out(next));\n }}\n onValueCommit={onValueCommit && ((next) => onValueCommit(out(next)))}\n className={s.control()}\n {...props}\n >\n <SliderPrimitive.Track className={s.track()}>\n {fill ? <span data-origin=\"\" className={s.range()} style={fill} /> : <SliderPrimitive.Range className={s.range()} />}\n </SliderPrimitive.Track>\n {current.map((v, i) => (\n <SliderPrimitive.Thumb\n key={i}\n aria-label={range ? (thumbLabels?.[i] ?? label) : showLabel ? undefined : label}\n aria-labelledby={!range && showLabel ? `${id}-label` : undefined}\n aria-valuetext={formatValue(v)}\n className={s.thumb()}\n />\n ))}\n </SliderPrimitive.Root>\n </div>\n );\n}\n"],"mappings":";;;AAGA,SAAS,UAAU,uBAAuB;AAC1C,YAAY,WAAW;AACvB,SAAS,UAAU;AA2EX,SACE,KADF;AAzED,IAAM,SAAS,GAAG;AAAA,EACvB,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SACE;AAAA,IACF,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OACE;AAAA,EAEJ;AACF,CAAC;AA4BD,IAAM,UAAU,CAAC,MAAgC,MAAM,SAAY,SAAY,OAAO,MAAM,WAAW,CAAC,CAAC,IAAI;AAGtG,SAAS,OAAuC;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN,MAAM;AAAA,EACN;AAAA,EACA,GAAG;AACL,GAAmB;AACjB,QAAM,IAAI,OAAO;AACjB,QAAM,QAAQ,MAAM,QAAQ,SAAS,YAAY;AACjD,QAAM,CAAC,OAAO,QAAQ,IAAU,eAAS,MAAM,QAAQ,YAAY,KAAK,CAAC,GAAG,CAAC;AAC7E,QAAM,UAAU,QAAQ,KAAK,KAAK;AAClC,QAAM,MAAM,CAAC,SAAoB,QAAQ,OAAO,KAAK,CAAC;AACtD,QAAM,MAAM,CAAC,OAAgB,IAAI,QAAQ,MAAM,OAAO,KAAM;AAC5D,QAAM,OACJ,WAAW,UAAa,CAAC,QACrB,EAAE,MAAM,GAAG,KAAK,IAAI,IAAI,MAAM,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,IAChH;AACN,QAAM,KAAW,YAAM;AACvB,SACE,qBAAC,SAAI,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,cAAY,QAAQ,KAAK,QAC7D;AAAA,iBACC,qBAAC,SAAI,WAAW,EAAE,OAAO,GACvB;AAAA,0BAAC,UAAK,IAAI,GAAG,EAAE,UAAW,iBAAM;AAAA,MAChC,oBAAC,UAAK,WAAW,EAAE,MAAM,GAAG,eAAW,MACpC,kBAAQ,IAAI,WAAW,EAAE,KAAK,UAAK,GACtC;AAAA,OACF;AAAA,IAEF;AAAA,MAAC,gBAAgB;AAAA,MAAhB;AAAA,QACC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,eAAe,CAAC,SAAS;AACvB,cAAI,UAAU,OAAW,UAAS,IAAI;AACtC,0BAAgB,IAAI,IAAI,CAAC;AAAA,QAC3B;AAAA,QACA,eAAe,kBAAkB,CAAC,SAAS,cAAc,IAAI,IAAI,CAAC;AAAA,QAClE,WAAW,EAAE,QAAQ;AAAA,QACpB,GAAG;AAAA,QAEJ;AAAA,8BAAC,gBAAgB,OAAhB,EAAsB,WAAW,EAAE,MAAM,GACvC,iBAAO,oBAAC,UAAK,eAAY,IAAG,WAAW,EAAE,MAAM,GAAG,OAAO,MAAM,IAAK,oBAAC,gBAAgB,OAAhB,EAAsB,WAAW,EAAE,MAAM,GAAG,GACpH;AAAA,UACC,QAAQ,IAAI,CAAC,GAAG,MACf;AAAA,YAAC,gBAAgB;AAAA,YAAhB;AAAA,cAEC,cAAY,QAAS,cAAc,CAAC,KAAK,QAAS,YAAY,SAAY;AAAA,cAC1E,mBAAiB,CAAC,SAAS,YAAY,GAAG,EAAE,WAAW;AAAA,cACvD,kBAAgB,YAAY,CAAC;AAAA,cAC7B,WAAW,EAAE,MAAM;AAAA;AAAA,YAJd;AAAA,UAKP,CACD;AAAA;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;","names":[]}
package/dist/spinner.d.ts CHANGED
@@ -22,6 +22,11 @@ declare const spinnerVariants: tailwind_variants.TVReturnType<{
22
22
  };
23
23
  }, undefined>>;
24
24
  type SpinnerProps = Omit<React.ComponentProps<"svg">, "children"> & VariantProps<typeof spinnerVariants> & {
25
+ /**
26
+ * sm · md · lg.
27
+ * @default "md"
28
+ */
29
+ size?: VariantProps<typeof spinnerVariants>["size"];
25
30
  /** The accessible name of the wait, e.g. "Loading" — passed translated. */
26
31
  label: string;
27
32
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/spinner/spinner.tsx"],"sourcesContent":["// Server-safe. An indeterminate wait: an SVG ring, announced as a status with its `label`.\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const spinnerVariants = tv({\n base: \"shrink-0 text-accent motion-safe:animate-spin\",\n variants: { size: { sm: \"h-4 w-4\", md: \"h-6 w-6\", lg: \"h-10 w-10\" } },\n defaultVariants: { size: \"md\" },\n});\n\nexport type SpinnerProps = Omit<React.ComponentProps<\"svg\">, \"children\"> &\n VariantProps<typeof spinnerVariants> & {\n /** The accessible name of the wait, e.g. \"Loading\" — passed translated. */\n label: string;\n };\n\n/** A turning ring with `role=\"status\"` (it stops turning under prefers-reduced-motion). */\nexport function Spinner({ label, size, className, ...props }: SpinnerProps) {\n return (\n <svg\n role=\"status\"\n aria-label={label}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n data-size={size ?? \"md\"}\n className={spinnerVariants({ size, className })}\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" strokeOpacity=\"0.2\" strokeWidth=\"3\" />\n <path d=\"M21 12a9 9 0 0 0-9-9\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n"],"mappings":";AAEA,SAAS,UAA6B;AAiBlC,SASE,KATF;AAfG,IAAM,kBAAkB,GAAG;AAAA,EAChC,MAAM;AAAA,EACN,UAAU,EAAE,MAAM,EAAE,IAAI,WAAW,IAAI,WAAW,IAAI,YAAY,EAAE;AAAA,EACpE,iBAAiB,EAAE,MAAM,KAAK;AAChC,CAAC;AASM,SAAS,QAAQ,EAAE,OAAO,MAAM,WAAW,GAAG,MAAM,GAAiB;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY;AAAA,MACZ,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,aAAW,QAAQ;AAAA,MACnB,WAAW,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAAA,MAC7C,GAAG;AAAA,MAEJ;AAAA,4BAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI,QAAO,gBAAe,eAAc,OAAM,aAAY,KAAI;AAAA,QACxF,oBAAC,UAAK,GAAE,wBAAuB,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ;AAAA;AAAA;AAAA,EAC7F;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../src/spinner/spinner.tsx"],"sourcesContent":["// Server-safe. An indeterminate wait: an SVG ring, announced as a status with its `label`.\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const spinnerVariants = tv({\n base: \"shrink-0 text-accent motion-safe:animate-spin\",\n variants: { size: { sm: \"h-4 w-4\", md: \"h-6 w-6\", lg: \"h-10 w-10\" } },\n defaultVariants: { size: \"md\" },\n});\n\nexport type SpinnerProps = Omit<React.ComponentProps<\"svg\">, \"children\"> &\n VariantProps<typeof spinnerVariants> & {\n /**\n * sm · md · lg.\n * @default \"md\"\n */\n size?: VariantProps<typeof spinnerVariants>[\"size\"];\n /** The accessible name of the wait, e.g. \"Loading\" — passed translated. */\n label: string;\n };\n\n/** A turning ring with `role=\"status\"` (it stops turning under prefers-reduced-motion). */\nexport function Spinner({ label, size, className, ...props }: SpinnerProps) {\n return (\n <svg\n role=\"status\"\n aria-label={label}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n data-size={size ?? \"md\"}\n className={spinnerVariants({ size, className })}\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" strokeOpacity=\"0.2\" strokeWidth=\"3\" />\n <path d=\"M21 12a9 9 0 0 0-9-9\" stroke=\"currentColor\" strokeWidth=\"3\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n"],"mappings":";AAEA,SAAS,UAA6B;AAsBlC,SASE,KATF;AApBG,IAAM,kBAAkB,GAAG;AAAA,EAChC,MAAM;AAAA,EACN,UAAU,EAAE,MAAM,EAAE,IAAI,WAAW,IAAI,WAAW,IAAI,YAAY,EAAE;AAAA,EACpE,iBAAiB,EAAE,MAAM,KAAK;AAChC,CAAC;AAcM,SAAS,QAAQ,EAAE,OAAO,MAAM,WAAW,GAAG,MAAM,GAAiB;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY;AAAA,MACZ,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,aAAW,QAAQ;AAAA,MACnB,WAAW,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAAA,MAC7C,GAAG;AAAA,MAEJ;AAAA,4BAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI,QAAO,gBAAe,eAAc,OAAM,aAAY,KAAI;AAAA,QACxF,oBAAC,UAAK,GAAE,wBAAuB,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ;AAAA;AAAA;AAAA,EAC7F;AAEJ;","names":[]}
package/dist/stat.d.ts CHANGED
@@ -61,7 +61,9 @@ declare const stat: tailwind_variants.TVReturnType<{
61
61
  }>>;
62
62
  type StatTrend = "up" | "down" | "flat";
63
63
  type StatProps = Omit<React.ComponentProps<"div">, "children"> & {
64
+ /** What the figure is ("Revenue"), above it. */
64
65
  label: React.ReactNode;
66
+ /** The figure, formatted by the app, in tabular digits. */
65
67
  value: React.ReactNode;
66
68
  /** A line under the value: the period, the comparison. */
67
69
  hint?: React.ReactNode;
package/dist/stat.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stat/stat.tsx"],"sourcesContent":["// Server-safe. A key figure: a label, the value in tabular digits, a hint, a trend. Every word is a prop.\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const stat = tv({\n slots: {\n root: \"flex min-w-0 flex-col gap-1\",\n label: \"text-xs font-semibold uppercase tracking-wider text-fg-secondary\",\n value: \"font-display text-2xl font-black tabular-nums text-fg\",\n meta: \"flex flex-wrap items-center gap-x-2 gap-y-1 text-xs\",\n // The status tokens are too light for small text on a light surface: the words stay a text role, the arrow carries\n // the direction's colour.\n trend: \"inline-flex items-center gap-1 font-semibold text-fg [&>svg]:h-3.5 [&>svg]:w-3.5 [&>svg]:shrink-0\",\n hint: \"text-fg-secondary\",\n },\n variants: {\n trend: {\n up: { trend: \"[&>svg]:text-success\" },\n down: { trend: \"[&>svg]:text-danger\" },\n flat: { trend: \"[&>svg]:text-fg-secondary\" },\n },\n },\n});\n\nexport type StatTrend = \"up\" | \"down\" | \"flat\";\n\nconst ARROW: Record<StatTrend, string> = { up: \"M7 17 17 7M8 7h9v9\", down: \"M7 7l10 10M17 8v9H8\", flat: \"M5 12h14M13 6l6 6-6 6\" };\n\nexport type StatProps = Omit<React.ComponentProps<\"div\">, \"children\"> & {\n label: React.ReactNode;\n value: React.ReactNode;\n /** A line under the value: the period, the comparison. */\n hint?: React.ReactNode;\n /** The direction of the change; its arrow is decorative. */\n trend?: StatTrend;\n /** The change, in words, as read and shown (e.g. \"+12 % vs last week\") — the arrow alone says nothing. */\n trendLabel?: React.ReactNode;\n};\n\nexport function Stat({ label, value, hint, trend, trendLabel, className, ...props }: StatProps) {\n const s = stat({ trend });\n return (\n <div data-trend={trend} className={s.root({ className })} {...props}>\n <p className={s.label()}>{label}</p>\n <p className={s.value()}>{value}</p>\n {(trendLabel || hint) && (\n <p className={s.meta()}>\n {trend && trendLabel && (\n <span className={s.trend()}>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d={ARROW[trend]} />\n </svg>\n {trendLabel}\n </span>\n )}\n {hint && <span className={s.hint()}>{hint}</span>}\n </p>\n )}\n </div>\n );\n}\n"],"mappings":";AAEA,SAAS,UAAU;AAyCb,cAKM,YALN;AAvCC,IAAM,OAAO,GAAG;AAAA,EACrB,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA;AAAA;AAAA,IAGN,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,MACL,IAAI,EAAE,OAAO,uBAAuB;AAAA,MACpC,MAAM,EAAE,OAAO,sBAAsB;AAAA,MACrC,MAAM,EAAE,OAAO,4BAA4B;AAAA,IAC7C;AAAA,EACF;AACF,CAAC;AAID,IAAM,QAAmC,EAAE,IAAI,sBAAsB,MAAM,uBAAuB,MAAM,wBAAwB;AAazH,SAAS,KAAK,EAAE,OAAO,OAAO,MAAM,OAAO,YAAY,WAAW,GAAG,MAAM,GAAc;AAC9F,QAAM,IAAI,KAAK,EAAE,MAAM,CAAC;AACxB,SACE,qBAAC,SAAI,cAAY,OAAO,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OAC5D;AAAA,wBAAC,OAAE,WAAW,EAAE,MAAM,GAAI,iBAAM;AAAA,IAChC,oBAAC,OAAE,WAAW,EAAE,MAAM,GAAI,iBAAM;AAAA,KAC9B,cAAc,SACd,qBAAC,OAAE,WAAW,EAAE,KAAK,GAClB;AAAA,eAAS,cACR,qBAAC,UAAK,WAAW,EAAE,MAAM,GACvB;AAAA,4BAAC,SAAI,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,OAAM,eAAc,SAAQ,gBAAe,SAAQ,eAAW,MACnI,8BAAC,UAAK,GAAG,MAAM,KAAK,GAAG,GACzB;AAAA,QACC;AAAA,SACH;AAAA,MAED,QAAQ,oBAAC,UAAK,WAAW,EAAE,KAAK,GAAI,gBAAK;AAAA,OAC5C;AAAA,KAEJ;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../src/stat/stat.tsx"],"sourcesContent":["// Server-safe. A key figure: a label, the value in tabular digits, a hint, a trend. Every word is a prop.\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const stat = tv({\n slots: {\n root: \"flex min-w-0 flex-col gap-1\",\n label: \"text-xs font-semibold uppercase tracking-wider text-fg-secondary\",\n value: \"font-display text-2xl font-black tabular-nums text-fg\",\n meta: \"flex flex-wrap items-center gap-x-2 gap-y-1 text-xs\",\n // The status tokens are too light for small text on a light surface: the words stay a text role, the arrow carries\n // the direction's colour.\n trend: \"inline-flex items-center gap-1 font-semibold text-fg [&>svg]:h-3.5 [&>svg]:w-3.5 [&>svg]:shrink-0\",\n hint: \"text-fg-secondary\",\n },\n variants: {\n trend: {\n up: { trend: \"[&>svg]:text-success\" },\n down: { trend: \"[&>svg]:text-danger\" },\n flat: { trend: \"[&>svg]:text-fg-secondary\" },\n },\n },\n});\n\nexport type StatTrend = \"up\" | \"down\" | \"flat\";\n\nconst ARROW: Record<StatTrend, string> = { up: \"M7 17 17 7M8 7h9v9\", down: \"M7 7l10 10M17 8v9H8\", flat: \"M5 12h14M13 6l6 6-6 6\" };\n\nexport type StatProps = Omit<React.ComponentProps<\"div\">, \"children\"> & {\n /** What the figure is (\"Revenue\"), above it. */\n label: React.ReactNode;\n /** The figure, formatted by the app, in tabular digits. */\n value: React.ReactNode;\n /** A line under the value: the period, the comparison. */\n hint?: React.ReactNode;\n /** The direction of the change; its arrow is decorative. */\n trend?: StatTrend;\n /** The change, in words, as read and shown (e.g. \"+12 % vs last week\") — the arrow alone says nothing. */\n trendLabel?: React.ReactNode;\n};\n\nexport function Stat({ label, value, hint, trend, trendLabel, className, ...props }: StatProps) {\n const s = stat({ trend });\n return (\n <div data-trend={trend} className={s.root({ className })} {...props}>\n <p className={s.label()}>{label}</p>\n <p className={s.value()}>{value}</p>\n {(trendLabel || hint) && (\n <p className={s.meta()}>\n {trend && trendLabel && (\n <span className={s.trend()}>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d={ARROW[trend]} />\n </svg>\n {trendLabel}\n </span>\n )}\n {hint && <span className={s.hint()}>{hint}</span>}\n </p>\n )}\n </div>\n );\n}\n"],"mappings":";AAEA,SAAS,UAAU;AA2Cb,cAKM,YALN;AAzCC,IAAM,OAAO,GAAG;AAAA,EACrB,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA;AAAA;AAAA,IAGN,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,MACL,IAAI,EAAE,OAAO,uBAAuB;AAAA,MACpC,MAAM,EAAE,OAAO,sBAAsB;AAAA,MACrC,MAAM,EAAE,OAAO,4BAA4B;AAAA,IAC7C;AAAA,EACF;AACF,CAAC;AAID,IAAM,QAAmC,EAAE,IAAI,sBAAsB,MAAM,uBAAuB,MAAM,wBAAwB;AAezH,SAAS,KAAK,EAAE,OAAO,OAAO,MAAM,OAAO,YAAY,WAAW,GAAG,MAAM,GAAc;AAC9F,QAAM,IAAI,KAAK,EAAE,MAAM,CAAC;AACxB,SACE,qBAAC,SAAI,cAAY,OAAO,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OAC5D;AAAA,wBAAC,OAAE,WAAW,EAAE,MAAM,GAAI,iBAAM;AAAA,IAChC,oBAAC,OAAE,WAAW,EAAE,MAAM,GAAI,iBAAM;AAAA,KAC9B,cAAc,SACd,qBAAC,OAAE,WAAW,EAAE,KAAK,GAClB;AAAA,eAAS,cACR,qBAAC,UAAK,WAAW,EAAE,MAAM,GACvB;AAAA,4BAAC,SAAI,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,OAAM,eAAc,SAAQ,gBAAe,SAAQ,eAAW,MACnI,8BAAC,UAAK,GAAG,MAAM,KAAK,GAAG,GACzB;AAAA,QACC;AAAA,SACH;AAAA,MAED,QAAQ,oBAAC,UAAK,WAAW,EAAE,KAAK,GAAI,gBAAK;AAAA,OAC5C;AAAA,KAEJ;AAEJ;","names":[]}
@@ -0,0 +1,76 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import { VariantProps } from 'tailwind-variants';
3
+ import { Switch as Switch$1 } from 'radix-ui';
4
+ import * as React from 'react';
5
+
6
+ declare const switchVariants: tailwind_variants.TVReturnType<{
7
+ size: {
8
+ sm: {
9
+ root: string;
10
+ thumb: string;
11
+ };
12
+ md: {
13
+ root: string;
14
+ thumb: string;
15
+ };
16
+ };
17
+ }, {
18
+ root: string;
19
+ thumb: string;
20
+ }, undefined, {
21
+ size: {
22
+ sm: {
23
+ root: string;
24
+ thumb: string;
25
+ };
26
+ md: {
27
+ root: string;
28
+ thumb: string;
29
+ };
30
+ };
31
+ }, {
32
+ root: string;
33
+ thumb: string;
34
+ }, tailwind_variants.TVReturnTypeLike<{
35
+ size: {
36
+ sm: {
37
+ root: string;
38
+ thumb: string;
39
+ };
40
+ md: {
41
+ root: string;
42
+ thumb: string;
43
+ };
44
+ };
45
+ }, {
46
+ root: string;
47
+ thumb: string;
48
+ }>>;
49
+ type SwitchVariants = VariantProps<typeof switchVariants>;
50
+ type Named = {
51
+ /** The accessible name — required when no visible label names it, passed translated. */
52
+ label: string;
53
+ }
54
+ /** Named by a visible `<label htmlFor={id}>` (e.g. `Field.Label`). */
55
+ | {
56
+ label?: undefined;
57
+ id: string;
58
+ }
59
+ /** Named by another element. */
60
+ | {
61
+ label?: undefined;
62
+ "aria-labelledby": string;
63
+ };
64
+ type SwitchProps = Omit<React.ComponentProps<typeof Switch$1.Root>, "children"> & SwitchVariants & Named & {
65
+ /**
66
+ * sm · md.
67
+ * @default "md"
68
+ */
69
+ size?: SwitchVariants["size"];
70
+ /** Marks it invalid: aria-invalid and data-invalid. */
71
+ invalid?: boolean;
72
+ };
73
+ /** An on/off switch: `checked`/`defaultChecked` + `onCheckedChange`. */
74
+ declare function Switch({ label, size, invalid, className, ...props }: SwitchProps): React.JSX.Element;
75
+
76
+ export { Switch, type SwitchProps, type SwitchVariants, switchVariants };
package/dist/switch.js ADDED
@@ -0,0 +1,38 @@
1
+ "use client";
2
+
3
+ // src/switch/switch.tsx
4
+ import { Switch as SwitchPrimitive } from "radix-ui";
5
+ import { tv } from "tailwind-variants";
6
+ import { jsx } from "react/jsx-runtime";
7
+ var switchVariants = tv({
8
+ slots: {
9
+ root: "peer relative inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent bg-fg-muted transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 disabled:cursor-not-allowed disabled:opacity-40 data-[state=checked]:bg-accent aria-invalid:border-danger",
10
+ thumb: "pointer-events-none block rounded-full bg-fg-on-media shadow-sm transition-transform data-[state=unchecked]:translate-x-0.5 motion-reduce:transition-none"
11
+ },
12
+ variants: {
13
+ size: {
14
+ sm: { root: "h-5 w-9", thumb: "h-4 w-4 data-[state=checked]:translate-x-[1.125rem]" },
15
+ md: { root: "h-6 w-11", thumb: "h-5 w-5 data-[state=checked]:translate-x-[1.375rem]" }
16
+ }
17
+ },
18
+ defaultVariants: { size: "md" }
19
+ });
20
+ function Switch({ label, size, invalid, className, ...props }) {
21
+ const s = switchVariants({ size });
22
+ return /* @__PURE__ */ jsx(
23
+ SwitchPrimitive.Root,
24
+ {
25
+ "aria-label": label,
26
+ "aria-invalid": invalid || void 0,
27
+ "data-invalid": invalid ? "" : void 0,
28
+ className: s.root({ className }),
29
+ ...props,
30
+ children: /* @__PURE__ */ jsx(SwitchPrimitive.Thumb, { className: s.thumb() })
31
+ }
32
+ );
33
+ }
34
+ export {
35
+ Switch,
36
+ switchVariants
37
+ };
38
+ //# sourceMappingURL=switch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/switch/switch.tsx"],"sourcesContent":["// Client. Radix Switch: role=\"switch\", aria-checked, Space and Enter toggle, a hidden input inside a form.\nimport { Switch as SwitchPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const switchVariants = tv({\n slots: {\n root:\n \"peer relative inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent bg-fg-muted transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"disabled:cursor-not-allowed disabled:opacity-40 data-[state=checked]:bg-accent aria-invalid:border-danger\",\n thumb:\n \"pointer-events-none block rounded-full bg-fg-on-media shadow-sm transition-transform data-[state=unchecked]:translate-x-0.5 motion-reduce:transition-none\",\n },\n variants: {\n size: {\n sm: { root: \"h-5 w-9\", thumb: \"h-4 w-4 data-[state=checked]:translate-x-[1.125rem]\" },\n md: { root: \"h-6 w-11\", thumb: \"h-5 w-5 data-[state=checked]:translate-x-[1.375rem]\" },\n },\n },\n defaultVariants: { size: \"md\" },\n});\n\nexport type SwitchVariants = VariantProps<typeof switchVariants>;\n\ntype Named =\n | {\n /** The accessible name — required when no visible label names it, passed translated. */\n label: string;\n }\n /** Named by a visible `<label htmlFor={id}>` (e.g. `Field.Label`). */\n | { label?: undefined; id: string }\n /** Named by another element. */\n | { label?: undefined; \"aria-labelledby\": string };\n\nexport type SwitchProps = Omit<React.ComponentProps<typeof SwitchPrimitive.Root>, \"children\"> &\n SwitchVariants &\n Named & {\n /**\n * sm · md.\n * @default \"md\"\n */\n size?: SwitchVariants[\"size\"];\n /** Marks it invalid: aria-invalid and data-invalid. */\n invalid?: boolean;\n };\n\n/** An on/off switch: `checked`/`defaultChecked` + `onCheckedChange`. */\nexport function Switch({ label, size, invalid, className, ...props }: SwitchProps) {\n const s = switchVariants({ size });\n return (\n <SwitchPrimitive.Root\n aria-label={label}\n aria-invalid={invalid || undefined}\n data-invalid={invalid ? \"\" : undefined}\n className={s.root({ className })}\n {...props}\n >\n <SwitchPrimitive.Thumb className={s.thumb()} />\n </SwitchPrimitive.Root>\n );\n}\n"],"mappings":";;;AACA,SAAS,UAAU,uBAAuB;AAE1C,SAAS,UAA6B;AAuDhC;AArDC,IAAM,iBAAiB,GAAG;AAAA,EAC/B,OAAO;AAAA,IACL,MACE;AAAA,IAGF,OACE;AAAA,EACJ;AAAA,EACA,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,IAAI,EAAE,MAAM,WAAW,OAAO,sDAAsD;AAAA,MACpF,IAAI,EAAE,MAAM,YAAY,OAAO,sDAAsD;AAAA,IACvF;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,MAAM,KAAK;AAChC,CAAC;AA2BM,SAAS,OAAO,EAAE,OAAO,MAAM,SAAS,WAAW,GAAG,MAAM,GAAgB;AACjF,QAAM,IAAI,eAAe,EAAE,KAAK,CAAC;AACjC,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,cAAY;AAAA,MACZ,gBAAc,WAAW;AAAA,MACzB,gBAAc,UAAU,KAAK;AAAA,MAC7B,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC;AAAA,MAC9B,GAAG;AAAA,MAEJ,8BAAC,gBAAgB,OAAhB,EAAsB,WAAW,EAAE,MAAM,GAAG;AAAA;AAAA,EAC/C;AAEJ;","names":[]}
package/dist/tabs.d.ts ADDED
@@ -0,0 +1,86 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import { VariantProps } from 'tailwind-variants';
3
+ import { Tabs as Tabs$1 } from 'radix-ui';
4
+ import * as React from 'react';
5
+
6
+ declare const tabs: tailwind_variants.TVReturnType<{
7
+ variant: {
8
+ underline: {
9
+ list: string;
10
+ trigger: string;
11
+ };
12
+ segmented: {
13
+ list: string;
14
+ trigger: string;
15
+ };
16
+ pills: {
17
+ list: string;
18
+ trigger: string;
19
+ };
20
+ };
21
+ }, {
22
+ root: string;
23
+ list: string;
24
+ trigger: string;
25
+ content: string;
26
+ }, undefined, {
27
+ variant: {
28
+ underline: {
29
+ list: string;
30
+ trigger: string;
31
+ };
32
+ segmented: {
33
+ list: string;
34
+ trigger: string;
35
+ };
36
+ pills: {
37
+ list: string;
38
+ trigger: string;
39
+ };
40
+ };
41
+ }, {
42
+ root: string;
43
+ list: string;
44
+ trigger: string;
45
+ content: string;
46
+ }, tailwind_variants.TVReturnTypeLike<{
47
+ variant: {
48
+ underline: {
49
+ list: string;
50
+ trigger: string;
51
+ };
52
+ segmented: {
53
+ list: string;
54
+ trigger: string;
55
+ };
56
+ pills: {
57
+ list: string;
58
+ trigger: string;
59
+ };
60
+ };
61
+ }, {
62
+ root: string;
63
+ list: string;
64
+ trigger: string;
65
+ content: string;
66
+ }>>;
67
+ type TabsVariants = VariantProps<typeof tabs>;
68
+ type TabsRootProps = React.ComponentProps<typeof Tabs$1.Root> & {
69
+ /** underline (the sections of a page) · segmented (a view switch) · pills (a feed's sections). */
70
+ variant?: TabsVariants["variant"];
71
+ };
72
+ /** `value`/`defaultValue` + `onValueChange`, `orientation` (horizontal by default), `variant` for the list. */
73
+ declare function TabsRoot({ variant, className, ...props }: TabsRootProps): React.JSX.Element;
74
+ /** The tabs. Name it (`aria-label`) when no heading says what it switches. */
75
+ declare function TabsList({ className, ...props }: React.ComponentProps<typeof Tabs$1.List>): React.JSX.Element;
76
+ declare function TabsTrigger({ className, ...props }: React.ComponentProps<typeof Tabs$1.Trigger>): React.JSX.Element;
77
+ declare function TabsContent({ className, ...props }: React.ComponentProps<typeof Tabs$1.Content>): React.JSX.Element;
78
+ /** `Tabs.Root/List/Trigger/Content` — `variant` underline · segmented · pills on the root. */
79
+ declare const Tabs: {
80
+ Root: typeof TabsRoot;
81
+ List: typeof TabsList;
82
+ Trigger: typeof TabsTrigger;
83
+ Content: typeof TabsContent;
84
+ };
85
+
86
+ export { Tabs, TabsContent, TabsList, TabsRoot, type TabsRootProps, TabsTrigger, type TabsVariants, tabs };
package/dist/tabs.js ADDED
@@ -0,0 +1,60 @@
1
+ "use client";
2
+
3
+ // src/tabs/tabs.tsx
4
+ import { Tabs as TabsPrimitive } from "radix-ui";
5
+ import * as React from "react";
6
+ import { tv } from "tailwind-variants";
7
+ import { jsx } from "react/jsx-runtime";
8
+ var tabs = tv({
9
+ slots: {
10
+ root: "flex gap-4 data-[orientation=horizontal]:flex-col data-[orientation=vertical]:flex-row",
11
+ list: "flex shrink-0 data-[orientation=vertical]:flex-col",
12
+ trigger: "inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40",
13
+ content: "kz-fade min-w-0 flex-1 rounded-lg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"
14
+ },
15
+ variants: {
16
+ variant: {
17
+ /* The section of a page: a line under the list, the active tab underlined in the accent. */
18
+ underline: {
19
+ list: "gap-1 border-border-default data-[orientation=horizontal]:border-b data-[orientation=vertical]:border-r",
20
+ trigger: "relative rounded-md px-3 py-2.5 text-sm text-fg-secondary hover:text-fg data-[state=active]:text-fg after:absolute after:rounded-full after:bg-transparent data-[state=active]:after:bg-accent data-[orientation=horizontal]:after:inset-x-2 data-[orientation=horizontal]:after:-bottom-px data-[orientation=horizontal]:after:h-0.5 data-[orientation=vertical]:justify-start data-[orientation=vertical]:after:inset-y-1.5 data-[orientation=vertical]:after:-right-px data-[orientation=vertical]:after:w-0.5"
21
+ },
22
+ /* A view switch: equal segments in a track, the active one filled. */
23
+ segmented: {
24
+ list: "inline-grid auto-cols-fr grid-flow-col gap-1 self-start rounded-xl border border-border-default bg-surface-1 p-1 data-[orientation=vertical]:grid-flow-row",
25
+ trigger: "min-h-8 rounded-lg px-3 py-1.5 text-xs text-fg-secondary hover:bg-surface-2 hover:text-fg data-[state=active]:bg-accent data-[state=active]:text-on-accent data-[state=active]:shadow-sm data-[state=active]:hover:bg-accent"
26
+ },
27
+ /* Pills that scroll sideways on a phone: a feed's sections. */
28
+ pills: {
29
+ list: "gap-1.5 overflow-x-auto overscroll-x-contain [scrollbar-width:none] data-[orientation=horizontal]:pb-1",
30
+ trigger: "h-9 rounded-full border border-border-default bg-surface-1 px-4 text-xs text-fg-secondary hover:border-border-strong hover:text-fg data-[state=active]:border-accent data-[state=active]:bg-accent-soft data-[state=active]:text-fg"
31
+ }
32
+ }
33
+ },
34
+ defaultVariants: { variant: "underline" }
35
+ });
36
+ var VariantContext = React.createContext("underline");
37
+ function TabsRoot({ variant = "underline", className, ...props }) {
38
+ return /* @__PURE__ */ jsx(VariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(TabsPrimitive.Root, { "data-variant": variant, className: tabs({ variant }).root({ className }), ...props }) });
39
+ }
40
+ function TabsList({ className, ...props }) {
41
+ const variant = React.useContext(VariantContext);
42
+ return /* @__PURE__ */ jsx(TabsPrimitive.List, { "data-variant": variant, className: tabs({ variant }).list({ className }), ...props });
43
+ }
44
+ function TabsTrigger({ className, ...props }) {
45
+ const variant = React.useContext(VariantContext);
46
+ return /* @__PURE__ */ jsx(TabsPrimitive.Trigger, { className: tabs({ variant }).trigger({ className }), ...props });
47
+ }
48
+ function TabsContent({ className, ...props }) {
49
+ return /* @__PURE__ */ jsx(TabsPrimitive.Content, { className: tabs().content({ className }), ...props });
50
+ }
51
+ var Tabs = { Root: TabsRoot, List: TabsList, Trigger: TabsTrigger, Content: TabsContent };
52
+ export {
53
+ Tabs,
54
+ TabsContent,
55
+ TabsList,
56
+ TabsRoot,
57
+ TabsTrigger,
58
+ tabs
59
+ };
60
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tabs/tabs.tsx"],"sourcesContent":["// Client (a context). Radix Tabs does the roles (tablist, tab, tabpanel), the aria-selected / aria-controls wiring,\n// the roving focus (arrows, Home, End) and automatic activation: this file only holds the three looks.\nimport { Tabs as TabsPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const tabs = tv({\n slots: {\n root: \"flex gap-4 data-[orientation=horizontal]:flex-col data-[orientation=vertical]:flex-row\",\n list: \"flex shrink-0 data-[orientation=vertical]:flex-col\",\n trigger:\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40\",\n content: \"kz-fade min-w-0 flex-1 rounded-lg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n },\n variants: {\n variant: {\n /* The section of a page: a line under the list, the active tab underlined in the accent. */\n underline: {\n list: \"gap-1 border-border-default data-[orientation=horizontal]:border-b data-[orientation=vertical]:border-r\",\n trigger:\n \"relative rounded-md px-3 py-2.5 text-sm text-fg-secondary hover:text-fg data-[state=active]:text-fg \" +\n \"after:absolute after:rounded-full after:bg-transparent data-[state=active]:after:bg-accent \" +\n \"data-[orientation=horizontal]:after:inset-x-2 data-[orientation=horizontal]:after:-bottom-px data-[orientation=horizontal]:after:h-0.5 \" +\n \"data-[orientation=vertical]:justify-start data-[orientation=vertical]:after:inset-y-1.5 data-[orientation=vertical]:after:-right-px data-[orientation=vertical]:after:w-0.5\",\n },\n /* A view switch: equal segments in a track, the active one filled. */\n segmented: {\n list: \"inline-grid auto-cols-fr grid-flow-col gap-1 self-start rounded-xl border border-border-default bg-surface-1 p-1 data-[orientation=vertical]:grid-flow-row\",\n trigger:\n \"min-h-8 rounded-lg px-3 py-1.5 text-xs text-fg-secondary hover:bg-surface-2 hover:text-fg \" +\n \"data-[state=active]:bg-accent data-[state=active]:text-on-accent data-[state=active]:shadow-sm data-[state=active]:hover:bg-accent\",\n },\n /* Pills that scroll sideways on a phone: a feed's sections. */\n pills: {\n list: \"gap-1.5 overflow-x-auto overscroll-x-contain [scrollbar-width:none] data-[orientation=horizontal]:pb-1\",\n trigger:\n \"h-9 rounded-full border border-border-default bg-surface-1 px-4 text-xs text-fg-secondary hover:border-border-strong hover:text-fg \" +\n \"data-[state=active]:border-accent data-[state=active]:bg-accent-soft data-[state=active]:text-fg\",\n },\n },\n },\n defaultVariants: { variant: \"underline\" },\n});\n\nexport type TabsVariants = VariantProps<typeof tabs>;\ntype Variant = NonNullable<TabsVariants[\"variant\"]>;\n\nconst VariantContext = React.createContext<Variant>(\"underline\");\n\nexport type TabsRootProps = React.ComponentProps<typeof TabsPrimitive.Root> & {\n /** underline (the sections of a page) · segmented (a view switch) · pills (a feed's sections). */\n variant?: TabsVariants[\"variant\"];\n};\n\n/** `value`/`defaultValue` + `onValueChange`, `orientation` (horizontal by default), `variant` for the list. */\nexport function TabsRoot({ variant = \"underline\", className, ...props }: TabsRootProps) {\n return (\n <VariantContext.Provider value={variant}>\n <TabsPrimitive.Root data-variant={variant} className={tabs({ variant }).root({ className })} {...props} />\n </VariantContext.Provider>\n );\n}\n\n/** The tabs. Name it (`aria-label`) when no heading says what it switches. */\nexport function TabsList({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.List>) {\n const variant = React.useContext(VariantContext);\n return <TabsPrimitive.List data-variant={variant} className={tabs({ variant }).list({ className })} {...props} />;\n}\n\nexport function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n const variant = React.useContext(VariantContext);\n return <TabsPrimitive.Trigger className={tabs({ variant }).trigger({ className })} {...props} />;\n}\n\nexport function TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {\n return <TabsPrimitive.Content className={tabs().content({ className })} {...props} />;\n}\n\n/** `Tabs.Root/List/Trigger/Content` — `variant` underline · segmented · pills on the root. */\nexport const Tabs = { Root: TabsRoot, List: TabsList, Trigger: TabsTrigger, Content: TabsContent };\n"],"mappings":";;;AAEA,SAAS,QAAQ,qBAAqB;AACtC,YAAY,WAAW;AACvB,SAAS,UAA6B;AAuDhC;AArDC,IAAM,OAAO,GAAG;AAAA,EACrB,OAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SACE;AAAA,IAEF,SAAS;AAAA,EACX;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA;AAAA,MAEP,WAAW;AAAA,QACT,MAAM;AAAA,QACN,SACE;AAAA,MAIJ;AAAA;AAAA,MAEA,WAAW;AAAA,QACT,MAAM;AAAA,QACN,SACE;AAAA,MAEJ;AAAA;AAAA,MAEA,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SACE;AAAA,MAEJ;AAAA,IACF;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,SAAS,YAAY;AAC1C,CAAC;AAKD,IAAM,iBAAuB,oBAAuB,WAAW;AAQxD,SAAS,SAAS,EAAE,UAAU,aAAa,WAAW,GAAG,MAAM,GAAkB;AACtF,SACE,oBAAC,eAAe,UAAf,EAAwB,OAAO,SAC9B,8BAAC,cAAc,MAAd,EAAmB,gBAAc,SAAS,WAAW,KAAK,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO,GAC1G;AAEJ;AAGO,SAAS,SAAS,EAAE,WAAW,GAAG,MAAM,GAAoD;AACjG,QAAM,UAAgB,iBAAW,cAAc;AAC/C,SAAO,oBAAC,cAAc,MAAd,EAAmB,gBAAc,SAAS,WAAW,KAAK,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO;AACjH;AAEO,SAAS,YAAY,EAAE,WAAW,GAAG,MAAM,GAAuD;AACvG,QAAM,UAAgB,iBAAW,cAAc;AAC/C,SAAO,oBAAC,cAAc,SAAd,EAAsB,WAAW,KAAK,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO;AAChG;AAEO,SAAS,YAAY,EAAE,WAAW,GAAG,MAAM,GAAuD;AACvG,SAAO,oBAAC,cAAc,SAAd,EAAsB,WAAW,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAI,GAAG,OAAO;AACrF;AAGO,IAAM,OAAO,EAAE,MAAM,UAAU,MAAM,UAAU,SAAS,aAAa,SAAS,YAAY;","names":[]}