@cloudflare/kumo 1.5.0 → 1.6.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 (166) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/ai/component-registry.json +62 -7
  3. package/ai/component-registry.md +378 -37
  4. package/ai/schemas.ts +12 -2
  5. package/bin/kumo.js +23 -19
  6. package/dist/.build-complete +1 -1
  7. package/dist/ai/schemas.d.ts +2166 -0
  8. package/dist/ai/schemas.d.ts.map +1 -0
  9. package/dist/catalog.js +1 -1
  10. package/dist/{checkbox-CWANiedi.js → checkbox-Dt8iSNOg.js} +3 -3
  11. package/dist/{checkbox-CWANiedi.js.map → checkbox-Dt8iSNOg.js.map} +1 -1
  12. package/dist/clipboard-text-Bw5rKPXz.js +185 -0
  13. package/dist/clipboard-text-Bw5rKPXz.js.map +1 -0
  14. package/dist/{combobox-C9koouxM.js → combobox-BIC-YZ2L.js} +41 -41
  15. package/dist/combobox-BIC-YZ2L.js.map +1 -0
  16. package/dist/command-line/cli.js +104 -47
  17. package/dist/command-line/commands/add.js +88 -30
  18. package/dist/command-line/commands/ai.js +2 -3
  19. package/dist/{command-palette-TGXgr6Vq.js → command-palette-D3MNR7w9.js} +31 -31
  20. package/dist/{command-palette-TGXgr6Vq.js.map → command-palette-D3MNR7w9.js.map} +1 -1
  21. package/dist/components/checkbox.js +1 -1
  22. package/dist/components/clipboard-text.js +1 -1
  23. package/dist/components/combobox.js +1 -1
  24. package/dist/components/command-palette.js +1 -1
  25. package/dist/components/date-picker.js +6 -0
  26. package/dist/components/date-picker.js.map +1 -0
  27. package/dist/components/dialog.js +1 -1
  28. package/dist/components/dropdown.js +1 -1
  29. package/dist/components/field.js +1 -1
  30. package/dist/components/input.js +3 -3
  31. package/dist/components/label.js +1 -1
  32. package/dist/components/link.js +1 -1
  33. package/dist/components/menubar.js +1 -1
  34. package/dist/components/meter.js +1 -1
  35. package/dist/components/pagination.js +1 -1
  36. package/dist/components/popover.js +1 -1
  37. package/dist/components/radio.js +1 -1
  38. package/dist/components/select.js +1 -1
  39. package/dist/components/sensitive-input.js +1 -1
  40. package/dist/components/switch.js +1 -1
  41. package/dist/components/table.js +1 -1
  42. package/dist/components/tabs.js +1 -1
  43. package/dist/components/toast.js +2 -2
  44. package/dist/components/tooltip.js +1 -1
  45. package/dist/date-picker-M6uNX5Ca.js +2921 -0
  46. package/dist/date-picker-M6uNX5Ca.js.map +1 -0
  47. package/dist/{dialog-CpCeOqSZ.js → dialog-toS9krNF.js} +17 -17
  48. package/dist/dialog-toS9krNF.js.map +1 -0
  49. package/dist/{dropdown-DFeFcKfn.js → dropdown-BquiYKKC.js} +38 -38
  50. package/dist/dropdown-BquiYKKC.js.map +1 -0
  51. package/dist/{field-Dt-XuSaQ.js → field-DCq04TgZ.js} +3 -3
  52. package/dist/{field-Dt-XuSaQ.js.map → field-DCq04TgZ.js.map} +1 -1
  53. package/dist/index.js +86 -73
  54. package/dist/index.js.map +1 -1
  55. package/dist/{input-GZAWBXYX.js → input-CCR8NGG7.js} +3 -3
  56. package/dist/{input-GZAWBXYX.js.map → input-CCR8NGG7.js.map} +1 -1
  57. package/dist/{input-area-CS1-ceY4.js → input-area-DU2Yvp_t.js} +3 -3
  58. package/dist/{input-area-CS1-ceY4.js.map → input-area-DU2Yvp_t.js.map} +1 -1
  59. package/dist/{input-group-COo-wz5O.js → input-group-C365-qBq.js} +2 -2
  60. package/dist/{input-group-COo-wz5O.js.map → input-group-C365-qBq.js.map} +1 -1
  61. package/dist/{label-ChZ2Pp5p.js → label-zjtV7oXa.js} +2 -2
  62. package/dist/{label-ChZ2Pp5p.js.map → label-zjtV7oXa.js.map} +1 -1
  63. package/dist/{link-Mj2WM1AS.js → link-C8pUZ4Q-.js} +8 -8
  64. package/dist/{link-Mj2WM1AS.js.map → link-C8pUZ4Q-.js.map} +1 -1
  65. package/dist/{menubar-CbXWXQYR.js → menubar-D7WvAf6x.js} +6 -6
  66. package/dist/menubar-D7WvAf6x.js.map +1 -0
  67. package/dist/{meter-Bu5f3mAc.js → meter-jQGKS1z4.js} +4 -4
  68. package/dist/{meter-Bu5f3mAc.js.map → meter-jQGKS1z4.js.map} +1 -1
  69. package/dist/{pagination-Bm8eMWpj.js → pagination-BN80iKY6.js} +21 -20
  70. package/dist/pagination-BN80iKY6.js.map +1 -0
  71. package/dist/{popover-D7yeRosi.js → popover-syU1104E.js} +4 -4
  72. package/dist/{popover-D7yeRosi.js.map → popover-syU1104E.js.map} +1 -1
  73. package/dist/primitives/accordion.js +1 -1
  74. package/dist/primitives/alert-dialog.js +1 -1
  75. package/dist/primitives/autocomplete.js +1 -1
  76. package/dist/primitives/avatar.js +1 -1
  77. package/dist/primitives/button.js +1 -1
  78. package/dist/primitives/checkbox-group.js +1 -1
  79. package/dist/primitives/checkbox.js +1 -1
  80. package/dist/primitives/collapsible.js +1 -1
  81. package/dist/primitives/combobox.js +1 -1
  82. package/dist/primitives/context-menu.js +1 -1
  83. package/dist/primitives/dialog.js +1 -1
  84. package/dist/primitives/direction-provider.js +1 -1
  85. package/dist/primitives/field.js +1 -1
  86. package/dist/primitives/fieldset.js +1 -1
  87. package/dist/primitives/form.js +1 -1
  88. package/dist/primitives/input.js +1 -1
  89. package/dist/primitives/menu.js +1 -1
  90. package/dist/primitives/menubar.js +1 -1
  91. package/dist/primitives/meter.js +1 -1
  92. package/dist/primitives/navigation-menu.js +1 -1
  93. package/dist/primitives/number-field.js +1 -1
  94. package/dist/primitives/popover.js +1 -1
  95. package/dist/primitives/preview-card.js +1 -1
  96. package/dist/primitives/progress.js +1 -1
  97. package/dist/primitives/radio-group.js +1 -1
  98. package/dist/primitives/radio.js +1 -1
  99. package/dist/primitives/scroll-area.js +1 -1
  100. package/dist/primitives/select.js +1 -1
  101. package/dist/primitives/separator.js +1 -1
  102. package/dist/primitives/slider.js +1 -1
  103. package/dist/primitives/switch.js +1 -1
  104. package/dist/primitives/tabs.js +1 -1
  105. package/dist/primitives/toast.js +1 -1
  106. package/dist/primitives/toggle-group.js +1 -1
  107. package/dist/primitives/toggle.js +1 -1
  108. package/dist/primitives/toolbar.js +1 -1
  109. package/dist/primitives/tooltip.js +1 -1
  110. package/dist/primitives.js +1 -1
  111. package/dist/{radio-CKn09bGo.js → radio-CWMtSx65.js} +8 -8
  112. package/dist/{radio-CKn09bGo.js.map → radio-CWMtSx65.js.map} +1 -1
  113. package/dist/{schemas-B-D2OT-O.js → schemas-DbIwo0ET.js} +254 -240
  114. package/dist/{schemas-B-D2OT-O.js.map → schemas-DbIwo0ET.js.map} +1 -1
  115. package/dist/{select-DvpgiOau.js → select-G6JqBVkg.js} +37 -37
  116. package/dist/{select-DvpgiOau.js.map → select-G6JqBVkg.js.map} +1 -1
  117. package/dist/{sensitive-input-BuYT6U6C.js → sensitive-input-DNFpycoy.js} +4 -4
  118. package/dist/{sensitive-input-BuYT6U6C.js.map → sensitive-input-DNFpycoy.js.map} +1 -1
  119. package/dist/src/blocks/delete-resource/delete-resource.d.ts.map +1 -1
  120. package/dist/src/blocks/delete-resource/delete-resource.tsx +213 -0
  121. package/dist/src/blocks/page-header/page-header.tsx +99 -0
  122. package/dist/src/blocks/resource-list/resource-list.test.tsx +28 -0
  123. package/dist/src/blocks/resource-list/resource-list.tsx +69 -0
  124. package/dist/src/command-line/commands/ai.d.ts.map +1 -1
  125. package/dist/src/command-line/utils/transformer.d.ts +8 -4
  126. package/dist/src/command-line/utils/transformer.d.ts.map +1 -1
  127. package/dist/src/components/clipboard-text/clipboard-text.d.ts +23 -0
  128. package/dist/src/components/clipboard-text/clipboard-text.d.ts.map +1 -1
  129. package/dist/src/components/date-picker/date-picker.d.ts +65 -0
  130. package/dist/src/components/date-picker/date-picker.d.ts.map +1 -0
  131. package/dist/src/components/date-picker/index.d.ts +4 -0
  132. package/dist/src/components/date-picker/index.d.ts.map +1 -0
  133. package/dist/src/components/dropdown/dropdown.d.ts.map +1 -1
  134. package/dist/src/components/pagination/pagination.d.ts +8 -1
  135. package/dist/src/components/pagination/pagination.d.ts.map +1 -1
  136. package/dist/src/components/table/table.d.ts +2 -0
  137. package/dist/src/components/table/table.d.ts.map +1 -1
  138. package/dist/src/index.d.ts +1 -0
  139. package/dist/src/index.d.ts.map +1 -1
  140. package/dist/styles/kumo-binding.css +0 -4
  141. package/dist/styles/kumo-standalone.css +1 -1
  142. package/dist/styles/kumo.css +541 -0
  143. package/dist/{switch-Tu34uFoa.js → switch-CmsZ4z-g.js} +9 -9
  144. package/dist/{switch-Tu34uFoa.js.map → switch-CmsZ4z-g.js.map} +1 -1
  145. package/dist/table-Dc0AGcLV.js +149 -0
  146. package/dist/table-Dc0AGcLV.js.map +1 -0
  147. package/dist/{tabs-B7THfqHW.js → tabs-BpD1iUiz.js} +2 -2
  148. package/dist/{tabs-B7THfqHW.js.map → tabs-BpD1iUiz.js.map} +1 -1
  149. package/dist/{toast-Du4y8qng.js → toast-BrR0pjLE.js} +8 -8
  150. package/dist/{toast-Du4y8qng.js.map → toast-BrR0pjLE.js.map} +1 -1
  151. package/dist/{tooltip-BxV1H6AV.js → tooltip-daVJYtXY.js} +2 -2
  152. package/dist/{tooltip-BxV1H6AV.js.map → tooltip-daVJYtXY.js.map} +1 -1
  153. package/dist/{vendor-base-ui-CQ6wEonS.js → vendor-base-ui-9w7J6BvW.js} +7246 -7245
  154. package/dist/{vendor-base-ui-CQ6wEonS.js.map → vendor-base-ui-9w7J6BvW.js.map} +1 -1
  155. package/package.json +6 -1
  156. package/scripts/component-registry/discovery.ts +1 -7
  157. package/scripts/css-build.ts +47 -1
  158. package/dist/clipboard-text-CqueQiB8.js +0 -108
  159. package/dist/clipboard-text-CqueQiB8.js.map +0 -1
  160. package/dist/combobox-C9koouxM.js.map +0 -1
  161. package/dist/dialog-CpCeOqSZ.js.map +0 -1
  162. package/dist/dropdown-DFeFcKfn.js.map +0 -1
  163. package/dist/menubar-CbXWXQYR.js.map +0 -1
  164. package/dist/pagination-Bm8eMWpj.js.map +0 -1
  165. package/dist/table-BUmvaBj8.js +0 -153
  166. package/dist/table-BUmvaBj8.js.map +0 -1
