@cloudflare/kumo 1.13.0 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/ai/component-registry.json +47 -21
  3. package/ai/component-registry.md +243 -15
  4. package/ai/schemas.ts +3 -2
  5. package/dist/.build-complete +1 -1
  6. package/dist/ai/schemas.d.ts +10 -2
  7. package/dist/ai/schemas.d.ts.map +1 -1
  8. package/dist/ai/schemas.js +175 -173
  9. package/dist/ai/schemas.js.map +1 -1
  10. package/dist/chunks/Legend-mkh1v83sz972e29d.js +407 -0
  11. package/dist/chunks/Legend-mkh1v83sz972e29d.js.map +1 -0
  12. package/dist/chunks/{breadcrumbs-e564gabk59go37cg.js → breadcrumbs-gr907zcoo65rpn90.js} +2 -2
  13. package/dist/chunks/{breadcrumbs-e564gabk59go37cg.js.map → breadcrumbs-gr907zcoo65rpn90.js.map} +1 -1
  14. package/dist/chunks/{button-b1yp3lbrhjr9eg07.js → button-d82sexqgnd834eaa.js} +2 -2
  15. package/dist/chunks/{button-b1yp3lbrhjr9eg07.js.map → button-d82sexqgnd834eaa.js.map} +1 -1
  16. package/dist/chunks/{checkbox-khvh0efmlzvlo6qi.js → checkbox-gebzflhsvo6zkcrm.js} +3 -3
  17. package/dist/chunks/{checkbox-khvh0efmlzvlo6qi.js.map → checkbox-gebzflhsvo6zkcrm.js.map} +1 -1
  18. package/dist/chunks/{clipboard-text-jvrlvyz5ulm49h5b.js → clipboard-text-nnmfwusts804p1qd.js} +4 -4
  19. package/dist/chunks/{clipboard-text-jvrlvyz5ulm49h5b.js.map → clipboard-text-nnmfwusts804p1qd.js.map} +1 -1
  20. package/dist/chunks/{combobox-hdstt4dqqxbtxwod.js → combobox-ds8qzpuaagb1udzg.js} +88 -77
  21. package/dist/chunks/combobox-ds8qzpuaagb1udzg.js.map +1 -0
  22. package/dist/chunks/{command-palette-l8dym46a74o7j8ci.js → command-palette-essubhvibj84mhx8.js} +3 -3
  23. package/dist/chunks/{command-palette-l8dym46a74o7j8ci.js.map → command-palette-essubhvibj84mhx8.js.map} +1 -1
  24. package/dist/chunks/{dialog-emk68n0piw8u7hkb.js → dialog-hmfums1yr41afbsx.js} +2 -2
  25. package/dist/chunks/{dialog-emk68n0piw8u7hkb.js.map → dialog-hmfums1yr41afbsx.js.map} +1 -1
  26. package/dist/chunks/{dropdown-ejgjnn9gq3daua1h.js → dropdown-nhhm3rddlt7fmd2a.js} +2 -2
  27. package/dist/chunks/{dropdown-ejgjnn9gq3daua1h.js.map → dropdown-nhhm3rddlt7fmd2a.js.map} +1 -1
  28. package/dist/chunks/{empty-crbntv0dhud7besh.js → empty-h3qhwtx0z8arupc9.js} +2 -2
  29. package/dist/chunks/{empty-crbntv0dhud7besh.js.map → empty-h3qhwtx0z8arupc9.js.map} +1 -1
  30. package/dist/chunks/{engine-javascript-hi1kqifa6nkcridk.js → engine-javascript-cvvdau2e8o59vsx6.js} +5 -5
  31. package/dist/chunks/{engine-javascript-hi1kqifa6nkcridk.js.map → engine-javascript-cvvdau2e8o59vsx6.js.map} +1 -1
  32. package/dist/chunks/{field-ftrgblg9mbmz9eo3.js → field-pcsc33yrvgq6g9ll.js} +3 -3
  33. package/dist/chunks/{field-ftrgblg9mbmz9eo3.js.map → field-pcsc33yrvgq6g9ll.js.map} +1 -1
  34. package/dist/chunks/input-area-oyw0rq0q2wm0blmb.js +74 -0
  35. package/dist/chunks/input-area-oyw0rq0q2wm0blmb.js.map +1 -0
  36. package/dist/chunks/{input-group-g6qyhe5jvpe02hee.js → input-group-fjq64pzze8kklmni.js} +3 -3
  37. package/dist/chunks/{input-group-g6qyhe5jvpe02hee.js.map → input-group-fjq64pzze8kklmni.js.map} +1 -1
  38. package/dist/chunks/{input-me56hug8sl0u650q.js → input-oaa51811nxs0z2mw.js} +20 -20
  39. package/dist/chunks/input-oaa51811nxs0z2mw.js.map +1 -0
  40. package/dist/chunks/{label-eooot7dhtfvw7n3x.js → label-m5dcn3mqhnmi0dgq.js} +3 -3
  41. package/dist/chunks/{label-eooot7dhtfvw7n3x.js.map → label-m5dcn3mqhnmi0dgq.js.map} +1 -1
  42. package/dist/chunks/{link-moetfdbgxda0yhwg.js → link-desli097365ac82o.js} +2 -2
  43. package/dist/chunks/{link-moetfdbgxda0yhwg.js.map → link-desli097365ac82o.js.map} +1 -1
  44. package/dist/chunks/{menubar-c2zwv4mbo3xqq7is.js → menubar-eir09makes5l9xby.js} +2 -2
  45. package/dist/chunks/{menubar-c2zwv4mbo3xqq7is.js.map → menubar-eir09makes5l9xby.js.map} +1 -1
  46. package/dist/chunks/{meter-em2hfu8j2rhmf5ae.js → meter-kl2puqzdbfkwrok9.js} +2 -2
  47. package/dist/chunks/{meter-em2hfu8j2rhmf5ae.js.map → meter-kl2puqzdbfkwrok9.js.map} +1 -1
  48. package/dist/chunks/{pagination-xt93wvwvow4z44lc.js → pagination-c2sv9vs43whhvznh.js} +3 -3
  49. package/dist/chunks/{pagination-xt93wvwvow4z44lc.js.map → pagination-c2sv9vs43whhvznh.js.map} +1 -1
  50. package/dist/chunks/{popover-irccwetx73p8pnua.js → popover-ji1zh9zqrj6at834.js} +2 -2
  51. package/dist/chunks/{popover-irccwetx73p8pnua.js.map → popover-ji1zh9zqrj6at834.js.map} +1 -1
  52. package/dist/chunks/radio-cnsup12f302rxkxl.js +200 -0
  53. package/dist/chunks/radio-cnsup12f302rxkxl.js.map +1 -0
  54. package/dist/chunks/{select-jxxef2rf76pgdrf8.js → select-hgn6ikyor1p6jd9r.js} +21 -14
  55. package/dist/chunks/select-hgn6ikyor1p6jd9r.js.map +1 -0
  56. package/dist/chunks/{sensitive-input-i7ey1w0ky7nco012.js → sensitive-input-drdu6upod3ucl6vt.js} +34 -34
  57. package/dist/chunks/sensitive-input-drdu6upod3ucl6vt.js.map +1 -0
  58. package/dist/chunks/switch-n7zyzirax1l016n2.js +241 -0
  59. package/dist/chunks/switch-n7zyzirax1l016n2.js.map +1 -0
  60. package/dist/chunks/{table-d4ql7fjvok30xs1f.js → table-l2yy3jtkbhvqlq43.js} +3 -3
  61. package/dist/chunks/table-l2yy3jtkbhvqlq43.js.map +1 -0
  62. package/dist/chunks/{tabs-n3rcvuzx0gbslyy6.js → tabs-omc1n6jaxkf41pvg.js} +2 -2
  63. package/dist/chunks/{tabs-n3rcvuzx0gbslyy6.js.map → tabs-omc1n6jaxkf41pvg.js.map} +1 -1
  64. package/dist/chunks/{toast-j05qj3vk688ht1i1.js → toast-bkvbwc1x3s7fbzkt.js} +3 -3
  65. package/dist/chunks/{toast-j05qj3vk688ht1i1.js.map → toast-bkvbwc1x3s7fbzkt.js.map} +1 -1
  66. package/dist/chunks/{tooltip-es2dwwbhftg4k2jy.js → tooltip-nwvv7fhpqpo2rqlc.js} +2 -2
  67. package/dist/chunks/{tooltip-es2dwwbhftg4k2jy.js.map → tooltip-nwvv7fhpqpo2rqlc.js.map} +1 -1
  68. package/dist/chunks/{vendor-base-ui-kxxocm122zr4pipe.js → vendor-base-ui-lgoligkf81eyvnde.js} +21 -21
  69. package/dist/chunks/{vendor-base-ui-kxxocm122zr4pipe.js.map → vendor-base-ui-lgoligkf81eyvnde.js.map} +1 -1
  70. package/dist/code/server.js +0 -2
  71. package/dist/code/server.js.map +1 -1
  72. package/dist/code.js +2 -3
  73. package/dist/code.js.map +1 -1
  74. package/dist/components/breadcrumbs.js +1 -1
  75. package/dist/components/button.js +1 -1
  76. package/dist/components/chart.js +1 -1
  77. package/dist/components/checkbox.js +1 -1
  78. package/dist/components/clipboard-text.js +1 -1
  79. package/dist/components/combobox.js +1 -1
  80. package/dist/components/command-palette.js +1 -1
  81. package/dist/components/dialog.js +1 -1
  82. package/dist/components/dropdown.js +1 -1
  83. package/dist/components/empty.js +1 -1
  84. package/dist/components/field.js +1 -1
  85. package/dist/components/flow.js +1435 -1431
  86. package/dist/components/flow.js.map +1 -1
  87. package/dist/components/input.js +3 -3
  88. package/dist/components/label.js +1 -1
  89. package/dist/components/link.js +1 -1
  90. package/dist/components/menubar.js +1 -1
  91. package/dist/components/meter.js +1 -1
  92. package/dist/components/pagination.js +1 -1
  93. package/dist/components/popover.js +1 -1
  94. package/dist/components/radio.js +1 -1
  95. package/dist/components/select.js +1 -1
  96. package/dist/components/sensitive-input.js +1 -1
  97. package/dist/components/switch.js +1 -1
  98. package/dist/components/table.js +1 -1
  99. package/dist/components/tabs.js +1 -1
  100. package/dist/components/toast.js +2 -2
  101. package/dist/components/tooltip.js +1 -1
  102. package/dist/index.js +69 -68
  103. package/dist/primitives/accordion.js +1 -1
  104. package/dist/primitives/alert-dialog.js +1 -1
  105. package/dist/primitives/autocomplete.js +1 -1
  106. package/dist/primitives/avatar.js +1 -1
  107. package/dist/primitives/button.js +1 -1
  108. package/dist/primitives/checkbox-group.js +1 -1
  109. package/dist/primitives/checkbox.js +1 -1
  110. package/dist/primitives/collapsible.js +1 -1
  111. package/dist/primitives/combobox.js +1 -1
  112. package/dist/primitives/context-menu.js +1 -1
  113. package/dist/primitives/csp-provider.js +1 -1
  114. package/dist/primitives/dialog.js +1 -1
  115. package/dist/primitives/direction-provider.js +1 -1
  116. package/dist/primitives/drawer.js +1 -1
  117. package/dist/primitives/field.js +1 -1
  118. package/dist/primitives/fieldset.js +1 -1
  119. package/dist/primitives/form.js +1 -1
  120. package/dist/primitives/input.js +1 -1
  121. package/dist/primitives/menu.js +1 -1
  122. package/dist/primitives/menubar.js +1 -1
  123. package/dist/primitives/meter.js +1 -1
  124. package/dist/primitives/navigation-menu.js +1 -1
  125. package/dist/primitives/number-field.js +1 -1
  126. package/dist/primitives/popover.js +1 -1
  127. package/dist/primitives/preview-card.js +1 -1
  128. package/dist/primitives/progress.js +1 -1
  129. package/dist/primitives/radio-group.js +1 -1
  130. package/dist/primitives/radio.js +1 -1
  131. package/dist/primitives/scroll-area.js +1 -1
  132. package/dist/primitives/select.js +1 -1
  133. package/dist/primitives/separator.js +1 -1
  134. package/dist/primitives/slider.js +1 -1
  135. package/dist/primitives/switch.js +1 -1
  136. package/dist/primitives/tabs.js +1 -1
  137. package/dist/primitives/toast.js +1 -1
  138. package/dist/primitives/toggle-group.js +1 -1
  139. package/dist/primitives/toggle.js +1 -1
  140. package/dist/primitives/toolbar.js +1 -1
  141. package/dist/primitives/tooltip.js +1 -1
  142. package/dist/primitives.js +1 -1
  143. package/dist/scripts/theme-generator/config.d.ts.map +1 -1
  144. package/dist/scripts/theme-generator/config.js +12 -3
  145. package/dist/scripts/theme-generator/config.js.map +1 -1
  146. package/dist/src/code/code-highlighted.d.ts +2 -2
  147. package/dist/src/code/code-highlighted.d.ts.map +1 -1
  148. package/dist/src/code/provider.d.ts +2 -2
  149. package/dist/src/code/provider.d.ts.map +1 -1
  150. package/dist/src/components/chart/EChart.d.ts +7 -2
  151. package/dist/src/components/chart/EChart.d.ts.map +1 -1
  152. package/dist/src/components/chart/TimeseriesChart.d.ts.map +1 -1
  153. package/dist/src/components/combobox/combobox.d.ts.map +1 -1
  154. package/dist/src/components/flow/diagram.d.ts.map +1 -1
  155. package/dist/src/components/input/input-area.d.ts.map +1 -1
  156. package/dist/src/components/radio/index.d.ts +1 -1
  157. package/dist/src/components/radio/index.d.ts.map +1 -1
  158. package/dist/src/components/radio/radio.d.ts +43 -4
  159. package/dist/src/components/radio/radio.d.ts.map +1 -1
  160. package/dist/src/components/select/select.d.ts.map +1 -1
  161. package/dist/src/components/switch/switch.d.ts +8 -8
  162. package/dist/src/components/switch/switch.d.ts.map +1 -1
  163. package/dist/src/index.d.ts +1 -1
  164. package/dist/src/index.d.ts.map +1 -1
  165. package/dist/styles/kumo-binding.css +5 -0
  166. package/dist/styles/kumo-standalone.css +1 -1
  167. package/dist/styles/theme-kumo.css +7 -0
  168. package/package.json +3 -6
  169. package/scripts/theme-generator/config.ts +12 -3
  170. package/dist/chunks/Legend-o2bjbo2pp24c2fqd.js +0 -402
  171. package/dist/chunks/Legend-o2bjbo2pp24c2fqd.js.map +0 -1
  172. package/dist/chunks/combobox-hdstt4dqqxbtxwod.js.map +0 -1
  173. package/dist/chunks/input-area-hxtyrqpp44m18j72.js +0 -59
  174. package/dist/chunks/input-area-hxtyrqpp44m18j72.js.map +0 -1
  175. package/dist/chunks/input-me56hug8sl0u650q.js.map +0 -1
  176. package/dist/chunks/radio-394mfs3au5m8cgd8.js +0 -125
  177. package/dist/chunks/radio-394mfs3au5m8cgd8.js.map +0 -1
  178. package/dist/chunks/select-jxxef2rf76pgdrf8.js.map +0 -1
  179. package/dist/chunks/sensitive-input-i7ey1w0ky7nco012.js.map +0 -1
  180. package/dist/chunks/switch-b0xo8fxsfzv87krj.js +0 -257
  181. package/dist/chunks/switch-b0xo8fxsfzv87krj.js.map +0 -1
  182. package/dist/chunks/table-d4ql7fjvok30xs1f.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"pagination-xt93wvwvow4z44lc.js","sources":["../../src/components/pagination/pagination.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport { InputGroup } from \"../input\";\nimport {\n CaretDoubleLeftIcon,\n CaretDoubleRightIcon,\n CaretLeftIcon,\n CaretRightIcon,\n} from \"@phosphor-icons/react\";\nimport { cn } from \"../../utils/cn\";\nimport { Select } from \"../select\";\n\nconst DEFAULT_PAGE_SIZE_OPTIONS = [25, 50, 100, 250] as const;\n\n/** Pagination controls variant definitions. */\nexport const KUMO_PAGINATION_VARIANTS = {\n controls: {\n full: {\n classes: \"\",\n description:\n \"Full pagination controls with first, previous, page input, next, and last buttons\",\n },\n simple: {\n classes: \"\",\n description:\n \"Simple pagination controls with only previous and next buttons\",\n },\n },\n} as const;\n\nexport type KumoPaginationControls =\n keyof typeof KUMO_PAGINATION_VARIANTS.controls;\n\nexport const KUMO_PAGINATION_DEFAULT_VARIANTS = {\n controls: \"full\",\n} as const;\n\nexport interface KumoPaginationVariantsProps {\n controls?: KumoPaginationControls;\n}\n\nexport function paginationVariants({\n controls = KUMO_PAGINATION_DEFAULT_VARIANTS.controls,\n}: KumoPaginationVariantsProps = {}) {\n return cn(\n \"flex items-center justify-between gap-2\",\n KUMO_PAGINATION_VARIANTS.controls[controls].classes,\n );\n}\n\n// ============================================================================\n// Pagination Context\n// ============================================================================\n\ninterface PaginationContextValue {\n page: number;\n perPage?: number;\n totalCount?: number;\n maxPage: number;\n pageShowingRange: string;\n setPage: (page: number) => void;\n editingPage: number;\n setEditingPage: (page: number) => void;\n}\n\nconst PaginationContext = createContext<PaginationContextValue | null>(null);\n\nfunction usePaginationContext() {\n const context = useContext(PaginationContext);\n if (!context) {\n throw new Error(\n \"Pagination compound components must be used within a Pagination component\",\n );\n }\n return context;\n}\n\n// ============================================================================\n// Pagination.Info\n// ============================================================================\n\nexport interface PaginationInfoProps {\n /** Custom render function for the info text */\n children?: (props: {\n page: number;\n perPage?: number;\n totalCount?: number;\n pageShowingRange: string;\n }) => ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction PaginationInfo({ children, className }: PaginationInfoProps) {\n const { page, perPage, totalCount, pageShowingRange } =\n usePaginationContext();\n\n const content = children ? (\n children({ page, perPage, totalCount, pageShowingRange })\n ) : totalCount && totalCount > 0 ? (\n <>\n Showing <span className=\"tabular-nums\">{pageShowingRange}</span> of{\" \"}\n <span className=\"tabular-nums\">{totalCount}</span>\n </>\n ) : null;\n\n return (\n <div\n data-slot=\"pagination-info\"\n className={cn(\"text-sm text-kumo-strong\", className)}\n >\n {content}\n </div>\n );\n}\n\nPaginationInfo.displayName = \"Pagination.Info\";\n\n// ============================================================================\n// Pagination.PageSize\n// ============================================================================\n\nexport interface PaginationPageSizeProps {\n /** Current page size value */\n value: number;\n /** Callback when page size changes */\n onChange: (size: number) => void;\n /** Available page size options */\n options?: number[];\n /** Label text shown before the selector */\n label?: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction PaginationPageSize({\n value,\n onChange,\n options = DEFAULT_PAGE_SIZE_OPTIONS as unknown as number[],\n label = \"Per page:\",\n className,\n}: PaginationPageSizeProps) {\n return (\n <div\n data-slot=\"pagination-page-size\"\n className={cn(\"flex items-center gap-2\", className)}\n >\n {label && <span className=\"text-sm text-kumo-strong\">{label}</span>}\n <Select\n aria-label=\"Page size\"\n value={value}\n onValueChange={(v) => onChange(v as number)}\n >\n {options.map((size) => (\n <Select.Option key={size} value={size}>\n {size}\n </Select.Option>\n ))}\n </Select>\n </div>\n );\n}\n\nPaginationPageSize.displayName = \"Pagination.PageSize\";\n\n// ============================================================================\n// Pagination.Controls\n// ============================================================================\n\nexport interface PaginationControlsProps extends KumoPaginationVariantsProps {\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction PaginationControls({\n controls = KUMO_PAGINATION_DEFAULT_VARIANTS.controls,\n className,\n}: PaginationControlsProps) {\n const { page, maxPage, setPage, editingPage, setEditingPage } =\n usePaginationContext();\n\n return (\n <div\n data-slot=\"pagination-controls\"\n className={cn(\"grow flex flex-col items-end\", className)}\n >\n <div>\n <InputGroup focusMode=\"individual\">\n {controls === \"full\" && (\n <InputGroup.Button\n variant=\"secondary\"\n aria-label=\"First page\"\n disabled={page <= 1}\n onClick={() => {\n setPage(1);\n setEditingPage(1);\n }}\n >\n <CaretDoubleLeftIcon size={16} />\n </InputGroup.Button>\n )}\n <InputGroup.Button\n variant=\"secondary\"\n aria-label=\"Previous page\"\n disabled={page <= 1}\n onClick={() => {\n const previousPage = Math.max(page - 1, 1);\n setPage(previousPage);\n setEditingPage(previousPage);\n }}\n >\n <CaretLeftIcon size={16} />\n </InputGroup.Button>\n {controls === \"full\" && (\n <InputGroup.Input\n style={{ width: 50 }}\n className=\"text-center\"\n aria-label=\"Page number\"\n value={editingPage}\n onValueChange={(value: string) => {\n setEditingPage(Number(value));\n }}\n onBlur={() => {\n let number = Math.max(editingPage, 1);\n number = Math.min(number, maxPage);\n setPage(number);\n setEditingPage(number);\n }}\n // Prevent password managers from auto-filling\n autoComplete=\"off\"\n data-1p-ignore\n data-lpignore=\"true\"\n data-form-type=\"other\"\n />\n )}\n <InputGroup.Button\n variant=\"secondary\"\n aria-label=\"Next page\"\n disabled={page === maxPage}\n onClick={() => {\n const nextPage = Math.min(page + 1, maxPage);\n setPage(nextPage);\n setEditingPage(nextPage);\n }}\n >\n <CaretRightIcon size={16} />\n </InputGroup.Button>\n {controls === \"full\" && (\n <InputGroup.Button\n variant=\"secondary\"\n aria-label=\"Last page\"\n disabled={page === maxPage}\n onClick={() => {\n setPage(maxPage);\n setEditingPage(maxPage);\n }}\n >\n <CaretDoubleRightIcon size={16} />\n </InputGroup.Button>\n )}\n </InputGroup>\n </div>\n </div>\n );\n}\n\nPaginationControls.displayName = \"Pagination.Controls\";\n\n// ============================================================================\n// Pagination.Separator\n// ============================================================================\n\nexport interface PaginationSeparatorProps {\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction PaginationSeparator({ className }: PaginationSeparatorProps) {\n return (\n <div\n data-slot=\"pagination-separator\"\n className={cn(\"mx-2 h-6 border-l border-kumo-line\", className)}\n />\n );\n}\n\nPaginationSeparator.displayName = \"Pagination.Separator\";\n\n// ============================================================================\n// Pagination Root\n// ============================================================================\n\n/** Base props shared by both compound and legacy Pagination APIs */\ninterface PaginationBaseProps {\n /** Callback fired when the current page changes. */\n setPage: (page: number) => void;\n /**\n * Current page number (1-indexed).\n * @default 1\n */\n page?: number;\n /** Number of items displayed per page. */\n perPage?: number;\n /** Total number of items across all pages. */\n totalCount?: number;\n /** Additional CSS classes for the container */\n className?: string;\n}\n\n/**\n * Props for the compound component API (recommended).\n *\n * @example\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={perPage} totalCount={500}>\n * <Pagination.Info />\n * <Pagination.PageSize value={perPage} onChange={setPerPage} />\n * <Pagination.Controls />\n * </Pagination>\n * ```\n */\nexport interface PaginationCompoundProps extends PaginationBaseProps {\n /**\n * Compound component children for custom layouts.\n * Use Pagination.Info, Pagination.PageSize, Pagination.Controls, and Pagination.Separator.\n */\n children: ReactNode;\n controls?: never;\n text?: never;\n}\n\n/**\n * Props for the legacy API (deprecated, use compound components instead).\n *\n * @deprecated Use the compound component API with children instead:\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={perPage} totalCount={500}>\n * <Pagination.Info />\n * <Pagination.Controls />\n * </Pagination>\n * ```\n *\n * @example\n * ```tsx\n * // Legacy usage (deprecated)\n * <Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />\n * ```\n */\nexport interface PaginationLegacyProps\n extends PaginationBaseProps,\n KumoPaginationVariantsProps {\n children?: never;\n /** @deprecated Use Pagination.Info with children prop instead */\n text?: (props: {\n page?: number;\n perPage?: number;\n totalCount?: number;\n pageShowingRange: string;\n }) => ReactNode;\n}\n\n/**\n * Pagination component props.\n *\n * Prefer the compound component API for new code:\n * @example\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={perPage} totalCount={500}>\n * <Pagination.Info />\n * <Pagination.PageSize value={perPage} onChange={setPerPage} />\n * <Pagination.Controls />\n * </Pagination>\n * ```\n */\nexport type PaginationProps = PaginationCompoundProps | PaginationLegacyProps;\n\n/**\n * Page navigation controls with page count display.\n *\n * Supports both compound component and legacy patterns. Prefer compound components for new code:\n *\n * @example\n * // Compound component (recommended)\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={perPage} totalCount={500}>\n * <Pagination.Info />\n * <Pagination.Separator />\n * <Pagination.PageSize value={perPage} onChange={setPerPage} />\n * <Pagination.Controls />\n * </Pagination>\n * ```\n *\n * @example\n * // Legacy (deprecated)\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />\n * ```\n */\nfunction PaginationRoot(props: PaginationProps) {\n const { page = 1, perPage, totalCount, setPage, children, className } = props;\n\n // Extract legacy props (only present when children is not provided)\n const text = \"text\" in props ? props.text : undefined;\n const controls =\n \"controls\" in props\n ? (props.controls ?? KUMO_PAGINATION_DEFAULT_VARIANTS.controls)\n : KUMO_PAGINATION_DEFAULT_VARIANTS.controls;\n const [editingPage, setEditingPage] = useState<number>(1);\n\n useEffect(() => {\n setEditingPage(page);\n }, [page]);\n\n const pageShowingRange = useMemo(() => {\n let lower = page * (perPage ?? 1) - (perPage ?? 0) + 1;\n let upper = Math.min(page * (perPage ?? 0), totalCount ?? 0);\n\n if (Number.isNaN(lower)) lower = 0;\n if (Number.isNaN(upper)) upper = 0;\n\n return `${lower}-${upper}`;\n }, [page, perPage, totalCount]);\n\n const maxPage = useMemo(() => {\n return Math.ceil((totalCount ?? 1) / (perPage ?? 1));\n }, [totalCount, perPage]);\n\n const contextValue: PaginationContextValue = {\n page,\n perPage,\n totalCount,\n maxPage,\n pageShowingRange,\n setPage,\n editingPage,\n setEditingPage,\n };\n\n // Compound component mode: render children within context\n if (children) {\n return (\n <PaginationContext.Provider value={contextValue}>\n <div\n data-slot=\"pagination\"\n className={cn(\"flex items-center gap-2 w-full\", className)}\n >\n {children}\n </div>\n </PaginationContext.Provider>\n );\n }\n\n // Legacy mode: render default layout for backwards compatibility\n const getPaginationText = () => {\n if (text) {\n return text({ page, perPage, totalCount, pageShowingRange });\n } else if (totalCount && totalCount > 0) {\n return (\n <>\n Showing <span className=\"tabular-nums\">{pageShowingRange}</span> of{\" \"}\n <span className=\"tabular-nums\">{totalCount}</span>\n </>\n );\n }\n return null;\n };\n\n return (\n <PaginationContext.Provider value={contextValue}>\n <div\n data-slot=\"pagination\"\n className={cn(\"flex items-center gap-2 w-full\", className)}\n >\n <div\n data-slot=\"pagination-info\"\n className=\"grow text-sm text-kumo-strong\"\n >\n {getPaginationText()}\n </div>\n <PaginationControls controls={controls} />\n </div>\n </PaginationContext.Provider>\n );\n}\n\nPaginationRoot.displayName = \"Pagination\";\n\n// ============================================================================\n// Compound Component Export\n// ============================================================================\n\nexport const Pagination = Object.assign(PaginationRoot, {\n Info: PaginationInfo,\n PageSize: PaginationPageSize,\n Controls: PaginationControls,\n Separator: PaginationSeparator,\n});\n\nexport {\n PaginationInfo,\n PaginationPageSize,\n PaginationControls,\n PaginationSeparator,\n};\n"],"names":["DEFAULT_PAGE_SIZE_OPTIONS","KUMO_PAGINATION_DEFAULT_VARIANTS","PaginationContext","createContext","usePaginationContext","context","useContext","PaginationInfo","children","className","page","perPage","totalCount","pageShowingRange","content","jsxs","Fragment","jsx","cn","PaginationPageSize","value","onChange","options","label","Select","v","size","PaginationControls","controls","maxPage","setPage","editingPage","setEditingPage","InputGroup","CaretDoubleLeftIcon","previousPage","CaretLeftIcon","number","nextPage","CaretRightIcon","CaretDoubleRightIcon","PaginationSeparator","PaginationRoot","props","text","useState","useEffect","useMemo","lower","upper","contextValue","getPaginationText","Pagination"],"mappings":"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"}
