@cloudflare/kumo 1.5.1 → 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 (150) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/ai/component-registry.json +52 -3
  3. package/ai/component-registry.md +291 -2
  4. package/ai/schemas.ts +11 -2
  5. package/dist/.build-complete +1 -1
  6. package/dist/ai/schemas.d.ts +24 -5
  7. package/dist/ai/schemas.d.ts.map +1 -1
  8. package/dist/catalog.js +1 -1
  9. package/dist/{checkbox-CWANiedi.js → checkbox-Dt8iSNOg.js} +3 -3
  10. package/dist/{checkbox-CWANiedi.js.map → checkbox-Dt8iSNOg.js.map} +1 -1
  11. package/dist/clipboard-text-Bw5rKPXz.js +185 -0
  12. package/dist/clipboard-text-Bw5rKPXz.js.map +1 -0
  13. package/dist/{combobox-C9koouxM.js → combobox-BIC-YZ2L.js} +41 -41
  14. package/dist/combobox-BIC-YZ2L.js.map +1 -0
  15. package/dist/command-line/cli.js +88 -30
  16. package/dist/command-line/commands/add.js +88 -30
  17. package/dist/{command-palette-TGXgr6Vq.js → command-palette-D3MNR7w9.js} +31 -31
  18. package/dist/{command-palette-TGXgr6Vq.js.map → command-palette-D3MNR7w9.js.map} +1 -1
  19. package/dist/components/checkbox.js +1 -1
  20. package/dist/components/clipboard-text.js +1 -1
  21. package/dist/components/combobox.js +1 -1
  22. package/dist/components/command-palette.js +1 -1
  23. package/dist/components/date-picker.js +6 -0
  24. package/dist/components/date-picker.js.map +1 -0
  25. package/dist/components/dialog.js +1 -1
  26. package/dist/components/dropdown.js +1 -1
  27. package/dist/components/field.js +1 -1
  28. package/dist/components/input.js +3 -3
  29. package/dist/components/label.js +1 -1
  30. package/dist/components/link.js +1 -1
  31. package/dist/components/menubar.js +1 -1
  32. package/dist/components/meter.js +1 -1
  33. package/dist/components/pagination.js +1 -1
  34. package/dist/components/popover.js +1 -1
  35. package/dist/components/radio.js +1 -1
  36. package/dist/components/select.js +1 -1
  37. package/dist/components/sensitive-input.js +1 -1
  38. package/dist/components/switch.js +1 -1
  39. package/dist/components/table.js +1 -1
  40. package/dist/components/tabs.js +1 -1
  41. package/dist/components/toast.js +2 -2
  42. package/dist/components/tooltip.js +1 -1
  43. package/dist/date-picker-M6uNX5Ca.js +2921 -0
  44. package/dist/date-picker-M6uNX5Ca.js.map +1 -0
  45. package/dist/{dialog-CpCeOqSZ.js → dialog-toS9krNF.js} +17 -17
  46. package/dist/dialog-toS9krNF.js.map +1 -0
  47. package/dist/{dropdown-DFeFcKfn.js → dropdown-BquiYKKC.js} +38 -38
  48. package/dist/dropdown-BquiYKKC.js.map +1 -0
  49. package/dist/{field-Dt-XuSaQ.js → field-DCq04TgZ.js} +3 -3
  50. package/dist/{field-Dt-XuSaQ.js.map → field-DCq04TgZ.js.map} +1 -1
  51. package/dist/index.js +51 -49
  52. package/dist/index.js.map +1 -1
  53. package/dist/{input-GZAWBXYX.js → input-CCR8NGG7.js} +3 -3
  54. package/dist/{input-GZAWBXYX.js.map → input-CCR8NGG7.js.map} +1 -1
  55. package/dist/{input-area-CS1-ceY4.js → input-area-DU2Yvp_t.js} +3 -3
  56. package/dist/{input-area-CS1-ceY4.js.map → input-area-DU2Yvp_t.js.map} +1 -1
  57. package/dist/{input-group-COo-wz5O.js → input-group-C365-qBq.js} +2 -2
  58. package/dist/{input-group-COo-wz5O.js.map → input-group-C365-qBq.js.map} +1 -1
  59. package/dist/{label-ChZ2Pp5p.js → label-zjtV7oXa.js} +2 -2
  60. package/dist/{label-ChZ2Pp5p.js.map → label-zjtV7oXa.js.map} +1 -1
  61. package/dist/{link-Mj2WM1AS.js → link-C8pUZ4Q-.js} +8 -8
  62. package/dist/{link-Mj2WM1AS.js.map → link-C8pUZ4Q-.js.map} +1 -1
  63. package/dist/{menubar-CbXWXQYR.js → menubar-D7WvAf6x.js} +6 -6
  64. package/dist/menubar-D7WvAf6x.js.map +1 -0
  65. package/dist/{meter-Bu5f3mAc.js → meter-jQGKS1z4.js} +4 -4
  66. package/dist/{meter-Bu5f3mAc.js.map → meter-jQGKS1z4.js.map} +1 -1
  67. package/dist/{pagination-Cf-yRO-n.js → pagination-BN80iKY6.js} +2 -2
  68. package/dist/{pagination-Cf-yRO-n.js.map → pagination-BN80iKY6.js.map} +1 -1
  69. package/dist/{popover-D7yeRosi.js → popover-syU1104E.js} +4 -4
  70. package/dist/{popover-D7yeRosi.js.map → popover-syU1104E.js.map} +1 -1
  71. package/dist/primitives/accordion.js +1 -1
  72. package/dist/primitives/alert-dialog.js +1 -1
  73. package/dist/primitives/autocomplete.js +1 -1
  74. package/dist/primitives/avatar.js +1 -1
  75. package/dist/primitives/button.js +1 -1
  76. package/dist/primitives/checkbox-group.js +1 -1
  77. package/dist/primitives/checkbox.js +1 -1
  78. package/dist/primitives/collapsible.js +1 -1
  79. package/dist/primitives/combobox.js +1 -1
  80. package/dist/primitives/context-menu.js +1 -1
  81. package/dist/primitives/dialog.js +1 -1
  82. package/dist/primitives/direction-provider.js +1 -1
  83. package/dist/primitives/field.js +1 -1
  84. package/dist/primitives/fieldset.js +1 -1
  85. package/dist/primitives/form.js +1 -1
  86. package/dist/primitives/input.js +1 -1
  87. package/dist/primitives/menu.js +1 -1
  88. package/dist/primitives/menubar.js +1 -1
  89. package/dist/primitives/meter.js +1 -1
  90. package/dist/primitives/navigation-menu.js +1 -1
  91. package/dist/primitives/number-field.js +1 -1
  92. package/dist/primitives/popover.js +1 -1
  93. package/dist/primitives/preview-card.js +1 -1
  94. package/dist/primitives/progress.js +1 -1
  95. package/dist/primitives/radio-group.js +1 -1
  96. package/dist/primitives/radio.js +1 -1
  97. package/dist/primitives/scroll-area.js +1 -1
  98. package/dist/primitives/select.js +1 -1
  99. package/dist/primitives/separator.js +1 -1
  100. package/dist/primitives/slider.js +1 -1
  101. package/dist/primitives/switch.js +1 -1
  102. package/dist/primitives/tabs.js +1 -1
  103. package/dist/primitives/toast.js +1 -1
  104. package/dist/primitives/toggle-group.js +1 -1
  105. package/dist/primitives/toggle.js +1 -1
  106. package/dist/primitives/toolbar.js +1 -1
  107. package/dist/primitives/tooltip.js +1 -1
  108. package/dist/primitives.js +1 -1
  109. package/dist/{radio-CKn09bGo.js → radio-CWMtSx65.js} +8 -8
  110. package/dist/{radio-CKn09bGo.js.map → radio-CWMtSx65.js.map} +1 -1
  111. package/dist/{schemas-H10xB2M_.js → schemas-DbIwo0ET.js} +251 -239
  112. package/dist/{schemas-H10xB2M_.js.map → schemas-DbIwo0ET.js.map} +1 -1
  113. package/dist/{select-DvpgiOau.js → select-G6JqBVkg.js} +37 -37
  114. package/dist/{select-DvpgiOau.js.map → select-G6JqBVkg.js.map} +1 -1
  115. package/dist/{sensitive-input-BuYT6U6C.js → sensitive-input-DNFpycoy.js} +4 -4
  116. package/dist/{sensitive-input-BuYT6U6C.js.map → sensitive-input-DNFpycoy.js.map} +1 -1
  117. package/dist/src/command-line/utils/transformer.d.ts +8 -4
  118. package/dist/src/command-line/utils/transformer.d.ts.map +1 -1
  119. package/dist/src/components/clipboard-text/clipboard-text.d.ts +23 -0
  120. package/dist/src/components/clipboard-text/clipboard-text.d.ts.map +1 -1
  121. package/dist/src/components/date-picker/date-picker.d.ts +65 -0
  122. package/dist/src/components/date-picker/date-picker.d.ts.map +1 -0
  123. package/dist/src/components/date-picker/index.d.ts +4 -0
  124. package/dist/src/components/date-picker/index.d.ts.map +1 -0
  125. package/dist/src/components/dropdown/dropdown.d.ts.map +1 -1
  126. package/dist/src/index.d.ts +1 -0
  127. package/dist/src/index.d.ts.map +1 -1
  128. package/dist/styles/kumo-binding.css +0 -4
  129. package/dist/styles/kumo-standalone.css +1 -1
  130. package/dist/styles/kumo.css +541 -0
  131. package/dist/{switch-Tu34uFoa.js → switch-CmsZ4z-g.js} +9 -9
  132. package/dist/{switch-Tu34uFoa.js.map → switch-CmsZ4z-g.js.map} +1 -1
  133. package/dist/{table-DtUrZ2Rj.js → table-Dc0AGcLV.js} +2 -2
  134. package/dist/{table-DtUrZ2Rj.js.map → table-Dc0AGcLV.js.map} +1 -1
  135. package/dist/{tabs-B7THfqHW.js → tabs-BpD1iUiz.js} +2 -2
  136. package/dist/{tabs-B7THfqHW.js.map → tabs-BpD1iUiz.js.map} +1 -1
  137. package/dist/{toast-Du4y8qng.js → toast-BrR0pjLE.js} +8 -8
  138. package/dist/{toast-Du4y8qng.js.map → toast-BrR0pjLE.js.map} +1 -1
  139. package/dist/{tooltip-BxV1H6AV.js → tooltip-daVJYtXY.js} +2 -2
  140. package/dist/{tooltip-BxV1H6AV.js.map → tooltip-daVJYtXY.js.map} +1 -1
  141. package/dist/{vendor-base-ui-CQ6wEonS.js → vendor-base-ui-9w7J6BvW.js} +7246 -7245
  142. package/dist/{vendor-base-ui-CQ6wEonS.js.map → vendor-base-ui-9w7J6BvW.js.map} +1 -1
  143. package/package.json +6 -1
  144. package/scripts/component-registry/discovery.ts +1 -7
  145. package/dist/clipboard-text-B32_yb2r.js +0 -108
  146. package/dist/clipboard-text-B32_yb2r.js.map +0 -1
  147. package/dist/combobox-C9koouxM.js.map +0 -1
  148. package/dist/dialog-CpCeOqSZ.js.map +0 -1
  149. package/dist/dropdown-DFeFcKfn.js.map +0 -1
  150. package/dist/menubar-CbXWXQYR.js.map +0 -1