@@ -512,10 +512,14 @@ Read-only text field with a one-click copy-to-clipboard button.
512
512
  The text to display and copy to clipboard.
513
513
  - `className`: string
514
514
  Additional CSS classes merged via `cn()`.
515
+ - `tooltip`: object
516
+ Tooltip config. Shows tooltip on hover, anchored toast on click.
517
+ - `labels`: object
518
+ Accessible labels for i18n.
515
519
 
516
520
  **Colors (kumo tokens used):**
517
521
 
518
- `bg-kumo-base`, `border-kumo-line`
522
+ `bg-kumo-base`, `border-kumo-line`, `outline-kumo-fill`, `text-kumo-default`
519
523
 
520
524
  **Styling:**
521
525
 
@@ -569,6 +573,13 @@ Read-only text field with a one-click copy-to-clipboard button.
569
573
  <ClipboardText text="0c239dd2" />
570
574
  ```
571
575
 
576
+ ```tsx
577
+ <ClipboardText
578
+ text="npx kumo add button"
579
+ tooltip={{ text: "Copy", copiedText: "Copied!", side: "top" }}
580
+ />
581
+ ```
582
+
572
583
 
573
584
  ---
574
585
 
@@ -1639,6 +1650,180 @@ CommandPalette — accessible command palette / spotlight search overlay. Compo
1639
1650
  ```
