@zag-js/color-picker 0.82.2 → 1.0.1

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.
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ var popper = require('@zag-js/popper');
7
7
  var core = require('@zag-js/core');
8
8
  var dismissable = require('@zag-js/dismissable');
9
9
  var utils = require('@zag-js/utils');
10
+ var types = require('@zag-js/types');
10
11
 
11
12
  // src/color-picker.anatomy.ts
12
13
  var anatomy = anatomy$1.createAnatomy("color-picker", [
@@ -36,58 +37,47 @@ var anatomy = anatomy$1.createAnatomy("color-picker", [
36
37
  "formatSelect"
37
38
  ]);
38
39
  var parts = anatomy.build();
39
- var dom = domQuery.createScope({
40
- getRootId: (ctx) => ctx.ids?.root ?? `color-picker:${ctx.id}`,
41
- getLabelId: (ctx) => ctx.ids?.label ?? `color-picker:${ctx.id}:label`,
42
- getHiddenInputId: (ctx) => ctx.ids?.hiddenInput ?? `color-picker:${ctx.id}:hidden-input`,
43
- getControlId: (ctx) => ctx.ids?.control ?? `color-picker:${ctx.id}:control`,
44
- getTriggerId: (ctx) => ctx.ids?.trigger ?? `color-picker:${ctx.id}:trigger`,
45
- getContentId: (ctx) => ctx.ids?.content ?? `color-picker:${ctx.id}:content`,
46
- getPositionerId: (ctx) => ctx.ids?.positioner ?? `color-picker:${ctx.id}:positioner`,
47
- getFormatSelectId: (ctx) => ctx.ids?.formatSelect ?? `color-picker:${ctx.id}:format-select`,
48
- getAreaId: (ctx) => ctx.ids?.area ?? `color-picker:${ctx.id}:area`,
49
- getAreaGradientId: (ctx) => ctx.ids?.areaGradient ?? `color-picker:${ctx.id}:area-gradient`,
50
- getAreaThumbId: (ctx) => ctx.ids?.areaThumb ?? `color-picker:${ctx.id}:area-thumb`,
51
- getChannelSliderTrackId: (ctx, channel) => ctx.ids?.channelSliderTrack?.(channel) ?? `color-picker:${ctx.id}:slider-track:${channel}`,
52
- getChannelSliderThumbId: (ctx, channel) => ctx.ids?.channelSliderThumb?.(channel) ?? `color-picker:${ctx.id}:slider-thumb:${channel}`,
53
- getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
54
- getAreaThumbEl: (ctx) => dom.getById(ctx, dom.getAreaThumbId(ctx)),
55
- getChannelSliderThumbEl: (ctx, channel) => dom.getById(ctx, dom.getChannelSliderThumbId(ctx, channel)),
56
- getChannelInputEl: (ctx, channel) => {
57
- const selector = `input[data-channel="${channel}"]`;
58
- return [
59
- ...domQuery.queryAll(dom.getContentEl(ctx), selector),
60
- ...domQuery.queryAll(dom.getControlEl(ctx), selector)
61
- ];
62
- },
63
- getFormatSelectEl: (ctx) => dom.getById(ctx, dom.getFormatSelectId(ctx)),
64
- getHiddenInputEl: (ctx) => dom.getById(ctx, dom.getHiddenInputId(ctx)),
65
- getAreaEl: (ctx) => dom.getById(ctx, dom.getAreaId(ctx)),
66
- getAreaValueFromPoint(ctx, point) {
67
- const areaEl = dom.getAreaEl(ctx);
68
- if (!areaEl) return;
69
- const { percent } = domQuery.getRelativePoint(point, areaEl);
70
- return percent;
71
- },
72
- getControlEl: (ctx) => dom.getById(ctx, dom.getControlId(ctx)),
73
- getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
74
- getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
75
- getChannelSliderTrackEl: (ctx, channel) => {
76
- return dom.getById(ctx, dom.getChannelSliderTrackId(ctx, channel));
77
- },
78
- getChannelSliderValueFromPoint(ctx, point, channel) {
79
- const trackEl = dom.getChannelSliderTrackEl(ctx, channel);
80
- if (!trackEl) return;
81
- const { percent } = domQuery.getRelativePoint(point, trackEl);
82
- return percent;
83
- },
84
- getChannelInputEls: (ctx) => {
85
- return [
86
- ...domQuery.queryAll(dom.getContentEl(ctx), "input[data-channel]"),
87
- ...domQuery.queryAll(dom.getControlEl(ctx), "input[data-channel]")
88
- ];
89
- }
90
- });
40
+ var getRootId = (ctx) => ctx.ids?.root ?? `color-picker:${ctx.id}`;
41
+ var getLabelId = (ctx) => ctx.ids?.label ?? `color-picker:${ctx.id}:label`;
42
+ var getHiddenInputId = (ctx) => ctx.ids?.hiddenInput ?? `color-picker:${ctx.id}:hidden-input`;
43
+ var getControlId = (ctx) => ctx.ids?.control ?? `color-picker:${ctx.id}:control`;
44
+ var getTriggerId = (ctx) => ctx.ids?.trigger ?? `color-picker:${ctx.id}:trigger`;
45
+ var getContentId = (ctx) => ctx.ids?.content ?? `color-picker:${ctx.id}:content`;
46
+ var getPositionerId = (ctx) => ctx.ids?.positioner ?? `color-picker:${ctx.id}:positioner`;
47
+ var getFormatSelectId = (ctx) => ctx.ids?.formatSelect ?? `color-picker:${ctx.id}:format-select`;
48
+ var getAreaId = (ctx) => ctx.ids?.area ?? `color-picker:${ctx.id}:area`;
49
+ var getAreaGradientId = (ctx) => ctx.ids?.areaGradient ?? `color-picker:${ctx.id}:area-gradient`;
50
+ var getAreaThumbId = (ctx) => ctx.ids?.areaThumb ?? `color-picker:${ctx.id}:area-thumb`;
51
+ var getChannelSliderTrackId = (ctx, channel) => ctx.ids?.channelSliderTrack?.(channel) ?? `color-picker:${ctx.id}:slider-track:${channel}`;
52
+ var getChannelSliderThumbId = (ctx, channel) => ctx.ids?.channelSliderThumb?.(channel) ?? `color-picker:${ctx.id}:slider-thumb:${channel}`;
53
+ var getContentEl = (ctx) => ctx.getById(getContentId(ctx));
54
+ var getAreaThumbEl = (ctx) => ctx.getById(getAreaThumbId(ctx));
55
+ var getChannelSliderThumbEl = (ctx, channel) => ctx.getById(getChannelSliderThumbId(ctx, channel));
56
+ var getFormatSelectEl = (ctx) => ctx.getById(getFormatSelectId(ctx));
57
+ var getHiddenInputEl = (ctx) => ctx.getById(getHiddenInputId(ctx));
58
+ var getAreaEl = (ctx) => ctx.getById(getAreaId(ctx));
59
+ var getAreaValueFromPoint = (ctx, point) => {
60
+ const areaEl = getAreaEl(ctx);
61
+ if (!areaEl) return;
62
+ const { percent } = domQuery.getRelativePoint(point, areaEl);
63
+ return percent;
64
+ };
65
+ var getControlEl = (ctx) => ctx.getById(getControlId(ctx));
66
+ var getTriggerEl = (ctx) => ctx.getById(getTriggerId(ctx));
67
+ var getPositionerEl = (ctx) => ctx.getById(getPositionerId(ctx));
68
+ var getChannelSliderTrackEl = (ctx, channel) => ctx.getById(getChannelSliderTrackId(ctx, channel));
69
+ var getChannelSliderValueFromPoint = (ctx, point, channel) => {
70
+ const trackEl = getChannelSliderTrackEl(ctx, channel);
71
+ if (!trackEl) return;
72
+ const { percent } = domQuery.getRelativePoint(point, trackEl);
73
+ return percent;
74
+ };
75
+ var getChannelInputEls = (ctx) => {
76
+ return [
77
+ ...domQuery.queryAll(getContentEl(ctx), "input[data-channel]"),
78
+ ...domQuery.queryAll(getControlEl(ctx), "input[data-channel]")
79
+ ];
80
+ };
91
81
  function getChannelDisplayColor(color, channel) {
92
82
  switch (channel) {
93
83
  case "hue":
@@ -173,8 +163,8 @@ function getSliderBackgroundDirection(orientation, dir) {
173
163
  return "left";
174
164
  }
175
165
  }
176
- var getSliderBackground = (props) => {
177
- const { channel, value, dir, orientation } = props;
166
+ var getSliderBackground = (props2) => {
167
+ const { channel, value, dir, orientation } = props2;
178
168
  const bgDirection = getSliderBackgroundDirection(orientation, dir);
179
169
  const { minValue, maxValue } = value.getChannelRange(channel);
180
170
  switch (channel) {
@@ -202,34 +192,36 @@ var getSliderBackground = (props) => {
202
192
  };
203
193
 
204
194
  // src/color-picker.connect.ts
205
- function connect(state, send, normalize) {
206
- const value = state.context.value;
207
- const areaValue = state.context.areaValue;
208
- const valueAsString = state.context.valueAsString;
209
- const disabled = state.context.isDisabled;
210
- const interactive = state.context.isInteractive;
195
+ function connect(service, normalize) {
196
+ const { context, send, prop, computed, state, scope } = service;
197
+ const value = context.get("value");
198
+ const format = context.get("format");
199
+ const areaValue = computed("areaValue");
200
+ const valueAsString = computed("valueAsString");
201
+ const disabled = computed("disabled");
202
+ const interactive = computed("interactive");
211
203
  const dragging = state.hasTag("dragging");
212
204
  const open = state.hasTag("open");
213
205
  const focused = state.hasTag("focused");
214
- const getAreaChannels = (props) => {
206
+ const getAreaChannels = (props2) => {
215
207
  const channels = areaValue.getChannels();
216
208
  return {
217
- xChannel: props.xChannel ?? channels[1],
218
- yChannel: props.yChannel ?? channels[2]
209
+ xChannel: props2.xChannel ?? channels[1],
210
+ yChannel: props2.yChannel ?? channels[2]
219
211
  };
220
212
  };
221
- const currentPlacement = state.context.currentPlacement;
213
+ const currentPlacement = context.get("currentPlacement");
222
214
  const popperStyles = popper.getPlacementStyles({
223
- ...state.context.positioning,
215
+ ...prop("positioning"),
224
216
  placement: currentPlacement
225
217
  });
226
- function getSwatchTriggerState(props) {
227
- const color = colorUtils.normalizeColor(props.value).toFormat(state.context.format);
218
+ function getSwatchTriggerState(props2) {
219
+ const color = colorUtils.normalizeColor(props2.value).toFormat(context.get("format"));
228
220
  return {
229
221
  value: color,
230
222
  valueAsString: color.toString("hex"),
231
223
  checked: color.isEqual(value),
232
- disabled: props.disabled || !interactive
224
+ disabled: props2.disabled || !interactive
233
225
  };
234
226
  }
235
227
  return {
@@ -254,9 +246,9 @@ function connect(state, send, normalize) {
254
246
  const color = value.withChannelValue(channel, channelValue);
255
247
  send({ type: "VALUE.SET", value: color, src: "set-channel" });
256
248
  },
257
- format: state.context.format,
258
- setFormat(format) {
259
- const formatValue = value.toFormat(format);
249
+ format: context.get("format"),
250
+ setFormat(format2) {
251
+ const formatValue = value.toFormat(format2);
260
252
  send({ type: "VALUE.SET", value: formatValue, src: "set-format" });
261
253
  },
262
254
  alpha: value.getChannelValue("alpha"),
@@ -267,11 +259,11 @@ function connect(state, send, normalize) {
267
259
  getRootProps() {
268
260
  return normalize.element({
269
261
  ...parts.root.attrs,
270
- dir: state.context.dir,
271
- id: dom.getRootId(state.context),
262
+ dir: prop("dir"),
263
+ id: getRootId(scope),
272
264
  "data-disabled": domQuery.dataAttr(disabled),
273
- "data-readonly": domQuery.dataAttr(state.context.readOnly),
274
- "data-invalid": domQuery.dataAttr(state.context.invalid),
265
+ "data-readonly": domQuery.dataAttr(prop("readOnly")),
266
+ "data-invalid": domQuery.dataAttr(prop("invalid")),
275
267
  style: {
276
268
  "--value": value.toString("css")
277
269
  }
@@ -280,16 +272,16 @@ function connect(state, send, normalize) {
280
272
  getLabelProps() {
281
273
  return normalize.element({
282
274
  ...parts.label.attrs,
283
- dir: state.context.dir,
284
- id: dom.getLabelId(state.context),
285
- htmlFor: dom.getHiddenInputId(state.context),
275
+ dir: prop("dir"),
276
+ id: getLabelId(scope),
277
+ htmlFor: getHiddenInputId(scope),
286
278
  "data-disabled": domQuery.dataAttr(disabled),
287
- "data-readonly": domQuery.dataAttr(state.context.readOnly),
288
- "data-invalid": domQuery.dataAttr(state.context.invalid),
279
+ "data-readonly": domQuery.dataAttr(prop("readOnly")),
280
+ "data-invalid": domQuery.dataAttr(prop("invalid")),
289
281
  "data-focus": domQuery.dataAttr(focused),
290
282
  onClick(event) {
291
283
  event.preventDefault();
292
- const inputEl = domQuery.query(dom.getControlEl(state.context), "[data-channel=hex]");
284
+ const inputEl = domQuery.query(getControlEl(scope), "[data-channel=hex]");
293
285
  inputEl?.focus({ preventScroll: true });
294
286
  }
295
287
  });
@@ -297,11 +289,11 @@ function connect(state, send, normalize) {
297
289
  getControlProps() {
298
290
  return normalize.element({
299
291
  ...parts.control.attrs,
300
- id: dom.getControlId(state.context),
301
- dir: state.context.dir,
292
+ id: getControlId(scope),
293
+ dir: prop("dir"),
302
294
  "data-disabled": domQuery.dataAttr(disabled),
303
- "data-readonly": domQuery.dataAttr(state.context.readOnly),
304
- "data-invalid": domQuery.dataAttr(state.context.invalid),
295
+ "data-readonly": domQuery.dataAttr(prop("readOnly")),
296
+ "data-invalid": domQuery.dataAttr(prop("invalid")),
305
297
  "data-state": open ? "open" : "closed",
306
298
  "data-focus": domQuery.dataAttr(focused)
307
299
  });
@@ -309,15 +301,15 @@ function connect(state, send, normalize) {
309
301
  getTriggerProps() {
310
302
  return normalize.button({
311
303
  ...parts.trigger.attrs,
312
- id: dom.getTriggerId(state.context),
313
- dir: state.context.dir,
304
+ id: getTriggerId(scope),
305
+ dir: prop("dir"),
314
306
  disabled,
315
307
  "aria-label": `select color. current color is ${valueAsString}`,
316
- "aria-controls": dom.getContentId(state.context),
317
- "aria-labelledby": dom.getLabelId(state.context),
308
+ "aria-controls": getContentId(scope),
309
+ "aria-labelledby": getLabelId(scope),
318
310
  "data-disabled": domQuery.dataAttr(disabled),
319
- "data-readonly": domQuery.dataAttr(state.context.readOnly),
320
- "data-invalid": domQuery.dataAttr(state.context.invalid),
311
+ "data-readonly": domQuery.dataAttr(prop("readOnly")),
312
+ "data-invalid": domQuery.dataAttr(prop("invalid")),
321
313
  "data-placement": currentPlacement,
322
314
  "aria-expanded": domQuery.dataAttr(open),
323
315
  "data-state": open ? "open" : "closed",
@@ -339,16 +331,16 @@ function connect(state, send, normalize) {
339
331
  getPositionerProps() {
340
332
  return normalize.element({
341
333
  ...parts.positioner.attrs,
342
- id: dom.getPositionerId(state.context),
343
- dir: state.context.dir,
334
+ id: getPositionerId(scope),
335
+ dir: prop("dir"),
344
336
  style: popperStyles.floating
345
337
  });
346
338
  },
347
339
  getContentProps() {
348
340
  return normalize.element({
349
341
  ...parts.content.attrs,
350
- id: dom.getContentId(state.context),
351
- dir: state.context.dir,
342
+ id: getContentId(scope),
343
+ dir: prop("dir"),
352
344
  "data-placement": currentPlacement,
353
345
  "data-state": open ? "open" : "closed",
354
346
  hidden: !open
@@ -357,25 +349,25 @@ function connect(state, send, normalize) {
357
349
  getValueTextProps() {
358
350
  return normalize.element({
359
351
  ...parts.valueText.attrs,
360
- dir: state.context.dir,
352
+ dir: prop("dir"),
361
353
  "data-disabled": domQuery.dataAttr(disabled),
362
354
  "data-focus": domQuery.dataAttr(focused)
363
355
  });
364
356
  },
365
- getAreaProps(props = {}) {
366
- const { xChannel, yChannel } = getAreaChannels(props);
357
+ getAreaProps(props2 = {}) {
358
+ const { xChannel, yChannel } = getAreaChannels(props2);
367
359
  const { areaStyles } = colorUtils.getColorAreaGradient(areaValue, {
368
360
  xChannel,
369
361
  yChannel,
370
- dir: state.context.dir
362
+ dir: prop("dir")
371
363
  });
372
364
  return normalize.element({
373
365
  ...parts.area.attrs,
374
- id: dom.getAreaId(state.context),
366
+ id: getAreaId(scope),
375
367
  role: "group",
376
- "data-invalid": domQuery.dataAttr(state.context.invalid),
368
+ "data-invalid": domQuery.dataAttr(prop("invalid")),
377
369
  "data-disabled": domQuery.dataAttr(disabled),
378
- "data-readonly": domQuery.dataAttr(state.context.readOnly),
370
+ "data-readonly": domQuery.dataAttr(prop("readOnly")),
379
371
  onPointerDown(event) {
380
372
  if (!interactive) return;
381
373
  if (!domQuery.isLeftClick(event)) return;
@@ -393,19 +385,19 @@ function connect(state, send, normalize) {
393
385
  }
394
386
  });
395
387
  },
396
- getAreaBackgroundProps(props = {}) {
397
- const { xChannel, yChannel } = getAreaChannels(props);
388
+ getAreaBackgroundProps(props2 = {}) {
389
+ const { xChannel, yChannel } = getAreaChannels(props2);
398
390
  const { areaGradientStyles } = colorUtils.getColorAreaGradient(areaValue, {
399
391
  xChannel,
400
392
  yChannel,
401
- dir: state.context.dir
393
+ dir: prop("dir")
402
394
  });
403
395
  return normalize.element({
404
396
  ...parts.areaBackground.attrs,
405
- id: dom.getAreaGradientId(state.context),
406
- "data-invalid": domQuery.dataAttr(state.context.invalid),
397
+ id: getAreaGradientId(scope),
398
+ "data-invalid": domQuery.dataAttr(prop("invalid")),
407
399
  "data-disabled": domQuery.dataAttr(disabled),
408
- "data-readonly": domQuery.dataAttr(state.context.readOnly),
400
+ "data-readonly": domQuery.dataAttr(prop("readOnly")),
409
401
  style: {
410
402
  position: "relative",
411
403
  touchAction: "none",
@@ -414,8 +406,8 @@ function connect(state, send, normalize) {
414
406
  }
415
407
  });
416
408
  },
417
- getAreaThumbProps(props = {}) {
418
- const { xChannel, yChannel } = getAreaChannels(props);
409
+ getAreaThumbProps(props2 = {}) {
410
+ const { xChannel, yChannel } = getAreaChannels(props2);
419
411
  const channel = { xChannel, yChannel };
420
412
  const xPercent = areaValue.getChannelValuePercent(xChannel);
421
413
  const yPercent = 1 - areaValue.getChannelValuePercent(yChannel);
@@ -424,12 +416,12 @@ function connect(state, send, normalize) {
424
416
  const color = areaValue.withChannelValue("alpha", 1).toString("css");
425
417
  return normalize.element({
426
418
  ...parts.areaThumb.attrs,
427
- id: dom.getAreaThumbId(state.context),
428
- dir: state.context.dir,
419
+ id: getAreaThumbId(scope),
420
+ dir: prop("dir"),
429
421
  tabIndex: disabled ? void 0 : 0,
430
422
  "data-disabled": domQuery.dataAttr(disabled),
431
- "data-invalid": domQuery.dataAttr(state.context.invalid),
432
- "data-readonly": domQuery.dataAttr(state.context.readOnly),
423
+ "data-invalid": domQuery.dataAttr(prop("invalid")),
424
+ "data-readonly": domQuery.dataAttr(prop("readOnly")),
433
425
  role: "slider",
434
426
  "aria-valuemin": 0,
435
427
  "aria-valuemax": 100,
@@ -478,7 +470,9 @@ function connect(state, send, normalize) {
478
470
  event2.stopPropagation();
479
471
  }
480
472
  };
481
- const exec = keyMap[domQuery.getEventKey(event, state.context)];
473
+ const exec = keyMap[domQuery.getEventKey(event, {
474
+ dir: prop("dir")
475
+ })];
482
476
  if (exec) {
483
477
  exec(event);
484
478
  event.preventDefault();
@@ -486,8 +480,8 @@ function connect(state, send, normalize) {
486
480
  }
487
481
  });
488
482
  },
489
- getTransparencyGridProps(props = {}) {
490
- const { size = "12px" } = props;
483
+ getTransparencyGridProps(props2 = {}) {
484
+ const { size = "12px" } = props2;
491
485
  return normalize.element({
492
486
  ...parts.transparencyGrid.attrs,
493
487
  style: {
@@ -504,8 +498,8 @@ function connect(state, send, normalize) {
504
498
  }
505
499
  });
506
500
  },
507
- getChannelSliderProps(props) {
508
- const { orientation = "horizontal", channel, format } = props;
501
+ getChannelSliderProps(props2) {
502
+ const { orientation = "horizontal", channel, format: format2 } = props2;
509
503
  return normalize.element({
510
504
  ...parts.channelSlider.attrs,
511
505
  "data-channel": channel,
@@ -516,7 +510,7 @@ function connect(state, send, normalize) {
516
510
  if (!domQuery.isLeftClick(event)) return;
517
511
  if (domQuery.isModifierKey(event)) return;
518
512
  const point = domQuery.getEventPoint(event);
519
- send({ type: "CHANNEL_SLIDER.POINTER_DOWN", channel, format, point, id: channel, orientation });
513
+ send({ type: "CHANNEL_SLIDER.POINTER_DOWN", channel, format: format2, point, id: channel, orientation });
520
514
  event.preventDefault();
521
515
  },
522
516
  style: {
@@ -525,12 +519,12 @@ function connect(state, send, normalize) {
525
519
  }
526
520
  });
527
521
  },
528
- getChannelSliderTrackProps(props) {
529
- const { orientation = "horizontal", channel, format } = props;
530
- const normalizedValue = format ? value.toFormat(format) : areaValue;
522
+ getChannelSliderTrackProps(props2) {
523
+ const { orientation = "horizontal", channel, format: format2 } = props2;
524
+ const normalizedValue = format2 ? value.toFormat(format2) : areaValue;
531
525
  return normalize.element({
532
526
  ...parts.channelSliderTrack.attrs,
533
- id: dom.getChannelSliderTrackId(state.context, channel),
527
+ id: getChannelSliderTrackId(scope, channel),
534
528
  role: "group",
535
529
  "data-channel": channel,
536
530
  "data-orientation": orientation,
@@ -540,22 +534,22 @@ function connect(state, send, normalize) {
540
534
  backgroundImage: getSliderBackground({
541
535
  orientation,
542
536
  channel,
543
- dir: state.context.dir,
537
+ dir: prop("dir"),
544
538
  value: normalizedValue
545
539
  })
546
540
  }
547
541
  });
548
542
  },
549
- getChannelSliderLabelProps(props) {
550
- const { channel } = props;
543
+ getChannelSliderLabelProps(props2) {
544
+ const { channel } = props2;
551
545
  return normalize.element({
552
546
  ...parts.channelSliderLabel.attrs,
553
547
  "data-channel": channel,
554
548
  onClick(event) {
555
549
  if (!interactive) return;
556
550
  event.preventDefault();
557
- const thumbId = dom.getChannelSliderThumbId(state.context, channel);
558
- dom.getById(state.context, thumbId)?.focus({ preventScroll: true });
551
+ const thumbId = getChannelSliderThumbId(scope, channel);
552
+ scope.getById(thumbId)?.focus({ preventScroll: true });
559
553
  },
560
554
  style: {
561
555
  userSelect: "none",
@@ -563,22 +557,22 @@ function connect(state, send, normalize) {
563
557
  }
564
558
  });
565
559
  },
566
- getChannelSliderValueTextProps(props) {
560
+ getChannelSliderValueTextProps(props2) {
567
561
  return normalize.element({
568
562
  ...parts.channelSliderValueText.attrs,
569
- "data-channel": props.channel
563
+ "data-channel": props2.channel
570
564
  });
571
565
  },
572
- getChannelSliderThumbProps(props) {
573
- const { orientation = "horizontal", channel, format } = props;
574
- const normalizedValue = format ? value.toFormat(format) : areaValue;
566
+ getChannelSliderThumbProps(props2) {
567
+ const { orientation = "horizontal", channel, format: format2 } = props2;
568
+ const normalizedValue = format2 ? value.toFormat(format2) : areaValue;
575
569
  const channelRange = normalizedValue.getChannelRange(channel);
576
570
  const channelValue = normalizedValue.getChannelValue(channel);
577
571
  const offset = (channelValue - channelRange.minValue) / (channelRange.maxValue - channelRange.minValue);
578
572
  const placementStyles = orientation === "horizontal" ? { left: `${offset * 100}%`, top: "50%" } : { top: `${offset * 100}%`, left: "50%" };
579
573
  return normalize.element({
580
574
  ...parts.channelSliderThumb.attrs,
581
- id: dom.getChannelSliderThumbId(state.context, channel),
575
+ id: getChannelSliderThumbId(scope, channel),
582
576
  role: "slider",
583
577
  "aria-label": channel,
584
578
  tabIndex: disabled ? void 0 : 0,
@@ -634,7 +628,9 @@ function connect(state, send, normalize) {
634
628
  event2.stopPropagation();
635
629
  }
636
630
  };
637
- const exec = keyMap[domQuery.getEventKey(event, state.context)];
631
+ const exec = keyMap[domQuery.getEventKey(event, {
632
+ dir: prop("dir")
633
+ })];
638
634
  if (exec) {
639
635
  exec(event);
640
636
  event.preventDefault();
@@ -642,13 +638,13 @@ function connect(state, send, normalize) {
642
638
  }
643
639
  });
644
640
  },
645
- getChannelInputProps(props) {
646
- const { channel } = props;
641
+ getChannelInputProps(props2) {
642
+ const { channel } = props2;
647
643
  const isTextField = channel === "hex" || channel === "css";
648
644
  const channelRange = getChannelRange(value, channel);
649
645
  return normalize.input({
650
646
  ...parts.channelInput.attrs,
651
- dir: state.context.dir,
647
+ dir: prop("dir"),
652
648
  type: isTextField ? "text" : "number",
653
649
  "data-channel": channel,
654
650
  "aria-label": channel,
@@ -656,9 +652,9 @@ function connect(state, send, normalize) {
656
652
  autoComplete: "off",
657
653
  disabled,
658
654
  "data-disabled": domQuery.dataAttr(disabled),
659
- "data-invalid": domQuery.dataAttr(state.context.invalid),
660
- "data-readonly": domQuery.dataAttr(state.context.readOnly),
661
- readOnly: state.context.readOnly,
655
+ "data-invalid": domQuery.dataAttr(prop("invalid")),
656
+ "data-readonly": domQuery.dataAttr(prop("readOnly")),
657
+ readOnly: prop("readOnly"),
662
658
  defaultValue: getChannelValue(value, channel),
663
659
  min: channelRange?.minValue,
664
660
  max: channelRange?.maxValue,
@@ -700,11 +696,11 @@ function connect(state, send, normalize) {
700
696
  return normalize.input({
701
697
  type: "text",
702
698
  disabled,
703
- name: state.context.name,
699
+ name: prop("name"),
704
700
  tabIndex: -1,
705
- readOnly: state.context.readOnly,
706
- required: state.context.required,
707
- id: dom.getHiddenInputId(state.context),
701
+ readOnly: prop("readOnly"),
702
+ required: prop("required"),
703
+ id: getHiddenInputId(scope),
708
704
  style: domQuery.visuallyHiddenStyle,
709
705
  defaultValue: valueAsString
710
706
  });
@@ -713,15 +709,15 @@ function connect(state, send, normalize) {
713
709
  return normalize.button({
714
710
  ...parts.eyeDropperTrigger.attrs,
715
711
  type: "button",
716
- dir: state.context.dir,
712
+ dir: prop("dir"),
717
713
  disabled,
718
714
  "data-disabled": domQuery.dataAttr(disabled),
719
- "data-invalid": domQuery.dataAttr(state.context.invalid),
720
- "data-readonly": domQuery.dataAttr(state.context.readOnly),
715
+ "data-invalid": domQuery.dataAttr(prop("invalid")),
716
+ "data-readonly": domQuery.dataAttr(prop("readOnly")),
721
717
  "aria-label": "Pick a color from the screen",
722
718
  onClick() {
723
719
  if (!interactive) return;
724
- send("EYEDROPPER.CLICK");
720
+ send({ type: "EYEDROPPER.CLICK" });
725
721
  }
726
722
  });
727
723
  },
@@ -732,12 +728,12 @@ function connect(state, send, normalize) {
732
728
  });
733
729
  },
734
730
  getSwatchTriggerState,
735
- getSwatchTriggerProps(props) {
736
- const swatchState = getSwatchTriggerState(props);
731
+ getSwatchTriggerProps(props2) {
732
+ const swatchState = getSwatchTriggerState(props2);
737
733
  return normalize.button({
738
734
  ...parts.swatchTrigger.attrs,
739
735
  disabled: swatchState.disabled,
740
- dir: state.context.dir,
736
+ dir: prop("dir"),
741
737
  type: "button",
742
738
  "aria-label": `select ${swatchState.valueAsString} as the color`,
743
739
  "data-state": swatchState.checked ? "checked" : "unchecked",
@@ -753,21 +749,21 @@ function connect(state, send, normalize) {
753
749
  }
754
750
  });
755
751
  },
756
- getSwatchIndicatorProps(props) {
757
- const swatchState = getSwatchTriggerState(props);
752
+ getSwatchIndicatorProps(props2) {
753
+ const swatchState = getSwatchTriggerState(props2);
758
754
  return normalize.element({
759
755
  ...parts.swatchIndicator.attrs,
760
- dir: state.context.dir,
756
+ dir: prop("dir"),
761
757
  hidden: !swatchState.checked
762
758
  });
763
759
  },
764
- getSwatchProps(props) {
765
- const { respectAlpha = true } = props;
766
- const swatchState = getSwatchTriggerState(props);
760
+ getSwatchProps(props2) {
761
+ const { respectAlpha = true } = props2;
762
+ const swatchState = getSwatchTriggerState(props2);
767
763
  const color = swatchState.value.toString(respectAlpha ? "css" : "hex");
768
764
  return normalize.element({
769
765
  ...parts.swatch.attrs,
770
- dir: state.context.dir,
766
+ dir: prop("dir"),
771
767
  "data-state": swatchState.checked ? "checked" : "unchecked",
772
768
  "data-value": swatchState.valueAsString,
773
769
  style: {
@@ -780,12 +776,12 @@ function connect(state, send, normalize) {
780
776
  getFormatTriggerProps() {
781
777
  return normalize.button({
782
778
  ...parts.formatTrigger.attrs,
783
- dir: state.context.dir,
779
+ dir: prop("dir"),
784
780
  type: "button",
785
- "aria-label": `change color format to ${getNextFormat(state.context.format)}`,
781
+ "aria-label": `change color format to ${getNextFormat(format)}`,
786
782
  onClick(event) {
787
783
  if (event.currentTarget.disabled) return;
788
- const nextFormat = getNextFormat(state.context.format);
784
+ const nextFormat = getNextFormat(format);
789
785
  send({ type: "FORMAT.SET", format: nextFormat, src: "format-trigger" });
790
786
  }
791
787
  });
@@ -794,12 +790,12 @@ function connect(state, send, normalize) {
794
790
  return normalize.select({
795
791
  ...parts.formatSelect.attrs,
796
792
  "aria-label": "change color format",
797
- dir: state.context.dir,
798
- defaultValue: state.context.format,
793
+ dir: prop("dir"),
794
+ defaultValue: prop("format"),
799
795
  disabled,
800
796
  onChange(event) {
801
- const format = assertFormat(event.currentTarget.value);
802
- send({ type: "FORMAT.SET", format, src: "format-select" });
797
+ const format2 = assertFormat(event.currentTarget.value);
798
+ send({ type: "FORMAT.SET", format: format2, src: "format-select" });
803
799
  }
804
800
  });
805
801
  }
@@ -820,594 +816,648 @@ var parse = (colorString) => {
820
816
  };
821
817
 
822
818
  // src/color-picker.machine.ts
823
- var { and } = core.guards;
824
- function machine(userContext) {
825
- const ctx = utils.compact(userContext);
826
- return core.createMachine(
827
- {
828
- id: "color-picker",
829
- initial: ctx.open ? "open" : "idle",
830
- context: {
831
- dir: "ltr",
832
- value: parse("#000000"),
833
- format: "rgba",
834
- disabled: false,
835
- closeOnSelect: false,
836
- openAutoFocus: true,
837
- ...ctx,
838
- activeId: null,
839
- activeChannel: null,
840
- activeOrientation: null,
841
- fieldsetDisabled: false,
842
- restoreFocus: true,
843
- positioning: {
844
- ...ctx.positioning,
845
- placement: "bottom"
846
- }
847
- },
848
- computed: {
849
- isRtl: (ctx2) => ctx2.dir === "rtl",
850
- isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled,
851
- isInteractive: (ctx2) => !(ctx2.isDisabled || ctx2.readOnly),
852
- valueAsString: (ctx2) => ctx2.value.toString(ctx2.format),
853
- areaValue: (ctx2) => {
854
- const format = ctx2.format.startsWith("hsl") ? "hsla" : "hsba";
855
- return ctx2.value.toFormat(format);
856
- }
857
- },
858
- activities: ["trackFormControl"],
859
- watch: {
860
- value: ["syncInputElements"],
861
- format: ["syncFormatSelectElement"],
862
- open: ["toggleVisibility"]
863
- },
864
- on: {
865
- "VALUE.SET": {
866
- actions: ["setValue"]
867
- },
868
- "FORMAT.SET": {
869
- actions: ["setFormat"]
870
- },
871
- "CHANNEL_INPUT.CHANGE": {
872
- actions: ["setChannelColorFromInput"]
819
+ var { and } = core.createGuards();
820
+ var machine = core.createMachine({
821
+ props({ props: props2 }) {
822
+ return {
823
+ dir: "ltr",
824
+ defaultValue: parse("#000000"),
825
+ defaultFormat: "rgba",
826
+ openAutoFocus: true,
827
+ ...props2,
828
+ positioning: {
829
+ placement: "bottom",
830
+ ...props2.positioning
831
+ }
832
+ };
833
+ },
834
+ initialState({ prop }) {
835
+ const open = prop("open") || prop("defaultOpen");
836
+ return open ? "open" : "idle";
837
+ },
838
+ context({ prop, bindable, getContext, scope }) {
839
+ return {
840
+ value: bindable(() => ({
841
+ defaultValue: prop("defaultValue"),
842
+ value: prop("value"),
843
+ isEqual(a, b) {
844
+ return a.toString("css") === b?.toString("css");
873
845
  },
874
- "EYEDROPPER.CLICK": {
875
- actions: ["openEyeDropper"]
846
+ hash(a) {
847
+ return a.toString("css");
876
848
  },
877
- "SWATCH_TRIGGER.CLICK": {
878
- actions: ["setValue"]
849
+ onChange(value) {
850
+ const ctx = getContext();
851
+ const valueAsString = value.toString(ctx.get("format"));
852
+ prop("onValueChange")?.({ value, valueAsString });
853
+ domQuery.dispatchInputValueEvent(getHiddenInputEl(scope), { value: valueAsString });
879
854
  }
880
- },
881
- states: {
882
- idle: {
883
- tags: ["closed"],
884
- on: {
885
- "CONTROLLED.OPEN": {
886
- target: "open",
887
- actions: ["setInitialFocus"]
888
- },
889
- OPEN: [
890
- {
891
- guard: "isOpenControlled",
892
- actions: ["invokeOnOpen"]
893
- },
894
- {
895
- target: "open",
896
- actions: ["invokeOnOpen", "setInitialFocus"]
897
- }
898
- ],
899
- "TRIGGER.CLICK": [
900
- {
901
- guard: "isOpenControlled",
902
- actions: ["invokeOnOpen"]
903
- },
904
- {
905
- target: "open",
906
- actions: ["invokeOnOpen", "setInitialFocus"]
907
- }
908
- ],
909
- "CHANNEL_INPUT.FOCUS": {
910
- target: "focused",
911
- actions: ["setActiveChannel"]
912
- }
913
- }
914
- },
915
- focused: {
916
- tags: ["closed", "focused"],
917
- on: {
918
- "CONTROLLED.OPEN": {
919
- target: "open",
920
- actions: ["setInitialFocus"]
921
- },
922
- OPEN: [
923
- {
924
- guard: "isOpenControlled",
925
- actions: ["invokeOnOpen"]
926
- },
927
- {
928
- target: "open",
929
- actions: ["invokeOnOpen", "setInitialFocus"]
930
- }
931
- ],
932
- "TRIGGER.CLICK": [
933
- {
934
- guard: "isOpenControlled",
935
- actions: ["invokeOnOpen"]
936
- },
937
- {
938
- target: "open",
939
- actions: ["invokeOnOpen", "setInitialFocus"]
940
- }
941
- ],
942
- "CHANNEL_INPUT.FOCUS": {
943
- actions: ["setActiveChannel"]
944
- },
945
- "CHANNEL_INPUT.BLUR": {
946
- target: "idle",
947
- actions: ["setChannelColorFromInput"]
948
- },
949
- "TRIGGER.BLUR": {
950
- target: "idle"
951
- }
952
- }
855
+ })),
856
+ format: bindable(() => ({
857
+ defaultValue: prop("defaultFormat"),
858
+ value: prop("format"),
859
+ onChange(format) {
860
+ prop("onFormatChange")?.({ format });
861
+ }
862
+ })),
863
+ activeId: bindable(() => ({ defaultValue: null })),
864
+ activeChannel: bindable(() => ({ defaultValue: null })),
865
+ activeOrientation: bindable(() => ({ defaultValue: null })),
866
+ fieldsetDisabled: bindable(() => ({ defaultValue: false })),
867
+ restoreFocus: bindable(() => ({ defaultValue: true })),
868
+ currentPlacement: bindable(() => ({
869
+ defaultValue: void 0
870
+ }))
871
+ };
872
+ },
873
+ computed: {
874
+ rtl: ({ prop }) => prop("dir") === "rtl",
875
+ disabled: ({ prop, context }) => !!prop("disabled") || context.get("fieldsetDisabled"),
876
+ interactive: ({ prop }) => !(prop("disabled") || prop("readOnly")),
877
+ valueAsString: ({ context }) => context.get("value").toString(context.get("format")),
878
+ areaValue: ({ context }) => {
879
+ const format = context.get("format").startsWith("hsl") ? "hsla" : "hsba";
880
+ return context.get("value").toFormat(format);
881
+ }
882
+ },
883
+ effects: ["trackFormControl"],
884
+ watch({ prop, context, action, track }) {
885
+ track([() => context.hash("value")], () => {
886
+ action(["syncInputElements"]);
887
+ });
888
+ track([() => context.get("format")], () => {
889
+ action(["syncFormatSelectElement"]);
890
+ });
891
+ track([() => prop("open")], () => {
892
+ action(["toggleVisibility"]);
893
+ });
894
+ },
895
+ on: {
896
+ "VALUE.SET": {
897
+ actions: ["setValue"]
898
+ },
899
+ "FORMAT.SET": {
900
+ actions: ["setFormat"]
901
+ },
902
+ "CHANNEL_INPUT.CHANGE": {
903
+ actions: ["setChannelColorFromInput"]
904
+ },
905
+ "EYEDROPPER.CLICK": {
906
+ actions: ["openEyeDropper"]
907
+ },
908
+ "SWATCH_TRIGGER.CLICK": {
909
+ actions: ["setValue"]
910
+ }
911
+ },
912
+ states: {
913
+ idle: {
914
+ tags: ["closed"],
915
+ on: {
916
+ "CONTROLLED.OPEN": {
917
+ target: "open",
918
+ actions: ["setInitialFocus"]
953
919
  },
954
- open: {
955
- tags: ["open"],
956
- activities: ["trackPositioning", "trackDismissableElement"],
957
- on: {
958
- "CONTROLLED.CLOSE": [
959
- {
960
- guard: "shouldRestoreFocus",
961
- target: "focused",
962
- actions: ["setReturnFocus"]
963
- },
964
- {
965
- target: "idle"
966
- }
967
- ],
968
- "TRIGGER.CLICK": [
969
- {
970
- guard: "isOpenControlled",
971
- actions: ["invokeOnClose"]
972
- },
973
- {
974
- target: "idle",
975
- actions: ["invokeOnClose"]
976
- }
977
- ],
978
- "AREA.POINTER_DOWN": {
979
- target: "open:dragging",
980
- actions: ["setActiveChannel", "setAreaColorFromPoint", "focusAreaThumb"]
981
- },
982
- "AREA.FOCUS": {
983
- actions: ["setActiveChannel"]
984
- },
985
- "CHANNEL_SLIDER.POINTER_DOWN": {
986
- target: "open:dragging",
987
- actions: ["setActiveChannel", "setChannelColorFromPoint", "focusChannelThumb"]
988
- },
989
- "CHANNEL_SLIDER.FOCUS": {
990
- actions: ["setActiveChannel"]
991
- },
992
- "AREA.ARROW_LEFT": {
993
- actions: ["decrementAreaXChannel"]
994
- },
995
- "AREA.ARROW_RIGHT": {
996
- actions: ["incrementAreaXChannel"]
997
- },
998
- "AREA.ARROW_UP": {
999
- actions: ["incrementAreaYChannel"]
1000
- },
1001
- "AREA.ARROW_DOWN": {
1002
- actions: ["decrementAreaYChannel"]
1003
- },
1004
- "AREA.PAGE_UP": {
1005
- actions: ["incrementAreaXChannel"]
1006
- },
1007
- "AREA.PAGE_DOWN": {
1008
- actions: ["decrementAreaXChannel"]
1009
- },
1010
- "CHANNEL_SLIDER.ARROW_LEFT": {
1011
- actions: ["decrementChannel"]
1012
- },
1013
- "CHANNEL_SLIDER.ARROW_RIGHT": {
1014
- actions: ["incrementChannel"]
1015
- },
1016
- "CHANNEL_SLIDER.ARROW_UP": {
1017
- actions: ["incrementChannel"]
1018
- },
1019
- "CHANNEL_SLIDER.ARROW_DOWN": {
1020
- actions: ["decrementChannel"]
1021
- },
1022
- "CHANNEL_SLIDER.PAGE_UP": {
1023
- actions: ["incrementChannel"]
1024
- },
1025
- "CHANNEL_SLIDER.PAGE_DOWN": {
1026
- actions: ["decrementChannel"]
1027
- },
1028
- "CHANNEL_SLIDER.HOME": {
1029
- actions: ["setChannelToMin"]
1030
- },
1031
- "CHANNEL_SLIDER.END": {
1032
- actions: ["setChannelToMax"]
1033
- },
1034
- "CHANNEL_INPUT.BLUR": {
1035
- actions: ["setChannelColorFromInput"]
1036
- },
1037
- INTERACT_OUTSIDE: [
1038
- {
1039
- guard: "isOpenControlled",
1040
- actions: ["invokeOnClose"]
1041
- },
1042
- {
1043
- guard: "shouldRestoreFocus",
1044
- target: "focused",
1045
- actions: ["invokeOnClose", "setReturnFocus"]
1046
- },
1047
- {
1048
- target: "idle",
1049
- actions: ["invokeOnClose"]
1050
- }
1051
- ],
1052
- CLOSE: [
1053
- {
1054
- guard: "isOpenControlled",
1055
- actions: ["invokeOnClose"]
1056
- },
1057
- {
1058
- target: "idle",
1059
- actions: ["invokeOnClose"]
1060
- }
1061
- ],
1062
- "SWATCH_TRIGGER.CLICK": [
1063
- {
1064
- guard: and("isOpenControlled", "closeOnSelect"),
1065
- actions: ["setValue", "invokeOnClose"]
1066
- },
1067
- {
1068
- guard: "closeOnSelect",
1069
- target: "focused",
1070
- actions: ["setValue", "invokeOnClose", "setReturnFocus"]
1071
- },
1072
- {
1073
- actions: ["setValue"]
1074
- }
1075
- ]
920
+ OPEN: [
921
+ {
922
+ guard: "isOpenControlled",
923
+ actions: ["invokeOnOpen"]
924
+ },
925
+ {
926
+ target: "open",
927
+ actions: ["invokeOnOpen", "setInitialFocus"]
1076
928
  }
1077
- },
1078
- "open:dragging": {
1079
- tags: ["open"],
1080
- exit: ["clearActiveChannel"],
1081
- activities: ["trackPointerMove", "disableTextSelection", "trackPositioning", "trackDismissableElement"],
1082
- on: {
1083
- "CONTROLLED.CLOSE": [
1084
- {
1085
- guard: "shouldRestoreFocus",
1086
- target: "focused",
1087
- actions: ["setReturnFocus"]
1088
- },
1089
- {
1090
- target: "idle"
1091
- }
1092
- ],
1093
- "AREA.POINTER_MOVE": {
1094
- actions: ["setAreaColorFromPoint", "focusAreaThumb"]
1095
- },
1096
- "AREA.POINTER_UP": {
1097
- target: "open",
1098
- actions: ["invokeOnChangeEnd"]
1099
- },
1100
- "CHANNEL_SLIDER.POINTER_MOVE": {
1101
- actions: ["setChannelColorFromPoint", "focusChannelThumb"]
1102
- },
1103
- "CHANNEL_SLIDER.POINTER_UP": {
1104
- target: "open",
1105
- actions: ["invokeOnChangeEnd"]
1106
- },
1107
- INTERACT_OUTSIDE: [
1108
- {
1109
- guard: "isOpenControlled",
1110
- actions: ["invokeOnClose"]
1111
- },
1112
- {
1113
- guard: "shouldRestoreFocus",
1114
- target: "focused",
1115
- actions: ["invokeOnClose", "setReturnFocus"]
1116
- },
1117
- {
1118
- target: "idle",
1119
- actions: ["invokeOnClose"]
1120
- }
1121
- ],
1122
- CLOSE: [
1123
- {
1124
- guard: "isOpenControlled",
1125
- actions: ["invokeOnClose"]
1126
- },
1127
- {
1128
- target: "idle",
1129
- actions: ["invokeOnClose"]
1130
- }
1131
- ]
929
+ ],
930
+ "TRIGGER.CLICK": [
931
+ {
932
+ guard: "isOpenControlled",
933
+ actions: ["invokeOnOpen"]
934
+ },
935
+ {
936
+ target: "open",
937
+ actions: ["invokeOnOpen", "setInitialFocus"]
1132
938
  }
939
+ ],
940
+ "CHANNEL_INPUT.FOCUS": {
941
+ target: "focused",
942
+ actions: ["setActiveChannel"]
1133
943
  }
1134
944
  }
1135
945
  },
1136
- {
1137
- guards: {
1138
- closeOnSelect: (ctx2) => !!ctx2.closeOnSelect,
1139
- isOpenControlled: (ctx2) => !!ctx2["open.controlled"],
1140
- shouldRestoreFocus: (ctx2) => !!ctx2.restoreFocus
1141
- },
1142
- activities: {
1143
- trackPositioning(ctx2) {
1144
- ctx2.currentPlacement || (ctx2.currentPlacement = ctx2.positioning.placement);
1145
- const anchorEl = dom.getTriggerEl(ctx2);
1146
- const getPositionerEl = () => dom.getPositionerEl(ctx2);
1147
- return popper.getPlacement(anchorEl, getPositionerEl, {
1148
- ...ctx2.positioning,
1149
- defer: true,
1150
- onComplete(data) {
1151
- ctx2.currentPlacement = data.placement;
1152
- }
1153
- });
1154
- },
1155
- trackDismissableElement(ctx2, _evt, { send }) {
1156
- const getContentEl = () => dom.getContentEl(ctx2);
1157
- return dismissable.trackDismissableElement(getContentEl, {
1158
- exclude: dom.getTriggerEl(ctx2),
1159
- defer: true,
1160
- onInteractOutside(event) {
1161
- ctx2.onInteractOutside?.(event);
1162
- if (event.defaultPrevented) return;
1163
- ctx2.restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
1164
- },
1165
- onPointerDownOutside: ctx2.onPointerDownOutside,
1166
- onFocusOutside: ctx2.onFocusOutside,
1167
- onDismiss() {
1168
- send({ type: "INTERACT_OUTSIDE" });
1169
- }
1170
- });
946
+ focused: {
947
+ tags: ["closed", "focused"],
948
+ on: {
949
+ "CONTROLLED.OPEN": {
950
+ target: "open",
951
+ actions: ["setInitialFocus"]
1171
952
  },
1172
- trackFormControl(ctx2, _evt, { send, initialContext }) {
1173
- const inputEl = dom.getHiddenInputEl(ctx2);
1174
- return domQuery.trackFormControl(inputEl, {
1175
- onFieldsetDisabledChange(disabled) {
1176
- ctx2.fieldsetDisabled = disabled;
1177
- },
1178
- onFormReset() {
1179
- send({ type: "VALUE.SET", value: initialContext.value, src: "form.reset" });
1180
- }
1181
- });
953
+ OPEN: [
954
+ {
955
+ guard: "isOpenControlled",
956
+ actions: ["invokeOnOpen"]
957
+ },
958
+ {
959
+ target: "open",
960
+ actions: ["invokeOnOpen", "setInitialFocus"]
961
+ }
962
+ ],
963
+ "TRIGGER.CLICK": [
964
+ {
965
+ guard: "isOpenControlled",
966
+ actions: ["invokeOnOpen"]
967
+ },
968
+ {
969
+ target: "open",
970
+ actions: ["invokeOnOpen", "setInitialFocus"]
971
+ }
972
+ ],
973
+ "CHANNEL_INPUT.FOCUS": {
974
+ actions: ["setActiveChannel"]
1182
975
  },
1183
- trackPointerMove(ctx2, evt, { send }) {
1184
- return domQuery.trackPointerMove(dom.getDoc(ctx2), {
1185
- onPointerMove({ point }) {
1186
- const type = ctx2.activeId === "area" ? "AREA.POINTER_MOVE" : "CHANNEL_SLIDER.POINTER_MOVE";
1187
- send({ type, point, format: evt.format });
1188
- },
1189
- onPointerUp() {
1190
- const type = ctx2.activeId === "area" ? "AREA.POINTER_UP" : "CHANNEL_SLIDER.POINTER_UP";
1191
- send({ type });
1192
- }
1193
- });
976
+ "CHANNEL_INPUT.BLUR": {
977
+ target: "idle",
978
+ actions: ["setChannelColorFromInput"]
1194
979
  },
1195
- disableTextSelection(ctx2) {
1196
- return domQuery.disableTextSelection({ doc: dom.getDoc(ctx2), target: dom.getContentEl(ctx2) });
980
+ "TRIGGER.BLUR": {
981
+ target: "idle"
1197
982
  }
1198
- },
1199
- actions: {
1200
- openEyeDropper(ctx2) {
1201
- const isSupported = "EyeDropper" in dom.getWin(ctx2);
1202
- if (!isSupported) return;
1203
- const win = dom.getWin(ctx2);
1204
- const picker = new win.EyeDropper();
1205
- picker.open().then(({ sRGBHex }) => {
1206
- const format = ctx2.value.getFormat();
1207
- const color = colorUtils.parseColor(sRGBHex).toFormat(format);
1208
- set.value(ctx2, color);
1209
- ctx2.onValueChangeEnd?.({ value: ctx2.value, valueAsString: ctx2.valueAsString });
1210
- }).catch(() => void 0);
1211
- },
1212
- setActiveChannel(ctx2, evt) {
1213
- ctx2.activeId = evt.id;
1214
- if (evt.channel) ctx2.activeChannel = evt.channel;
1215
- if (evt.orientation) ctx2.activeOrientation = evt.orientation;
1216
- },
1217
- clearActiveChannel(ctx2) {
1218
- ctx2.activeChannel = null;
1219
- ctx2.activeId = null;
1220
- ctx2.activeOrientation = null;
983
+ }
984
+ },
985
+ open: {
986
+ tags: ["open"],
987
+ effects: ["trackPositioning", "trackDismissableElement"],
988
+ on: {
989
+ "CONTROLLED.CLOSE": [
990
+ {
991
+ guard: "shouldRestoreFocus",
992
+ target: "focused",
993
+ actions: ["setReturnFocus"]
994
+ },
995
+ {
996
+ target: "idle"
997
+ }
998
+ ],
999
+ "TRIGGER.CLICK": [
1000
+ {
1001
+ guard: "isOpenControlled",
1002
+ actions: ["invokeOnClose"]
1003
+ },
1004
+ {
1005
+ target: "idle",
1006
+ actions: ["invokeOnClose"]
1007
+ }
1008
+ ],
1009
+ "AREA.POINTER_DOWN": {
1010
+ target: "open:dragging",
1011
+ actions: ["setActiveChannel", "setAreaColorFromPoint", "focusAreaThumb"]
1221
1012
  },
1222
- setAreaColorFromPoint(ctx2, evt) {
1223
- const normalizedValue = evt.format ? ctx2.value.toFormat(evt.format) : ctx2.areaValue;
1224
- const { xChannel, yChannel } = evt.channel || ctx2.activeChannel;
1225
- const percent = dom.getAreaValueFromPoint(ctx2, evt.point);
1226
- if (!percent) return;
1227
- const xValue = normalizedValue.getChannelPercentValue(xChannel, percent.x);
1228
- const yValue = normalizedValue.getChannelPercentValue(yChannel, 1 - percent.y);
1229
- const color = normalizedValue.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue);
1230
- set.value(ctx2, color);
1013
+ "AREA.FOCUS": {
1014
+ actions: ["setActiveChannel"]
1231
1015
  },
1232
- setChannelColorFromPoint(ctx2, evt) {
1233
- const channel = evt.channel || ctx2.activeId;
1234
- const normalizedValue = evt.format ? ctx2.value.toFormat(evt.format) : ctx2.areaValue;
1235
- const percent = dom.getChannelSliderValueFromPoint(ctx2, evt.point, channel);
1236
- if (!percent) return;
1237
- const orientation = ctx2.activeOrientation || "horizontal";
1238
- const channelPercent = orientation === "horizontal" ? percent.x : percent.y;
1239
- const value = normalizedValue.getChannelPercentValue(channel, channelPercent);
1240
- const color = normalizedValue.withChannelValue(channel, value);
1241
- set.value(ctx2, color);
1016
+ "CHANNEL_SLIDER.POINTER_DOWN": {
1017
+ target: "open:dragging",
1018
+ actions: ["setActiveChannel", "setChannelColorFromPoint", "focusChannelThumb"]
1242
1019
  },
1243
- setValue(ctx2, evt) {
1244
- set.value(ctx2, evt.value);
1020
+ "CHANNEL_SLIDER.FOCUS": {
1021
+ actions: ["setActiveChannel"]
1245
1022
  },
1246
- setFormat(ctx2, evt) {
1247
- set.format(ctx2, evt.format);
1023
+ "AREA.ARROW_LEFT": {
1024
+ actions: ["decrementAreaXChannel"]
1248
1025
  },
1249
- syncInputElements(ctx2) {
1250
- sync.inputs(ctx2);
1026
+ "AREA.ARROW_RIGHT": {
1027
+ actions: ["incrementAreaXChannel"]
1251
1028
  },
1252
- invokeOnChangeEnd(ctx2) {
1253
- invoke.changeEnd(ctx2);
1029
+ "AREA.ARROW_UP": {
1030
+ actions: ["incrementAreaYChannel"]
1254
1031
  },
1255
- setChannelColorFromInput(ctx2, evt) {
1256
- const { channel, isTextField, value } = evt;
1257
- const currentAlpha = ctx2.value.getChannelValue("alpha");
1258
- let color;
1259
- if (channel === "alpha") {
1260
- let valueAsNumber = parseFloat(value);
1261
- valueAsNumber = Number.isNaN(valueAsNumber) ? currentAlpha : valueAsNumber;
1262
- color = ctx2.value.withChannelValue("alpha", valueAsNumber);
1263
- } else if (isTextField) {
1264
- color = utils.tryCatch(
1265
- () => parse(value).withChannelValue("alpha", currentAlpha),
1266
- () => ctx2.value
1267
- );
1268
- } else {
1269
- const current = ctx2.value.toFormat(ctx2.format);
1270
- const valueAsNumber = Number.isNaN(value) ? current.getChannelValue(channel) : value;
1271
- color = current.withChannelValue(channel, valueAsNumber);
1272
- }
1273
- sync.inputs(ctx2, color);
1274
- set.value(ctx2, color);
1032
+ "AREA.ARROW_DOWN": {
1033
+ actions: ["decrementAreaYChannel"]
1275
1034
  },
1276
- incrementChannel(ctx2, evt) {
1277
- const color = ctx2.value.incrementChannel(evt.channel, evt.step);
1278
- set.value(ctx2, color);
1035
+ "AREA.PAGE_UP": {
1036
+ actions: ["incrementAreaXChannel"]
1279
1037
  },
1280
- decrementChannel(ctx2, evt) {
1281
- const color = ctx2.value.decrementChannel(evt.channel, evt.step);
1282
- set.value(ctx2, color);
1038
+ "AREA.PAGE_DOWN": {
1039
+ actions: ["decrementAreaXChannel"]
1283
1040
  },
1284
- incrementAreaXChannel(ctx2, evt) {
1285
- const { xChannel } = evt.channel;
1286
- const color = ctx2.areaValue.incrementChannel(xChannel, evt.step);
1287
- set.value(ctx2, color);
1041
+ "CHANNEL_SLIDER.ARROW_LEFT": {
1042
+ actions: ["decrementChannel"]
1288
1043
  },
1289
- decrementAreaXChannel(ctx2, evt) {
1290
- const { xChannel } = evt.channel;
1291
- const color = ctx2.areaValue.decrementChannel(xChannel, evt.step);
1292
- set.value(ctx2, color);
1044
+ "CHANNEL_SLIDER.ARROW_RIGHT": {
1045
+ actions: ["incrementChannel"]
1293
1046
  },
1294
- incrementAreaYChannel(ctx2, evt) {
1295
- const { yChannel } = evt.channel;
1296
- const color = ctx2.areaValue.incrementChannel(yChannel, evt.step);
1297
- set.value(ctx2, color);
1047
+ "CHANNEL_SLIDER.ARROW_UP": {
1048
+ actions: ["incrementChannel"]
1298
1049
  },
1299
- decrementAreaYChannel(ctx2, evt) {
1300
- const { yChannel } = evt.channel;
1301
- const color = ctx2.areaValue.decrementChannel(yChannel, evt.step);
1302
- set.value(ctx2, color);
1050
+ "CHANNEL_SLIDER.ARROW_DOWN": {
1051
+ actions: ["decrementChannel"]
1303
1052
  },
1304
- setChannelToMax(ctx2, evt) {
1305
- const range = ctx2.value.getChannelRange(evt.channel);
1306
- const color = ctx2.value.withChannelValue(evt.channel, range.maxValue);
1307
- set.value(ctx2, color);
1053
+ "CHANNEL_SLIDER.PAGE_UP": {
1054
+ actions: ["incrementChannel"]
1308
1055
  },
1309
- setChannelToMin(ctx2, evt) {
1310
- const range = ctx2.value.getChannelRange(evt.channel);
1311
- const color = ctx2.value.withChannelValue(evt.channel, range.minValue);
1312
- set.value(ctx2, color);
1056
+ "CHANNEL_SLIDER.PAGE_DOWN": {
1057
+ actions: ["decrementChannel"]
1313
1058
  },
1314
- focusAreaThumb(ctx2) {
1315
- domQuery.raf(() => {
1316
- dom.getAreaThumbEl(ctx2)?.focus({ preventScroll: true });
1317
- });
1059
+ "CHANNEL_SLIDER.HOME": {
1060
+ actions: ["setChannelToMin"]
1318
1061
  },
1319
- focusChannelThumb(ctx2, evt) {
1320
- domQuery.raf(() => {
1321
- dom.getChannelSliderThumbEl(ctx2, evt.channel)?.focus({ preventScroll: true });
1322
- });
1062
+ "CHANNEL_SLIDER.END": {
1063
+ actions: ["setChannelToMax"]
1323
1064
  },
1324
- setInitialFocus(ctx2) {
1325
- if (!ctx2.openAutoFocus) return;
1326
- domQuery.raf(() => {
1327
- const element = domQuery.getInitialFocus({
1328
- root: dom.getContentEl(ctx2),
1329
- getInitialEl: ctx2.initialFocusEl
1330
- });
1331
- element?.focus({ preventScroll: true });
1332
- });
1065
+ "CHANNEL_INPUT.BLUR": {
1066
+ actions: ["setChannelColorFromInput"]
1333
1067
  },
1334
- setReturnFocus(ctx2) {
1335
- domQuery.raf(() => {
1336
- dom.getTriggerEl(ctx2)?.focus({ preventScroll: true });
1337
- });
1068
+ INTERACT_OUTSIDE: [
1069
+ {
1070
+ guard: "isOpenControlled",
1071
+ actions: ["invokeOnClose"]
1072
+ },
1073
+ {
1074
+ guard: "shouldRestoreFocus",
1075
+ target: "focused",
1076
+ actions: ["invokeOnClose", "setReturnFocus"]
1077
+ },
1078
+ {
1079
+ target: "idle",
1080
+ actions: ["invokeOnClose"]
1081
+ }
1082
+ ],
1083
+ CLOSE: [
1084
+ {
1085
+ guard: "isOpenControlled",
1086
+ actions: ["invokeOnClose"]
1087
+ },
1088
+ {
1089
+ target: "idle",
1090
+ actions: ["invokeOnClose"]
1091
+ }
1092
+ ],
1093
+ "SWATCH_TRIGGER.CLICK": [
1094
+ {
1095
+ guard: and("isOpenControlled", "closeOnSelect"),
1096
+ actions: ["setValue", "invokeOnClose"]
1097
+ },
1098
+ {
1099
+ guard: "closeOnSelect",
1100
+ target: "focused",
1101
+ actions: ["setValue", "invokeOnClose", "setReturnFocus"]
1102
+ },
1103
+ {
1104
+ actions: ["setValue"]
1105
+ }
1106
+ ]
1107
+ }
1108
+ },
1109
+ "open:dragging": {
1110
+ tags: ["open"],
1111
+ exit: ["clearActiveChannel"],
1112
+ effects: ["trackPointerMove", "disableTextSelection", "trackPositioning", "trackDismissableElement"],
1113
+ on: {
1114
+ "CONTROLLED.CLOSE": [
1115
+ {
1116
+ guard: "shouldRestoreFocus",
1117
+ target: "focused",
1118
+ actions: ["setReturnFocus"]
1119
+ },
1120
+ {
1121
+ target: "idle"
1122
+ }
1123
+ ],
1124
+ "AREA.POINTER_MOVE": {
1125
+ actions: ["setAreaColorFromPoint", "focusAreaThumb"]
1338
1126
  },
1339
- syncFormatSelectElement(ctx2) {
1340
- sync.formatSelect(ctx2);
1127
+ "AREA.POINTER_UP": {
1128
+ target: "open",
1129
+ actions: ["invokeOnChangeEnd"]
1341
1130
  },
1342
- invokeOnOpen(ctx2) {
1343
- ctx2.onOpenChange?.({ open: true });
1131
+ "CHANNEL_SLIDER.POINTER_MOVE": {
1132
+ actions: ["setChannelColorFromPoint", "focusChannelThumb"]
1344
1133
  },
1345
- invokeOnClose(ctx2) {
1346
- ctx2.onOpenChange?.({ open: false });
1134
+ "CHANNEL_SLIDER.POINTER_UP": {
1135
+ target: "open",
1136
+ actions: ["invokeOnChangeEnd"]
1347
1137
  },
1348
- toggleVisibility(ctx2, evt, { send }) {
1349
- send({ type: ctx2.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: evt });
1138
+ INTERACT_OUTSIDE: [
1139
+ {
1140
+ guard: "isOpenControlled",
1141
+ actions: ["invokeOnClose"]
1142
+ },
1143
+ {
1144
+ guard: "shouldRestoreFocus",
1145
+ target: "focused",
1146
+ actions: ["invokeOnClose", "setReturnFocus"]
1147
+ },
1148
+ {
1149
+ target: "idle",
1150
+ actions: ["invokeOnClose"]
1151
+ }
1152
+ ],
1153
+ CLOSE: [
1154
+ {
1155
+ guard: "isOpenControlled",
1156
+ actions: ["invokeOnClose"]
1157
+ },
1158
+ {
1159
+ target: "idle",
1160
+ actions: ["invokeOnClose"]
1161
+ }
1162
+ ]
1163
+ }
1164
+ }
1165
+ },
1166
+ implementations: {
1167
+ guards: {
1168
+ closeOnSelect: ({ prop }) => !!prop("closeOnSelect"),
1169
+ isOpenControlled: ({ prop }) => prop("open") != null,
1170
+ shouldRestoreFocus: ({ context }) => !!context.get("restoreFocus")
1171
+ },
1172
+ effects: {
1173
+ trackPositioning({ context, prop, scope }) {
1174
+ if (!context.get("currentPlacement")) {
1175
+ context.set("currentPlacement", prop("positioning")?.placement);
1176
+ }
1177
+ const anchorEl = getTriggerEl(scope);
1178
+ const getPositionerEl2 = () => getPositionerEl(scope);
1179
+ return popper.getPlacement(anchorEl, getPositionerEl2, {
1180
+ ...prop("positioning"),
1181
+ defer: true,
1182
+ onComplete(data) {
1183
+ context.set("currentPlacement", data.placement);
1184
+ }
1185
+ });
1186
+ },
1187
+ trackDismissableElement({ context, scope, prop, send }) {
1188
+ const getContentEl2 = () => getContentEl(scope);
1189
+ return dismissable.trackDismissableElement(getContentEl2, {
1190
+ exclude: getTriggerEl(scope),
1191
+ defer: true,
1192
+ onInteractOutside(event) {
1193
+ prop("onInteractOutside")?.(event);
1194
+ if (event.defaultPrevented) return;
1195
+ context.set("restoreFocus", !(event.detail.focusable || event.detail.contextmenu));
1196
+ },
1197
+ onPointerDownOutside: prop("onPointerDownOutside"),
1198
+ onFocusOutside: prop("onFocusOutside"),
1199
+ onDismiss() {
1200
+ send({ type: "INTERACT_OUTSIDE" });
1201
+ }
1202
+ });
1203
+ },
1204
+ trackFormControl({ context, scope, send }) {
1205
+ const inputEl = getHiddenInputEl(scope);
1206
+ return domQuery.trackFormControl(inputEl, {
1207
+ onFieldsetDisabledChange(disabled) {
1208
+ context.set("fieldsetDisabled", disabled);
1209
+ },
1210
+ onFormReset() {
1211
+ send({ type: "VALUE.SET", value: context.initial("value"), src: "form.reset" });
1212
+ }
1213
+ });
1214
+ },
1215
+ trackPointerMove({ context, scope, event, send }) {
1216
+ return domQuery.trackPointerMove(scope.getDoc(), {
1217
+ onPointerMove({ point }) {
1218
+ const type = context.get("activeId") === "area" ? "AREA.POINTER_MOVE" : "CHANNEL_SLIDER.POINTER_MOVE";
1219
+ send({ type, point, format: event.format });
1220
+ },
1221
+ onPointerUp() {
1222
+ const type = context.get("activeId") === "area" ? "AREA.POINTER_UP" : "CHANNEL_SLIDER.POINTER_UP";
1223
+ send({ type });
1224
+ }
1225
+ });
1226
+ },
1227
+ disableTextSelection({ scope }) {
1228
+ return domQuery.disableTextSelection({
1229
+ doc: scope.getDoc(),
1230
+ target: getContentEl(scope)
1231
+ });
1232
+ }
1233
+ },
1234
+ actions: {
1235
+ openEyeDropper({ scope, context }) {
1236
+ const win = scope.getWin();
1237
+ const isSupported = "EyeDropper" in win;
1238
+ if (!isSupported) return;
1239
+ const picker = new win.EyeDropper();
1240
+ picker.open().then(({ sRGBHex }) => {
1241
+ const format = context.get("value").getFormat();
1242
+ const color = colorUtils.parseColor(sRGBHex).toFormat(format);
1243
+ context.set("value", color);
1244
+ }).catch(() => void 0);
1245
+ },
1246
+ setActiveChannel({ context, event }) {
1247
+ context.set("activeId", event.id);
1248
+ if (event.channel) context.set("activeChannel", event.channel);
1249
+ if (event.orientation) context.set("activeOrientation", event.orientation);
1250
+ },
1251
+ clearActiveChannel({ context }) {
1252
+ context.set("activeChannel", null);
1253
+ context.set("activeId", null);
1254
+ context.set("activeOrientation", null);
1255
+ },
1256
+ setAreaColorFromPoint({ context, event, computed, scope }) {
1257
+ const v = event.format ? context.get("value").toFormat(event.format) : computed("areaValue");
1258
+ const { xChannel, yChannel } = event.channel || context.get("activeChannel");
1259
+ const percent = getAreaValueFromPoint(scope, event.point);
1260
+ if (!percent) return;
1261
+ const xValue = v.getChannelPercentValue(xChannel, percent.x);
1262
+ const yValue = v.getChannelPercentValue(yChannel, 1 - percent.y);
1263
+ const color = v.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue);
1264
+ context.set("value", color);
1265
+ },
1266
+ setChannelColorFromPoint({ context, event, computed, scope }) {
1267
+ const channel = event.channel || context.get("activeId");
1268
+ const normalizedValue = event.format ? context.get("value").toFormat(event.format) : computed("areaValue");
1269
+ const percent = getChannelSliderValueFromPoint(scope, event.point, channel);
1270
+ if (!percent) return;
1271
+ const orientation = context.get("activeOrientation") || "horizontal";
1272
+ const channelPercent = orientation === "horizontal" ? percent.x : percent.y;
1273
+ const value = normalizedValue.getChannelPercentValue(channel, channelPercent);
1274
+ const color = normalizedValue.withChannelValue(channel, value);
1275
+ context.set("value", color);
1276
+ },
1277
+ setValue({ context, event }) {
1278
+ context.set("value", event.value);
1279
+ },
1280
+ setFormat({ context, event }) {
1281
+ context.set("format", event.format);
1282
+ },
1283
+ syncInputElements({ context, scope }) {
1284
+ syncInputs(scope, context.get("value"));
1285
+ },
1286
+ invokeOnChangeEnd({ context, prop, computed }) {
1287
+ prop("onValueChangeEnd")?.({
1288
+ value: context.get("value"),
1289
+ valueAsString: computed("valueAsString")
1290
+ });
1291
+ },
1292
+ setChannelColorFromInput({ context, event, scope }) {
1293
+ const { channel, isTextField, value } = event;
1294
+ const currentAlpha = context.get("value").getChannelValue("alpha");
1295
+ let color;
1296
+ if (channel === "alpha") {
1297
+ let valueAsNumber = parseFloat(value);
1298
+ valueAsNumber = Number.isNaN(valueAsNumber) ? currentAlpha : valueAsNumber;
1299
+ color = context.get("value").withChannelValue("alpha", valueAsNumber);
1300
+ } else if (isTextField) {
1301
+ color = utils.tryCatch(
1302
+ () => parse(value).withChannelValue("alpha", currentAlpha),
1303
+ () => context.get("value")
1304
+ );
1305
+ } else {
1306
+ const current = context.get("value").toFormat(context.get("format"));
1307
+ const valueAsNumber = Number.isNaN(value) ? current.getChannelValue(channel) : value;
1308
+ color = current.withChannelValue(channel, valueAsNumber);
1350
1309
  }
1310
+ syncInputs(scope, context.get("value"), color);
1311
+ context.set("value", color);
1312
+ },
1313
+ incrementChannel({ context, event }) {
1314
+ const color = context.get("value").incrementChannel(event.channel, event.step);
1315
+ context.set("value", color);
1316
+ },
1317
+ decrementChannel({ context, event }) {
1318
+ const color = context.get("value").decrementChannel(event.channel, event.step);
1319
+ context.set("value", color);
1320
+ },
1321
+ incrementAreaXChannel({ context, event, computed }) {
1322
+ const { xChannel } = event.channel;
1323
+ const color = computed("areaValue").incrementChannel(xChannel, event.step);
1324
+ context.set("value", color);
1325
+ },
1326
+ decrementAreaXChannel({ context, event, computed }) {
1327
+ const { xChannel } = event.channel;
1328
+ const color = computed("areaValue").decrementChannel(xChannel, event.step);
1329
+ context.set("value", color);
1330
+ },
1331
+ incrementAreaYChannel({ context, event, computed }) {
1332
+ const { yChannel } = event.channel;
1333
+ const color = computed("areaValue").incrementChannel(yChannel, event.step);
1334
+ context.set("value", color);
1335
+ },
1336
+ decrementAreaYChannel({ context, event, computed }) {
1337
+ const { yChannel } = event.channel;
1338
+ const color = computed("areaValue").decrementChannel(yChannel, event.step);
1339
+ context.set("value", color);
1340
+ },
1341
+ setChannelToMax({ context, event }) {
1342
+ const value = context.get("value");
1343
+ const range = value.getChannelRange(event.channel);
1344
+ const color = value.withChannelValue(event.channel, range.maxValue);
1345
+ context.set("value", color);
1346
+ },
1347
+ setChannelToMin({ context, event }) {
1348
+ const value = context.get("value");
1349
+ const range = value.getChannelRange(event.channel);
1350
+ const color = value.withChannelValue(event.channel, range.minValue);
1351
+ context.set("value", color);
1352
+ },
1353
+ focusAreaThumb({ scope }) {
1354
+ domQuery.raf(() => {
1355
+ getAreaThumbEl(scope)?.focus({ preventScroll: true });
1356
+ });
1357
+ },
1358
+ focusChannelThumb({ event, scope }) {
1359
+ domQuery.raf(() => {
1360
+ getChannelSliderThumbEl(scope, event.channel)?.focus({ preventScroll: true });
1361
+ });
1362
+ },
1363
+ setInitialFocus({ prop, scope }) {
1364
+ if (!prop("openAutoFocus")) return;
1365
+ domQuery.raf(() => {
1366
+ const element = domQuery.getInitialFocus({
1367
+ root: getContentEl(scope),
1368
+ getInitialEl: prop("initialFocusEl")
1369
+ });
1370
+ element?.focus({ preventScroll: true });
1371
+ });
1372
+ },
1373
+ setReturnFocus({ scope }) {
1374
+ domQuery.raf(() => {
1375
+ getTriggerEl(scope)?.focus({ preventScroll: true });
1376
+ });
1377
+ },
1378
+ syncFormatSelectElement({ context, scope }) {
1379
+ syncFormatSelect(scope, context.get("format"));
1351
1380
  },
1352
- compareFns: {
1353
- value: (a, b) => a.isEqual(b)
1381
+ invokeOnOpen({ prop }) {
1382
+ prop("onOpenChange")?.({ open: true });
1383
+ },
1384
+ invokeOnClose({ prop }) {
1385
+ prop("onOpenChange")?.({ open: false });
1386
+ },
1387
+ toggleVisibility({ prop, event, send }) {
1388
+ send({ type: prop("open") ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: event });
1354
1389
  }
1355
1390
  }
1356
- );
1357
- }
1358
- var sync = {
1359
- // sync channel inputs
1360
- inputs(ctx, color) {
1361
- const channelInputs = dom.getChannelInputEls(ctx);
1362
- domQuery.raf(() => {
1363
- channelInputs.forEach((inputEl) => {
1364
- const channel = inputEl.dataset.channel;
1365
- dom.setValue(inputEl, getChannelValue(color || ctx.value, channel));
1366
- });
1367
- });
1368
- },
1369
- // sync format select
1370
- formatSelect(ctx) {
1371
- const selectEl = dom.getFormatSelectEl(ctx);
1372
- domQuery.raf(() => {
1373
- dom.setValue(selectEl, ctx.format);
1374
- });
1375
1391
  }
1376
- };
1377
- var invoke = {
1378
- changeEnd(ctx) {
1379
- const value = ctx.value.toFormat(ctx.format);
1380
- ctx.onValueChangeEnd?.({
1381
- value,
1382
- valueAsString: ctx.valueAsString
1383
- });
1384
- },
1385
- change(ctx) {
1386
- const value = ctx.value.toFormat(ctx.format);
1387
- ctx.onValueChange?.({
1388
- value,
1389
- valueAsString: ctx.valueAsString
1392
+ });
1393
+ function syncInputs(scope, currentValue, nextValue) {
1394
+ const channelInputEls = getChannelInputEls(scope);
1395
+ domQuery.raf(() => {
1396
+ channelInputEls.forEach((inputEl) => {
1397
+ const channel = inputEl.dataset.channel;
1398
+ domQuery.setElementValue(inputEl, getChannelValue(nextValue || currentValue, channel));
1390
1399
  });
1391
- domQuery.dispatchInputValueEvent(dom.getHiddenInputEl(ctx), { value: ctx.valueAsString });
1392
- },
1393
- formatChange(ctx) {
1394
- ctx.onFormatChange?.({ format: ctx.format });
1395
- }
1396
- };
1397
- var set = {
1398
- value(ctx, color) {
1399
- if (!color || ctx.value.isEqual(color)) return;
1400
- ctx.value = color;
1401
- invoke.change(ctx);
1402
- },
1403
- format(ctx, format) {
1404
- if (ctx.format === format) return;
1405
- ctx.format = format;
1406
- invoke.formatChange(ctx);
1407
- }
1408
- };
1400
+ });
1401
+ }
1402
+ function syncFormatSelect(scope, format) {
1403
+ const selectEl = getFormatSelectEl(scope);
1404
+ if (!selectEl) return;
1405
+ domQuery.raf(() => domQuery.setElementValue(selectEl, format));
1406
+ }
1407
+ var props = types.createProps()([
1408
+ "closeOnSelect",
1409
+ "dir",
1410
+ "disabled",
1411
+ "format",
1412
+ "defaultFormat",
1413
+ "getRootNode",
1414
+ "id",
1415
+ "ids",
1416
+ "initialFocusEl",
1417
+ "name",
1418
+ "positioning",
1419
+ "onFocusOutside",
1420
+ "onFormatChange",
1421
+ "onInteractOutside",
1422
+ "onOpenChange",
1423
+ "onPointerDownOutside",
1424
+ "onValueChange",
1425
+ "onValueChangeEnd",
1426
+ "defaultOpen",
1427
+ "open",
1428
+ "positioning",
1429
+ "required",
1430
+ "readOnly",
1431
+ "value",
1432
+ "defaultValue",
1433
+ "invalid",
1434
+ "openAutoFocus"
1435
+ ]);
1436
+ var splitProps = utils.createSplitProps(props);
1437
+ var areaProps = types.createProps()(["xChannel", "yChannel"]);
1438
+ var splitAreaProps = utils.createSplitProps(areaProps);
1439
+ var channelProps = types.createProps()(["channel", "orientation"]);
1440
+ var splitChannelProps = utils.createSplitProps(channelProps);
1441
+ var swatchTriggerProps = types.createProps()(["value", "disabled"]);
1442
+ var splitSwatchTriggerProps = utils.createSplitProps(swatchTriggerProps);
1443
+ var swatchProps = types.createProps()(["value", "respectAlpha"]);
1444
+ var splitSwatchProps = utils.createSplitProps(swatchProps);
1445
+ var transparencyGridProps = types.createProps()(["size"]);
1446
+ var splitTransparencyGridProps = utils.createSplitProps(transparencyGridProps);
1409
1447
 
1410
1448
  exports.anatomy = anatomy;
1449
+ exports.areaProps = areaProps;
1450
+ exports.channelProps = channelProps;
1411
1451
  exports.connect = connect;
1412
1452
  exports.machine = machine;
1413
1453
  exports.parse = parse;
1454
+ exports.props = props;
1455
+ exports.splitAreaProps = splitAreaProps;
1456
+ exports.splitChannelProps = splitChannelProps;
1457
+ exports.splitProps = splitProps;
1458
+ exports.splitSwatchProps = splitSwatchProps;
1459
+ exports.splitSwatchTriggerProps = splitSwatchTriggerProps;
1460
+ exports.splitTransparencyGridProps = splitTransparencyGridProps;
1461
+ exports.swatchProps = swatchProps;
1462
+ exports.swatchTriggerProps = swatchTriggerProps;
1463
+ exports.transparencyGridProps = transparencyGridProps;