@@ -1,16 +1,16 @@
1
1
  "use client";
2
- import { jsx as e, jsxs as i } from "react/jsx-runtime";
2
+ import { jsx as e, jsxs as n } from "react/jsx-runtime";
3
3
  import { CheckIcon as k, XIcon as p, CaretDownIcon as d } from "@phosphor-icons/react";
4
4
  import { Fragment as T } from "react";
5
- import { i as b } from "./input-GZAWBXYX.js";
5
+ import { i as b } from "./input-CCR8NGG7.js";
6
6
  import { c as l } from "./cn-Bhsu1vx2.js";
7
- import { F as R } from "./field-Dt-XuSaQ.js";
8
- import { P as V, Q as G, U as L, V as P, W as j, X as z, Y as u, Z as F, _ as W, $ as E, a0 as M, a1 as X, a2 as x, a3 as _, a4 as h, a5 as g, a6 as D, a7 as O, a8 as Q } from "./vendor-base-ui-CQ6wEonS.js";
7
+ import { F as R } from "./field-DCq04TgZ.js";
8
+ import { a3 as j, a4 as G, a5 as L, a6 as V, a7 as F, a8 as P, a9 as u, aa as E, ab as M, ac as W, ad as z, ae as D, af as x, ag as O, ah as h, ai as g, aj as X, ak as _, al as q } from "./vendor-base-ui-9w7J6BvW.js";
9
9
  function f({
10
10
  label: o,
11
11
  required: a,
12
12
  labelTooltip: s,
13
- description: n,
13
+ description: i,
14
14
  error: t,
15
15
  children: r,
16
16
  ...m
@@ -22,7 +22,7 @@ function f({
22
22
  label: o,
23
23
  required: a,
24
24
  labelTooltip: s,
25
- description: n,
25
+ description: i,
26
26
  error: t ? typeof t == "string" ? { message: t, match: !0 } : t : void 0,
27
27
  children: c
28
28
  }
@@ -32,24 +32,24 @@ function C({
32
32
  children: o,
33
33
  className: a,
34
34
  align: s = "start",
35
- sideOffset: n = 4,
35
+ sideOffset: i = 4,
36
36
  alignOffset: t,
37
37
  side: r
38
38
  }) {
39
- return /* @__PURE__ */ e(D, { children: /* @__PURE__ */ e(
40
- O,
39
+ return /* @__PURE__ */ e(X, { children: /* @__PURE__ */ e(
40
+ _,
41
41
  {
42
- className: "z-50 outline-none",
42
+ className: "outline-none",
43
43
  align: s,
44
- sideOffset: n,
44
+ sideOffset: i,
45
45
  alignOffset: t,
46
46
  side: r,
47
47
  children: /* @__PURE__ */ e(
48
- Q,
48
+ q,
49
49
  {
50
50
  className: l(
51
51
  "max-h-[min(var(--available-height),24rem)] max-w-(--available-width) min-w-(--anchor-width) scroll-pt-2 scroll-pb-2 overflow-y-auto overscroll-contain p-1.5",
52
- "z-50 overflow-hidden bg-kumo-control text-kumo-default",
52
+ "overflow-hidden bg-kumo-control text-kumo-default",
53
53
  // background
54
54
  "rounded-lg shadow-lg ring ring-kumo-line",
55
55
  // border part
@@ -65,7 +65,7 @@ function N({
65
65
  className: o,
66
66
  ...a
67
67
  }) {
68
- return /* @__PURE__ */ i(
68
+ return /* @__PURE__ */ n(
69
69
  h,
70
70
  {
71
71
  className: l(
@@ -81,7 +81,7 @@ function N({
81
81
  );
82
82
  }
83
83
  function y(o) {
84
- return /* @__PURE__ */ i(
84
+ return /* @__PURE__ */ n(
85
85
  "div",
86
86
  {
87
87
  className: l("relative inline-block w-full max-w-xs", o.className),
@@ -93,28 +93,28 @@ function y(o) {
93
93
  className: l(b(), "w-full pr-12")
94
94
  }
95
95
  ),
96
- /* @__PURE__ */ e(_, { className: "absolute top-1/2 right-8 flex -translate-y-1/2 cursor-pointer bg-transparent p-0", children: /* @__PURE__ */ e(p, {}) }),
96
+ /* @__PURE__ */ e(O, { className: "absolute top-1/2 right-8 flex -translate-y-1/2 cursor-pointer bg-transparent p-0", children: /* @__PURE__ */ e(p, {}) }),
97
97
  /* @__PURE__ */ e(h, { className: "p-0", children: /* @__PURE__ */ e(g, { className: "absolute top-1/2 right-2 flex -translate-y-1/2 cursor-pointer", children: /* @__PURE__ */ e(d, { className: "fill-kumo-ring" }) }) })
98
98
  ]
99
99
  }
100
100
  );
101
101
  }
102
102
  function v({ children: o, ...a }) {
103
- return /* @__PURE__ */ i(
104
- F,
103
+ return /* @__PURE__ */ n(
104
+ E,
105
105
  {
106
106
  ...a,
107
107
  className: "group grid cursor-pointer grid-cols-[1fr_16px] gap-2 rounded px-2 py-1.5 text-base data-highlighted:bg-kumo-overlay",
108
108
  children: [
109
109
  /* @__PURE__ */ e("div", { className: "col-start-1", children: o }),
110
- /* @__PURE__ */ e(W, { className: "col-start-2 flex items-center", children: /* @__PURE__ */ e(k, {}) })
110
+ /* @__PURE__ */ e(M, { className: "col-start-2 flex items-center", children: /* @__PURE__ */ e(k, {}) })
111
111
  ]
112
112
  }
113
113
  );
114
114
  }
115
- function U(o) {
115
+ function A(o) {
116
116
  return /* @__PURE__ */ e(
117
- z,
117
+ P,
118
118
  {
119
119
  ...o,
120
120
  className: l(
@@ -124,7 +124,7 @@ function U(o) {
124
124
  }
125
125
  );
126
126
  }
127
- function Y(o) {
127
+ function B(o) {
128
128
  return /* @__PURE__ */ e(
129
129
  u,
130
130
  {
@@ -133,27 +133,27 @@ function Y(o) {
133
133
  }
134
134
  );
135
135
  }
136
- function Z(o) {
136
+ function H(o) {
137
137
  return /* @__PURE__ */ e(
138
- j,
138
+ F,
139
139
  {
140
140
  ...o,
141
141
  className: "ml-[16px] px-4 py-1.5 text-sm font-medium"
142
142
  }
143
143
  );
144
144
  }
145
- function $(o) {
146
- return /* @__PURE__ */ e(P, { ...o, className: "mt-2 first:mt-0" });
145
+ function J(o) {
146
+ return /* @__PURE__ */ e(V, { ...o, className: "mt-2 first:mt-0" });
147
147
  }
148
148
  function w(o) {
149
- return /* @__PURE__ */ i(
150
- E,
149
+ return /* @__PURE__ */ n(
150
+ W,
151
151
  {
152
152
  ...o,
153
153
  className: "flex items-center gap-1 rounded-md bg-kumo-overlay px-2 py-1",
154
154
  children: [
155
155
  o.children,
156
- /* @__PURE__ */ e(M, { className: "cursor-pointer rounded-md p-1 hover:bg-kumo-fill-hover", children: /* @__PURE__ */ e(p, { size: 12, weight: "bold" }) })
156
+ /* @__PURE__ */ e(z, { className: "cursor-pointer rounded-md p-1 hover:bg-kumo-fill-hover", children: /* @__PURE__ */ e(p, { size: 12, weight: "bold" }) })
157
157
  ]
158
158
  }
159
159
  );
@@ -162,12 +162,12 @@ function I({
162
162
  placeholder: o,
163
163
  renderItem: a,
164
164
  className: s,
165
- inputSide: n = "right",
165
+ inputSide: i = "right",
166
166
  value: t
167
167
  }) {
168
168
  const r = t;
169
- return /* @__PURE__ */ i(
170
- X,
169
+ return /* @__PURE__ */ n(
170
+ D,
171
171
  {
172
172
  className: l(
173
173
  b(),
@@ -175,17 +175,17 @@ function I({
175
175
  s
176
176
  ),
177
177
  children: [
178
- n === "top" && /* @__PURE__ */ e(
178
+ i === "top" && /* @__PURE__ */ e(
179
179
  u,
180
180
  {
181
181
  placeholder: o,
182
182
  className: "w-full px-2 py-1 outline-none"
183
183
  }
184
184
  ),
185
- /* @__PURE__ */ i("div", { className: "flex flex-wrap gap-1", children: [
185
+ /* @__PURE__ */ n("div", { className: "flex flex-wrap gap-1", children: [
186
186
  r !== void 0 && r.length > 0 && r.map((m) => a(m)),
187
187
  /* @__PURE__ */ e(x, { children: (m) => r !== void 0 ? null : /* @__PURE__ */ e(T, { children: m.map((c) => a(c)) }) }),
188
- n === "right" && /* @__PURE__ */ e(
188
+ i === "right" && /* @__PURE__ */ e(
189
189
  u,
190
190
  {
191
191
  placeholder: o,
@@ -214,15 +214,15 @@ const oo = Object.assign(f, {
214
214
  Chip: w,
215
215
  Item: v,
216
216
  // Styled BaseUI
217
- Input: Y,
218
- Empty: U,
219
- GroupLabel: Z,
220
- Group: $,
217
+ Input: B,
218
+ Empty: A,
219
+ GroupLabel: H,
220
+ Group: J,
221
221
  // BaseUI
222
222
  List: G,
223
- Collection: V
223
+ Collection: j
224
224
  });
225
225
  export {
226
226
  oo as C
227
227
  };
228
- //# sourceMappingURL=combobox-C9koouxM.js.map
228
+ //# sourceMappingURL=combobox-BIC-YZ2L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combobox-BIC-YZ2L.js","sources":["../src/components/combobox/combobox.tsx"],"sourcesContent":["import { Combobox as ComboboxBase } from \"@base-ui/react/combobox\";\nimport { CaretDownIcon, CheckIcon, XIcon } from \"@phosphor-icons/react\";\nimport { Fragment, type PropsWithChildren, type ReactNode } from \"react\";\nimport { inputVariants } from \"../input/input\";\nimport { cn } from \"../../utils/cn\";\nimport { Field, type FieldErrorMatch } from \"../field/field\";\n\n/** Combobox input position variant definitions. */\nexport const KUMO_COMBOBOX_VARIANTS = {\n inputSide: {\n right: {\n classes: \"\",\n description: \"Input positioned inline to the right of chips\",\n },\n top: {\n classes: \"\",\n description: \"Input positioned above chips\",\n },\n },\n} as const;\n\nexport const KUMO_COMBOBOX_DEFAULT_VARIANTS = {\n inputSide: \"right\",\n} as const;\n\n// Derived types from KUMO_COMBOBOX_VARIANTS\nexport type KumoComboboxInputSide =\n keyof typeof KUMO_COMBOBOX_VARIANTS.inputSide;\n\nexport interface KumoComboboxVariantsProps {\n /**\n * Position of the text input relative to chips in multi-select mode.\n * - `\"right\"` — Input inline to the right of chips\n * - `\"top\"` — Input above chips\n * @default \"right\"\n */\n inputSide?: KumoComboboxInputSide;\n}\n\nexport function comboboxVariants({\n inputSide = KUMO_COMBOBOX_DEFAULT_VARIANTS.inputSide,\n}: KumoComboboxVariantsProps = {}) {\n return cn(KUMO_COMBOBOX_VARIANTS.inputSide[inputSide].classes);\n}\n\n// Legacy type alias for backwards compatibility\nexport type ComboboxInputSide = KumoComboboxInputSide;\n\nexport type ComboboxRootProps<\n Value = unknown,\n Multiple extends boolean | undefined = false,\n> = ComboboxBase.Root.Props<Value, Multiple>;\n\n/**\n * Combobox component props (simplified for documentation; the actual Root is generic).\n *\n * Combobox provides an autocomplete/typeahead input with a filterable dropdown.\n * Supports single-select, multi-select with chips, grouped items, and Field wrapper integration.\n *\n * @example\n * ```tsx\n * // Single-select with search input\n * <Combobox value={value} onValueChange={setValue} items={options}>\n * <Combobox.TriggerInput placeholder=\"Search…\" />\n * <Combobox.Content>\n * <Combobox.List>\n * {(item) => <Combobox.Item value={item}>{item.label}</Combobox.Item>}\n * </Combobox.List>\n * <Combobox.Empty>No results</Combobox.Empty>\n * </Combobox.Content>\n * </Combobox>\n *\n * // Multi-select with chips\n * <Combobox multiple items={options} label=\"Tags\">\n * <Combobox.TriggerMultipleWithInput\n * placeholder=\"Add tag…\"\n * renderItem={(item) => <Combobox.Chip value={item}>{item.label}</Combobox.Chip>}\n * />\n * <Combobox.Content>\n * <Combobox.List>\n * {(item) => <Combobox.Item value={item}>{item.label}</Combobox.Item>}\n * </Combobox.List>\n * </Combobox.Content>\n * </Combobox>\n * ```\n */\nexport interface ComboboxProps extends KumoComboboxVariantsProps {\n /** Array of items to display in the dropdown */\n items: unknown[];\n /** Currently selected value(s) */\n value?: unknown;\n /** Callback when selection changes */\n onValueChange?: (value: unknown) => void;\n /** Enable multi-select mode */\n multiple?: boolean;\n /** Combobox content (trigger, content, items) */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n /** Label content for the combobox (enables Field wrapper) - can be a string or any React node */\n label?: ReactNode;\n /** Whether the combobox is required */\n required?: boolean;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /** Helper text displayed below the combobox */\n description?: ReactNode;\n /** Error message or validation error object */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n}\n\nfunction Root<Value, Multiple extends boolean | undefined = false>({\n label,\n required,\n labelTooltip,\n description,\n error,\n children,\n ...props\n}: ComboboxBase.Root.Props<Value, Multiple> & {\n label?: ReactNode;\n required?: boolean;\n labelTooltip?: ReactNode;\n description?: ReactNode;\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n}) {\n const comboboxControl = (\n <ComboboxBase.Root {...props}>{children}</ComboboxBase.Root>\n );\n\n // Render with Field wrapper if label, description, or error are provided\n if (label) {\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 {comboboxControl}\n </Field>\n );\n }\n\n // Render bare combobox without Field wrapper\n return comboboxControl;\n}\n\nfunction Content({\n children,\n className,\n align = \"start\",\n sideOffset = 4,\n alignOffset,\n side,\n}: PropsWithChildren<{\n className?: string;\n align?: ComboboxBase.Positioner.Props[\"align\"];\n alignOffset?: ComboboxBase.Positioner.Props[\"alignOffset\"];\n side?: ComboboxBase.Positioner.Props[\"side\"];\n sideOffset?: ComboboxBase.Positioner.Props[\"sideOffset\"];\n}>) {\n return (\n <ComboboxBase.Portal>\n <ComboboxBase.Positioner\n className=\"outline-none\"\n align={align}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n side={side}\n >\n <ComboboxBase.Popup\n className={cn(\n \"max-h-[min(var(--available-height),24rem)] max-w-(--available-width) min-w-(--anchor-width) scroll-pt-2 scroll-pb-2 overflow-y-auto overscroll-contain p-1.5\",\n \"overflow-hidden bg-kumo-control text-kumo-default\", // background\n \"rounded-lg shadow-lg ring ring-kumo-line\", // border part\n className,\n )}\n >\n {children}\n </ComboboxBase.Popup>\n </ComboboxBase.Positioner>\n </ComboboxBase.Portal>\n );\n}\n\nfunction TriggerValue({\n className,\n ...props\n}: ComboboxBase.Value.Props & { className?: string }) {\n return (\n <ComboboxBase.Trigger\n className={cn(\n inputVariants(),\n \"relative flex items-center pr-8\",\n className,\n )}\n >\n <ComboboxBase.Value>{props.children}</ComboboxBase.Value>\n <ComboboxBase.Icon className=\"absolute top-1/2 right-2 -translate-y-1/2\">\n <CaretDownIcon className=\"fill-kumo-ring\" />\n </ComboboxBase.Icon>\n </ComboboxBase.Trigger>\n );\n}\n\nfunction TriggerInput(props: ComboboxBase.Input.Props) {\n return (\n <div\n className={cn(\"relative inline-block w-full max-w-xs\", props.className)}\n >\n <ComboboxBase.Input\n {...props}\n className={cn(inputVariants(), \"w-full pr-12\")}\n />\n\n <ComboboxBase.Clear className=\"absolute top-1/2 right-8 flex -translate-y-1/2 cursor-pointer bg-transparent p-0\">\n <XIcon />\n </ComboboxBase.Clear>\n\n <ComboboxBase.Trigger className=\"p-0\">\n <ComboboxBase.Icon className=\"absolute top-1/2 right-2 flex -translate-y-1/2 cursor-pointer\">\n <CaretDownIcon className=\"fill-kumo-ring\" />\n </ComboboxBase.Icon>\n </ComboboxBase.Trigger>\n </div>\n );\n}\n\nfunction Item({ children, ...props }: ComboboxBase.Item.Props) {\n return (\n <ComboboxBase.Item\n {...props}\n className=\"group grid cursor-pointer grid-cols-[1fr_16px] gap-2 rounded px-2 py-1.5 text-base data-highlighted:bg-kumo-overlay\"\n >\n <div className=\"col-start-1\">{children}</div>\n <ComboboxBase.ItemIndicator className=\"col-start-2 flex items-center\">\n <CheckIcon />\n </ComboboxBase.ItemIndicator>\n </ComboboxBase.Item>\n );\n}\n\nfunction Empty(props: ComboboxBase.Empty.Props) {\n return (\n <ComboboxBase.Empty\n {...props}\n className={cn(\n \"px-4 py-2 text-[0.925rem] leading-4 text-kumo-subtle empty:m-0 empty:p-0\",\n )}\n children={props.children ?? \"No labels found.\"}\n />\n );\n}\n\nfunction Input(props: ComboboxBase.Input.Props) {\n return (\n <ComboboxBase.Input\n {...props}\n className={cn(inputVariants(), \"w-full first:mb-2\", props.className)}\n />\n );\n}\n\nfunction GroupLabel(props: ComboboxBase.GroupLabel.Props) {\n return (\n <ComboboxBase.GroupLabel\n {...props}\n className=\"ml-[16px] px-4 py-1.5 text-sm font-medium\"\n />\n );\n}\n\nfunction Group(props: ComboboxBase.Group.Props) {\n return <ComboboxBase.Group {...props} className=\"mt-2 first:mt-0\" />;\n}\n\nfunction Chip(props: ComboboxBase.Chip.Props) {\n return (\n <ComboboxBase.Chip\n {...props}\n className=\"flex items-center gap-1 rounded-md bg-kumo-overlay px-2 py-1\"\n >\n {props.children}\n <ComboboxBase.ChipRemove className=\"cursor-pointer rounded-md p-1 hover:bg-kumo-fill-hover\">\n <XIcon size={12} weight=\"bold\" />\n </ComboboxBase.ChipRemove>\n </ComboboxBase.Chip>\n );\n}\n\nfunction TriggerMultipleWithInput<ValueType>({\n placeholder,\n renderItem,\n className,\n inputSide = \"right\",\n value: controlledValue,\n}: {\n placeholder?: string;\n renderItem: (value: ValueType) => React.ReactNode;\n className?: string;\n inputSide?: \"right\" | \"top\";\n /** Optional controlled value for rendering chips (use when pre-selecting values) */\n value?: ValueType[];\n}) {\n // Determine which value to use for rendering chips\n const chipsToRender = controlledValue;\n\n return (\n <ComboboxBase.Chips\n className={cn(\n inputVariants(),\n cn(\"flex flex-col\", \"gap-1 p-1\", \"min-h-9\", \"h-auto\"),\n className,\n )}\n >\n {inputSide === \"top\" && (\n <ComboboxBase.Input\n placeholder={placeholder}\n className=\"w-full px-2 py-1 outline-none\"\n />\n )}\n {/* Chips container */}\n <div className=\"flex flex-wrap gap-1\">\n {/* Render chips from controlled value if provided */}\n {chipsToRender !== undefined &&\n chipsToRender.length > 0 &&\n chipsToRender.map((item) => renderItem(item))}\n {/* Also render from BaseUI's internal value for user selections */}\n <ComboboxBase.Value>\n {(internalValue: ValueType[]) => {\n // Skip rendering if using controlled value (to avoid duplicates)\n if (chipsToRender !== undefined) return null;\n return (\n <Fragment>\n {internalValue.map((item) => renderItem(item))}\n </Fragment>\n );\n }}\n </ComboboxBase.Value>\n {inputSide === \"right\" && (\n <ComboboxBase.Input\n placeholder={placeholder}\n className=\"min-w-[100px] flex-1 px-2 py-1 outline-none\"\n />\n )}\n </div>\n </ComboboxBase.Chips>\n );\n}\n\nRoot.displayName = \"Combobox.Root\";\nContent.displayName = \"Combobox.Content\";\nTriggerValue.displayName = \"Combobox.TriggerValue\";\nTriggerInput.displayName = \"Combobox.TriggerInput\";\nItem.displayName = \"Combobox.Item\";\nChip.displayName = \"Combobox.Chip\";\nTriggerMultipleWithInput.displayName = \"Combobox.TriggerMultipleWithInput\";\n\n/**\n * Combobox — autocomplete input with filterable dropdown list.\n *\n * Compound component: `Combobox` (Root), `.TriggerInput`, `.TriggerValue`,\n * `.TriggerMultipleWithInput`, `.Content`, `.Item`, `.Chip`, `.Input`,\n * `.Empty`, `.GroupLabel`, `.Group`, `.List`, `.Collection`.\n *\n * @example\n * ```tsx\n * <Combobox items={fruits} label=\"Fruit\">\n * <Combobox.TriggerInput placeholder=\"Pick a fruit…\" />\n * <Combobox.Content>\n * <Combobox.List>\n * {(item) => <Combobox.Item value={item}>{item}</Combobox.Item>}\n * </Combobox.List>\n * </Combobox.Content>\n * </Combobox>\n * ```\n *\n * @see https://base-ui.com/react/components/combobox\n */\nexport const Combobox = Object.assign(Root, {\n // Helper components\n Content,\n TriggerValue,\n TriggerInput,\n TriggerMultipleWithInput,\n\n // Slightly modified BaseUI\n Chip,\n Item,\n\n // Styled BaseUI\n Input,\n Empty,\n GroupLabel,\n Group,\n\n // BaseUI\n List: ComboboxBase.List,\n Collection: ComboboxBase.Collection,\n});\n"],"names":["Root","label","required","labelTooltip","description","error","children","props","comboboxControl","jsx","ComboboxBase.Root","Field","Content","className","align","sideOffset","alignOffset","side","ComboboxBase.Portal","ComboboxBase.Positioner","ComboboxBase.Popup","cn","TriggerValue","jsxs","ComboboxBase.Trigger","inputVariants","ComboboxBase.Value","ComboboxBase.Icon","CaretDownIcon","TriggerInput","ComboboxBase.Input","ComboboxBase.Clear","XIcon","Item","ComboboxBase.Item","ComboboxBase.ItemIndicator","CheckIcon","Empty","ComboboxBase.Empty","Input","GroupLabel","ComboboxBase.GroupLabel","Group","ComboboxBase.Group","Chip","ComboboxBase.Chip","ComboboxBase.ChipRemove","TriggerMultipleWithInput","placeholder","renderItem","inputSide","controlledValue","chipsToRender","ComboboxBase.Chips","item","internalValue","Fragment","Combobox","ComboboxBase.List","ComboboxBase.Collection"],"mappings":"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"}
@@ -382,40 +382,98 @@ import { dirname as dirname4, join as join5, resolve, relative, isAbsolute } fro
382
382
  import { fileURLToPath as fileURLToPath4 } from "node:url";
383
383
 
384
384
  // src/command-line/utils/transformer.ts
385
- function transformImports(content) {
386
- const importRegex = /import\s+(?:type\s+)?{([^}]+)}\s+from\s+["']([^"']+)["'];?/g;
387
- return content.replace(importRegex, (match, imports, path) => {
388
- if (!path.startsWith("../")) {
389
- return match;
390
- }
391
- const isComponentOrUtil = path.includes("/components/") || path.includes("/utils/");
392
- if (!isComponentOrUtil) {
393
- return match;
385
+ function parseImports(content) {
386
+ const importRegex = /import\s+(type\s+)?{([^}]+)}\s+from\s+["']([^"']+)["'];?/g;
387
+ const imports = [];
388
+ let match;
389
+ while ((match = importRegex.exec(content)) !== null) {
390
+ imports.push({
391
+ fullMatch: match[0],
392
+ imports: match[2],
393
+ path: match[3],
394
+ startIndex: match.index,
395
+ endIndex: match.index + match[0].length,
396
+ isTypeOnlyImport: match[1] !== void 0
397
+ });
398
+ }
399
+ return imports;
400
+ }
401
+ function shouldTransformToKumo(path) {
402
+ if (!path.startsWith("../")) {
403
+ return false;
404
+ }
405
+ return path.includes("/components/") || path.includes("/utils/");
406
+ }
407
+ function parseImportItems(imports, isTypeOnlyImport) {
408
+ const items = imports.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
409
+ const valueImports = [];
410
+ const typeImports = [];
411
+ for (const item of items) {
412
+ if (isTypeOnlyImport || item.startsWith("type ")) {
413
+ const typeName = item.startsWith("type ") ? item.slice(5).trim() : item;
414
+ typeImports.push(typeName);
415
+ } else {
416
+ valueImports.push(item);
394
417
  }
395
- const isTypeOnlyImport = match.trim().startsWith("import type ");
396
- const importItems = imports.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
397
- const typeImports = [];
398
- const valueImports = [];
399
- for (const item of importItems) {
400
- if (item.startsWith("type ")) {
401
- typeImports.push(item.slice(5).trim());
402
- } else {
403
- valueImports.push(item);
404
- }
418
+ }
419
+ return { valueImports, typeImports };
420
+ }
421
+ function buildConsolidatedImport(valueImports, typeImports) {
422
+ const parts = [];
423
+ for (const item of valueImports) {
424
+ parts.push(item);
425
+ }
426
+ for (const item of typeImports) {
427
+ parts.push(`type ${item}`);
428
+ }
429
+ return `import { ${parts.join(", ")} } from "@cloudflare/kumo";`;
430
+ }
431
+ function transformImports(content) {
432
+ const parsedImports = parseImports(content);
433
+ const kumoImports = [];
434
+ const nonKumoImports = [];
435
+ for (const imp of parsedImports) {
436
+ if (shouldTransformToKumo(imp.path)) {
437
+ kumoImports.push(imp);
438
+ } else {
439
+ nonKumoImports.push(imp);
405
440
  }
406
- if (isTypeOnlyImport) {
407
- return `import type { ${importItems.join(", ")} } from "@cloudflare/kumo";`;
408
- } else if (typeImports.length > 0 && valueImports.length > 0) {
409
- const valueImport = `import { ${valueImports.join(", ")} } from "@cloudflare/kumo";`;
410
- const typeImport = `import type { ${typeImports.join(", ")} } from "@cloudflare/kumo";`;
411
- return `${valueImport}
412
- ${typeImport}`;
413
- } else if (typeImports.length > 0) {
414
- return `import type { ${typeImports.join(", ")} } from "@cloudflare/kumo";`;
441
+ }
442
+ if (kumoImports.length === 0) {
443
+ return content;
444
+ }
445
+ const allValueImports = [];
446
+ const allTypeImports = [];
447
+ for (const imp of kumoImports) {
448
+ const { valueImports, typeImports } = parseImportItems(
449
+ imp.imports,
450
+ imp.isTypeOnlyImport
451
+ );
452
+ allValueImports.push(...valueImports);
453
+ allTypeImports.push(...typeImports);
454
+ }
455
+ const consolidatedImport = buildConsolidatedImport(
456
+ allValueImports,
457
+ allTypeImports
458
+ );
459
+ let result = content;
460
+ const sortedKumoImports = [...kumoImports].sort(
461
+ (a, b) => b.startIndex - a.startIndex
462
+ );
463
+ for (let i = 0; i < sortedKumoImports.length; i++) {
464
+ const imp = sortedKumoImports[i];
465
+ if (i === sortedKumoImports.length - 1) {
466
+ result = result.slice(0, imp.startIndex) + consolidatedImport + result.slice(imp.endIndex);
415
467
  } else {
416
- return `import { ${valueImports.join(", ")} } from "@cloudflare/kumo";`;
468
+ let startIndex = imp.startIndex;
469
+ let endIndex = imp.endIndex;
470
+ if (startIndex > 0 && result[startIndex - 1] === "\n") {
471
+ startIndex--;
472
+ }
473
+ result = result.slice(0, startIndex) + result.slice(endIndex);
417
474
  }
418
- });
475
+ }
476
+ return result;
419
477
  }
420
478
 
421
479
  // src/command-line/commands/add.ts
@@ -33,40 +33,98 @@ function readConfig(projectRoot = process.cwd()) {
33
33
  }
34
34
 
35
35
  // src/command-line/utils/transformer.ts
36
- function transformImports(content) {
37
- const importRegex = /import\s+(?:type\s+)?{([^}]+)}\s+from\s+["']([^"']+)["'];?/g;
38
- return content.replace(importRegex, (match, imports, path) => {
39
- if (!path.startsWith("../")) {
40
- return match;
41
- }
42
- const isComponentOrUtil = path.includes("/components/") || path.includes("/utils/");
43
- if (!isComponentOrUtil) {
44
- return match;
36
+ function parseImports(content) {
37
+ const importRegex = /import\s+(type\s+)?{([^}]+)}\s+from\s+["']([^"']+)["'];?/g;
38
+ const imports = [];
39
+ let match;
40
+ while ((match = importRegex.exec(content)) !== null) {
41
+ imports.push({
42
+ fullMatch: match[0],
43
+ imports: match[2],
44
+ path: match[3],
45
+ startIndex: match.index,
46
+ endIndex: match.index + match[0].length,
47
+ isTypeOnlyImport: match[1] !== void 0
48
+ });
49
+ }
50
+ return imports;
51
+ }
52
+ function shouldTransformToKumo(path) {
53
+ if (!path.startsWith("../")) {
54
+ return false;
55
+ }
56
+ return path.includes("/components/") || path.includes("/utils/");
57
+ }
58
+ function parseImportItems(imports, isTypeOnlyImport) {
59
+ const items = imports.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
60
+ const valueImports = [];
61
+ const typeImports = [];
62
+ for (const item of items) {
63
+ if (isTypeOnlyImport || item.startsWith("type ")) {
64
+ const typeName = item.startsWith("type ") ? item.slice(5).trim() : item;
65
+ typeImports.push(typeName);
66
+ } else {
67
+ valueImports.push(item);
45
68
  }
46
- const isTypeOnlyImport = match.trim().startsWith("import type ");
47
- const importItems = imports.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
48
- const typeImports = [];
49
- const valueImports = [];
50
- for (const item of importItems) {
51
- if (item.startsWith("type ")) {
52
- typeImports.push(item.slice(5).trim());
53
- } else {
54
- valueImports.push(item);
55
- }
69
+ }
70
+ return { valueImports, typeImports };
71
+ }
72
+ function buildConsolidatedImport(valueImports, typeImports) {
73
+ const parts = [];
74
+ for (const item of valueImports) {
75
+ parts.push(item);
76
+ }
77
+ for (const item of typeImports) {
78
+ parts.push(`type ${item}`);
79
+ }
80
+ return `import { ${parts.join(", ")} } from "@cloudflare/kumo";`;
81
+ }
82
+ function transformImports(content) {
83
+ const parsedImports = parseImports(content);
84
+ const kumoImports = [];
85
+ const nonKumoImports = [];
86
+ for (const imp of parsedImports) {
87
+ if (shouldTransformToKumo(imp.path)) {
88
+ kumoImports.push(imp);
89
+ } else {
90
+ nonKumoImports.push(imp);
56
91
  }
57
- if (isTypeOnlyImport) {
58
- return `import type { ${importItems.join(", ")} } from "@cloudflare/kumo";`;
59
- } else if (typeImports.length > 0 && valueImports.length > 0) {
60
- const valueImport = `import { ${valueImports.join(", ")} } from "@cloudflare/kumo";`;
61
- const typeImport = `import type { ${typeImports.join(", ")} } from "@cloudflare/kumo";`;
62
- return `${valueImport}
63
- ${typeImport}`;
64
- } else if (typeImports.length > 0) {
65
- return `import type { ${typeImports.join(", ")} } from "@cloudflare/kumo";`;
92
+ }
93
+ if (kumoImports.length === 0) {
94
+ return content;
95
+ }
96
+ const allValueImports = [];
97
+ const allTypeImports = [];
98
+ for (const imp of kumoImports) {
99
+ const { valueImports, typeImports } = parseImportItems(
100
+ imp.imports,
101
+ imp.isTypeOnlyImport
102
+ );
103
+ allValueImports.push(...valueImports);
104
+ allTypeImports.push(...typeImports);
105
+ }
106
+ const consolidatedImport = buildConsolidatedImport(
107
+ allValueImports,
108
+ allTypeImports
109
+ );
110
+ let result = content;
111
+ const sortedKumoImports = [...kumoImports].sort(
112
+ (a, b) => b.startIndex - a.startIndex
113
+ );
114
+ for (let i = 0; i < sortedKumoImports.length; i++) {
115
+ const imp = sortedKumoImports[i];
116
+ if (i === sortedKumoImports.length - 1) {
117
+ result = result.slice(0, imp.startIndex) + consolidatedImport + result.slice(imp.endIndex);
66
118
  } else {
67
- return `import { ${valueImports.join(", ")} } from "@cloudflare/kumo";`;
119
+ let startIndex = imp.startIndex;
120
+ let endIndex = imp.endIndex;
121
+ if (startIndex > 0 && result[startIndex - 1] === "\n") {
122
+ startIndex--;
123
+ }
124
+ result = result.slice(0, startIndex) + result.slice(endIndex);
68
125
  }
69
- });
126
+ }
127
+ return result;
70
128
  }
71
129
 
72
130
  // src/command-line/commands/add.ts