@devalok/shilp-sutra 0.51.0 → 0.52.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 (47) hide show
  1. package/AGENTS.md +1 -1
  2. package/MIGRATION.md +6 -0
  3. package/dist/tokens/semantic.css +20 -1
  4. package/dist/ui/button-group.js +2 -0
  5. package/dist/ui/button-group.js.map +1 -1
  6. package/dist/ui/button-processing.d.ts.map +1 -1
  7. package/dist/ui/button-processing.js +1 -0
  8. package/dist/ui/button-processing.js.map +1 -1
  9. package/dist/ui/button.d.ts +3 -3
  10. package/dist/ui/button.d.ts.map +1 -1
  11. package/dist/ui/button.js +26 -0
  12. package/dist/ui/button.js.map +1 -1
  13. package/dist/ui/color-input.d.ts.map +1 -1
  14. package/dist/ui/color-input.js +82 -82
  15. package/dist/ui/color-input.js.map +1 -1
  16. package/dist/ui/icon.d.ts +2 -0
  17. package/dist/ui/icon.d.ts.map +1 -1
  18. package/dist/ui/icon.js +31 -26
  19. package/dist/ui/icon.js.map +1 -1
  20. package/dist/ui/search-input.d.ts.map +1 -1
  21. package/dist/ui/search-input.js +1 -0
  22. package/dist/ui/search-input.js.map +1 -1
  23. package/dist/ui/segmented-control.d.ts +28 -6
  24. package/dist/ui/segmented-control.d.ts.map +1 -1
  25. package/dist/ui/segmented-control.js +61 -43
  26. package/dist/ui/segmented-control.js.map +1 -1
  27. package/dist/ui/split-button.d.ts.map +1 -1
  28. package/dist/ui/split-button.js +7 -0
  29. package/dist/ui/split-button.js.map +1 -1
  30. package/docs/components/ui/button.md +2 -2
  31. package/docs/components/ui/segmented-control.md +31 -11
  32. package/docs/recipes/install-remix.md +3 -3
  33. package/docs/recipes/install-vite.md +3 -3
  34. package/docs/recipes/server-components.md +2 -2
  35. package/llms.txt +1 -1
  36. package/make-kit/foundations/color.md +20 -0
  37. package/make-kit/foundations/dark-mode.md +6 -9
  38. package/make-kit/foundations/icons.md +3 -3
  39. package/make-kit/setup.md +4 -4
  40. package/mcp-manifest.json +61 -10
  41. package/package.json +1 -1
  42. package/scripts/welcome.mjs +59 -1
  43. package/skill/SKILL.md +1 -1
  44. package/skill/references/components.md +1 -1
  45. package/skill/references/server-components.md +2 -2
  46. package/skill/references/setup-remix.md +3 -3
  47. package/skill/references/setup-vite.md +3 -3
@@ -48,7 +48,7 @@ function g(e, t, n) {
48
48
  };
49
49
  return m(o(0), o(8), o(4));
50
50
  }
