@zag-js/color-picker 0.56.1 → 0.58.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.
package/dist/index.mjs CHANGED
@@ -11,8 +11,10 @@ var anatomy = createAnatomy("color-picker", [
11
11
  "areaThumb",
12
12
  "areaBackground",
13
13
  "channelSlider",
14
+ "channelSliderLabel",
14
15
  "channelSliderTrack",
15
16
  "channelSliderThumb",
17
+ "channelSliderValueText",
16
18
  "channelInput",
17
19
  "transparencyGrid",
18
20
  "swatchGroup",
@@ -43,24 +45,25 @@ import { createScope, queryAll } from "@zag-js/dom-query";
43
45
  var dom = createScope({
44
46
  getRootId: (ctx) => ctx.ids?.root ?? `color-picker:${ctx.id}`,
45
47
  getLabelId: (ctx) => ctx.ids?.label ?? `color-picker:${ctx.id}:label`,
46
- getHiddenInputId: (ctx) => `color-picker:${ctx.id}:hidden-input`,
48
+ getHiddenInputId: (ctx) => ctx.ids?.hiddenInput ?? `color-picker:${ctx.id}:hidden-input`,
47
49
  getControlId: (ctx) => ctx.ids?.control ?? `color-picker:${ctx.id}:control`,
48
50
  getTriggerId: (ctx) => ctx.ids?.trigger ?? `color-picker:${ctx.id}:trigger`,
49
51
  getContentId: (ctx) => ctx.ids?.content ?? `color-picker:${ctx.id}:content`,
50
- getPositionerId: (ctx) => `color-picker:${ctx.id}:positioner`,
51
- getFormatSelectId: (ctx) => `color-picker:${ctx.id}:format-select`,
52
+ getPositionerId: (ctx) => ctx.ids?.positioner ?? `color-picker:${ctx.id}:positioner`,
53
+ getFormatSelectId: (ctx) => ctx.ids?.formatSelect ?? `color-picker:${ctx.id}:format-select`,
52
54
  getAreaId: (ctx) => ctx.ids?.area ?? `color-picker:${ctx.id}:area`,
53
55
  getAreaGradientId: (ctx) => ctx.ids?.areaGradient ?? `color-picker:${ctx.id}:area-gradient`,
54
56
  getAreaThumbId: (ctx) => ctx.ids?.areaThumb ?? `color-picker:${ctx.id}:area-thumb`,
55
- getChannelSliderId: (ctx, channel) => ctx.ids?.channelSliderTrack?.(channel) ?? `color-picker:${ctx.id}:slider-track:${channel}`,
57
+ getChannelSliderTrackId: (ctx, channel) => ctx.ids?.channelSliderTrack?.(channel) ?? `color-picker:${ctx.id}:slider-track:${channel}`,
56
58
  getChannelSliderThumbId: (ctx, channel) => ctx.ids?.channelSliderThumb?.(channel) ?? `color-picker:${ctx.id}:slider-thumb:${channel}`,
57
59
  getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
58
60
  getAreaThumbEl: (ctx) => dom.getById(ctx, dom.getAreaThumbId(ctx)),
59
61
  getChannelSliderThumbEl: (ctx, channel) => dom.getById(ctx, dom.getChannelSliderThumbId(ctx, channel)),
60
62
  getChannelInputEl: (ctx, channel) => {
63
+ const selector = `input[data-channel="${channel}"]`;
61
64
  return [
62
- ...queryAll(dom.getContentEl(ctx), `input[data-channel="${channel}"]`),
63
- ...queryAll(dom.getControlEl(ctx), `input[data-channel="${channel}"]`)
65
+ ...queryAll(dom.getContentEl(ctx), selector),
66
+ ...queryAll(dom.getControlEl(ctx), selector)
64
67
  ];
65
68
  },
66
69
  getFormatSelectEl: (ctx) => dom.getById(ctx, dom.getFormatSelectId(ctx)),
@@ -76,7 +79,7 @@ var dom = createScope({
76
79
  getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
77
80
  getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
78
81
  getChannelSliderTrackEl: (ctx, channel) => {
79
- return dom.getById(ctx, dom.getChannelSliderId(ctx, channel));
82
+ return dom.getById(ctx, dom.getChannelSliderTrackId(ctx, channel));
80
83
  },
81
84
  getChannelSliderValueFromPoint(ctx, point, channel) {
82
85
  const trackEl = dom.getChannelSliderTrackEl(ctx, channel);
@@ -256,6 +259,9 @@ function connect(state, send, normalize) {
256
259
  getChannelValue(channel) {
257
260
  return getChannelValue(value, channel);
258
261
  },
262
+ getChannelValueText(channel, locale) {
263
+ return value.formatChannelValue(channel, locale);
264
+ },
259
265
  setChannelValue(channel, channelValue) {
260
266
  const color = value.withChannelValue(channel, channelValue);
261
267
  send({ type: "VALUE.SET", value: color, src: "set-channel" });
@@ -489,7 +495,7 @@ function connect(state, send, normalize) {
489
495
  });
490
496
  },
491
497
  getChannelSliderProps(props) {
492
- const { orientation = "horizontal", channel } = props;
498
+ const { orientation = "horizontal", channel, format } = props;
493
499
  return normalize.element({
494
500
  ...parts.channelSlider.attrs,
495
501
  "data-channel": channel,
@@ -500,7 +506,7 @@ function connect(state, send, normalize) {
500
506
  if (!isLeftClick(event)) return;
501
507
  if (isModifierKey(event)) return;
502
508
  const point = getEventPoint(event);
503
- send({ type: "CHANNEL_SLIDER.POINTER_DOWN", channel, point, id: channel, orientation });
509
+ send({ type: "CHANNEL_SLIDER.POINTER_DOWN", channel, format, point, id: channel, orientation });
504
510
  event.preventDefault();
505
511
  },
506
512
  style: {
@@ -510,10 +516,11 @@ function connect(state, send, normalize) {
510
516
  });
511
517
  },
512
518
  getChannelSliderTrackProps(props) {
513
- const { orientation = "horizontal", channel } = props;
519
+ const { orientation = "horizontal", channel, format } = props;
520
+ const normalizedValue = format ? value.toFormat(format) : areaValue;
514
521
  return normalize.element({
515
522
  ...parts.channelSliderTrack.attrs,
516
- id: dom.getChannelSliderId(state.context, channel),
523
+ id: dom.getChannelSliderTrackId(state.context, channel),
517
524
  role: "group",
518
525
  "data-channel": channel,
519
526
  "data-orientation": orientation,
@@ -524,16 +531,40 @@ function connect(state, send, normalize) {
524
531
  orientation,
525
532
  channel,
526
533
  dir: state.context.dir,
527
- value: areaValue
534
+ value: normalizedValue
528
535
  })
529
536
  }
530
537
  });
531
538
  },
539
+ getChannelSliderLabelProps(props) {
540
+ const { channel } = props;
541
+ return normalize.element({
542
+ ...parts.channelSliderLabel.attrs,
543
+ "data-channel": channel,
544
+ onClick(event) {
545
+ if (!interactive) return;
546
+ event.preventDefault();
547
+ const thumbId = dom.getChannelSliderThumbId(state.context, channel);
548
+ dom.getById(state.context, thumbId)?.focus({ preventScroll: true });
549
+ },
550
+ style: {
551
+ userSelect: "none",
552
+ WebkitUserSelect: "none"
553
+ }
554
+ });
555
+ },
556
+ getChannelSliderValueTextProps(props) {
557
+ return normalize.element({
558
+ ...parts.channelSliderValueText.attrs,
559
+ "data-channel": props.channel
560
+ });
561
+ },
532
562
  getChannelSliderThumbProps(props) {
533
- const { orientation = "horizontal", channel } = props;
534
- const { minValue, maxValue, step: stepValue } = areaValue.getChannelRange(channel);
535
- const channelValue = areaValue.getChannelValue(channel);
536
- const offset = (channelValue - minValue) / (maxValue - minValue);
563
+ const { orientation = "horizontal", channel, format } = props;
564
+ const normalizedValue = format ? value.toFormat(format) : areaValue;
565
+ const channelRange = normalizedValue.getChannelRange(channel);
566
+ const channelValue = normalizedValue.getChannelValue(channel);
567
+ const offset = (channelValue - channelRange.minValue) / (channelRange.maxValue - channelRange.minValue);
537
568
  const placementStyles = orientation === "horizontal" ? { left: `${offset * 100}%`, top: "50%" } : { top: `${offset * 100}%`, left: "50%" };
538
569
  return normalize.element({
539
570
  ...parts.channelSliderThumb.attrs,
@@ -546,8 +577,8 @@ function connect(state, send, normalize) {
546
577
  "data-orientation": orientation,
547
578
  "aria-disabled": dataAttr(disabled),
548
579
  "aria-orientation": orientation,
549
- "aria-valuemax": maxValue,
550
- "aria-valuemin": minValue,
580
+ "aria-valuemax": channelRange.maxValue,
581
+ "aria-valuemin": channelRange.minValue,
551
582
  "aria-valuenow": channelValue,
552
583
  "aria-valuetext": `${channel} ${channelValue}`,
553
584
  style: {
@@ -563,7 +594,7 @@ function connect(state, send, normalize) {
563
594
  onKeyDown(event) {
564
595
  if (event.defaultPrevented) return;
565
596
  if (!interactive) return;
566
- const step = getEventStep(event) * stepValue;
597
+ const step = getEventStep(event) * channelRange.step;
567
598
  const keyMap = {
568
599
  ArrowUp() {
569
600
  send({ type: "CHANNEL_SLIDER.ARROW_UP", channel, step });
@@ -604,7 +635,7 @@ function connect(state, send, normalize) {
604
635
  getChannelInputProps(props) {
605
636
  const { channel } = props;
606
637
  const isTextField = channel === "hex" || channel === "css";
607
- const range = getChannelRange(value, channel);
638
+ const channelRange = getChannelRange(value, channel);
608
639
  return normalize.input({
609
640
  ...parts.channelInput.attrs,
610
641
  dir: state.context.dir,
@@ -617,9 +648,9 @@ function connect(state, send, normalize) {
617
648
  "data-disabled": dataAttr(disabled),
618
649
  readOnly: state.context.readOnly,
619
650
  defaultValue: getChannelValue(value, channel),
620
- min: range?.minValue,
621
- max: range?.maxValue,
622
- step: range?.step,
651
+ min: channelRange?.minValue,
652
+ max: channelRange?.maxValue,
653
+ step: channelRange?.step,
623
654
  onBeforeInput(event) {
624
655
  if (isTextField || !interactive) return;
625
656
  const value2 = event.currentTarget.value;
@@ -658,6 +689,8 @@ function connect(state, send, normalize) {
658
689
  type: "text",
659
690
  disabled,
660
691
  name: state.context.name,
692
+ readOnly: state.context.readOnly,
693
+ required: state.context.required,
661
694
  id: dom.getHiddenInputId(state.context),
662
695
  style: visuallyHiddenStyle,
663
696
  defaultValue: valueAsString
@@ -949,22 +982,22 @@ function machine(userContext) {
949
982
  actions: ["setActiveChannel"]
950
983
  },
951
984
  "AREA.ARROW_LEFT": {
952
- actions: ["decrementXChannel"]
985
+ actions: ["decrementAreaXChannel"]
953
986
  },
954
987
  "AREA.ARROW_RIGHT": {
955
- actions: ["incrementXChannel"]
988
+ actions: ["incrementAreaXChannel"]
956
989
  },
957
990
  "AREA.ARROW_UP": {
958
- actions: ["incrementYChannel"]
991
+ actions: ["incrementAreaYChannel"]
959
992
  },
960
993
  "AREA.ARROW_DOWN": {
961
- actions: ["decrementYChannel"]
994
+ actions: ["decrementAreaYChannel"]
962
995
  },
963
996
  "AREA.PAGE_UP": {
964
- actions: ["incrementXChannel"]
997
+ actions: ["incrementAreaXChannel"]
965
998
  },
966
999
  "AREA.PAGE_DOWN": {
967
- actions: ["decrementXChannel"]
1000
+ actions: ["decrementAreaXChannel"]
968
1001
  },
969
1002
  "CHANNEL_SLIDER.ARROW_LEFT": {
970
1003
  actions: ["decrementChannel"]
@@ -1139,11 +1172,11 @@ function machine(userContext) {
1139
1172
  }
1140
1173
  });
1141
1174
  },
1142
- trackPointerMove(ctx2, _evt, { send }) {
1175
+ trackPointerMove(ctx2, evt, { send }) {
1143
1176
  return trackPointerMove(dom.getDoc(ctx2), {
1144
1177
  onPointerMove({ point }) {
1145
1178
  const type = ctx2.activeId === "area" ? "AREA.POINTER_MOVE" : "CHANNEL_SLIDER.POINTER_MOVE";
1146
- send({ type, point });
1179
+ send({ type, point, format: evt.format });
1147
1180
  },
1148
1181
  onPointerUp() {
1149
1182
  const type = ctx2.activeId === "area" ? "AREA.POINTER_UP" : "CHANNEL_SLIDER.POINTER_UP";
@@ -1179,22 +1212,24 @@ function machine(userContext) {
1179
1212
  ctx2.activeOrientation = null;
1180
1213
  },
1181
1214
  setAreaColorFromPoint(ctx2, evt) {
1215
+ const normalizedValue = evt.format ? ctx2.value.toFormat(evt.format) : ctx2.areaValue;
1182
1216
  const { xChannel, yChannel } = evt.channel || ctx2.activeChannel;
1183
1217
  const percent = dom.getAreaValueFromPoint(ctx2, evt.point);
1184
1218
  if (!percent) return;
1185
- const xValue = ctx2.areaValue.getChannelPercentValue(xChannel, percent.x);
1186
- const yValue = ctx2.areaValue.getChannelPercentValue(yChannel, 1 - percent.y);
1187
- const color = ctx2.areaValue.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue);
1219
+ const xValue = normalizedValue.getChannelPercentValue(xChannel, percent.x);
1220
+ const yValue = normalizedValue.getChannelPercentValue(yChannel, 1 - percent.y);
1221
+ const color = normalizedValue.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue);
1188
1222
  set.value(ctx2, color);
1189
1223
  },
1190
1224
  setChannelColorFromPoint(ctx2, evt) {
1191
1225
  const channel = evt.channel || ctx2.activeId;
1226
+ const normalizedValue = evt.format ? ctx2.value.toFormat(evt.format) : ctx2.areaValue;
1192
1227
  const percent = dom.getChannelSliderValueFromPoint(ctx2, evt.point, channel);
1193
1228
  if (!percent) return;
1194
1229
  const orientation = ctx2.activeOrientation || "horizontal";
1195
1230
  const channelPercent = orientation === "horizontal" ? percent.x : percent.y;
1196
- const value = ctx2.areaValue.getChannelPercentValue(channel, channelPercent);
1197
- const color = ctx2.areaValue.withChannelValue(channel, value);
1231
+ const value = normalizedValue.getChannelPercentValue(channel, channelPercent);
1232
+ const color = normalizedValue.withChannelValue(channel, value);
1198
1233
  set.value(ctx2, color);
1199
1234
  },
1200
1235
  setValue(ctx2, evt) {
@@ -1238,22 +1273,22 @@ function machine(userContext) {
1238
1273
  const color = ctx2.value.decrementChannel(evt.channel, evt.step);
1239
1274
  set.value(ctx2, color);
1240
1275
  },
1241
- incrementXChannel(ctx2, evt) {
1276
+ incrementAreaXChannel(ctx2, evt) {
1242
1277
  const { xChannel } = evt.channel;
1243
1278
  const color = ctx2.areaValue.incrementChannel(xChannel, evt.step);
1244
1279
  set.value(ctx2, color);
1245
1280
  },
1246
- decrementXChannel(ctx2, evt) {
1281
+ decrementAreaXChannel(ctx2, evt) {
1247
1282
  const { xChannel } = evt.channel;
1248
1283
  const color = ctx2.areaValue.decrementChannel(xChannel, evt.step);
1249
1284
  set.value(ctx2, color);
1250
1285
  },
1251
- incrementYChannel(ctx2, evt) {
1286
+ incrementAreaYChannel(ctx2, evt) {
1252
1287
  const { yChannel } = evt.channel;
1253
1288
  const color = ctx2.areaValue.incrementChannel(yChannel, evt.step);
1254
1289
  set.value(ctx2, color);
1255
1290
  },
1256
- decrementYChannel(ctx2, evt) {
1291
+ decrementAreaYChannel(ctx2, evt) {
1257
1292
  const { yChannel } = evt.channel;
1258
1293
  const color = ctx2.areaValue.decrementChannel(yChannel, evt.step);
1259
1294
  set.value(ctx2, color);