1640
1651
 
1641
1652
 
1653
+ ---
1654
+
1655
+ ### DatePicker
1656
+
1657
+ DatePicker — a date selection calendar. Built on [react-day-picker](https://daypicker.dev) with Kumo styling. Supports three selection modes: single, multiple, and range.
1658
+
1659
+ **Type:** component
1660
+
1661
+ **Import:** `import { DatePicker } from "@cloudflare/kumo";`
1662
+
1663
+ **Category:** Other
1664
+
1665
+ **Props:**
1666
+
1667
+ - `className`: string
1668
+ Additional CSS classes
1669
+ - `children`: ReactNode
1670
+ Child elements
1671
+
1672
+ **Colors (kumo tokens used):**
1673
+
1674
+ `bg-kumo-base`
1675
+
1676
+ **Examples:**
1677
+
1678
+ ```tsx
1679
+ <div className="flex flex-col gap-4">
1680
+ <DatePicker mode="single" selected={date} onChange={d => {
1681
+ if (d) {
1682
+ setDate(d);
1683
+ }
1684
+ }} />
1685
+ <p className="text-sm text-kumo-subtle">
1686
+ Selected: {date ? date.toLocaleDateString() : "None"}
1687
+ </p>
1688
+ </div>
1689
+ ```
1690
+
1691
+ ```tsx
1692
+ <div className="flex flex-col gap-4">
1693
+ <DatePicker
1694
+ mode="multiple"
1695
+ selected={dates}
1696
+ onChange={setDates}
1697
+ max={5}
1698
+ />
1699
+ <p className="text-sm text-kumo-subtle">
1700
+ Selected: {dates?.length ?? 0} date(s)
1701
+ </p>
1702
+ </div>
1703
+ ```
1704
+
1705
+ ```tsx
1706
+ <div className="flex flex-col gap-4">
1707
+ <DatePicker
1708
+ mode="range"
1709
+ selected={range}
1710
+ onChange={setRange}
1711
+ numberOfMonths={2}
1712
+ />
1713
+ <p className="text-sm text-kumo-subtle">
1714
+ Range:{" "}
1715
+ {range?.from
1716
+ ? `${range.from.toLocaleDateString()} - ${range.to?.toLocaleDateString() ?? "..."}`
1717
+ : "None"}
1718
+ </p>
1719
+ </div>
1720
+ ```
1721
+
1722
+ ```tsx
1723
+ <div className="flex flex-col gap-4">
1724
+ <DatePicker
1725
+ mode="range"
1726
+ selected={range}
1727
+ onChange={setRange}
1728
+ min={3}
1729
+ max={7}
1730
+ footer={
1731
+ <span className="text-xs text-kumo-subtle">Select 3-7 nights</span>
1732
+ }
1733
+ />
1734
+ </div>
1735
+ ```
1736
+
1737
+ ```tsx
1738
+ <Popover>
1739
+ <Popover.Trigger asChild>
1740
+ <Button variant="outline" icon={CalendarDotsIcon}>
1741
+ {date ? date.toLocaleDateString() : "Pick a date"}
1742
+ </Button>
1743
+ </Popover.Trigger>
1744
+ <Popover.Content className="p-3">
1745
+ <DatePicker mode="single" selected={date} onChange={setDate} />
1746
+ </Popover.Content>
1747
+ </Popover>
1748
+ ```
1749
+
1750
+ ```tsx
1751
+ <Popover>
1752
+ <Popover.Trigger asChild>
1753
+ <Button variant="outline" icon={CalendarDotsIcon}>
1754
+ {formatRange()}
1755
+ </Button>
1756
+ </Popover.Trigger>
1757
+ <Popover.Content className="p-3">
1758
+ <DatePicker
1759
+ mode="range"
1760
+ selected={range}
1761
+ onChange={setRange}
1762
+ numberOfMonths={2}
1763
+ />
1764
+ </Popover.Content>
1765
+ </Popover>
1766
+ ```
1767
+
1768
+ ```tsx
1769
+ <Popover>
1770
+ <Popover.Trigger asChild>
1771
+ <Button variant="outline" icon={CalendarDotsIcon}>
1772
+ {formatRange()}
1773
+ </Button>
1774
+ </Popover.Trigger>
1775
+ <Popover.Content className="p-0">
1776
+ <div className="flex">
1777
+ <div className="flex flex-col gap-1 border-r border-kumo-line p-2 text-sm">
1778
+ {presets.map((preset) => {
1779
+ const isActive = isPresetActive(preset);
1780
+ return (
1781
+ <button
1782
+ key={preset.label}
1783
+ type="button"
1784
+ onClick={() => handlePresetClick(preset)}
1785
+ className={`rounded-md px-3 py-1.5 text-left whitespace-nowrap ${isActive
1786
+ ? "bg-kumo-bg-inverse text-kumo-text-inverse"
1787
+ : "text-kumo-strong hover:bg-kumo-control"
1788
+ }`}
1789
+ >
1790
+ {preset.label}
1791
+ </button>
1792
+ );
1793
+ })}
1794
+ </div>
1795
+ <div className="p-3">
1796
+ <DatePicker
1797
+ mode="range"
1798
+ selected={range}
1799
+ onChange={setRange}
1800
+ month={month}
1801
+ onMonthChange={setMonth}
1802
+ numberOfMonths={2}
1803
+ />
1804
+ </div>
1805
+ </div>
1806
+ </Popover.Content>
1807
+ </Popover>
1808
+ ```
1809
+
1810
+ ```tsx
1811
+ <DatePicker
1812
+ mode="multiple"
1813
+ selected={dates}
1814
+ onChange={setDates}
1815
+ max={maxDays}
1816
+ disabled={unavailableDates}
1817
+ fixedWeeks
1818
+ footer={
1819
+ <p className="text-xs text-kumo-subtle pt-2 w-full">
1820
+ {selectedCount}/{maxDays} days selected. Grayed dates are unavailable.
1821
+ </p>
1822
+ }
1823
+ />
1824
+ ```
1825
+
1826
+
1642
1827
  ---
1643
1828
 
1644
1829
  ### DateRangePicker
@@ -1970,6 +2155,110 @@ Close sub-component
1970
2155
  </Dialog.Root>
1971
2156
  ```
1972
2157
 
2158
+ ```tsx
2159
+ <Dialog.Root>
2160
+ <Dialog.Trigger render={(p) => <Button {...p}>Open Form</Button>} />
2161
+ <Dialog className="p-8">
2162
+ <div className="mb-4 flex items-start justify-between gap-4">
2163
+ <Dialog.Title className="text-2xl font-semibold">
2164
+ Create Resource
2165
+ </Dialog.Title>
2166
+ <Dialog.Close
2167
+ aria-label="Close"
2168
+ render={(props) => (
2169
+ <Button
2170
+ {...props}
2171
+ variant="secondary"
2172
+ shape="square"
2173
+ icon={<X />}
2174
+ aria-label="Close"
2175
+ />
2176
+ )}
2177
+ />
2178
+ </div>
2179
+ <Dialog.Description className="mb-4 text-kumo-subtle">
2180
+ Select a region for your new resource.
2181
+ </Dialog.Description>
2182
+ <Select
2183
+ className="w-full"
2184
+ renderValue={(v) =>
2185
+ regions.find((r) => r.value === v)?.label ?? "Select region..."
2186
+ }
2187
+ >
2188
+ {regions.map((region) => (
2189
+ <Select.Option key={region.value} value={region.value}>
2190
+ {region.label}
2191
+ </Select.Option>
2192
+ ))}
2193
+ </Select>
2194
+ <div className="mt-8 flex justify-end gap-2">
2195
+ <Dialog.Close
2196
+ render={(props) => (
2197
+ <Button variant="secondary" {...props}>
2198
+ Cancel
2199
+ </Button>
2200
+ )}
2201
+ />
2202
+ <Button variant="primary">Create</Button>
2203
+ </div>
2204
+ </Dialog>
2205
+ </Dialog.Root>
2206
+ ```
2207
+
2208
+ ```tsx
2209
+ <Dialog.Root>
2210
+ <Dialog.Trigger render={(p) => <Button {...p}>Open Form</Button>} />
2211
+ <Dialog className="p-8">
2212
+ <div className="mb-4 flex items-start justify-between gap-4">
2213
+ <Dialog.Title className="text-2xl font-semibold">
2214
+ Create Resource
2215
+ </Dialog.Title>
2216
+ <Dialog.Close
2217
+ aria-label="Close"
2218
+ render={(props) => (
2219
+ <Button
2220
+ {...props}
2221
+ variant="secondary"
2222
+ shape="square"
2223
+ icon={<X />}
2224
+ aria-label="Close"
2225
+ />
2226
+ )}
2227
+ />
2228
+ </div>
2229
+ <Dialog.Description className="mb-4 text-kumo-subtle">
2230
+ Search and select a region for your new resource.
2231
+ </Dialog.Description>
2232
+ <Combobox value={value} onValueChange={setValue} items={regions}>
2233
+ <Combobox.TriggerInput
2234
+ className="w-full"
2235
+ placeholder="Search regions..."
2236
+ />
2237
+ <Combobox.Content>
2238
+ <Combobox.Empty>No regions found</Combobox.Empty>
2239
+ <Combobox.List>
2240
+ {(item: { value: string; label: string }) => (
2241
+ <Combobox.Item key={item.value} value={item}>
2242
+ {item.label}
2243
+ </Combobox.Item>
2244
+ )}
2245
+ </Combobox.List>
2246
+ </Combobox.Content>
2247
+ </Combobox>
2248
+ <div className="mt-8 flex justify-end gap-2">
2249
+ <Dialog.Close
2250
+ render={(props) => (
2251
+ <Button variant="secondary" {...props}>
2252
+ Cancel
2253
+ </Button>
2254
+ )}
2255
+ />
2256
+ <Button variant="primary">Create</Button>
2257
+ </div>
2258
+ </Dialog>
2259
+ </Dialog.Root>
2260
+ ```
2261
+
1973
2262
 
1974
2263
  ---
1975
2264
 
@@ -3090,6 +3379,8 @@ Page navigation controls with page count display.
3090
3379
  Number of items displayed per page.
3091
3380
  - `totalCount`: number
3092
3381
  Total number of items across all pages.
3382
+ - `text`: object
3383
+ Method to provide custom pagination text
3093
3384
 
3094
3385
  **Colors (kumo tokens used):**
3095
3386
 
@@ -3114,6 +3405,16 @@ Page navigation controls with page count display.
3114
3405
  />
3115
3406
  ```
3116
3407
 
3408
+ ```tsx
3409
+ <Pagination
3410
+ text={({ perPage }) => `Page ${page} - showing ${perPage} per page`}
3411
+ page={page}
3412
+ setPage={setPage}
3413
+ perPage={25}
3414
+ totalCount={100}
3415
+ />
3416
+ ```
3417
+
3117
3418
 
3118
3419
  ---
3119
3420
 
@@ -3955,16 +4256,27 @@ ResizeHandle sub-component
3955
4256
  <Table>
3956
4257
  <Table.Header>
3957
4258
  <Table.Row>
3958
- <Table.CheckHead aria-label="Select all rows" />
4259
+ <Table.CheckHead
4260
+ checked={selectedIds.size === rows.length}
4261
+ indeterminate={
4262
+ selectedIds.size > 0 && selectedIds.size < rows.length
4263
+ }
4264
+ onValueChange={toggleAll}
4265
+ aria-label="Select all rows"
4266
+ />
3959
4267
  <Table.Head>Subject</Table.Head>
3960
4268
  <Table.Head>From</Table.Head>
3961
4269
  <Table.Head>Date</Table.Head>
3962
4270
  </Table.Row>
3963
4271
  </Table.Header>
3964
4272
  <Table.Body>
3965
- {emailData.slice(0, 3).map((row) => (
4273
+ {rows.map((row) => (
3966
4274
  <Table.Row key={row.id}>
3967
- <Table.CheckCell aria-label={`Select ${row.subject}`} />
4275
+ <Table.CheckCell
4276
+ checked={selectedIds.has(row.id)}
4277
+ onValueChange={() => toggleRow(row.id)}
4278
+ aria-label={`Select ${row.subject}`}
4279
+ />
3968
4280
  <Table.Cell>{row.subject}</Table.Cell>
3969
4281
  <Table.Cell>{row.from}</Table.Cell>
3970
4282
  <Table.Cell>{row.date}</Table.Cell>
@@ -3982,31 +4294,35 @@ ResizeHandle sub-component
3982
4294
  <Table>
3983
4295
  <Table.Header>
3984
4296
  <Table.Row>
3985
- <Table.CheckHead aria-label="Select all rows" />
4297
+ <Table.CheckHead
4298
+ checked={selectedIds.size === rows.length}
4299
+ indeterminate={
4300
+ selectedIds.size > 0 && selectedIds.size < rows.length
4301
+ }
4302
+ onValueChange={toggleAll}
4303
+ aria-label="Select all rows"
4304
+ />
3986
4305
  <Table.Head>Subject</Table.Head>
3987
4306
  <Table.Head>From</Table.Head>
3988
4307
  <Table.Head>Date</Table.Head>
3989
4308
  </Table.Row>
3990
4309
  </Table.Header>
3991
4310
  <Table.Body>
3992
- <Table.Row>
3993
- <Table.CheckCell aria-label="Select row 1" />
3994
- <Table.Cell>Kumo v1.0.0 released</Table.Cell>
3995
- <Table.Cell>Visal In</Table.Cell>
3996
- <Table.Cell>5 seconds ago</Table.Cell>
3997
- </Table.Row>
3998
- <Table.Row variant="selected">
3999
- <Table.CheckCell checked aria-label="Select row 2" />
4000
- <Table.Cell>New Job Offer</Table.Cell>
4001
- <Table.Cell>Cloudflare</Table.Cell>
4002
- <Table.Cell>10 minutes ago</Table.Cell>
4003
- </Table.Row>
4004
- <Table.Row>
4005
- <Table.CheckCell aria-label="Select row 3" />
4006
- <Table.Cell>Daily Email Digest</Table.Cell>
4007
- <Table.Cell>Cloudflare</Table.Cell>
4008
- <Table.Cell>1 hour ago</Table.Cell>
4009
- </Table.Row>
4311
+ {rows.map((row) => (
4312
+ <Table.Row
4313
+ key={row.id}
4314
+ variant={selectedIds.has(row.id) ? "selected" : "default"}
4315
+ >
4316
+ <Table.CheckCell
4317
+ checked={selectedIds.has(row.id)}
4318
+ onValueChange={() => toggleRow(row.id)}
4319
+ aria-label={`Select ${row.subject}`}
4320
+ />
4321
+ <Table.Cell>{row.subject}</Table.Cell>
4322
+ <Table.Cell>{row.from}</Table.Cell>
4323
+ <Table.Cell>{row.date}</Table.Cell>
4324
+ </Table.Row>
4325
+ ))}
4010
4326
  </Table.Body>
4011
4327
  </Table>
4012
4328
  </LayerCard.Primary>
@@ -4048,7 +4364,8 @@ ResizeHandle sub-component
4048
4364
  <LayerCard.Primary className="w-full overflow-x-auto p-0">
4049
4365
  <Table layout="fixed">
4050
4366
  <colgroup>
4051
- <col style={{ width: "40px" }} />
4367
+ <col />{" "}
4368
+ {/* Checkbox column - width handled by Table.CheckHead/CheckCell */}
4052
4369
  <col />
4053
4370
  <col style={{ width: "150px" }} />
4054
4371
  <col style={{ width: "120px" }} />
@@ -4056,7 +4373,14 @@ ResizeHandle sub-component
4056
4373
  </colgroup>
4057
4374
  <Table.Header>
4058
4375
  <Table.Row>
4059
- <Table.CheckHead aria-label="Select all rows" />
4376
+ <Table.CheckHead
4377
+ checked={selectedIds.size === emailData.length}
4378
+ indeterminate={
4379
+ selectedIds.size > 0 && selectedIds.size < emailData.length
4380
+ }
4381
+ onValueChange={toggleAll}
4382
+ aria-label="Select all rows"
4383
+ />
4060
4384
  <Table.Head>Subject</Table.Head>
4061
4385
  <Table.Head>From</Table.Head>
4062
4386
  <Table.Head>Date</Table.Head>
@@ -4064,13 +4388,14 @@ ResizeHandle sub-component
4064
4388
  </Table.Row>
4065
4389
  </Table.Header>
4066
4390
  <Table.Body>
4067
- {emailData.map((row, index) => (
4391
+ {emailData.map((row) => (
4068
4392
  <Table.Row
4069
4393
  key={row.id}
4070
- variant={index === 1 ? "selected" : "default"}
4394
+ variant={selectedIds.has(row.id) ? "selected" : "default"}
4071
4395
  >
4072
4396
  <Table.CheckCell
4073
- checked={index === 1}
4397
+ checked={selectedIds.has(row.id)}
4398
+ onValueChange={() => toggleRow(row.id)}
4074
4399
  aria-label={`Select ${row.subject}`}
4075
4400
  />
4076
4401
  <Table.Cell>
@@ -4093,14 +4418,30 @@ ResizeHandle sub-component
4093
4418
  <span className="truncate">{row.date}</span>
4094
4419
  </Table.Cell>
4095
4420
  <Table.Cell className="text-right">
4096
- <Button
4097
- variant="ghost"
4098
- size="sm"
4099
- shape="square"
4100
- aria-label="More options"
4101
- >
4102
- <DotsThree weight="bold" size={16} />
4103
- </Button>
4421
+ <DropdownMenu>
4422
+ <DropdownMenu.Trigger
4423
+ render={
4424
+ <Button
4425
+ variant="ghost"
4426
+ size="sm"
4427
+ shape="square"
4428
+ aria-label="More options"
4429
+ >
4430
+ <DotsThree weight="bold" size={16} />
4431
+ </Button>
4432
+ }
4433
+ />
4434
+ <DropdownMenu.Content>
4435
+ <DropdownMenu.Item icon={Eye}>View</DropdownMenu.Item>
4436
+ <DropdownMenu.Item icon={PencilSimple}>
4437
+ Edit
4438
+ </DropdownMenu.Item>
4439
+ <DropdownMenu.Separator />
4440
+ <DropdownMenu.Item icon={Trash} variant="danger">
4441
+ Delete
4442
+ </DropdownMenu.Item>
4443
+ </DropdownMenu.Content>
4444
+ </DropdownMenu>
4104
4445
  </Table.Cell>
4105
4446
  </Table.Row>
4106
4447
  ))}
@@ -4482,7 +4823,7 @@ Multi-line textarea input with Input variants and InputArea-specific dimensions
4482
4823
  - **Feedback:** Banner, Loader, Toasty
4483
4824
  - **Action:** Button, ClipboardText
4484
4825
  - **Input:** Checkbox, Combobox, DateRangePicker, Field, Input, Radio, Select, Switch
4485
- - **Other:** CloudflareLogo, Label, Link, SensitiveInput, Table, DeleteResource
4826
+ - **Other:** CloudflareLogo, DatePicker, Label, Link, SensitiveInput, Table, DeleteResource
4486
4827
  - **Navigation:** CommandPalette, MenuBar, Pagination, Tabs
4487
4828
  - **Overlay:** Dialog, DropdownMenu, Popover, Tooltip
4488
4829
  - **Layout:** Grid, Surface, PageHeader, ResourceListPage
package/ai/schemas.ts CHANGED
@@ -165,6 +165,8 @@ export const ClipboardTextPropsSchema = z.object({
165
165
  size: z.enum(["sm", "base", "lg"]).optional(), // Size of the clipboard text field. - `"sm"` — Small clipboard text for compact UIs - `"base"` — Default clipboard text size - `"lg"` — Large clipboard text for prominent display
166
166
  text: z.string(), // The text to display and copy to clipboard.
167
167
  className: z.string().optional(), // Additional CSS classes merged via `cn()`.
168
+ tooltip: z.unknown().optional(), // Tooltip config. Shows tooltip on hover, anchored toast on click.
169
+ labels: z.unknown().optional(), // Accessible labels for i18n.
168
170
  });
169
171
 
170
172
  export const CloudflareLogoPropsSchema = z.object({
@@ -460,6 +462,11 @@ export const CommandPalettePropsSchema = z.object({
460
462
  children: z.union([z.string(), z.number(), z.boolean(), z.null(), DynamicValueSchema]).optional(), // Child content - typically one or more Panel components
461
463
  });
462
464
 
465
+ export const DatePickerPropsSchema = z.object({
466
+ className: z.string().optional(), // Additional CSS classes
467
+ children: z.union([z.string(), z.number(), z.boolean(), z.null(), DynamicValueSchema]).optional(), // Child elements
468
+ });
469
+
463
470
  export const DateRangePickerPropsSchema = z.object({
464
471
  size: z.enum(["sm", "base", "lg"]).optional(), // Calendar size. - `"sm"` — Compact calendar for tight spaces - `"base"` — Default calendar size - `"lg"` — Large calendar for prominent date selection
465
472
  variant: z.enum(["default", "subtle"]).optional(), // Visual variant. - `"default"` — Standard appearance with overlay background - `"subtle"` — Minimal background
@@ -583,6 +590,7 @@ export const PaginationPropsSchema = z.object({
583
590
  page: z.number().optional(), // Current page number (1-indexed).
584
591
  perPage: z.number().optional(), // Number of items displayed per page.
585
592
  totalCount: z.number().optional(), // Total number of items across all pages.
593
+ text: z.unknown().optional(), // Method to provide custom pagination text
586
594
  });
587
595
 
588
596
  export const PopoverPropsSchema = z.object({
@@ -719,7 +727,7 @@ export const TooltipPropsSchema = z.object({
719
727
  /**
720
728
  * All valid component type names
721
729
  */
722
- export type KumoComponentType = "Badge" | "Banner" | "Breadcrumbs" | "Button" | "Checkbox" | "ClipboardText" | "CloudflareLogo" | "Code" | "Collapsible" | "Combobox" | "CommandPalette" | "DateRangePicker" | "Dialog" | "DropdownMenu" | "Empty" | "Field" | "Grid" | "Input" | "InputArea" | "Label" | "LayerCard" | "Link" | "Loader" | "MenuBar" | "Meter" | "Pagination" | "Popover" | "Radio" | "Select" | "SensitiveInput" | "Surface" | "Switch" | "Table" | "Tabs" | "Text" | "Toasty" | "Tooltip";
730
+ export type KumoComponentType = "Badge" | "Banner" | "Breadcrumbs" | "Button" | "Checkbox" | "ClipboardText" | "CloudflareLogo" | "Code" | "Collapsible" | "Combobox" | "CommandPalette" | "DatePicker" | "DateRangePicker" | "Dialog" | "DropdownMenu" | "Empty" | "Field" | "Grid" | "Input" | "InputArea" | "Label" | "LayerCard" | "Link" | "Loader" | "MenuBar" | "Meter" | "Pagination" | "Popover" | "Radio" | "Select" | "SensitiveInput" | "Surface" | "Switch" | "Table" | "Tabs" | "Text" | "Toasty" | "Tooltip";
723
731
 
724
732
  export const KumoComponentTypeSchema = z.enum([
725
733
  "Badge",
@@ -733,6 +741,7 @@ export const KumoComponentTypeSchema = z.enum([
733
741
  "Collapsible",
734
742
  "Combobox",
735
743
  "CommandPalette",
744
+ "DatePicker",
736
745
  "DateRangePicker",
737
746
  "Dialog",
738
747
  "DropdownMenu",
@@ -776,6 +785,7 @@ export const ComponentPropsSchemas = {
776
785
  Collapsible: CollapsiblePropsSchema,
777
786
  Combobox: ComboboxPropsSchema,
778
787
  CommandPalette: CommandPalettePropsSchema,
788
+ DatePicker: DatePickerPropsSchema,
779
789
  DateRangePicker: DateRangePickerPropsSchema,
780
790
  Dialog: DialogPropsSchema,
781
791
  DropdownMenu: DropdownMenuPropsSchema,
@@ -858,4 +868,4 @@ export function validateUITree(tree: unknown): SafeParseResult<UITree> {
858
868
  /**
859
869
  * List of all component names (for catalog generation)
860
870
  */
861
- export const KUMO_COMPONENT_NAMES = ["Badge", "Banner", "Breadcrumbs", "Button", "Checkbox", "ClipboardText", "CloudflareLogo", "Code", "Collapsible", "Combobox", "CommandPalette", "DateRangePicker", "Dialog", "DropdownMenu", "Empty", "Field", "Grid", "Input", "InputArea", "Label", "LayerCard", "Link", "Loader", "MenuBar", "Meter", "Pagination", "Popover", "Radio", "Select", "SensitiveInput", "Surface", "Switch", "Table", "Tabs", "Text", "Toasty", "Tooltip"] as const;
871
+ export const KUMO_COMPONENT_NAMES = ["Badge", "Banner", "Breadcrumbs", "Button", "Checkbox", "ClipboardText", "CloudflareLogo", "Code", "Collapsible", "Combobox", "CommandPalette", "DatePicker", "DateRangePicker", "Dialog", "DropdownMenu", "Empty", "Field", "Grid", "Input", "InputArea", "Label", "LayerCard", "Link", "Loader", "MenuBar", "Meter", "Pagination", "Popover", "Radio", "Select", "SensitiveInput", "Surface", "Switch", "Table", "Tabs", "Text", "Toasty", "Tooltip"] as const;
package/bin/kumo.js CHANGED
@@ -7,26 +7,30 @@ import { fileURLToPath, pathToFileURL } from "node:url";
7
7
  const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = path.dirname(__filename);
9
9
 
10
- const distCliPath = path.resolve(__dirname, "../dist/command-line/cli.js");
11
- if (existsSync(distCliPath)) {
12
- await import(pathToFileURL(distCliPath).href);
13
- process.exit(0);
14
- }
10
+ async function main() {
11
+ const distCliPath = path.resolve(__dirname, "../dist/command-line/cli.js");
12
+ if (existsSync(distCliPath)) {
13
+ await import(pathToFileURL(distCliPath).href);
14
+ return;
15
+ }
15
16
 
16
- // In a repo checkout, the CLI may not be built yet. If `tsx` is available,
17
- // run the TypeScript entrypoint directly.
18
- const srcCliPath = path.resolve(__dirname, "../src/command-line/cli.ts");
19
- if (existsSync(srcCliPath)) {
20
- const result = spawnSync(
21
- process.execPath,
22
- ["--import", "tsx", srcCliPath, ...process.argv.slice(2)],
23
- { stdio: "inherit" },
24
- );
17
+ // In a repo checkout, the CLI may not be built yet. If `tsx` is available,
18
+ // run the TypeScript entrypoint directly.
19
+ const srcCliPath = path.resolve(__dirname, "../src/command-line/cli.ts");
20
+ if (existsSync(srcCliPath)) {
21
+ const result = spawnSync(
22
+ process.execPath,
23
+ ["--import", "tsx", srcCliPath, ...process.argv.slice(2)],
24
+ { stdio: "inherit" },
25
+ );
25
26
 
26
- process.exit(result.status ?? 1);
27
+ process.exit(result.status ?? 1);
28
+ }
29
+
30
+ console.error(
31
+ "Kumo CLI entrypoint not found. If you're in the repo, run: pnpm --filter @cloudflare/kumo build",
32
+ );
33
+ process.exit(1);
27
34
  }
28
35
 
29
- console.error(
30
- "Kumo CLI entrypoint not found. If you're in the repo, run: pnpm --filter @cloudflare/kumo build",
31
- );
32
- process.exit(1);
36
+ main();
@@ -1 +1 @@
1
- 1770743558382
1
+ 1771426000663