51
- var _ = [
51
+ var ee = [
52
52
  {
53
53
  hex: "#C53637",
54
54
  label: "Red"
@@ -90,7 +90,7 @@ var _ = [
90
90
  label: "Pink"
91
91
  }
92
92
  ];
93
- function v(e) {
93
+ function te(e) {
94
94
  let t = p(e);
95
95
  if (!t) return !1;
96
96
  let [n, r, i] = [
@@ -103,7 +103,7 @@ function v(e) {
103
103
  });
104
104
  return .2126 * n + .7152 * r + .0722 * i > .4;
105
105
  }
106
- function y({ label: e, value: t, onChange: r, onBlur: i, disabled: a, maxLength: o = 3, prefix: s, className: c, id: d }) {
106
+ function _({ label: e, value: t, onChange: r, onBlur: i, disabled: a, maxLength: o = 3, prefix: s, className: c, id: d }) {
107
107
  return /* @__PURE__ */ u("div", {
108
108
  className: n("flex flex-col gap-ds-01", c),
109
109
  children: [/* @__PURE__ */ l("label", {
@@ -128,33 +128,33 @@ function y({ label: e, value: t, onChange: r, onBlur: i, disabled: a, maxLength:
128
128
  })]
129
129
  });
130
130
  }
131
- var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled: C = !1, showPicker: w = !0, defaultFormat: T = "hex", align: E = "start", variant: D = "default", className: O, id: k, ...ee }, te) => {
132
- let [A, ne] = c.useState(T), [j, M] = c.useState(!1), N = c.useId(), P = r(), F = k ?? P.inputId, [I, L] = c.useState(b);
131
+ var v = c.forwardRef(({ value: v = "#000000", onChange: y, presets: b, disabled: x = !1, showPicker: S = !0, defaultFormat: C = "hex", align: ne = "start", variant: re = "default", className: w, id: ie, ...T }, E) => {
132
+ let [D, O] = c.useState(C), [k, A] = c.useState(!1), j = c.useId(), M = r(), N = ie ?? M.inputId, [P, F] = c.useState(v), [I, L] = c.useState(null);
133
133
  c.useEffect(() => {
134
- L(b);
135
- }, [b]);
136
- let [R, z] = c.useState(b), [B, V] = c.useState([]), H = c.useRef(!1), U = (e) => {
137
- C || (e && (z(I), V([])), M(e));
134
+ F(v), L(null);
135
+ }, [v]);
136
+ let [R, z] = c.useState(v), [B, V] = c.useState([]), H = c.useRef(!1), U = (e) => {
137
+ x || (e && (z(P), V([])), L(null), A(e));
138
138
  }, W = (e) => {
139
- if (C) return;
139
+ if (x) return;
140
140
  let t = (e.startsWith("#") ? e : `#${e}`).toLowerCase();
141
- V((e) => e[e.length - 1] === I ? e : [...e.slice(-19), I]), L(t), x?.(t);
141
+ V((e) => e[e.length - 1] === P ? e : [...e.slice(-19), P]), F(t), L(null), y?.(t);
142
142
  }, G = (e) => {
143
- if (C) return;
143
+ if (x) return;
144
144
  let t = (e.startsWith("#") ? e : `#${e}`).toLowerCase();
145
- H.current || (H.current = !0, V((e) => e[e.length - 1] === I ? e : [...e.slice(-19), I])), L(t), x?.(t);
145
+ H.current || (H.current = !0, V((e) => e[e.length - 1] === P ? e : [...e.slice(-19), P])), F(t), y?.(t);
146
146
  }, K = () => {
147
147
  H.current = !1;
148
148
  }, q = () => {
149
149
  if (B.length === 0) return;
150
150
  let e = B[B.length - 1];
151
- V((e) => e.slice(0, -1)), L(e), x?.(e);
151
+ V((e) => e.slice(0, -1)), F(e), y?.(e);
152
152
  }, J = () => {
153
- L(R), x?.(R), V([]);
154
- }, Y = S === !1 ? [] : S ? S.map((e) => typeof e == "string" ? {
153
+ F(R), y?.(R), V([]);
154
+ }, Y = b === !1 ? [] : b ? b.map((e) => typeof e == "string" ? {
155
155
  hex: e,
156
156
  label: e
157
- } : e) : _, X = p(I), Z = h(I), Q = (e, t) => {
157
+ } : e) : ee, X = p(P), Z = h(P), Q = (e, t) => {
158
158
  if (!X) return;
159
159
  let n = parseInt(t, 10);
160
160
  if (isNaN(n)) return;
@@ -166,27 +166,27 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
166
166
  if (isNaN(n)) return;
167
167
  let r = Math.max(0, Math.min(e === "h" ? 360 : 100, n));
168
168
  W(g(e === "h" ? r : Z.h, e === "s" ? r : Z.s, e === "l" ? r : Z.l));
169
- }, re = [
169
+ }, ae = [
170
170
  "hex",
171
171
  "rgb",
172
172
  "hsl"
173
173
  ];
174
174
  return /* @__PURE__ */ l("div", {
175
- ref: te,
176
- className: n("inline-flex flex-col", O),
177
- ...ee,
175
+ ref: E,
176
+ className: n("inline-flex flex-col", w),
177
+ ...T,
178
178
  children: /* @__PURE__ */ u(a, {
179
- open: j,
179
+ open: k,
180
180
  onOpenChange: U,
181
181
  children: [/* @__PURE__ */ l(s, {
182
182
  asChild: !0,
183
- children: D === "inline" ? /* @__PURE__ */ l(f.button, {
183
+ children: re === "inline" ? /* @__PURE__ */ l(f.button, {
184
184
  type: "button",
185
- disabled: C,
186
- className: n("group flex items-center justify-center rounded-control px-ds-04 py-ds-02 font-mono text-body-sm font-medium", "focus:outline-hidden focus:ring-2 focus:ring-accent-9 focus:ring-offset-2 focus:ring-offset-surface-base", C && "cursor-not-allowed opacity-50"),
185
+ disabled: x,
186
+ className: n("group flex items-center justify-center rounded-control px-ds-04 py-ds-02 font-mono text-body-sm font-medium", "focus:outline-hidden focus:ring-2 focus:ring-accent-9 focus:ring-offset-2 focus:ring-offset-surface-base", x && "cursor-not-allowed opacity-50"),
187
187
  animate: {
188
- backgroundColor: I,
189
- color: v(I) ? "rgba(0,0,0,0.8)" : "rgba(255,255,255,0.95)"
188
+ backgroundColor: P,
189
+ color: te(P) ? "rgba(0,0,0,0.8)" : "rgba(255,255,255,0.95)"
190
190
  },
191
191
  whileHover: {
192
192
  y: -1,
@@ -194,26 +194,26 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
194
194
  },
195
195
  whileTap: { scale: .97 },
196
196
  transition: t.smooth,
197
- id: F,
198
- "aria-describedby": P.helperTextId,
199
- "aria-invalid": P.state === "error" || void 0,
200
- "aria-label": P.inputId ? void 0 : `Color picker: ${I}`,
201
- children: I.toUpperCase()
197
+ id: N,
198
+ "aria-describedby": M.helperTextId,
199
+ "aria-invalid": M.state === "error" || void 0,
200
+ "aria-label": M.inputId ? void 0 : `Color picker: ${P}`,
201
+ children: P.toUpperCase()
202
202
  }) : /* @__PURE__ */ u(f.button, {
203
203
  type: "button",
204
- disabled: C,
205
- className: n("group relative flex items-center overflow-hidden rounded-control border border-surface-border-strong", "hover:border-accent-7 focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9", C && "cursor-not-allowed opacity-50"),
204
+ disabled: x,
205
+ className: n("group relative flex items-center overflow-hidden rounded-control border border-surface-border-strong", "hover:border-accent-7 focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9", x && "cursor-not-allowed opacity-50"),
206
206
  whileHover: { scale: 1.02 },
207
207
  whileTap: { scale: .98 },
208
208
  transition: t.snappy,
209
- id: F,
210
- "aria-describedby": P.helperTextId,
211
- "aria-invalid": P.state === "error" || void 0,
212
- "aria-label": P.inputId ? void 0 : `Color picker: ${I}`,
209
+ id: N,
210
+ "aria-describedby": M.helperTextId,
211
+ "aria-invalid": M.state === "error" || void 0,
212
+ "aria-label": M.inputId ? void 0 : `Color picker: ${P}`,
213
213
  children: [
214
214
  /* @__PURE__ */ l(f.span, {
215
215
  className: "absolute inset-0",
216
- animate: { background: `linear-gradient(to right, ${I} 0%, ${I} 35%, transparent 70%)` },
216
+ animate: { background: `linear-gradient(to right, ${P} 0%, ${P} 35%, transparent 70%)` },
217
217
  transition: { duration: .3 }
218
218
  }),
219
219
  /* @__PURE__ */ l("span", {
@@ -225,25 +225,25 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
225
225
  }),
226
226
  /* @__PURE__ */ l("span", {
227
227
  className: "relative z-10 py-ds-02 pl-6 pr-ds-03 font-mono text-body-sm text-surface-fg",
228
- children: I.toUpperCase()
228
+ children: P.toUpperCase()
229
229
  })
230
230
  ]
231
231
  })
232
232
  }), /* @__PURE__ */ l(o, {
233
233
  role: "dialog",
234
234
  "aria-label": "Color picker",
235
- align: E,
235
+ align: ne,
236
236
  sideOffset: 8,
237
237
  className: "w-[272px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating",
238
238
  children: /* @__PURE__ */ u("div", {
239
239
  className: "flex flex-col",
240
240
  children: [
241
- w && /* @__PURE__ */ l("div", {
241
+ S && /* @__PURE__ */ l("div", {
242
242
  className: "p-ds-04 pb-ds-03",
243
243
  onPointerUp: K,
244
244
  onPointerLeave: K,
245
245
  children: /* @__PURE__ */ l(i, {
246
- color: I,
246
+ color: P,
247
247
  onChange: G,
248
248
  className: "w-full!",
249
249
  style: { height: 160 }
@@ -253,12 +253,12 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
253
253
  className: "border-t border-surface-border px-ds-04 py-ds-03",
254
254
  children: [/* @__PURE__ */ l("div", {
255
255
  className: "mb-ds-03 flex items-center gap-ds-01",
256
- children: re.map((e) => /* @__PURE__ */ u("button", {
256
+ children: ae.map((e) => /* @__PURE__ */ u("button", {
257
257
  type: "button",
258
- onClick: () => ne(e),
259
- className: n("relative min-h-6 rounded-control-inner px-ds-02 py-px text-label-xs font-semibold uppercase tracking-wider transition-colors", A === e ? "text-accent-11" : "text-surface-fg-muted hover:text-surface-fg"),
260
- children: [A === e && /* @__PURE__ */ l(f.span, {
261
- layoutId: `color-input-format-pill-${N}`,
258
+ onClick: () => O(e),
259
+ className: n("relative min-h-6 rounded-control-inner px-ds-02 py-px text-label-xs font-semibold uppercase tracking-wider transition-colors", D === e ? "text-accent-11" : "text-surface-fg-muted hover:text-surface-fg"),
260
+ children: [D === e && /* @__PURE__ */ l(f.span, {
261
+ layoutId: `color-input-format-pill-${j}`,
262
262
  className: "absolute inset-0 rounded-control-inner bg-accent-3",
263
263
  transition: t.snappy
264
264
  }), /* @__PURE__ */ l("span", {
@@ -269,7 +269,7 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
269
269
  }), /* @__PURE__ */ u(d, {
270
270
  mode: "wait",
271
271
  children: [
272
- A === "hex" && /* @__PURE__ */ l(f.div, {
272
+ D === "hex" && /* @__PURE__ */ l(f.div, {
273
273
  initial: {
274
274
  opacity: 0,
275
275
  y: 4
@@ -284,24 +284,24 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
284
284
  },
285
285
  transition: { duration: e.moderate01 },
286
286
  className: "flex gap-ds-02",
287
- children: /* @__PURE__ */ l(y, {
288
- id: `${N}-hex`,
287
+ children: /* @__PURE__ */ l(_, {
288
+ id: `${j}-hex`,
289
289
  label: "Hex",
290
- value: I.replace("#", "").toUpperCase(),
290
+ value: I ?? P.replace("#", "").toUpperCase(),
291
291
  onChange: (e) => {
292
292
  let t = e.replace(/[^0-9a-fA-F]/g, "").slice(0, 6);
293
- t.length === 6 && W(`#${t}`);
293
+ L(t.toUpperCase()), t.length === 6 && W(`#${t}`);
294
294
  },
295
295
  onBlur: () => {
296
- I.replace("#", "").toUpperCase().length !== 6 && L(I);
296
+ L(null);
297
297
  },
298
- disabled: C,
298
+ disabled: x,
299
299
  maxLength: 6,
300
300
  prefix: "#",
301
301
  className: "flex-1"
302
302
  })
303
303
  }, "hex"),
304
- A === "rgb" && X && /* @__PURE__ */ u(f.div, {
304
+ D === "rgb" && X && /* @__PURE__ */ u(f.div, {
305
305
  initial: {
306
306
  opacity: 0,
307
307
  y: 4
@@ -317,33 +317,33 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
317
317
  transition: { duration: e.moderate01 },
318
318
  className: "flex gap-ds-02",
319
319
  children: [
320
- /* @__PURE__ */ l(y, {
321
- id: `${N}-r`,
320
+ /* @__PURE__ */ l(_, {
321
+ id: `${j}-r`,
322
322
  label: "R",
323
323
  value: String(X.r),
324
324
  onChange: (e) => Q("r", e),
325
- disabled: C,
325
+ disabled: x,
326
326
  className: "flex-1"
327
327
  }),
328
- /* @__PURE__ */ l(y, {
329
- id: `${N}-g`,
328
+ /* @__PURE__ */ l(_, {
329
+ id: `${j}-g`,
330
330
  label: "G",
331
331
  value: String(X.g),
332
332
  onChange: (e) => Q("g", e),
333
- disabled: C,
333
+ disabled: x,
334
334
  className: "flex-1"
335
335
  }),
336
- /* @__PURE__ */ l(y, {
337
- id: `${N}-b`,
336
+ /* @__PURE__ */ l(_, {
337
+ id: `${j}-b`,
338
338
  label: "B",
339
339
  value: String(X.b),
340
340
  onChange: (e) => Q("b", e),
341
- disabled: C,
341
+ disabled: x,
342
342
  className: "flex-1"
343
343
  })
344
344
  ]
345
345
  }, "rgb"),
346
- A === "hsl" && Z && /* @__PURE__ */ u(f.div, {
346
+ D === "hsl" && Z && /* @__PURE__ */ u(f.div, {
347
347
  initial: {
348
348
  opacity: 0,
349
349
  y: 4
@@ -359,28 +359,28 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
359
359
  transition: { duration: e.moderate01 },
360
360
  className: "flex gap-ds-02",
361
361
  children: [
362
- /* @__PURE__ */ l(y, {
363
- id: `${N}-h`,
362
+ /* @__PURE__ */ l(_, {
363
+ id: `${j}-h`,
364
364
  label: "H",
365
365
  value: String(Z.h),
366
366
  onChange: (e) => $("h", e),
367
- disabled: C,
367
+ disabled: x,
368
368
  className: "flex-1"
369
369
  }),
370
- /* @__PURE__ */ l(y, {
371
- id: `${N}-s`,
370
+ /* @__PURE__ */ l(_, {
371
+ id: `${j}-s`,
372
372
  label: "S",
373
373
  value: String(Z.s),
374
374
  onChange: (e) => $("s", e),
375
- disabled: C,
375
+ disabled: x,
376
376
  className: "flex-1"
377
377
  }),
378
- /* @__PURE__ */ l(y, {
379
- id: `${N}-l`,
378
+ /* @__PURE__ */ l(_, {
379
+ id: `${j}-l`,
380
380
  label: "L",
381
381
  value: String(Z.l),
382
382
  onChange: (e) => $("l", e),
383
- disabled: C,
383
+ disabled: x,
384
384
  className: "flex-1"
385
385
  })
386
386
  ]
@@ -393,10 +393,10 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
393
393
  children: /* @__PURE__ */ l("div", {
394
394
  className: "flex flex-wrap gap-ds-02",
395
395
  children: Y.map((e, r) => {
396
- let i = I.toLowerCase() === e.hex.toLowerCase();
396
+ let i = P.toLowerCase() === e.hex.toLowerCase();
397
397
  return /* @__PURE__ */ l(f.button, {
398
398
  type: "button",
399
- disabled: C,
399
+ disabled: x,
400
400
  onClick: () => W(e.hex),
401
401
  initial: {
402
402
  opacity: 0,
@@ -412,7 +412,7 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
412
412
  ...t.bouncy,
413
413
  delay: r * .02
414
414
  },
415
- className: n("h-6 w-6 rounded-control-inner border", i ? "border-accent-7 ring-2 ring-accent-9/30" : "border-surface-border hover:border-surface-border-strong", C && "cursor-not-allowed opacity-50"),
415
+ className: n("h-6 w-6 rounded-control-inner border", i ? "border-accent-7 ring-2 ring-accent-9/30" : "border-surface-border hover:border-surface-border-strong", x && "cursor-not-allowed opacity-50"),
416
416
  style: { backgroundColor: e.hex },
417
417
  title: e.label,
418
418
  "aria-label": `${e.label}: ${e.hex}`
@@ -420,7 +420,7 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
420
420
  })
421
421
  })
422
422
  }),
423
- (B.length > 0 || I !== R) && /* @__PURE__ */ u(f.div, {
423
+ (B.length > 0 || P !== R) && /* @__PURE__ */ u(f.div, {
424
424
  initial: {
425
425
  opacity: 0,
426
426
  height: 0
@@ -451,7 +451,7 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
451
451
  className: "min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-surface-fg",
452
452
  children: "Undo"
453
453
  }),
454
- I !== R && /* @__PURE__ */ l("button", {
454
+ P !== R && /* @__PURE__ */ l("button", {
455
455
  type: "button",
456
456
  onClick: J,
457
457
  className: "min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-error-11",
@@ -465,6 +465,6 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
465
465
  })
466
466
  });
467
467
  });
468
- b.displayName = "ColorInput";
468
+ v.displayName = "ColorInput";
469
469
  //#endregion
470
- export { b as ColorInput };
470
+ export { v as ColorInput };
@@ -1 +1 @@
1
- {"version":3,"file":"color-input.js","names":[],"sources":["../../src/ui/color-input.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\nimport { HexColorPicker } from 'react-colorful'\n\nimport { useFormField } from './form'\nimport { durations,springs } from './lib/motion'\nimport { cn } from './lib/utils'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from './popover'\n\n// ── Color conversion helpers ──\n\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex)\n if (!m) return null\n const n = parseInt(m[1], 16)\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 }\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')).join('')\n}\n\nfunction hexToHsl(hex: string): { h: number; s: number; l: number } | null {\n const rgb = hexToRgb(hex)\n if (!rgb) return null\n const r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255\n const max = Math.max(r, g, b), min = Math.min(r, g, b)\n const l = (max + min) / 2\n if (max === min) return { h: 0, s: 0, l: Math.round(l * 100) }\n const d = max - min\n const s = l > 0.5 ? d / (2 - max - min) : d / (max - min)\n let h = 0\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6\n else if (max === g) h = ((b - r) / d + 2) / 6\n else h = ((r - g) / d + 4) / 6\n return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) }\n}\n\nfunction hslToHex(h: number, s: number, l: number): string {\n const sn = s / 100, ln = l / 100\n const a = sn * Math.min(ln, 1 - ln)\n const f = (n: number) => {\n const k = (n + h / 30) % 12\n const c = ln - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\n return Math.round(255 * c)\n }\n return rgbToHex(f(0), f(8), f(4))\n}\n\n// ── Named color presets ──\n// Brand spectrum derived from our OKLCH scales (step-9), spanning the wheel —\n// intentional and on-brand, NOT the raw framework palette. Led by red, not indigo.\n\nconst NAMED_PRESETS: { hex: string; label: string }[] = [\n { hex: '#C53637', label: 'Red' },\n { hex: '#BE5A0A', label: 'Orange' },\n { hex: '#DF911A', label: 'Amber' },\n { hex: '#308639', label: 'Green' },\n { hex: '#118659', label: 'Emerald' },\n { hex: '#11846E', label: 'Teal' },\n { hex: '#028A9B', label: 'Cyan' },\n { hex: '#1479B0', label: 'Blue' },\n { hex: '#7D5FAD', label: 'Purple' },\n { hex: '#C22D6D', label: 'Pink' },\n]\n\n// ── Contrast helper ──\n\nfunction isLightColor(hex: string): boolean {\n const rgb = hexToRgb(hex)\n if (!rgb) return false\n // Relative luminance (sRGB)\n const [r, g, b] = [rgb.r, rgb.g, rgb.b].map((c) => {\n const s = c / 255\n return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4)\n })\n return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.4\n}\n\n// ── Format mode type ──\n\ntype ColorFormat = 'hex' | 'rgb' | 'hsl'\n\n// ── Props ──\n\nexport interface ColorInputProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Current color value (hex string, e.g. \"#d33163\") */\n value?: string\n /** Called when the color changes */\n onChange?: (value: string) => void\n /** Preset color swatches. Defaults to 10 named colors. Pass `false` to hide. */\n presets?: { hex: string; label: string }[] | string[] | false\n /** Whether the input is disabled */\n disabled?: boolean\n /** Show the interactive color picker. Default: true. */\n showPicker?: boolean\n /** Default format for the input fields. Default: 'hex'. */\n defaultFormat?: ColorFormat\n /** Popover alignment. Default: 'start'. */\n align?: 'start' | 'center' | 'end'\n /**\n * Trigger style variant.\n * - `default`: Swatch bleeds to left edge + hex text\n * - `inline`: Entire trigger is the selected color with hex text overlaid\n */\n variant?: 'default' | 'inline'\n}\n\n// ── Small format input ──\n\nfunction FormatInput({\n label,\n value,\n onChange,\n onBlur,\n disabled,\n maxLength = 3,\n prefix,\n className,\n id,\n}: {\n label: string\n value: string\n onChange: (v: string) => void\n onBlur?: () => void\n disabled?: boolean\n maxLength?: number\n prefix?: string\n className?: string\n id: string\n}) {\n return (\n <div className={cn('flex flex-col gap-ds-01', className)}>\n <label htmlFor={id} className=\"text-label-xs font-medium uppercase tracking-wider text-surface-fg-muted\">\n {label}\n </label>\n <div className=\"flex items-center\">\n {prefix && (\n <span className=\"text-body-sm text-surface-fg-muted\">{prefix}</span>\n )}\n <input\n id={id}\n type=\"text\"\n value={value}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n maxLength={maxLength}\n className={cn(\n 'h-ds-xs-plus w-full rounded-control-inner border border-surface-border bg-surface-overlay px-ds-02 font-mono text-body-sm text-surface-fg transition-colors',\n 'focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n />\n </div>\n </div>\n )\n}\n\n// ── Main component ──\n\nconst ColorInput = React.forwardRef<HTMLDivElement, ColorInputProps>(\n ({\n value = '#000000',\n onChange,\n presets,\n disabled = false,\n showPicker = true,\n defaultFormat = 'hex',\n align = 'start',\n variant = 'default',\n className,\n id: externalId,\n ...props\n }, ref) => {\n const [format, setFormat] = React.useState<ColorFormat>(defaultFormat)\n const [open, setOpen] = React.useState(false)\n const instanceId = React.useId()\n const fieldCtx = useFormField()\n // Explicit id wins; otherwise adopt FormField's inputId so <Label htmlFor> resolves\n // onto the (labelable) trigger button. The root is a <div>, which can't be a label target.\n const triggerId = externalId ?? fieldCtx.inputId\n\n // Internal color state — syncs with prop, allows uncontrolled use\n const [internalColor, setInternalColor] = React.useState(value)\n React.useEffect(() => { setInternalColor(value) }, [value])\n\n // Track color when popover opened (for reset) + undo history\n const [openColor, setOpenColor] = React.useState(value)\n const [undoStack, setUndoStack] = React.useState<string[]>([])\n // Track whether current change is from continuous drag (skip undo push)\n const isDragging = React.useRef(false)\n\n const handleOpenChange = (isOpen: boolean) => {\n if (disabled) return\n if (isOpen) {\n setOpenColor(internalColor)\n setUndoStack([])\n }\n setOpen(isOpen)\n }\n\n // Discrete change (preset click, field commit) — pushes to undo\n const handleDiscreteChange = (newValue: string) => {\n if (disabled) return\n const normalized = newValue.startsWith('#') ? newValue : `#${newValue}`\n const hex = normalized.toLowerCase()\n setUndoStack((prev) => {\n if (prev[prev.length - 1] === internalColor) return prev\n return [...prev.slice(-19), internalColor]\n })\n setInternalColor(hex)\n onChange?.(hex)\n }\n\n // Continuous change (picker drag) — updates color but only pushes undo on drag start\n const handleChange = (newValue: string) => {\n if (disabled) return\n const normalized = newValue.startsWith('#') ? newValue : `#${newValue}`\n const hex = normalized.toLowerCase()\n if (!isDragging.current) {\n // First change in a drag sequence — push current color to undo\n isDragging.current = true\n setUndoStack((prev) => {\n if (prev[prev.length - 1] === internalColor) return prev\n return [...prev.slice(-19), internalColor]\n })\n }\n setInternalColor(hex)\n onChange?.(hex)\n }\n\n // Called when picker drag ends\n const handlePickerChangeComplete = () => {\n isDragging.current = false\n }\n\n const handleUndo = () => {\n if (undoStack.length === 0) return\n const prev = undoStack[undoStack.length - 1]\n setUndoStack((s) => s.slice(0, -1))\n setInternalColor(prev)\n onChange?.(prev)\n }\n\n const handleReset = () => {\n setInternalColor(openColor)\n onChange?.(openColor)\n setUndoStack([])\n }\n\n // Resolve presets\n const resolvedPresets = presets === false\n ? []\n : presets\n ? presets.map((p) =>\n typeof p === 'string' ? { hex: p, label: p } : p\n )\n : NAMED_PRESETS\n\n // Parsed color values — use internal state\n const rgb = hexToRgb(internalColor)\n const hsl = hexToHsl(internalColor)\n\n // RGB field handlers (clamped 0-255)\n const handleRgbChange = (channel: 'r' | 'g' | 'b', v: string) => {\n if (!rgb) return\n const num = parseInt(v, 10)\n if (isNaN(num)) return\n const clamped = Math.max(0, Math.min(255, num))\n handleDiscreteChange(rgbToHex(\n channel === 'r' ? clamped : rgb.r,\n channel === 'g' ? clamped : rgb.g,\n channel === 'b' ? clamped : rgb.b,\n ))\n }\n\n // HSL field handlers (H: 0-360, S/L: 0-100)\n const handleHslChange = (channel: 'h' | 's' | 'l', v: string) => {\n if (!hsl) return\n const num = parseInt(v, 10)\n if (isNaN(num)) return\n const max = channel === 'h' ? 360 : 100\n const clamped = Math.max(0, Math.min(max, num))\n handleDiscreteChange(hslToHex(\n channel === 'h' ? clamped : hsl.h,\n channel === 's' ? clamped : hsl.s,\n channel === 'l' ? clamped : hsl.l,\n ))\n }\n\n const formats: ColorFormat[] = ['hex', 'rgb', 'hsl']\n\n return (\n <div ref={ref} className={cn('inline-flex flex-col', className)} {...props}>\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n {variant === 'inline' ? (\n <motion.button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'group flex items-center justify-center rounded-control px-ds-04 py-ds-02 font-mono text-body-sm font-medium',\n 'focus:outline-hidden focus:ring-2 focus:ring-accent-9 focus:ring-offset-2 focus:ring-offset-surface-base',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n animate={{\n backgroundColor: internalColor,\n color: isLightColor(internalColor) ? 'rgba(0,0,0,0.8)' : 'rgba(255,255,255,0.95)',\n }}\n whileHover={{ y: -1, boxShadow: '0 4px 12px rgba(0,0,0,0.12)' }}\n whileTap={{ scale: 0.97 }}\n transition={springs.smooth}\n id={triggerId}\n aria-describedby={fieldCtx.helperTextId}\n aria-invalid={fieldCtx.state === 'error' || undefined}\n // Inside a FormField, let the visible <Label> name the trigger; else describe it.\n aria-label={fieldCtx.inputId ? undefined : `Color picker: ${internalColor}`}\n >\n {internalColor.toUpperCase()}\n </motion.button>\n ) : (\n <motion.button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'group relative flex items-center overflow-hidden rounded-control border border-surface-border-strong',\n 'hover:border-accent-7 focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n whileHover={{ scale: 1.02 }}\n whileTap={{ scale: 0.98 }}\n transition={springs.snappy}\n id={triggerId}\n aria-describedby={fieldCtx.helperTextId}\n aria-invalid={fieldCtx.state === 'error' || undefined}\n // Inside a FormField, let the visible <Label> name the trigger; else describe it.\n aria-label={fieldCtx.inputId ? undefined : `Color picker: ${internalColor}`}\n >\n {/* Gradient background: color → surface */}\n <motion.span\n className=\"absolute inset-0\"\n animate={{\n background: `linear-gradient(to right, ${internalColor} 0%, ${internalColor} 35%, transparent 70%)`,\n }}\n /* Between durations.moderate02 (0.24) and durations.slow01 (0.4) — gradient lerp feel */\n transition={{ duration: 0.3 }}\n />\n <span className=\"absolute inset-0 bg-surface-overlay/60\" style={{\n maskImage: 'linear-gradient(to right, transparent 0%, black 40%)',\n WebkitMaskImage: 'linear-gradient(to right, transparent 0%, black 40%)',\n }} />\n {/* Hex value */}\n <span className=\"relative z-10 py-ds-02 pl-6 pr-ds-03 font-mono text-body-sm text-surface-fg\">\n {internalColor.toUpperCase()}\n </span>\n </motion.button>\n )}\n </PopoverTrigger>\n\n <PopoverContent\n role=\"dialog\"\n aria-label=\"Color picker\"\n align={align}\n sideOffset={8}\n className=\"w-[272px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating\"\n >\n <div className=\"flex flex-col\">\n {/* Interactive picker */}\n {showPicker && (\n <div className=\"p-ds-04 pb-ds-03\" onPointerUp={handlePickerChangeComplete} onPointerLeave={handlePickerChangeComplete}>\n <HexColorPicker\n color={internalColor}\n onChange={handleChange}\n className=\"w-full!\"\n style={{ height: 160 }}\n />\n </div>\n )}\n\n {/* Format inputs */}\n <div className=\"border-t border-surface-border px-ds-04 py-ds-03\">\n {/* Format switcher */}\n <div className=\"mb-ds-03 flex items-center gap-ds-01\">\n {formats.map((f) => (\n <button\n key={f}\n type=\"button\"\n onClick={() => setFormat(f)}\n className={cn(\n 'relative min-h-6 rounded-control-inner px-ds-02 py-px text-label-xs font-semibold uppercase tracking-wider transition-colors',\n format === f\n ? 'text-accent-11'\n : 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n {format === f && (\n <motion.span\n layoutId={`color-input-format-pill-${instanceId}`}\n className=\"absolute inset-0 rounded-control-inner bg-accent-3\"\n transition={springs.snappy}\n />\n )}\n <span className=\"relative z-10\">{f}</span>\n </button>\n ))}\n </div>\n\n {/* Format fields — animated swap */}\n <AnimatePresence mode=\"wait\">\n {format === 'hex' && (\n <motion.div\n key=\"hex\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput\n id={`${instanceId}-hex`}\n label=\"Hex\"\n value={internalColor.replace('#', '').toUpperCase()}\n onChange={(v) => {\n const clean = v.replace(/[^0-9a-fA-F]/g, '').slice(0, 6)\n if (clean.length === 6) handleDiscreteChange(`#${clean}`)\n }}\n onBlur={() => {\n // Revert display to current color if input is incomplete\n const display = internalColor.replace('#', '').toUpperCase()\n if (display.length !== 6) setInternalColor(internalColor)\n }}\n disabled={disabled}\n maxLength={6}\n prefix=\"#\"\n className=\"flex-1\"\n />\n </motion.div>\n )}\n\n {format === 'rgb' && rgb && (\n <motion.div\n key=\"rgb\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput id={`${instanceId}-r`} label=\"R\" value={String(rgb.r)} onChange={(v) => handleRgbChange('r', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-g`} label=\"G\" value={String(rgb.g)} onChange={(v) => handleRgbChange('g', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-b`} label=\"B\" value={String(rgb.b)} onChange={(v) => handleRgbChange('b', v)} disabled={disabled} className=\"flex-1\" />\n </motion.div>\n )}\n\n {format === 'hsl' && hsl && (\n <motion.div\n key=\"hsl\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput id={`${instanceId}-h`} label=\"H\" value={String(hsl.h)} onChange={(v) => handleHslChange('h', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-s`} label=\"S\" value={String(hsl.s)} onChange={(v) => handleHslChange('s', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-l`} label=\"L\" value={String(hsl.l)} onChange={(v) => handleHslChange('l', v)} disabled={disabled} className=\"flex-1\" />\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n\n {/* Preset swatches */}\n {resolvedPresets.length > 0 && (\n <div className=\"border-t border-surface-border px-ds-04 py-ds-03\">\n <div className=\"flex flex-wrap gap-ds-02\">\n {resolvedPresets.map((preset, i) => {\n const isSelected = internalColor.toLowerCase() === preset.hex.toLowerCase()\n return (\n <motion.button\n key={preset.hex}\n type=\"button\"\n disabled={disabled}\n onClick={() => handleDiscreteChange(preset.hex)}\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: isSelected ? 1.15 : 1 }}\n whileHover={{ scale: isSelected ? 1.15 : 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={{ ...springs.bouncy, delay: i * 0.02 }}\n className={cn(\n 'h-6 w-6 rounded-control-inner border',\n isSelected\n ? 'border-accent-7 ring-2 ring-accent-9/30'\n : 'border-surface-border hover:border-surface-border-strong',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n style={{ backgroundColor: preset.hex }}\n title={preset.label}\n aria-label={`${preset.label}: ${preset.hex}`}\n />\n )\n })}\n </div>\n </div>\n )}\n\n {/* Reset / Undo footer */}\n {(undoStack.length > 0 || internalColor !== openColor) && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n className=\"flex items-center gap-ds-02 border-t border-surface-border px-ds-04 py-ds-02\"\n >\n {/* Original color preview */}\n <span\n className=\"h-4 w-4 shrink-0 rounded-pill border border-surface-border\"\n style={{ backgroundColor: openColor }}\n title={`Original: ${openColor}`}\n />\n <span className=\"text-caption text-surface-fg-muted\">\n {openColor.toUpperCase()}\n </span>\n <span className=\"flex-1\" />\n {undoStack.length > 0 && (\n <button\n type=\"button\"\n onClick={handleUndo}\n className=\"min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-surface-fg\"\n >\n Undo\n </button>\n )}\n {internalColor !== openColor && (\n <button\n type=\"button\"\n onClick={handleReset}\n className=\"min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-error-11\"\n >\n Reset\n </button>\n )}\n </motion.div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n )\n },\n)\nColorInput.displayName = 'ColorInput'\n\nexport { ColorInput }\n"],"mappings":"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"}
1
+ {"version":3,"file":"color-input.js","names":[],"sources":["../../src/ui/color-input.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\nimport { HexColorPicker } from 'react-colorful'\n\nimport { useFormField } from './form'\nimport { durations,springs } from './lib/motion'\nimport { cn } from './lib/utils'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from './popover'\n\n// ── Color conversion helpers ──\n\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex)\n if (!m) return null\n const n = parseInt(m[1], 16)\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 }\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')).join('')\n}\n\nfunction hexToHsl(hex: string): { h: number; s: number; l: number } | null {\n const rgb = hexToRgb(hex)\n if (!rgb) return null\n const r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255\n const max = Math.max(r, g, b), min = Math.min(r, g, b)\n const l = (max + min) / 2\n if (max === min) return { h: 0, s: 0, l: Math.round(l * 100) }\n const d = max - min\n const s = l > 0.5 ? d / (2 - max - min) : d / (max - min)\n let h = 0\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6\n else if (max === g) h = ((b - r) / d + 2) / 6\n else h = ((r - g) / d + 4) / 6\n return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) }\n}\n\nfunction hslToHex(h: number, s: number, l: number): string {\n const sn = s / 100, ln = l / 100\n const a = sn * Math.min(ln, 1 - ln)\n const f = (n: number) => {\n const k = (n + h / 30) % 12\n const c = ln - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\n return Math.round(255 * c)\n }\n return rgbToHex(f(0), f(8), f(4))\n}\n\n// ── Named color presets ──\n// Brand spectrum derived from our OKLCH scales (step-9), spanning the wheel —\n// intentional and on-brand, NOT the raw framework palette. Led by red, not indigo.\n\nconst NAMED_PRESETS: { hex: string; label: string }[] = [\n { hex: '#C53637', label: 'Red' },\n { hex: '#BE5A0A', label: 'Orange' },\n { hex: '#DF911A', label: 'Amber' },\n { hex: '#308639', label: 'Green' },\n { hex: '#118659', label: 'Emerald' },\n { hex: '#11846E', label: 'Teal' },\n { hex: '#028A9B', label: 'Cyan' },\n { hex: '#1479B0', label: 'Blue' },\n { hex: '#7D5FAD', label: 'Purple' },\n { hex: '#C22D6D', label: 'Pink' },\n]\n\n// ── Contrast helper ──\n\nfunction isLightColor(hex: string): boolean {\n const rgb = hexToRgb(hex)\n if (!rgb) return false\n // Relative luminance (sRGB)\n const [r, g, b] = [rgb.r, rgb.g, rgb.b].map((c) => {\n const s = c / 255\n return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4)\n })\n return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.4\n}\n\n// ── Format mode type ──\n\ntype ColorFormat = 'hex' | 'rgb' | 'hsl'\n\n// ── Props ──\n\nexport interface ColorInputProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Current color value (hex string, e.g. \"#d33163\") */\n value?: string\n /** Called when the color changes */\n onChange?: (value: string) => void\n /** Preset color swatches. Defaults to 10 named colors. Pass `false` to hide. */\n presets?: { hex: string; label: string }[] | string[] | false\n /** Whether the input is disabled */\n disabled?: boolean\n /** Show the interactive color picker. Default: true. */\n showPicker?: boolean\n /** Default format for the input fields. Default: 'hex'. */\n defaultFormat?: ColorFormat\n /** Popover alignment. Default: 'start'. */\n align?: 'start' | 'center' | 'end'\n /**\n * Trigger style variant.\n * - `default`: Swatch bleeds to left edge + hex text\n * - `inline`: Entire trigger is the selected color with hex text overlaid\n */\n variant?: 'default' | 'inline'\n}\n\n// ── Small format input ──\n\nfunction FormatInput({\n label,\n value,\n onChange,\n onBlur,\n disabled,\n maxLength = 3,\n prefix,\n className,\n id,\n}: {\n label: string\n value: string\n onChange: (v: string) => void\n onBlur?: () => void\n disabled?: boolean\n maxLength?: number\n prefix?: string\n className?: string\n id: string\n}) {\n return (\n <div className={cn('flex flex-col gap-ds-01', className)}>\n <label htmlFor={id} className=\"text-label-xs font-medium uppercase tracking-wider text-surface-fg-muted\">\n {label}\n </label>\n <div className=\"flex items-center\">\n {prefix && (\n <span className=\"text-body-sm text-surface-fg-muted\">{prefix}</span>\n )}\n <input\n id={id}\n type=\"text\"\n value={value}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n maxLength={maxLength}\n className={cn(\n 'h-ds-xs-plus w-full rounded-control-inner border border-surface-border bg-surface-overlay px-ds-02 font-mono text-body-sm text-surface-fg transition-colors',\n 'focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n />\n </div>\n </div>\n )\n}\n\n// ── Main component ──\n\nconst ColorInput = React.forwardRef<HTMLDivElement, ColorInputProps>(\n ({\n value = '#000000',\n onChange,\n presets,\n disabled = false,\n showPicker = true,\n defaultFormat = 'hex',\n align = 'start',\n variant = 'default',\n className,\n id: externalId,\n ...props\n }, ref) => {\n const [format, setFormat] = React.useState<ColorFormat>(defaultFormat)\n const [open, setOpen] = React.useState(false)\n const instanceId = React.useId()\n const fieldCtx = useFormField()\n // Explicit id wins; otherwise adopt FormField's inputId so <Label htmlFor> resolves\n // onto the (labelable) trigger button. The root is a <div>, which can't be a label target.\n const triggerId = externalId ?? fieldCtx.inputId\n\n // Internal color state — syncs with prop, allows uncontrolled use\n const [internalColor, setInternalColor] = React.useState(value)\n // Draft state for the hex field so in-progress (<6 char) typing isn't clobbered\n // by re-renders off internalColor. null = show the committed color.\n const [hexDraft, setHexDraft] = React.useState<string | null>(null)\n React.useEffect(() => { setInternalColor(value); setHexDraft(null) }, [value])\n\n // Track color when popover opened (for reset) + undo history\n const [openColor, setOpenColor] = React.useState(value)\n const [undoStack, setUndoStack] = React.useState<string[]>([])\n // Track whether current change is from continuous drag (skip undo push)\n const isDragging = React.useRef(false)\n\n const handleOpenChange = (isOpen: boolean) => {\n if (disabled) return\n if (isOpen) {\n setOpenColor(internalColor)\n setUndoStack([])\n }\n setHexDraft(null)\n setOpen(isOpen)\n }\n\n // Discrete change (preset click, field commit) — pushes to undo\n const handleDiscreteChange = (newValue: string) => {\n if (disabled) return\n const normalized = newValue.startsWith('#') ? newValue : `#${newValue}`\n const hex = normalized.toLowerCase()\n setUndoStack((prev) => {\n if (prev[prev.length - 1] === internalColor) return prev\n return [...prev.slice(-19), internalColor]\n })\n setInternalColor(hex)\n setHexDraft(null)\n onChange?.(hex)\n }\n\n // Continuous change (picker drag) — updates color but only pushes undo on drag start\n const handleChange = (newValue: string) => {\n if (disabled) return\n const normalized = newValue.startsWith('#') ? newValue : `#${newValue}`\n const hex = normalized.toLowerCase()\n if (!isDragging.current) {\n // First change in a drag sequence — push current color to undo\n isDragging.current = true\n setUndoStack((prev) => {\n if (prev[prev.length - 1] === internalColor) return prev\n return [...prev.slice(-19), internalColor]\n })\n }\n setInternalColor(hex)\n onChange?.(hex)\n }\n\n // Called when picker drag ends\n const handlePickerChangeComplete = () => {\n isDragging.current = false\n }\n\n const handleUndo = () => {\n if (undoStack.length === 0) return\n const prev = undoStack[undoStack.length - 1]\n setUndoStack((s) => s.slice(0, -1))\n setInternalColor(prev)\n onChange?.(prev)\n }\n\n const handleReset = () => {\n setInternalColor(openColor)\n onChange?.(openColor)\n setUndoStack([])\n }\n\n // Resolve presets\n const resolvedPresets = presets === false\n ? []\n : presets\n ? presets.map((p) =>\n typeof p === 'string' ? { hex: p, label: p } : p\n )\n : NAMED_PRESETS\n\n // Parsed color values — use internal state\n const rgb = hexToRgb(internalColor)\n const hsl = hexToHsl(internalColor)\n\n // RGB field handlers (clamped 0-255)\n const handleRgbChange = (channel: 'r' | 'g' | 'b', v: string) => {\n if (!rgb) return\n const num = parseInt(v, 10)\n if (isNaN(num)) return\n const clamped = Math.max(0, Math.min(255, num))\n handleDiscreteChange(rgbToHex(\n channel === 'r' ? clamped : rgb.r,\n channel === 'g' ? clamped : rgb.g,\n channel === 'b' ? clamped : rgb.b,\n ))\n }\n\n // HSL field handlers (H: 0-360, S/L: 0-100)\n const handleHslChange = (channel: 'h' | 's' | 'l', v: string) => {\n if (!hsl) return\n const num = parseInt(v, 10)\n if (isNaN(num)) return\n const max = channel === 'h' ? 360 : 100\n const clamped = Math.max(0, Math.min(max, num))\n handleDiscreteChange(hslToHex(\n channel === 'h' ? clamped : hsl.h,\n channel === 's' ? clamped : hsl.s,\n channel === 'l' ? clamped : hsl.l,\n ))\n }\n\n const formats: ColorFormat[] = ['hex', 'rgb', 'hsl']\n\n return (\n <div ref={ref} className={cn('inline-flex flex-col', className)} {...props}>\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n {variant === 'inline' ? (\n <motion.button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'group flex items-center justify-center rounded-control px-ds-04 py-ds-02 font-mono text-body-sm font-medium',\n 'focus:outline-hidden focus:ring-2 focus:ring-accent-9 focus:ring-offset-2 focus:ring-offset-surface-base',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n animate={{\n backgroundColor: internalColor,\n color: isLightColor(internalColor) ? 'rgba(0,0,0,0.8)' : 'rgba(255,255,255,0.95)',\n }}\n whileHover={{ y: -1, boxShadow: '0 4px 12px rgba(0,0,0,0.12)' }}\n whileTap={{ scale: 0.97 }}\n transition={springs.smooth}\n id={triggerId}\n aria-describedby={fieldCtx.helperTextId}\n aria-invalid={fieldCtx.state === 'error' || undefined}\n // Inside a FormField, let the visible <Label> name the trigger; else describe it.\n aria-label={fieldCtx.inputId ? undefined : `Color picker: ${internalColor}`}\n >\n {internalColor.toUpperCase()}\n </motion.button>\n ) : (\n <motion.button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'group relative flex items-center overflow-hidden rounded-control border border-surface-border-strong',\n 'hover:border-accent-7 focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n whileHover={{ scale: 1.02 }}\n whileTap={{ scale: 0.98 }}\n transition={springs.snappy}\n id={triggerId}\n aria-describedby={fieldCtx.helperTextId}\n aria-invalid={fieldCtx.state === 'error' || undefined}\n // Inside a FormField, let the visible <Label> name the trigger; else describe it.\n aria-label={fieldCtx.inputId ? undefined : `Color picker: ${internalColor}`}\n >\n {/* Gradient background: color → surface */}\n <motion.span\n className=\"absolute inset-0\"\n animate={{\n background: `linear-gradient(to right, ${internalColor} 0%, ${internalColor} 35%, transparent 70%)`,\n }}\n /* Between durations.moderate02 (0.24) and durations.slow01 (0.4) — gradient lerp feel */\n transition={{ duration: 0.3 }}\n />\n <span className=\"absolute inset-0 bg-surface-overlay/60\" style={{\n maskImage: 'linear-gradient(to right, transparent 0%, black 40%)',\n WebkitMaskImage: 'linear-gradient(to right, transparent 0%, black 40%)',\n }} />\n {/* Hex value */}\n <span className=\"relative z-10 py-ds-02 pl-6 pr-ds-03 font-mono text-body-sm text-surface-fg\">\n {internalColor.toUpperCase()}\n </span>\n </motion.button>\n )}\n </PopoverTrigger>\n\n <PopoverContent\n role=\"dialog\"\n aria-label=\"Color picker\"\n align={align}\n sideOffset={8}\n className=\"w-[272px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating\"\n >\n <div className=\"flex flex-col\">\n {/* Interactive picker */}\n {showPicker && (\n <div className=\"p-ds-04 pb-ds-03\" onPointerUp={handlePickerChangeComplete} onPointerLeave={handlePickerChangeComplete}>\n <HexColorPicker\n color={internalColor}\n onChange={handleChange}\n className=\"w-full!\"\n style={{ height: 160 }}\n />\n </div>\n )}\n\n {/* Format inputs */}\n <div className=\"border-t border-surface-border px-ds-04 py-ds-03\">\n {/* Format switcher */}\n <div className=\"mb-ds-03 flex items-center gap-ds-01\">\n {formats.map((f) => (\n <button\n key={f}\n type=\"button\"\n onClick={() => setFormat(f)}\n className={cn(\n 'relative min-h-6 rounded-control-inner px-ds-02 py-px text-label-xs font-semibold uppercase tracking-wider transition-colors',\n format === f\n ? 'text-accent-11'\n : 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n {format === f && (\n <motion.span\n layoutId={`color-input-format-pill-${instanceId}`}\n className=\"absolute inset-0 rounded-control-inner bg-accent-3\"\n transition={springs.snappy}\n />\n )}\n <span className=\"relative z-10\">{f}</span>\n </button>\n ))}\n </div>\n\n {/* Format fields — animated swap */}\n <AnimatePresence mode=\"wait\">\n {format === 'hex' && (\n <motion.div\n key=\"hex\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput\n id={`${instanceId}-hex`}\n label=\"Hex\"\n value={hexDraft ?? internalColor.replace('#', '').toUpperCase()}\n onChange={(v) => {\n const clean = v.replace(/[^0-9a-fA-F]/g, '').slice(0, 6)\n setHexDraft(clean.toUpperCase())\n if (clean.length === 6) handleDiscreteChange(`#${clean}`)\n }}\n onBlur={() => {\n // Drop any incomplete draft; display falls back to the\n // committed color. A complete value already committed onChange.\n setHexDraft(null)\n }}\n disabled={disabled}\n maxLength={6}\n prefix=\"#\"\n className=\"flex-1\"\n />\n </motion.div>\n )}\n\n {format === 'rgb' && rgb && (\n <motion.div\n key=\"rgb\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput id={`${instanceId}-r`} label=\"R\" value={String(rgb.r)} onChange={(v) => handleRgbChange('r', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-g`} label=\"G\" value={String(rgb.g)} onChange={(v) => handleRgbChange('g', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-b`} label=\"B\" value={String(rgb.b)} onChange={(v) => handleRgbChange('b', v)} disabled={disabled} className=\"flex-1\" />\n </motion.div>\n )}\n\n {format === 'hsl' && hsl && (\n <motion.div\n key=\"hsl\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput id={`${instanceId}-h`} label=\"H\" value={String(hsl.h)} onChange={(v) => handleHslChange('h', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-s`} label=\"S\" value={String(hsl.s)} onChange={(v) => handleHslChange('s', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-l`} label=\"L\" value={String(hsl.l)} onChange={(v) => handleHslChange('l', v)} disabled={disabled} className=\"flex-1\" />\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n\n {/* Preset swatches */}\n {resolvedPresets.length > 0 && (\n <div className=\"border-t border-surface-border px-ds-04 py-ds-03\">\n <div className=\"flex flex-wrap gap-ds-02\">\n {resolvedPresets.map((preset, i) => {\n const isSelected = internalColor.toLowerCase() === preset.hex.toLowerCase()\n return (\n <motion.button\n key={preset.hex}\n type=\"button\"\n disabled={disabled}\n onClick={() => handleDiscreteChange(preset.hex)}\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: isSelected ? 1.15 : 1 }}\n whileHover={{ scale: isSelected ? 1.15 : 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={{ ...springs.bouncy, delay: i * 0.02 }}\n className={cn(\n 'h-6 w-6 rounded-control-inner border',\n isSelected\n ? 'border-accent-7 ring-2 ring-accent-9/30'\n : 'border-surface-border hover:border-surface-border-strong',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n style={{ backgroundColor: preset.hex }}\n title={preset.label}\n aria-label={`${preset.label}: ${preset.hex}`}\n />\n )\n })}\n </div>\n </div>\n )}\n\n {/* Reset / Undo footer */}\n {(undoStack.length > 0 || internalColor !== openColor) && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n className=\"flex items-center gap-ds-02 border-t border-surface-border px-ds-04 py-ds-02\"\n >\n {/* Original color preview */}\n <span\n className=\"h-4 w-4 shrink-0 rounded-pill border border-surface-border\"\n style={{ backgroundColor: openColor }}\n title={`Original: ${openColor}`}\n />\n <span className=\"text-caption text-surface-fg-muted\">\n {openColor.toUpperCase()}\n </span>\n <span className=\"flex-1\" />\n {undoStack.length > 0 && (\n <button\n type=\"button\"\n onClick={handleUndo}\n className=\"min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-surface-fg\"\n >\n Undo\n </button>\n )}\n {internalColor !== openColor && (\n <button\n type=\"button\"\n onClick={handleReset}\n className=\"min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-error-11\"\n >\n Reset\n </button>\n )}\n </motion.div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n )\n },\n)\nColorInput.displayName = 'ColorInput'\n\nexport { ColorInput }\n"],"mappings":"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"}
package/dist/ui/icon.d.ts CHANGED
@@ -33,6 +33,8 @@ export interface IconProps {
33
33
  */
34
34
  state?: 'idle' | 'loading' | 'success' | 'error';
35
35
  className?: string;
36
+ /** Inline styles forwarded to the rendered icon (e.g. decorative opacity/transform). */
37
+ style?: React.CSSProperties;
36
38
  }
37
39
  /**
38
40
  * Icon — context-aware wrapper for Tabler icons with standardized sizing,
@@ -1 +1 @@
1
- {"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../src/ui/icon.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAiB,MAAM,gBAAgB,CAAA;AAiB9E,6EAA6E;AAC7E,KAAK,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG;IACzF,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAqBD,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,IAAI,EAAE,KAAK,CAAC,yBAAyB,CAAC,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAA;IAC9F,oDAAoD;IACpD,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,wDAAwD;IACxD,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7F;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;IAChD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,IAAI,iFAwHhB,CAAA"}
1
+ {"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../src/ui/icon.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAiB,MAAM,gBAAgB,CAAA;AAiB9E,6EAA6E;AAC7E,KAAK,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG;IACzF,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAqBD,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,IAAI,EAAE,KAAK,CAAC,yBAAyB,CAAC,kBAAkB,GAAG,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAA;IAC9F,oDAAoD;IACpD,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,wDAAwD;IACxD,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7F;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;IAChD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wFAAwF;IACxF,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;CAC5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,IAAI,iFA2HhB,CAAA"}