1
+ {"version":3,"file":"pagination-c2sv9vs43whhvznh.js","sources":["../../src/components/pagination/pagination.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport { InputGroup } from \"../input\";\nimport {\n CaretDoubleLeftIcon,\n CaretDoubleRightIcon,\n CaretLeftIcon,\n CaretRightIcon,\n} from \"@phosphor-icons/react\";\nimport { cn } from \"../../utils/cn\";\nimport { Select } from \"../select\";\n\nconst DEFAULT_PAGE_SIZE_OPTIONS = [25, 50, 100, 250] as const;\n\n/** Pagination controls variant definitions. */\nexport const KUMO_PAGINATION_VARIANTS = {\n controls: {\n full: {\n classes: \"\",\n description:\n \"Full pagination controls with first, previous, page input, next, and last buttons\",\n },\n simple: {\n classes: \"\",\n description:\n \"Simple pagination controls with only previous and next buttons\",\n },\n },\n} as const;\n\nexport type KumoPaginationControls =\n keyof typeof KUMO_PAGINATION_VARIANTS.controls;\n\nexport const KUMO_PAGINATION_DEFAULT_VARIANTS = {\n controls: \"full\",\n} as const;\n\nexport interface KumoPaginationVariantsProps {\n controls?: KumoPaginationControls;\n}\n\nexport function paginationVariants({\n controls = KUMO_PAGINATION_DEFAULT_VARIANTS.controls,\n}: KumoPaginationVariantsProps = {}) {\n return cn(\n \"flex items-center justify-between gap-2\",\n KUMO_PAGINATION_VARIANTS.controls[controls].classes,\n );\n}\n\n// ============================================================================\n// Pagination Context\n// ============================================================================\n\ninterface PaginationContextValue {\n page: number;\n perPage?: number;\n totalCount?: number;\n maxPage: number;\n pageShowingRange: string;\n setPage: (page: number) => void;\n editingPage: number;\n setEditingPage: (page: number) => void;\n}\n\nconst PaginationContext = createContext<PaginationContextValue | null>(null);\n\nfunction usePaginationContext() {\n const context = useContext(PaginationContext);\n if (!context) {\n throw new Error(\n \"Pagination compound components must be used within a Pagination component\",\n );\n }\n return context;\n}\n\n// ============================================================================\n// Pagination.Info\n// ============================================================================\n\nexport interface PaginationInfoProps {\n /** Custom render function for the info text */\n children?: (props: {\n page: number;\n perPage?: number;\n totalCount?: number;\n pageShowingRange: string;\n }) => ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction PaginationInfo({ children, className }: PaginationInfoProps) {\n const { page, perPage, totalCount, pageShowingRange } =\n usePaginationContext();\n\n const content = children ? (\n children({ page, perPage, totalCount, pageShowingRange })\n ) : totalCount && totalCount > 0 ? (\n <>\n Showing <span className=\"tabular-nums\">{pageShowingRange}</span> of{\" \"}\n <span className=\"tabular-nums\">{totalCount}</span>\n </>\n ) : null;\n\n return (\n <div\n data-slot=\"pagination-info\"\n className={cn(\"text-sm text-kumo-strong\", className)}\n >\n {content}\n </div>\n );\n}\n\nPaginationInfo.displayName = \"Pagination.Info\";\n\n// ============================================================================\n// Pagination.PageSize\n// ============================================================================\n\nexport interface PaginationPageSizeProps {\n /** Current page size value */\n value: number;\n /** Callback when page size changes */\n onChange: (size: number) => void;\n /** Available page size options */\n options?: number[];\n /** Label text shown before the selector */\n label?: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction PaginationPageSize({\n value,\n onChange,\n options = DEFAULT_PAGE_SIZE_OPTIONS as unknown as number[],\n label = \"Per page:\",\n className,\n}: PaginationPageSizeProps) {\n return (\n <div\n data-slot=\"pagination-page-size\"\n className={cn(\"flex items-center gap-2\", className)}\n >\n {label && <span className=\"text-sm text-kumo-strong\">{label}</span>}\n <Select\n aria-label=\"Page size\"\n value={value}\n onValueChange={(v) => onChange(v as number)}\n >\n {options.map((size) => (\n <Select.Option key={size} value={size}>\n {size}\n </Select.Option>\n ))}\n </Select>\n </div>\n );\n}\n\nPaginationPageSize.displayName = \"Pagination.PageSize\";\n\n// ============================================================================\n// Pagination.Controls\n// ============================================================================\n\nexport interface PaginationControlsProps extends KumoPaginationVariantsProps {\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction PaginationControls({\n controls = KUMO_PAGINATION_DEFAULT_VARIANTS.controls,\n className,\n}: PaginationControlsProps) {\n const { page, maxPage, setPage, editingPage, setEditingPage } =\n usePaginationContext();\n\n return (\n <div\n data-slot=\"pagination-controls\"\n className={cn(\"grow flex flex-col items-end\", className)}\n >\n <div>\n <InputGroup focusMode=\"individual\">\n {controls === \"full\" && (\n <InputGroup.Button\n variant=\"secondary\"\n aria-label=\"First page\"\n disabled={page <= 1}\n onClick={() => {\n setPage(1);\n setEditingPage(1);\n }}\n >\n <CaretDoubleLeftIcon size={16} />\n </InputGroup.Button>\n )}\n <InputGroup.Button\n variant=\"secondary\"\n aria-label=\"Previous page\"\n disabled={page <= 1}\n onClick={() => {\n const previousPage = Math.max(page - 1, 1);\n setPage(previousPage);\n setEditingPage(previousPage);\n }}\n >\n <CaretLeftIcon size={16} />\n </InputGroup.Button>\n {controls === \"full\" && (\n <InputGroup.Input\n style={{ width: 50 }}\n className=\"text-center\"\n aria-label=\"Page number\"\n value={editingPage}\n onValueChange={(value: string) => {\n setEditingPage(Number(value));\n }}\n onBlur={() => {\n let number = Math.max(editingPage, 1);\n number = Math.min(number, maxPage);\n setPage(number);\n setEditingPage(number);\n }}\n // Prevent password managers from auto-filling\n autoComplete=\"off\"\n data-1p-ignore\n data-lpignore=\"true\"\n data-form-type=\"other\"\n />\n )}\n <InputGroup.Button\n variant=\"secondary\"\n aria-label=\"Next page\"\n disabled={page === maxPage}\n onClick={() => {\n const nextPage = Math.min(page + 1, maxPage);\n setPage(nextPage);\n setEditingPage(nextPage);\n }}\n >\n <CaretRightIcon size={16} />\n </InputGroup.Button>\n {controls === \"full\" && (\n <InputGroup.Button\n variant=\"secondary\"\n aria-label=\"Last page\"\n disabled={page === maxPage}\n onClick={() => {\n setPage(maxPage);\n setEditingPage(maxPage);\n }}\n >\n <CaretDoubleRightIcon size={16} />\n </InputGroup.Button>\n )}\n </InputGroup>\n </div>\n </div>\n );\n}\n\nPaginationControls.displayName = \"Pagination.Controls\";\n\n// ============================================================================\n// Pagination.Separator\n// ============================================================================\n\nexport interface PaginationSeparatorProps {\n /** Additional CSS classes */\n className?: string;\n}\n\nfunction PaginationSeparator({ className }: PaginationSeparatorProps) {\n return (\n <div\n data-slot=\"pagination-separator\"\n className={cn(\"mx-2 h-6 border-l border-kumo-line\", className)}\n />\n );\n}\n\nPaginationSeparator.displayName = \"Pagination.Separator\";\n\n// ============================================================================\n// Pagination Root\n// ============================================================================\n\n/** Base props shared by both compound and legacy Pagination APIs */\ninterface PaginationBaseProps {\n /** Callback fired when the current page changes. */\n setPage: (page: number) => void;\n /**\n * Current page number (1-indexed).\n * @default 1\n */\n page?: number;\n /** Number of items displayed per page. */\n perPage?: number;\n /** Total number of items across all pages. */\n totalCount?: number;\n /** Additional CSS classes for the container */\n className?: string;\n}\n\n/**\n * Props for the compound component API (recommended).\n *\n * @example\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={perPage} totalCount={500}>\n * <Pagination.Info />\n * <Pagination.PageSize value={perPage} onChange={setPerPage} />\n * <Pagination.Controls />\n * </Pagination>\n * ```\n */\nexport interface PaginationCompoundProps extends PaginationBaseProps {\n /**\n * Compound component children for custom layouts.\n * Use Pagination.Info, Pagination.PageSize, Pagination.Controls, and Pagination.Separator.\n */\n children: ReactNode;\n controls?: never;\n text?: never;\n}\n\n/**\n * Props for the legacy API (deprecated, use compound components instead).\n *\n * @deprecated Use the compound component API with children instead:\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={perPage} totalCount={500}>\n * <Pagination.Info />\n * <Pagination.Controls />\n * </Pagination>\n * ```\n *\n * @example\n * ```tsx\n * // Legacy usage (deprecated)\n * <Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />\n * ```\n */\nexport interface PaginationLegacyProps\n extends PaginationBaseProps,\n KumoPaginationVariantsProps {\n children?: never;\n /** @deprecated Use Pagination.Info with children prop instead */\n text?: (props: {\n page?: number;\n perPage?: number;\n totalCount?: number;\n pageShowingRange: string;\n }) => ReactNode;\n}\n\n/**\n * Pagination component props.\n *\n * Prefer the compound component API for new code:\n * @example\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={perPage} totalCount={500}>\n * <Pagination.Info />\n * <Pagination.PageSize value={perPage} onChange={setPerPage} />\n * <Pagination.Controls />\n * </Pagination>\n * ```\n */\nexport type PaginationProps = PaginationCompoundProps | PaginationLegacyProps;\n\n/**\n * Page navigation controls with page count display.\n *\n * Supports both compound component and legacy patterns. Prefer compound components for new code:\n *\n * @example\n * // Compound component (recommended)\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={perPage} totalCount={500}>\n * <Pagination.Info />\n * <Pagination.Separator />\n * <Pagination.PageSize value={perPage} onChange={setPerPage} />\n * <Pagination.Controls />\n * </Pagination>\n * ```\n *\n * @example\n * // Legacy (deprecated)\n * ```tsx\n * <Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />\n * ```\n */\nfunction PaginationRoot(props: PaginationProps) {\n const { page = 1, perPage, totalCount, setPage, children, className } = props;\n\n // Extract legacy props (only present when children is not provided)\n const text = \"text\" in props ? props.text : undefined;\n const controls =\n \"controls\" in props\n ? (props.controls ?? KUMO_PAGINATION_DEFAULT_VARIANTS.controls)\n : KUMO_PAGINATION_DEFAULT_VARIANTS.controls;\n const [editingPage, setEditingPage] = useState<number>(1);\n\n useEffect(() => {\n setEditingPage(page);\n }, [page]);\n\n const pageShowingRange = useMemo(() => {\n let lower = page * (perPage ?? 1) - (perPage ?? 0) + 1;\n let upper = Math.min(page * (perPage ?? 0), totalCount ?? 0);\n\n if (Number.isNaN(lower)) lower = 0;\n if (Number.isNaN(upper)) upper = 0;\n\n return `${lower}-${upper}`;\n }, [page, perPage, totalCount]);\n\n const maxPage = useMemo(() => {\n return Math.ceil((totalCount ?? 1) / (perPage ?? 1));\n }, [totalCount, perPage]);\n\n const contextValue: PaginationContextValue = {\n page,\n perPage,\n totalCount,\n maxPage,\n pageShowingRange,\n setPage,\n editingPage,\n setEditingPage,\n };\n\n // Compound component mode: render children within context\n if (children) {\n return (\n <PaginationContext.Provider value={contextValue}>\n <div\n data-slot=\"pagination\"\n className={cn(\"flex items-center gap-2 w-full\", className)}\n >\n {children}\n </div>\n </PaginationContext.Provider>\n );\n }\n\n // Legacy mode: render default layout for backwards compatibility\n const getPaginationText = () => {\n if (text) {\n return text({ page, perPage, totalCount, pageShowingRange });\n } else if (totalCount && totalCount > 0) {\n return (\n <>\n Showing <span className=\"tabular-nums\">{pageShowingRange}</span> of{\" \"}\n <span className=\"tabular-nums\">{totalCount}</span>\n </>\n );\n }\n return null;\n };\n\n return (\n <PaginationContext.Provider value={contextValue}>\n <div\n data-slot=\"pagination\"\n className={cn(\"flex items-center gap-2 w-full\", className)}\n >\n <div\n data-slot=\"pagination-info\"\n className=\"grow text-sm text-kumo-strong\"\n >\n {getPaginationText()}\n </div>\n <PaginationControls controls={controls} />\n </div>\n </PaginationContext.Provider>\n );\n}\n\nPaginationRoot.displayName = \"Pagination\";\n\n// ============================================================================\n// Compound Component Export\n// ============================================================================\n\nexport const Pagination = Object.assign(PaginationRoot, {\n Info: PaginationInfo,\n PageSize: PaginationPageSize,\n Controls: PaginationControls,\n Separator: PaginationSeparator,\n});\n\nexport {\n PaginationInfo,\n PaginationPageSize,\n PaginationControls,\n PaginationSeparator,\n};\n"],"names":["DEFAULT_PAGE_SIZE_OPTIONS","KUMO_PAGINATION_DEFAULT_VARIANTS","PaginationContext","createContext","usePaginationContext","context","useContext","PaginationInfo","children","className","page","perPage","totalCount","pageShowingRange","content","jsxs","Fragment","jsx","cn","PaginationPageSize","value","onChange","options","label","Select","v","size","PaginationControls","controls","maxPage","setPage","editingPage","setEditingPage","InputGroup","CaretDoubleLeftIcon","previousPage","CaretLeftIcon","number","nextPage","CaretRightIcon","CaretDoubleRightIcon","PaginationSeparator","PaginationRoot","props","text","useState","useEffect","useMemo","lower","upper","contextValue","getPaginationText","Pagination"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as o, jsxs as i } from "react/jsx-runtime";
3
3
  import { c as s } from "./cn-ct4n7r74mh8y0f48.js";
4
- import { b9 as P, ba as f, bb as b, bc as h, bd as C, be as x, bf as N, bg as y, bh as L } from "./vendor-base-ui-kxxocm122zr4pipe.js";
4
+ import { b9 as P, ba as f, bb as b, bc as h, bd as C, be as x, bf as N, bg as y, bh as L } from "./vendor-base-ui-lgoligkf81eyvnde.js";
5
5
  const H = {
6
6
  side: {
7
7
  top: {
@@ -177,4 +177,4 @@ export {
177
177
  m as f,
178
178
  T as g
179
179
  };
180
- //# sourceMappingURL=popover-irccwetx73p8pnua.js.map
180
+ //# sourceMappingURL=popover-ji1zh9zqrj6at834.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover-irccwetx73p8pnua.js","sources":["../../src/components/popover/popover.tsx"],"sourcesContent":["import { Popover as PopoverBase } from \"@base-ui/react/popover\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Popover side variant definitions mapping positions to their Tailwind classes. */\nexport const KUMO_POPOVER_VARIANTS = {\n side: {\n top: {\n classes: \"\",\n description: \"Popover appears above the trigger\",\n },\n bottom: {\n classes: \"\",\n description: \"Popover appears below the trigger\",\n },\n left: {\n classes: \"\",\n description: \"Popover appears to the left of the trigger\",\n },\n right: {\n classes: \"\",\n description: \"Popover appears to the right of the trigger\",\n },\n },\n} as const;\n\nexport const KUMO_POPOVER_DEFAULT_VARIANTS = {\n side: \"bottom\",\n} as const;\n\n// Derived types from KUMO_POPOVER_VARIANTS\nexport type KumoPopoverSide = keyof typeof KUMO_POPOVER_VARIANTS.side;\n\nexport interface KumoPopoverVariantsProps {\n /**\n * Which side of the trigger the popover appears on.\n * - `\"top\"` — Above the trigger\n * - `\"bottom\"` — Below the trigger\n * - `\"left\"` — Left of the trigger\n * - `\"right\"` — Right of the trigger\n * @default \"bottom\"\n */\n side?: KumoPopoverSide;\n}\n\n// ============================================================================\n// Popover Root\n// ============================================================================\n\ntype BasePopoverRootProps = ComponentPropsWithoutRef<typeof PopoverBase.Root>;\n\nexport type PopoverRootProps = BasePopoverRootProps;\n\nfunction PopoverRoot({ children, ...props }: PopoverRootProps) {\n return <PopoverBase.Root {...props}>{children}</PopoverBase.Root>;\n}\n\nPopoverRoot.displayName = \"Popover\";\n\n// ============================================================================\n// Popover Trigger\n// ============================================================================\n\ntype BasePopoverTriggerProps = ComponentPropsWithoutRef<\n typeof PopoverBase.Trigger\n>;\n\nexport type PopoverTriggerProps = BasePopoverTriggerProps & {\n /** When true, the trigger element will be the child element */\n asChild?: boolean;\n};\n\nfunction PopoverTrigger({\n children,\n className,\n asChild,\n ...props\n}: PopoverTriggerProps) {\n return (\n <PopoverBase.Trigger\n className={className}\n render={\n asChild ? (children as BasePopoverTriggerProps[\"render\"]) : undefined\n }\n {...props}\n >\n {asChild ? undefined : children}\n </PopoverBase.Trigger>\n );\n}\n\nPopoverTrigger.displayName = \"Popover.Trigger\";\n\n// ============================================================================\n// Popover Content\n// ============================================================================\n\n/** Alignment options for popover positioning */\ntype PopoverAlign = \"start\" | \"center\" | \"end\";\n\n/**\n * Popover content panel props.\n *\n * @example\n * ```tsx\n * <Popover.Content side=\"top\" align=\"start\" sideOffset={12}>\n * <p>Popover body</p>\n * </Popover.Content>\n * ```\n */\nexport type PopoverContentProps = KumoPopoverVariantsProps & {\n /**\n * How to align the popover relative to the trigger.\n * @default \"center\"\n */\n align?: PopoverAlign;\n /**\n * Distance between the trigger and the popover in pixels.\n * @default 8\n */\n sideOffset?: number;\n /**\n * Additional offset along the alignment axis in pixels.\n * @default 0\n */\n alignOffset?: number;\n /**\n * Determines which CSS `position` property to use.\n * Use \"fixed\" when the popover needs to escape stacking contexts (e.g., inside sticky headers).\n * @default \"absolute\"\n */\n positionMethod?: \"absolute\" | \"fixed\";\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Content to render inside the popover. */\n children?: ReactNode;\n};\n\nfunction PopoverContent({\n children,\n side = KUMO_POPOVER_DEFAULT_VARIANTS.side,\n align = \"center\",\n sideOffset = 8,\n alignOffset = 0,\n positionMethod = \"absolute\",\n className,\n}: PopoverContentProps) {\n return (\n <PopoverBase.Portal>\n <PopoverBase.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n positionMethod={positionMethod}\n >\n <PopoverBase.Popup\n className={cn(\n \"flex origin-(--transform-origin) flex-col rounded-lg bg-kumo-base px-4 py-3 text-sm text-kumo-default\",\n \"shadow-lg shadow-kumo-tip-shadow outline outline-kumo-fill\",\n \"transition-[transform,scale,opacity] duration-150\",\n \"data-starting-style:scale-90 data-starting-style:opacity-0\",\n \"data-ending-style:scale-90 data-ending-style:opacity-0\",\n \"data-instant:duration-0\",\n \"kumo-popover-popup\",\n className,\n )}\n >\n <PopoverBase.Arrow\n className={cn(\n \"flex\",\n \"data-[side=bottom]:-top-2\",\n \"data-[side=left]:right-[-13px] data-[side=left]:rotate-90\",\n \"data-[side=right]:left-[-13px] data-[side=right]:-rotate-90\",\n \"data-[side=top]:-bottom-2 data-[side=top]:rotate-180\",\n )}\n >\n <ArrowSvg />\n </PopoverBase.Arrow>\n {children}\n </PopoverBase.Popup>\n </PopoverBase.Positioner>\n </PopoverBase.Portal>\n );\n}\n\nPopoverContent.displayName = \"Popover.Content\";\n\n// ============================================================================\n// Popover Title\n// ============================================================================\n\ntype BasePopoverTitleProps = ComponentPropsWithoutRef<typeof PopoverBase.Title>;\n\nexport type PopoverTitleProps = BasePopoverTitleProps;\n\nfunction PopoverTitle({ className, ...props }: PopoverTitleProps) {\n return (\n <PopoverBase.Title\n className={cn(\"m-0 text-base leading-6 font-medium\", className)}\n {...props}\n />\n );\n}\n\nPopoverTitle.displayName = \"Popover.Title\";\n\n// ============================================================================\n// Popover Description\n// ============================================================================\n\ntype BasePopoverDescriptionProps = ComponentPropsWithoutRef<\n typeof PopoverBase.Description\n>;\n\nexport type PopoverDescriptionProps = BasePopoverDescriptionProps;\n\nfunction PopoverDescription({ className, ...props }: PopoverDescriptionProps) {\n return (\n <PopoverBase.Description\n className={cn(\"m-0 text-base leading-6 text-kumo-subtle\", className)}\n {...props}\n />\n );\n}\n\nPopoverDescription.displayName = \"Popover.Description\";\n\n// ============================================================================\n// Popover Close\n// ============================================================================\n\ntype BasePopoverCloseProps = ComponentPropsWithoutRef<typeof PopoverBase.Close>;\n\nexport type PopoverCloseProps = BasePopoverCloseProps & {\n /** When true, the close element will be the child element */\n asChild?: boolean;\n};\n\nfunction PopoverClose({\n children,\n className,\n asChild,\n ...props\n}: PopoverCloseProps) {\n return (\n <PopoverBase.Close\n className={className}\n render={\n asChild ? (children as BasePopoverCloseProps[\"render\"]) : undefined\n }\n {...props}\n >\n {asChild ? undefined : children}\n </PopoverBase.Close>\n );\n}\n\nPopoverClose.displayName = \"Popover.Close\";\n\n// ============================================================================\n// Arrow SVG\n// ============================================================================\n\n/**\n * Arrow SVG with three paths for proper border rendering in both light and dark modes.\n * This approach matches Base UI's popover/tooltip implementation.\n *\n * The three paths are:\n * 1. ArrowFill - The main arrow body, matches popover background\n * 2. ArrowOuterStroke - Border visible in light mode only (transparent in dark)\n * 3. ArrowInnerStroke - Border visible in dark mode only (transparent in light)\n *\n * This is necessary because the outer and inner stroke paths have different geometries,\n * and using both ensures the arrow border aligns perfectly with the popover's outline\n * in both color modes.\n *\n * @see https://base-ui.com/react/components/popover\n */\nfunction ArrowSvg(props: React.ComponentProps<\"svg\">) {\n return (\n <svg width=\"20\" height=\"10\" viewBox=\"0 0 20 10\" fill=\"none\" {...props}>\n <path\n d=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n className=\"fill-kumo-base\"\n />\n <path\n d=\"M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z\"\n className=\"fill-kumo-tip-shadow\"\n />\n <path\n d=\"M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z\"\n className=\"fill-kumo-tip-stroke\"\n />\n </svg>\n );\n}\n\n// ============================================================================\n// Compound Component Export\n// ============================================================================\n\n/**\n * Popover component for displaying accessible popup content anchored to a trigger.\n *\n * @example\n * ```tsx\n * <Popover>\n * <Popover.Trigger asChild>\n * <Button>Open</Button>\n * </Popover.Trigger>\n * <Popover.Content>\n * <Popover.Title>Notifications</Popover.Title>\n * <Popover.Description>You are all caught up!</Popover.Description>\n * </Popover.Content>\n * </Popover>\n * ```\n *\n * @see https://base-ui.com/react/components/popover\n */\nexport const Popover = Object.assign(PopoverRoot, {\n Trigger: PopoverTrigger,\n Content: PopoverContent,\n Title: PopoverTitle,\n Description: PopoverDescription,\n Close: PopoverClose,\n});\n\n// Export sub-components for direct access and type inference\nexport {\n PopoverRoot,\n PopoverTrigger,\n PopoverContent,\n PopoverTitle,\n PopoverDescription,\n PopoverClose,\n};\n"],"names":["KUMO_POPOVER_VARIANTS","KUMO_POPOVER_DEFAULT_VARIANTS","PopoverRoot","children","props","PopoverBase.Root","PopoverTrigger","className","asChild","jsx","PopoverBase.Trigger","PopoverContent","side","align","sideOffset","alignOffset","positionMethod","PopoverBase.Portal","PopoverBase.Positioner","jsxs","PopoverBase.Popup","cn","PopoverBase.Arrow","ArrowSvg","PopoverTitle","PopoverBase.Title","PopoverDescription","PopoverBase.Description","PopoverClose","PopoverBase.Close","Popover"],"mappings":"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"}
1
+ {"version":3,"file":"popover-ji1zh9zqrj6at834.js","sources":["../../src/components/popover/popover.tsx"],"sourcesContent":["import { Popover as PopoverBase } from \"@base-ui/react/popover\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Popover side variant definitions mapping positions to their Tailwind classes. */\nexport const KUMO_POPOVER_VARIANTS = {\n side: {\n top: {\n classes: \"\",\n description: \"Popover appears above the trigger\",\n },\n bottom: {\n classes: \"\",\n description: \"Popover appears below the trigger\",\n },\n left: {\n classes: \"\",\n description: \"Popover appears to the left of the trigger\",\n },\n right: {\n classes: \"\",\n description: \"Popover appears to the right of the trigger\",\n },\n },\n} as const;\n\nexport const KUMO_POPOVER_DEFAULT_VARIANTS = {\n side: \"bottom\",\n} as const;\n\n// Derived types from KUMO_POPOVER_VARIANTS\nexport type KumoPopoverSide = keyof typeof KUMO_POPOVER_VARIANTS.side;\n\nexport interface KumoPopoverVariantsProps {\n /**\n * Which side of the trigger the popover appears on.\n * - `\"top\"` — Above the trigger\n * - `\"bottom\"` — Below the trigger\n * - `\"left\"` — Left of the trigger\n * - `\"right\"` — Right of the trigger\n * @default \"bottom\"\n */\n side?: KumoPopoverSide;\n}\n\n// ============================================================================\n// Popover Root\n// ============================================================================\n\ntype BasePopoverRootProps = ComponentPropsWithoutRef<typeof PopoverBase.Root>;\n\nexport type PopoverRootProps = BasePopoverRootProps;\n\nfunction PopoverRoot({ children, ...props }: PopoverRootProps) {\n return <PopoverBase.Root {...props}>{children}</PopoverBase.Root>;\n}\n\nPopoverRoot.displayName = \"Popover\";\n\n// ============================================================================\n// Popover Trigger\n// ============================================================================\n\ntype BasePopoverTriggerProps = ComponentPropsWithoutRef<\n typeof PopoverBase.Trigger\n>;\n\nexport type PopoverTriggerProps = BasePopoverTriggerProps & {\n /** When true, the trigger element will be the child element */\n asChild?: boolean;\n};\n\nfunction PopoverTrigger({\n children,\n className,\n asChild,\n ...props\n}: PopoverTriggerProps) {\n return (\n <PopoverBase.Trigger\n className={className}\n render={\n asChild ? (children as BasePopoverTriggerProps[\"render\"]) : undefined\n }\n {...props}\n >\n {asChild ? undefined : children}\n </PopoverBase.Trigger>\n );\n}\n\nPopoverTrigger.displayName = \"Popover.Trigger\";\n\n// ============================================================================\n// Popover Content\n// ============================================================================\n\n/** Alignment options for popover positioning */\ntype PopoverAlign = \"start\" | \"center\" | \"end\";\n\n/**\n * Popover content panel props.\n *\n * @example\n * ```tsx\n * <Popover.Content side=\"top\" align=\"start\" sideOffset={12}>\n * <p>Popover body</p>\n * </Popover.Content>\n * ```\n */\nexport type PopoverContentProps = KumoPopoverVariantsProps & {\n /**\n * How to align the popover relative to the trigger.\n * @default \"center\"\n */\n align?: PopoverAlign;\n /**\n * Distance between the trigger and the popover in pixels.\n * @default 8\n */\n sideOffset?: number;\n /**\n * Additional offset along the alignment axis in pixels.\n * @default 0\n */\n alignOffset?: number;\n /**\n * Determines which CSS `position` property to use.\n * Use \"fixed\" when the popover needs to escape stacking contexts (e.g., inside sticky headers).\n * @default \"absolute\"\n */\n positionMethod?: \"absolute\" | \"fixed\";\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Content to render inside the popover. */\n children?: ReactNode;\n};\n\nfunction PopoverContent({\n children,\n side = KUMO_POPOVER_DEFAULT_VARIANTS.side,\n align = \"center\",\n sideOffset = 8,\n alignOffset = 0,\n positionMethod = \"absolute\",\n className,\n}: PopoverContentProps) {\n return (\n <PopoverBase.Portal>\n <PopoverBase.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n positionMethod={positionMethod}\n >\n <PopoverBase.Popup\n className={cn(\n \"flex origin-(--transform-origin) flex-col rounded-lg bg-kumo-base px-4 py-3 text-sm text-kumo-default\",\n \"shadow-lg shadow-kumo-tip-shadow outline outline-kumo-fill\",\n \"transition-[transform,scale,opacity] duration-150\",\n \"data-starting-style:scale-90 data-starting-style:opacity-0\",\n \"data-ending-style:scale-90 data-ending-style:opacity-0\",\n \"data-instant:duration-0\",\n \"kumo-popover-popup\",\n className,\n )}\n >\n <PopoverBase.Arrow\n className={cn(\n \"flex\",\n \"data-[side=bottom]:-top-2\",\n \"data-[side=left]:right-[-13px] data-[side=left]:rotate-90\",\n \"data-[side=right]:left-[-13px] data-[side=right]:-rotate-90\",\n \"data-[side=top]:-bottom-2 data-[side=top]:rotate-180\",\n )}\n >\n <ArrowSvg />\n </PopoverBase.Arrow>\n {children}\n </PopoverBase.Popup>\n </PopoverBase.Positioner>\n </PopoverBase.Portal>\n );\n}\n\nPopoverContent.displayName = \"Popover.Content\";\n\n// ============================================================================\n// Popover Title\n// ============================================================================\n\ntype BasePopoverTitleProps = ComponentPropsWithoutRef<typeof PopoverBase.Title>;\n\nexport type PopoverTitleProps = BasePopoverTitleProps;\n\nfunction PopoverTitle({ className, ...props }: PopoverTitleProps) {\n return (\n <PopoverBase.Title\n className={cn(\"m-0 text-base leading-6 font-medium\", className)}\n {...props}\n />\n );\n}\n\nPopoverTitle.displayName = \"Popover.Title\";\n\n// ============================================================================\n// Popover Description\n// ============================================================================\n\ntype BasePopoverDescriptionProps = ComponentPropsWithoutRef<\n typeof PopoverBase.Description\n>;\n\nexport type PopoverDescriptionProps = BasePopoverDescriptionProps;\n\nfunction PopoverDescription({ className, ...props }: PopoverDescriptionProps) {\n return (\n <PopoverBase.Description\n className={cn(\"m-0 text-base leading-6 text-kumo-subtle\", className)}\n {...props}\n />\n );\n}\n\nPopoverDescription.displayName = \"Popover.Description\";\n\n// ============================================================================\n// Popover Close\n// ============================================================================\n\ntype BasePopoverCloseProps = ComponentPropsWithoutRef<typeof PopoverBase.Close>;\n\nexport type PopoverCloseProps = BasePopoverCloseProps & {\n /** When true, the close element will be the child element */\n asChild?: boolean;\n};\n\nfunction PopoverClose({\n children,\n className,\n asChild,\n ...props\n}: PopoverCloseProps) {\n return (\n <PopoverBase.Close\n className={className}\n render={\n asChild ? (children as BasePopoverCloseProps[\"render\"]) : undefined\n }\n {...props}\n >\n {asChild ? undefined : children}\n </PopoverBase.Close>\n );\n}\n\nPopoverClose.displayName = \"Popover.Close\";\n\n// ============================================================================\n// Arrow SVG\n// ============================================================================\n\n/**\n * Arrow SVG with three paths for proper border rendering in both light and dark modes.\n * This approach matches Base UI's popover/tooltip implementation.\n *\n * The three paths are:\n * 1. ArrowFill - The main arrow body, matches popover background\n * 2. ArrowOuterStroke - Border visible in light mode only (transparent in dark)\n * 3. ArrowInnerStroke - Border visible in dark mode only (transparent in light)\n *\n * This is necessary because the outer and inner stroke paths have different geometries,\n * and using both ensures the arrow border aligns perfectly with the popover's outline\n * in both color modes.\n *\n * @see https://base-ui.com/react/components/popover\n */\nfunction ArrowSvg(props: React.ComponentProps<\"svg\">) {\n return (\n <svg width=\"20\" height=\"10\" viewBox=\"0 0 20 10\" fill=\"none\" {...props}>\n <path\n d=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n className=\"fill-kumo-base\"\n />\n <path\n d=\"M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z\"\n className=\"fill-kumo-tip-shadow\"\n />\n <path\n d=\"M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z\"\n className=\"fill-kumo-tip-stroke\"\n />\n </svg>\n );\n}\n\n// ============================================================================\n// Compound Component Export\n// ============================================================================\n\n/**\n * Popover component for displaying accessible popup content anchored to a trigger.\n *\n * @example\n * ```tsx\n * <Popover>\n * <Popover.Trigger asChild>\n * <Button>Open</Button>\n * </Popover.Trigger>\n * <Popover.Content>\n * <Popover.Title>Notifications</Popover.Title>\n * <Popover.Description>You are all caught up!</Popover.Description>\n * </Popover.Content>\n * </Popover>\n * ```\n *\n * @see https://base-ui.com/react/components/popover\n */\nexport const Popover = Object.assign(PopoverRoot, {\n Trigger: PopoverTrigger,\n Content: PopoverContent,\n Title: PopoverTitle,\n Description: PopoverDescription,\n Close: PopoverClose,\n});\n\n// Export sub-components for direct access and type inference\nexport {\n PopoverRoot,\n PopoverTrigger,\n PopoverContent,\n PopoverTitle,\n PopoverDescription,\n PopoverClose,\n};\n"],"names":["KUMO_POPOVER_VARIANTS","KUMO_POPOVER_DEFAULT_VARIANTS","PopoverRoot","children","props","PopoverBase.Root","PopoverTrigger","className","asChild","jsx","PopoverBase.Trigger","PopoverContent","side","align","sideOffset","alignOffset","positionMethod","PopoverBase.Portal","PopoverBase.Positioner","jsxs","PopoverBase.Popup","cn","PopoverBase.Arrow","ArrowSvg","PopoverTitle","PopoverBase.Title","PopoverDescription","PopoverBase.Description","PopoverClose","PopoverBase.Close","Popover"],"mappings":"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"}
@@ -0,0 +1,200 @@
1
+ "use client";
2
+ import { jsx as e, jsxs as m } from "react/jsx-runtime";
3
+ import { forwardRef as y, createContext as j, useContext as A } from "react";
4
+ import { c as o } from "./cn-ct4n7r74mh8y0f48.js";
5
+ import { R as I, P as C, Q as G, bi as k, bj as h } from "./vendor-base-ui-lgoligkf81eyvnde.js";
6
+ const b = {
7
+ variant: {
8
+ default: {
9
+ classes: "ring-kumo-line",
10
+ description: "Default radio appearance"
11
+ },
12
+ error: {
13
+ classes: "ring-kumo-danger",
14
+ description: "Error state for validation failures"
15
+ }
16
+ },
17
+ appearance: {
18
+ default: {
19
+ classes: "",
20
+ description: "Standard inline radio item"
21
+ },
22
+ card: {
23
+ classes: "rounded-lg border border-kumo-ring bg-kumo-base p-3 transition-colors hover:bg-kumo-tint has-[[data-checked]]:border-kumo-interact has-[[data-checked]]:bg-kumo-tint",
24
+ description: "Choice card appearance with border, padding, and highlighted selection state"
25
+ }
26
+ }
27
+ }, x = {
28
+ variant: "default",
29
+ appearance: "default"
30
+ };
31
+ function O({
32
+ variant: t = x.variant,
33
+ appearance: r = x.appearance
34
+ } = {}) {
35
+ return o(
36
+ b.variant[t].classes,
37
+ b.appearance[r].classes
38
+ );
39
+ }
40
+ const v = j({
41
+ controlPosition: "start",
42
+ appearance: "default"
43
+ }), N = y(
44
+ ({
45
+ className: t,
46
+ disabled: r,
47
+ variant: a = "default",
48
+ appearance: s,
49
+ label: n,
50
+ description: i,
51
+ value: c
52
+ }, l) => {
53
+ const { controlPosition: f, appearance: d } = A(v), u = (s ?? d) === "card", p = u ? "end" : f;
54
+ return u ? /* @__PURE__ */ m(
55
+ "label",
56
+ {
57
+ className: o(
58
+ "m-0 group relative flex items-start gap-3 rounded-lg border border-kumo-ring bg-kumo-base p-3 transition-colors has-[[data-checked]]:border-kumo-interact has-[[data-checked]]:bg-kumo-tint",
59
+ a === "error" && "border-kumo-danger has-[[data-checked]]:border-kumo-danger has-[[data-checked]]:bg-kumo-base",
60
+ r ? "cursor-not-allowed opacity-50" : o(
61
+ "has-[[data-disabled]]:cursor-not-allowed has-[[data-disabled]]:opacity-50 cursor-pointer",
62
+ a !== "error" && "hover:not-has-[[data-disabled]]:bg-kumo-tint"
63
+ ),
64
+ t
65
+ ),
66
+ children: [
67
+ /* @__PURE__ */ m("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
68
+ /* @__PURE__ */ e("span", { className: "text-base font-medium text-kumo-default", children: n }),
69
+ i && /* @__PURE__ */ e("span", { className: "text-sm text-kumo-subtle", children: i })
70
+ ] }),
71
+ /* @__PURE__ */ e(
72
+ k,
73
+ {
74
+ ref: l,
75
+ value: c,
76
+ disabled: r,
77
+ className: o(
78
+ "relative mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full border-0 bg-kumo-base ring",
79
+ a === "error" ? "ring-kumo-danger" : "ring-kumo-line",
80
+ !r && a !== "error" && "group-hover:ring-kumo-ring focus-visible:ring-kumo-ring focus-visible:outline-offset-3",
81
+ !r && a === "error" && "focus-visible:ring-kumo-danger focus-visible:outline-offset-3",
82
+ "data-[checked]:bg-kumo-contrast"
83
+ ),
84
+ children: /* @__PURE__ */ e(
85
+ h,
86
+ {
87
+ keepMounted: !0,
88
+ className: "flex items-center justify-center",
89
+ children: /* @__PURE__ */ e("span", { className: "h-2 w-2 rounded-full bg-kumo-base" })
90
+ }
91
+ )
92
+ }
93
+ )
94
+ ]
95
+ }
96
+ ) : /* @__PURE__ */ m(
97
+ "label",
98
+ {
99
+ className: o(
100
+ "m-0 group relative inline-flex items-center gap-2",
101
+ // "start" (default): radio before label
102
+ // "end": label before radio using flex-row-reverse
103
+ p === "end" && "flex-row-reverse justify-end",
104
+ r ? "cursor-not-allowed opacity-50" : "cursor-pointer",
105
+ t
106
+ ),
107
+ children: [
108
+ /* @__PURE__ */ e(
109
+ k,
110
+ {
111
+ ref: l,
112
+ value: c,
113
+ disabled: r,
114
+ className: o(
115
+ "relative flex h-4 w-4 items-center justify-center rounded-full border-0 bg-kumo-base ring after:absolute after:-inset-x-3 after:-inset-y-2",
116
+ a === "error" ? "ring-kumo-danger" : "ring-kumo-line",
117
+ !r && a !== "error" && "group-hover:ring-kumo-ring focus-visible:ring-kumo-ring focus-visible:outline-offset-3",
118
+ !r && a === "error" && "focus-visible:ring-kumo-danger focus-visible:outline-offset-3",
119
+ "data-[checked]:bg-kumo-contrast"
120
+ ),
121
+ children: /* @__PURE__ */ e(
122
+ h,
123
+ {
124
+ keepMounted: !0,
125
+ className: "flex items-center justify-center",
126
+ children: /* @__PURE__ */ e("span", { className: "h-2 w-2 rounded-full bg-kumo-base" })
127
+ }
128
+ )
129
+ }
130
+ ),
131
+ /* @__PURE__ */ e("span", { className: "text-base font-medium text-kumo-default", children: n })
132
+ ]
133
+ }
134
+ );
135
+ }
136
+ );
137
+ N.displayName = "Radio.Item";
138
+ function R({
139
+ legend: t,
140
+ children: r,
141
+ orientation: a = "vertical",
142
+ appearance: s = "default",
143
+ error: n,
144
+ description: i,
145
+ defaultValue: c,
146
+ value: l,
147
+ onValueChange: f,
148
+ disabled: d,
149
+ controlPosition: g = "start",
150
+ name: u,
151
+ className: p
152
+ }) {
153
+ return /* @__PURE__ */ e(v.Provider, { value: { controlPosition: g, appearance: s }, children: /* @__PURE__ */ e(
154
+ I,
155
+ {
156
+ defaultValue: c,
157
+ value: l,
158
+ onValueChange: (w) => f?.(w),
159
+ disabled: d,
160
+ name: u,
161
+ children: /* @__PURE__ */ m(
162
+ C,
163
+ {
164
+ disabled: d,
165
+ className: o(
166
+ "flex flex-col gap-4 rounded-lg border border-kumo-line p-4",
167
+ p
168
+ ),
169
+ children: [
170
+ /* @__PURE__ */ e(G, { className: "text-lg font-medium text-kumo-default", children: t }),
171
+ /* @__PURE__ */ e(
172
+ "div",
173
+ {
174
+ className: o(
175
+ a === "vertical" ? o("flex flex-col", s === "card" ? "gap-3" : "gap-2") : s === "card" ? "grid grid-cols-2 gap-3" : "flex flex-row flex-wrap gap-2"
176
+ ),
177
+ children: r
178
+ }
179
+ ),
180
+ n && /* @__PURE__ */ e("p", { className: "text-sm text-kumo-danger", children: n }),
181
+ i && /* @__PURE__ */ e("p", { className: "text-sm text-kumo-subtle", children: i })
182
+ ]
183
+ }
184
+ )
185
+ }
186
+ ) });
187
+ }
188
+ R.displayName = "Radio.Group";
189
+ const V = {
190
+ Item: N,
191
+ Group: R
192
+ };
193
+ export {
194
+ b as K,
195
+ V as R,
196
+ R as a,
197
+ x as b,
198
+ O as r
199
+ };
200
+ //# sourceMappingURL=radio-cnsup12f302rxkxl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-cnsup12f302rxkxl.js","sources":["../../src/components/radio/radio.tsx"],"sourcesContent":["import { forwardRef, createContext, useContext, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Fieldset } from \"@base-ui/react/fieldset\";\nimport { RadioGroup as BaseRadioGroup } from \"@base-ui/react/radio-group\";\nimport { Radio as BaseRadio } from \"@base-ui/react/radio\";\n\n/** Radio variant definitions mapping variant names to their Tailwind classes. */\nexport const KUMO_RADIO_VARIANTS = {\n variant: {\n default: {\n classes: \"ring-kumo-line\",\n description: \"Default radio appearance\",\n },\n error: {\n classes: \"ring-kumo-danger\",\n description: \"Error state for validation failures\",\n },\n },\n appearance: {\n default: {\n classes: \"\",\n description: \"Standard inline radio item\",\n },\n card: {\n classes:\n \"rounded-lg border border-kumo-ring bg-kumo-base p-3 transition-colors hover:bg-kumo-tint has-[[data-checked]]:border-kumo-interact has-[[data-checked]]:bg-kumo-tint\",\n description:\n \"Choice card appearance with border, padding, and highlighted selection state\",\n },\n },\n} as const;\n\nexport const KUMO_RADIO_DEFAULT_VARIANTS = {\n variant: \"default\",\n appearance: \"default\",\n} as const;\n\n// Derived types from KUMO_RADIO_VARIANTS\nexport type KumoRadioVariant = keyof typeof KUMO_RADIO_VARIANTS.variant;\nexport type KumoRadioAppearance = keyof typeof KUMO_RADIO_VARIANTS.appearance;\n\nexport interface KumoRadioVariantsProps {\n /**\n * Visual variant.\n * - `\"default\"` — Standard radio appearance\n * - `\"error\"` — Error state for validation failures\n * @default \"default\"\n */\n variant?: KumoRadioVariant;\n /**\n * Visual appearance.\n * - `\"default\"` — Standard inline radio item\n * - `\"card\"` — Choice card with border, padding, and highlighted selection state\n * @default \"default\"\n */\n appearance?: KumoRadioAppearance;\n}\n\nexport function radioVariants({\n variant = KUMO_RADIO_DEFAULT_VARIANTS.variant,\n appearance = KUMO_RADIO_DEFAULT_VARIANTS.appearance,\n}: KumoRadioVariantsProps = {}) {\n return cn(\n KUMO_RADIO_VARIANTS.variant[variant].classes,\n KUMO_RADIO_VARIANTS.appearance[appearance].classes,\n );\n}\n\n// Legacy type alias for backwards compatibility\nexport type RadioVariant = KumoRadioVariant;\n\n/** Position of the radio control relative to its label */\nexport type RadioControlPosition = \"start\" | \"end\";\n\n// Context for passing controlPosition and appearance from Group to Items\nconst RadioGroupContext = createContext<{\n controlPosition: RadioControlPosition;\n appearance: KumoRadioAppearance;\n}>({\n controlPosition: \"start\",\n appearance: \"default\",\n});\n\n/**\n * Radio group component props (with built-in Fieldset and RadioGroup)\n *\n * @example\n * // Basic usage\n * ```tsx\n * <Radio.Group legend=\"Notification preference\" defaultValue=\"email\">\n * <Radio.Item label=\"Email\" value=\"email\" />\n * <Radio.Item label=\"SMS\" value=\"sms\" />\n * <Radio.Item label=\"Push\" value=\"push\" />\n * </Radio.Group>\n * ```\n *\n * @example\n * // Horizontal layout\n * ```tsx\n * <Radio.Group legend=\"Size\" orientation=\"horizontal\" defaultValue=\"md\">\n * <Radio.Item label=\"Small\" value=\"sm\" />\n * <Radio.Item label=\"Medium\" value=\"md\" />\n * <Radio.Item label=\"Large\" value=\"lg\" />\n * </Radio.Group>\n * ```\n *\n * @example\n * // With error and description\n * ```tsx\n * <Radio.Group\n * legend=\"Payment method\"\n * error=\"Please select a payment method\"\n * description=\"Choose how you'd like to pay\"\n * >\n * <Radio.Item label=\"Credit Card\" value=\"card\" />\n * <Radio.Item label=\"PayPal\" value=\"paypal\" />\n * </Radio.Group>\n * ```\n *\n * @example\n * // Controlled\n * ```tsx\n * const [value, setValue] = useState(\"email\");\n * <Radio.Group legend=\"Contact\" value={value} onValueChange={setValue}>\n * <Radio.Item label=\"Email\" value=\"email\" />\n * <Radio.Item label=\"Phone\" value=\"phone\" />\n * </Radio.Group>\n * ```\n *\n * @example\n * // Label before radio (controlPosition=\"end\")\n * ```tsx\n * <Radio.Group legend=\"Options\" controlPosition=\"end\" defaultValue=\"a\">\n * <Radio.Item label=\"Option A\" value=\"a\" />\n * <Radio.Item label=\"Option B\" value=\"b\" />\n * </Radio.Group>\n * ```\n */\nexport interface RadioGroupProps {\n /** Legend text for the group (required for accessibility) */\n legend: string;\n /** Child Radio.Item components */\n children: ReactNode;\n /** Layout direction of the radio items */\n orientation?: \"vertical\" | \"horizontal\";\n /**\n * Visual appearance applied to all Radio.Item children.\n * - `\"default\"` — Standard inline radio items\n * - `\"card\"` — Choice card with border, padding, and highlighted selection state\n *\n * Individual items can override this with their own `appearance` prop.\n * @default \"default\"\n */\n appearance?: KumoRadioAppearance;\n /** Error message for the group */\n error?: string;\n /** Helper text for the group */\n description?: ReactNode;\n /** Value of the radio that should be initially selected (uncontrolled) */\n defaultValue?: string;\n /** Value of the radio that should be selected (controlled) */\n value?: string;\n /** Event handler called when radio value changes */\n onValueChange?: (value: string) => void;\n /** Whether all radios in the group are disabled */\n disabled?: boolean;\n /** Position of radio control relative to label: \"start\" (default) puts radio before label, \"end\" puts label before radio. Note: In card appearance, the control is always positioned at the end. */\n controlPosition?: RadioControlPosition;\n /** Form submission name for the radio group */\n name?: string;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Individual radio item within a group\n *\n * @example\n * ```tsx\n * <Radio.Item label=\"Option A\" value=\"a\" />\n * ```\n *\n * @example\n * // Disabled item\n * ```tsx\n * <Radio.Item label=\"Unavailable\" value=\"unavailable\" disabled />\n * ```\n */\nexport type RadioItemProps = {\n /** Visual variant: \"default\" or \"error\" for validation failures */\n variant?: RadioVariant;\n /**\n * Visual appearance of the radio item.\n * - `\"default\"` — Standard inline radio item\n * - `\"card\"` — Choice card with border, padding, and highlighted selection state\n *\n * When set on an individual item, overrides the group-level `appearance`.\n * @default \"default\"\n */\n appearance?: KumoRadioAppearance;\n /** Label text displayed next to radio (required) */\n label: string;\n /** Description text displayed below the label (only visible in card appearance) */\n description?: ReactNode;\n /** Value of the radio (required) */\n value: string;\n /** Additional CSS classes for the label wrapper */\n className?: string;\n /** Whether the radio is disabled */\n disabled?: boolean;\n};\n\n// Radio.Item for use within Radio.Group\nconst RadioItem = forwardRef<HTMLButtonElement, RadioItemProps>(\n (\n {\n className,\n disabled,\n variant = \"default\",\n appearance: appearanceProp,\n label,\n description,\n value,\n },\n ref,\n ) => {\n const { controlPosition, appearance: groupAppearance } =\n useContext(RadioGroupContext);\n const appearance = appearanceProp ?? groupAppearance;\n const isCard = appearance === \"card\";\n\n // In card mode, default to \"end\" (radio on the right); otherwise follow group setting\n const effectiveControlPosition = isCard ? \"end\" : controlPosition;\n\n if (isCard) {\n return (\n <label\n className={cn(\n \"m-0 group relative flex items-start gap-3 rounded-lg border border-kumo-ring bg-kumo-base p-3 transition-colors has-[[data-checked]]:border-kumo-interact has-[[data-checked]]:bg-kumo-tint\",\n variant === \"error\" &&\n \"border-kumo-danger has-[[data-checked]]:border-kumo-danger has-[[data-checked]]:bg-kumo-base\",\n disabled\n ? \"cursor-not-allowed opacity-50\"\n : cn(\n \"has-[[data-disabled]]:cursor-not-allowed has-[[data-disabled]]:opacity-50 cursor-pointer\",\n variant !== \"error\" &&\n \"hover:not-has-[[data-disabled]]:bg-kumo-tint\",\n ),\n className,\n )}\n >\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n <span className=\"text-base font-medium text-kumo-default\">\n {label}\n </span>\n {description && (\n <span className=\"text-sm text-kumo-subtle\">{description}</span>\n )}\n </div>\n <BaseRadio.Root\n ref={ref}\n value={value}\n disabled={disabled}\n className={cn(\n \"relative mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full border-0 bg-kumo-base ring\",\n variant === \"error\" ? \"ring-kumo-danger\" : \"ring-kumo-line\",\n !disabled &&\n variant !== \"error\" &&\n \"group-hover:ring-kumo-ring focus-visible:ring-kumo-ring focus-visible:outline-offset-3\",\n !disabled &&\n variant === \"error\" &&\n \"focus-visible:ring-kumo-danger focus-visible:outline-offset-3\",\n \"data-[checked]:bg-kumo-contrast\",\n )}\n >\n <BaseRadio.Indicator\n keepMounted\n className=\"flex items-center justify-center\"\n >\n <span className=\"h-2 w-2 rounded-full bg-kumo-base\" />\n </BaseRadio.Indicator>\n </BaseRadio.Root>\n </label>\n );\n }\n\n return (\n <label\n className={cn(\n \"m-0 group relative inline-flex items-center gap-2\",\n // \"start\" (default): radio before label\n // \"end\": label before radio using flex-row-reverse\n effectiveControlPosition === \"end\" && \"flex-row-reverse justify-end\",\n disabled ? \"cursor-not-allowed opacity-50\" : \"cursor-pointer\",\n className,\n )}\n >\n <BaseRadio.Root\n ref={ref}\n value={value}\n disabled={disabled}\n className={cn(\n \"relative flex h-4 w-4 items-center justify-center rounded-full border-0 bg-kumo-base ring after:absolute after:-inset-x-3 after:-inset-y-2\",\n variant === \"error\" ? \"ring-kumo-danger\" : \"ring-kumo-line\",\n !disabled &&\n variant !== \"error\" &&\n \"group-hover:ring-kumo-ring focus-visible:ring-kumo-ring focus-visible:outline-offset-3\",\n !disabled &&\n variant === \"error\" &&\n \"focus-visible:ring-kumo-danger focus-visible:outline-offset-3\",\n \"data-[checked]:bg-kumo-contrast\",\n )}\n >\n <BaseRadio.Indicator\n keepMounted\n className=\"flex items-center justify-center\"\n >\n <span className=\"h-2 w-2 rounded-full bg-kumo-base\" />\n </BaseRadio.Indicator>\n </BaseRadio.Root>\n <span className=\"text-base font-medium text-kumo-default\">{label}</span>\n </label>\n );\n },\n);\n\nRadioItem.displayName = \"Radio.Item\";\n\n// Radio.Group with built-in Fieldset and RadioGroup\nfunction RadioGroup({\n legend,\n children,\n orientation = \"vertical\",\n appearance = \"default\",\n error,\n description,\n defaultValue,\n value,\n onValueChange,\n disabled,\n controlPosition = \"start\",\n name,\n className,\n}: RadioGroupProps) {\n return (\n <RadioGroupContext.Provider value={{ controlPosition, appearance }}>\n <BaseRadioGroup\n defaultValue={defaultValue}\n value={value}\n onValueChange={(newValue) => onValueChange?.(newValue)}\n disabled={disabled}\n name={name}\n >\n <Fieldset.Root\n disabled={disabled}\n className={cn(\n \"flex flex-col gap-4 rounded-lg border border-kumo-line p-4\",\n className,\n )}\n >\n <Fieldset.Legend className=\"text-lg font-medium text-kumo-default\">\n {legend}\n </Fieldset.Legend>\n <div\n className={cn(\n orientation === \"vertical\"\n ? cn(\"flex flex-col\", appearance === \"card\" ? \"gap-3\" : \"gap-2\")\n : appearance === \"card\"\n ? \"grid grid-cols-2 gap-3\"\n : \"flex flex-row flex-wrap gap-2\",\n )}\n >\n {children}\n </div>\n {error && <p className=\"text-sm text-kumo-danger\">{error}</p>}\n {description && (\n <p className=\"text-sm text-kumo-subtle\">{description}</p>\n )}\n </Fieldset.Root>\n </BaseRadioGroup>\n </RadioGroupContext.Provider>\n );\n}\n\nRadioGroup.displayName = \"Radio.Group\";\n\n// Export RadioGroup directly for external usage\nexport { RadioGroup };\n\n/**\n * Radio — radio button group for single-select choices.\n *\n * Compound component: `Radio.Group` (with built-in Fieldset) and `Radio.Item`.\n * Built on `@base-ui/react/radio-group` + `@base-ui/react/radio`.\n *\n * @example\n * ```tsx\n * <Radio.Group legend=\"Notification preference\" defaultValue=\"email\">\n * <Radio.Item label=\"Email\" value=\"email\" />\n * <Radio.Item label=\"SMS\" value=\"sms\" />\n * <Radio.Item label=\"Push\" value=\"push\" />\n * </Radio.Group>\n * ```\n */\nexport const Radio = {\n Item: RadioItem,\n Group: RadioGroup,\n};\n"],"names":["KUMO_RADIO_VARIANTS","KUMO_RADIO_DEFAULT_VARIANTS","radioVariants","variant","appearance","cn","RadioGroupContext","createContext","RadioItem","forwardRef","className","disabled","appearanceProp","label","description","value","ref","controlPosition","groupAppearance","useContext","isCard","effectiveControlPosition","jsxs","jsx","BaseRadio.Root","BaseRadio.Indicator","RadioGroup","legend","children","orientation","error","defaultValue","onValueChange","name","BaseRadioGroup","newValue","Fieldset.Root","Fieldset.Legend","Radio"],"mappings":"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"}
@@ -3,17 +3,17 @@ import { jsxs as r, jsx as e } from "react/jsx-runtime";
3
3
  import { CaretUpDownIcon as z, CheckIcon as C } from "@phosphor-icons/react";
4
4
  import { useId as O } from "react";
5
5
  import { c as v } from "./cn-ct4n7r74mh8y0f48.js";
6
- import { b as V } from "./button-b1yp3lbrhjr9eg07.js";
6
+ import { b as V } from "./button-d82sexqgnd834eaa.js";
7
7
  import { S as A } from "./skeleton-line-1j5exu6vv07mmhfb.js";
8
- import { F as E } from "./field-ftrgblg9mbmz9eo3.js";
9
- import { aU as P, aV as D, aW as T, aX as U, aY as W, aZ as _, a_ as $, a$ as B, b0 as K, b1 as M } from "./vendor-base-ui-kxxocm122zr4pipe.js";
8
+ import { F as E } from "./field-pcsc33yrvgq6g9ll.js";
9
+ import { aV as P, aW as D, aX as T, aY as W, aZ as _, a_ as $, a$ as B, b0 as K, b1 as M, b2 as R } from "./vendor-base-ui-lgoligkf81eyvnde.js";
10
10
  function y(t) {
11
11
  return Array.isArray(t) ? t : Object.entries(t).map(([o, a]) => ({
12
12
  value: o,
13
13
  label: a
14
14
  }));
15
15
  }
16
- function R(t) {
16
+ function U(t) {
17
17
  return y(t).filter((a) => a.value !== null).map((a, n) => /* @__PURE__ */ e(
18
18
  S,
19
19
  {
@@ -41,7 +41,7 @@ function X({
41
41
  process.env.NODE_ENV !== "production" && c !== void 0 && console.warn(
42
42
  '[Kumo Select]: `hideLabel` is deprecated. For hidden labels, use `aria-label` instead of `label` + `hideLabel={true}`.\n Migration:\n - For visible labels: <Select label="Country" /> (hideLabel no longer needed)\n - For hidden labels: <Select aria-label="Select a country" /> (remove label and hideLabel)'
43
43
  );
44
- const f = n && c !== !0, g = f ? void 0 : N ?? (n ? u : void 0), L = k ?? (g ? void 0 : w), F = i.items ? y(i.items) : void 0, j = t ?? (i.items ? R(i.items) : null), h = /* @__PURE__ */ r(
44
+ const f = n && c !== !0, g = f ? void 0 : N ?? (n ? u : void 0), L = k ?? (g ? void 0 : w), F = i.items ? y(i.items) : void 0, j = t ?? (i.items ? U(i.items) : null), h = /* @__PURE__ */ r(
45
45
  P,
46
46
  {
47
47
  ...i,
@@ -54,20 +54,27 @@ function X({
54
54
  className: v(
55
55
  V(),
56
56
  "justify-between font-normal",
57
- "outline-none focus:opacity-100 focus-visible:ring-1 focus-visible:ring-kumo-ring *:in-focus:opacity-100",
57
+ "focus:opacity-100 focus-visible:ring-1 focus-visible:ring-kumo-ring *:in-focus:opacity-100",
58
58
  i.disabled && "cursor-not-allowed opacity-50",
59
59
  o
60
60
  ),
61
61
  "aria-label": L,
62
62
  "aria-labelledby": g,
63
63
  children: [
64
- m ? /* @__PURE__ */ e(A, { className: "w-32" }) : /* @__PURE__ */ e(T, { placeholder: d, children: a }),
65
- /* @__PURE__ */ e(U, { className: "flex items-center", children: /* @__PURE__ */ e(z, {}) })
64
+ m ? /* @__PURE__ */ e(A, { className: "w-32" }) : /* @__PURE__ */ e(
65
+ T,
66
+ {
67
+ placeholder: d,
68
+ className: "min-w-0 truncate",
69
+ children: a
70
+ }
71
+ ),
72
+ /* @__PURE__ */ e(W, { className: "flex shrink-0 items-center", children: /* @__PURE__ */ e(z, {}) })
66
73
  ]
67
74
  }
68
75
  ),
69
- /* @__PURE__ */ e(W, { children: /* @__PURE__ */ e(_, { children: /* @__PURE__ */ e(
70
- $,
76
+ /* @__PURE__ */ e(_, { children: /* @__PURE__ */ e($, { children: /* @__PURE__ */ e(
77
+ B,
71
78
  {
72
79
  className: v(
73
80
  "overflow-hidden bg-kumo-control text-kumo-default",
@@ -105,13 +112,13 @@ function X({
105
112
  }
106
113
  function S({ children: t, value: o }) {
107
114
  return /* @__PURE__ */ r(
108
- B,
115
+ K,
109
116
  {
110
117
  value: o,
111
118
  className: "group flex cursor-pointer items-center justify-between gap-2 rounded px-2 py-1.5 text-base data-highlighted:bg-kumo-overlay",
112
119
  children: [
113
- /* @__PURE__ */ e(K, { children: t }),
114
- /* @__PURE__ */ e(M, { children: /* @__PURE__ */ e(C, {}) })
120
+ /* @__PURE__ */ e(M, { children: t }),
121
+ /* @__PURE__ */ e(R, { children: /* @__PURE__ */ e(C, {}) })
115
122
  ]
116
123
  }
117
124
  );
@@ -120,4 +127,4 @@ X.Option = S;
120
127
  export {
121
128
  X as S
122
129
  };
123
- //# sourceMappingURL=select-jxxef2rf76pgdrf8.js.map
130
+ //# sourceMappingURL=select-hgn6ikyor1p6jd9r.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-hgn6ikyor1p6jd9r.js","sources":["../../src/components/select/select.tsx"],"sourcesContent":["import { Select as SelectBase } from \"@base-ui/react/select\";\nimport { CaretUpDownIcon, CheckIcon } from \"@phosphor-icons/react\";\nimport { useId } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { buttonVariants } from \"../button\";\nimport { SkeletonLine } from \"../loader\";\nimport { Field, type FieldErrorMatch } from \"../field/field\";\n\n/** Select variant definitions (currently empty, reserved for future additions). */\nexport const KUMO_SELECT_VARIANTS = {\n // Select currently has no variant options but structure is ready for future additions\n} as const;\n\nexport const KUMO_SELECT_DEFAULT_VARIANTS = {} as const;\n\n/**\n * Select component styling metadata for Figma plugin code generation\n * Extracted from select.tsx implementation (source of truth)\n */\nexport const KUMO_SELECT_STYLING = {\n trigger: {\n height: 36, // h-9\n paddingX: 12, // px-3\n borderRadius: 8, // rounded-lg\n background: \"color-secondary\",\n text: \"text-color-surface\",\n ring: \"color-border\",\n fontSize: 16, // text-base\n fontWeight: 400, // font-normal\n },\n stateTokens: {\n focus: { ring: \"color-active\" },\n disabled: { opacity: 0.5 },\n },\n icons: {\n caret: { name: \"ph-caret-up-down\", size: 20 },\n check: { name: \"ph-check\", size: 20 },\n },\n popup: {\n background: \"color-secondary\",\n ring: \"color-border\",\n borderRadius: 8, // rounded-lg\n padding: 6, // p-1.5\n },\n option: {\n paddingX: 8, // px-2\n paddingY: 6, // py-1.5\n borderRadius: 4, // rounded\n fontSize: 16, // text-base\n highlightBackground: \"color-surface-secondary\",\n },\n} as const;\n\n// Derived types from KUMO_SELECT_VARIANTS\nexport interface KumoSelectVariantsProps {}\n\nexport function selectVariants(_props: KumoSelectVariantsProps = {}) {\n return cn(\n buttonVariants(),\n \"justify-between font-normal\",\n \"focus:opacity-100 focus-visible:ring-1 focus-visible:ring-kumo-ring *:in-focus:opacity-100\",\n );\n}\n\n/**\n * Normalizes items to array format for Base UI.\n * Object maps are converted to array format so Base UI can properly\n * handle value matching and placeholder display.\n */\nfunction normalizeItems<T>(\n items:\n | Record<string, ReactNode>\n | ReadonlyArray<{ label: ReactNode; value: T }>,\n): ReadonlyArray<{ label: ReactNode; value: T }> {\n if (Array.isArray(items)) {\n return items;\n }\n // Convert object map to array format\n return Object.entries(items).map(([key, label]) => ({\n value: key as T,\n label,\n }));\n}\n\n/**\n * Auto-generates Select.Option elements from items prop.\n * Only used when children are not explicitly provided.\n * Filters out null values (typically used for placeholders).\n */\nfunction renderOptionsFromItems<T>(\n items:\n | Record<string, ReactNode>\n | ReadonlyArray<{ label: ReactNode; value: T }>,\n): ReactNode {\n const normalizedItems = normalizeItems(items);\n\n // Filter out null values and render options\n return normalizedItems\n .filter((item) => item.value !== null)\n .map((item, index) => (\n <Option\n key={typeof item.value === \"string\" ? item.value : `option-${index}`}\n value={item.value}\n >\n {item.label}\n </Option>\n ));\n}\n\ntype SelectPropsGeneric<\n T,\n Multiple extends boolean | undefined = false,\n> = SelectBase.Root.Props<T, Multiple> &\n KumoSelectVariantsProps & {\n multiple?: Multiple;\n renderValue?: (value: Multiple extends true ? T[] : T) => ReactNode;\n className?: string;\n /**\n * Label content for the select.\n * When provided, enables the Field wrapper with a visible label.\n * For accessibility without a visible label, use `aria-label` instead.\n */\n label?: ReactNode;\n /**\n * @deprecated Use `aria-label` for hidden labels instead of `label` + `hideLabel={true}`.\n * When `label` is provided without `hideLabel`, the label is now visible by default (matching Input behavior).\n * This prop will be removed in a future version.\n */\n hideLabel?: boolean;\n placeholder?: string;\n loading?: boolean;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /** Helper text displayed below the select */\n description?: ReactNode;\n /** Error message or validation error object */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n };\n\n/**\n * Select component props.\n *\n * **Accessible Name Required:** Select should have one of:\n * 1. `label` prop (recommended) - enables Field wrapper with visible label\n * 2. `aria-label` - for selects without visible label (accessibility-only)\n * 3. `aria-labelledby` - for custom label association\n *\n * @example\n * ```tsx\n * // With visible label (recommended)\n * <Select label=\"Country\" onValueChange={setValue}>\n * <Select.Option value=\"us\">United States</Select.Option>\n * <Select.Option value=\"uk\">United Kingdom</Select.Option>\n * </Select>\n *\n * // Without visible label (use aria-label for accessibility)\n * <Select aria-label=\"Select a country\" onValueChange={setValue}>\n * <Select.Option value=\"us\">United States</Select.Option>\n * </Select>\n * ```\n */\nexport interface SelectProps {\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /**\n * Label content for the select.\n * When provided, enables the Field wrapper with a visible label above the select.\n * For accessibility without a visible label, use `aria-label` instead.\n */\n label?: ReactNode;\n /**\n * @deprecated Use `aria-label` for hidden labels instead of `label` + `hideLabel={true}`.\n * When `label` is provided without `hideLabel`, the label is now visible by default (matching Input behavior).\n * This prop will be removed in a future version.\n */\n hideLabel?: boolean;\n /** Placeholder text shown when no value is selected. */\n placeholder?: string;\n /** When `true`, shows a skeleton loader in place of the selected value. */\n loading?: boolean;\n /** Whether the select is disabled. */\n disabled?: boolean;\n /** Whether the select is required. When `false`, shows \"(optional)\" text. */\n required?: boolean;\n /** Tooltip content displayed next to the label via an info icon. */\n labelTooltip?: ReactNode;\n /** Currently selected value (controlled mode). */\n value?: unknown;\n /** Initial value for uncontrolled mode. */\n defaultValue?: unknown;\n /** Callback fired when the selected value changes. */\n onValueChange?: (value: unknown) => void;\n /** Enable multi-select mode. */\n multiple?: boolean;\n /** `Select.Option` elements to render in the dropdown. */\n children?: ReactNode;\n /** Helper text displayed below the select. */\n description?: ReactNode;\n /** Error message string or validation error object with `match` key. */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n}\n\n/**\n * Dropdown for selecting a value from a list of options.\n * Wraps Base UI Select with Kumo styling and optional Field integration.\n *\n * @example\n * ```tsx\n * <Select label=\"Fruit\" onValueChange={setFruit}>\n * <Select.Option value=\"apple\">Apple</Select.Option>\n * <Select.Option value=\"banana\">Banana</Select.Option>\n * </Select>\n * ```\n */\nexport function Select<T, Multiple extends boolean | undefined = false>({\n children,\n className,\n renderValue,\n label,\n hideLabel,\n placeholder,\n loading,\n labelTooltip,\n description,\n error,\n required,\n ...props\n}: SelectPropsGeneric<T, Multiple> & { required?: boolean }) {\n const labelId = useId();\n const propLookup = props as Record<string, unknown>;\n const ariaLabel = propLookup[\"aria-label\"] as string | undefined;\n const ariaLabelledby = propLookup[\"aria-labelledby\"] as string | undefined;\n // For aria-label, use string label or placeholder (ReactNode labels can't be used for aria-label)\n const fallbackLabel = typeof label === \"string\" ? label : placeholder;\n\n // Deprecation warning for hideLabel\n if (process.env.NODE_ENV !== \"production\" && hideLabel !== undefined) {\n console.warn(\n \"[Kumo Select]: `hideLabel` is deprecated. For hidden labels, use `aria-label` instead of `label` + `hideLabel={true}`.\\n\" +\n \" Migration:\\n\" +\n ' - For visible labels: <Select label=\"Country\" /> (hideLabel no longer needed)\\n' +\n ' - For hidden labels: <Select aria-label=\"Select a country\" /> (remove label and hideLabel)',\n );\n }\n\n // New behavior: label presence determines Field wrapper visibility (like Input)\n // hideLabel is only respected for backward compatibility when explicitly set to true\n const useFieldWrapper = label && hideLabel !== true;\n const triggerLabelledBy = useFieldWrapper\n ? undefined\n : (ariaLabelledby ?? (label ? labelId : undefined));\n const triggerAriaLabel =\n ariaLabel ?? (!triggerLabelledBy ? fallbackLabel : undefined);\n\n // Normalize items to array format for Base UI compatibility\n // This fixes placeholder not showing with object map items\n const normalizedItems = props.items ? normalizeItems(props.items) : undefined;\n\n // Auto-render children from items if children not provided\n const renderedChildren =\n children ?? (props.items ? renderOptionsFromItems(props.items) : null);\n\n const selectControl = (\n <SelectBase.Root\n {...props}\n items={normalizedItems}\n disabled={loading || props.disabled}\n >\n <SelectBase.Trigger\n className={cn(\n buttonVariants(),\n \"justify-between font-normal\",\n \"focus:opacity-100 focus-visible:ring-1 focus-visible:ring-kumo-ring *:in-focus:opacity-100\",\n props.disabled && \"cursor-not-allowed opacity-50\",\n className,\n )}\n aria-label={triggerAriaLabel}\n aria-labelledby={triggerLabelledBy}\n >\n {loading ? (\n <SkeletonLine className=\"w-32\" />\n ) : (\n <SelectBase.Value\n placeholder={placeholder}\n className=\"min-w-0 truncate\"\n >\n {renderValue}\n </SelectBase.Value>\n )}\n <SelectBase.Icon className=\"flex shrink-0 items-center\">\n <CaretUpDownIcon />\n </SelectBase.Icon>\n </SelectBase.Trigger>\n <SelectBase.Portal>\n <SelectBase.Positioner>\n <SelectBase.Popup\n className={cn(\n \"overflow-hidden bg-kumo-control text-kumo-default\", // background\n \"rounded-lg shadow-lg ring ring-kumo-line\", // border part\n // 3px adjustment to account for padding + border differences\n \"min-w-[calc(var(--anchor-width)+3px)] p-1.5\", // spacing\n )}\n >\n {renderedChildren}\n </SelectBase.Popup>\n </SelectBase.Positioner>\n </SelectBase.Portal>\n </SelectBase.Root>\n );\n\n // Use Field wrapper when label is provided and not hidden\n if (useFieldWrapper) {\n return (\n <Field\n label={label}\n required={required}\n labelTooltip={labelTooltip}\n description={description}\n error={\n error\n ? typeof error === \"string\"\n ? { message: error, match: true }\n : error\n : undefined\n }\n >\n {selectControl}\n </Field>\n );\n }\n\n // Render with standalone label when label is hidden (sr-only)\n // Still show description/error for accessibility and UX\n const normalizedError = error\n ? typeof error === \"string\"\n ? { message: error, match: true as const }\n : error\n : undefined;\n\n return (\n <div className=\"grid gap-2\">\n {label && (\n <span id={labelId} className=\"sr-only\">\n {label}\n </span>\n )}\n {selectControl}\n {normalizedError ? (\n <span className=\"text-sm text-kumo-danger\">\n {normalizedError.message}\n </span>\n ) : (\n description && (\n <span className=\"text-sm leading-snug text-kumo-subtle\">\n {description}\n </span>\n )\n )}\n </div>\n );\n}\n\ntype OptionProps<T> = {\n children: ReactNode;\n value: T;\n};\n\nfunction Option<T>({ children, value }: OptionProps<T>) {\n return (\n <SelectBase.Item\n value={value}\n className=\"group flex cursor-pointer items-center justify-between gap-2 rounded px-2 py-1.5 text-base data-highlighted:bg-kumo-overlay\"\n >\n <SelectBase.ItemText>{children}</SelectBase.ItemText>\n <SelectBase.ItemIndicator>\n <CheckIcon />\n </SelectBase.ItemIndicator>\n </SelectBase.Item>\n );\n}\n\nSelect.Option = Option;\n"],"names":["normalizeItems","items","key","label","renderOptionsFromItems","item","index","jsx","Option","Select","children","className","renderValue","hideLabel","placeholder","loading","labelTooltip","description","error","required","props","labelId","useId","propLookup","ariaLabel","ariaLabelledby","fallbackLabel","useFieldWrapper","triggerLabelledBy","triggerAriaLabel","normalizedItems","renderedChildren","selectControl","jsxs","SelectBase.Root","SelectBase.Trigger","cn","buttonVariants","SkeletonLine","SelectBase.Value","SelectBase.Icon","CaretUpDownIcon","SelectBase.Portal","SelectBase.Positioner","SelectBase.Popup","Field","normalizedError","value","SelectBase.Item","SelectBase.ItemText","SelectBase.ItemIndicator","CheckIcon"],"mappings":"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"}