@zag-js/color-picker 0.23.0 → 0.24.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.d.mts +107 -32
- package/dist/index.d.ts +107 -32
- package/dist/index.js +484 -294
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +483 -297
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -12
- package/src/color-picker.anatomy.ts +11 -5
- package/src/color-picker.connect.ts +200 -125
- package/src/color-picker.dom.ts +22 -3
- package/src/color-picker.machine.ts +227 -125
- package/src/color-picker.parse.ts +4 -0
- package/src/color-picker.types.ts +116 -30
- package/src/index.ts +7 -6
- package/src/utils/get-channel-input-value.ts +45 -11
- package/src/utils/get-slider-background.ts +7 -7
- package/src/utils/get-channel-details.ts +0 -60
package/dist/index.mjs
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
// src/color-picker.anatomy.ts
|
|
2
2
|
import { createAnatomy } from "@zag-js/anatomy";
|
|
3
3
|
var anatomy = createAnatomy("color-picker", [
|
|
4
|
+
"root",
|
|
5
|
+
"label",
|
|
6
|
+
"control",
|
|
7
|
+
"trigger",
|
|
8
|
+
"positioner",
|
|
9
|
+
"content",
|
|
4
10
|
"area",
|
|
5
11
|
"areaThumb",
|
|
6
|
-
"
|
|
12
|
+
"areaBackground",
|
|
13
|
+
"channelSlider",
|
|
7
14
|
"channelSliderTrack",
|
|
8
|
-
"channelSliderTrackBackground",
|
|
9
15
|
"channelSliderThumb",
|
|
10
16
|
"channelInput",
|
|
17
|
+
"transparancyGrid",
|
|
18
|
+
"swatchGroup",
|
|
19
|
+
"swatchTrigger",
|
|
11
20
|
"swatch",
|
|
12
|
-
"swatchBackground",
|
|
13
|
-
"content",
|
|
14
|
-
"label",
|
|
15
21
|
"eyeDropperTrigger"
|
|
16
22
|
]);
|
|
17
23
|
var parts = anatomy.build();
|
|
18
24
|
|
|
19
25
|
// src/color-picker.connect.ts
|
|
20
|
-
import {
|
|
21
|
-
getColorAreaGradient,
|
|
22
|
-
normalizeColor
|
|
23
|
-
} from "@zag-js/color-utils";
|
|
26
|
+
import { getColorAreaGradient, normalizeColor } from "@zag-js/color-utils";
|
|
24
27
|
import {
|
|
25
28
|
getEventKey,
|
|
26
29
|
getEventPoint,
|
|
@@ -29,21 +32,29 @@ import {
|
|
|
29
32
|
isLeftClick,
|
|
30
33
|
isModifiedEvent
|
|
31
34
|
} from "@zag-js/dom-event";
|
|
32
|
-
import { dataAttr,
|
|
35
|
+
import { dataAttr, query } from "@zag-js/dom-query";
|
|
36
|
+
import { getPlacementStyles } from "@zag-js/popper";
|
|
33
37
|
import { visuallyHiddenStyle } from "@zag-js/visually-hidden";
|
|
34
38
|
|
|
35
39
|
// src/color-picker.dom.ts
|
|
36
40
|
import { getRelativePoint } from "@zag-js/dom-event";
|
|
37
41
|
import { createScope, queryAll } from "@zag-js/dom-query";
|
|
42
|
+
import { getFirstFocusable } from "@zag-js/tabbable";
|
|
43
|
+
import { runIfFn } from "@zag-js/utils";
|
|
38
44
|
var dom = createScope({
|
|
45
|
+
getRootId: (ctx) => ctx.ids?.root ?? `color-picker:${ctx.id}`,
|
|
46
|
+
getLabelId: (ctx) => ctx.ids?.label ?? `color-picker:${ctx.id}:label`,
|
|
47
|
+
getHiddenInputId: (ctx) => `color-picker:${ctx.id}:hidden-input`,
|
|
48
|
+
getControlId: (ctx) => ctx.ids?.control ?? `color-picker:${ctx.id}:control`,
|
|
49
|
+
getTriggerId: (ctx) => ctx.ids?.trigger ?? `color-picker:${ctx.id}:trigger`,
|
|
39
50
|
getContentId: (ctx) => ctx.ids?.content ?? `color-picker:${ctx.id}:content`,
|
|
51
|
+
getPositionerId: (ctx) => `color-picker:${ctx.id}:positioner`,
|
|
40
52
|
getAreaId: (ctx) => ctx.ids?.area ?? `color-picker:${ctx.id}:area`,
|
|
41
53
|
getAreaGradientId: (ctx) => ctx.ids?.areaGradient ?? `color-picker:${ctx.id}:area-gradient`,
|
|
42
54
|
getAreaThumbId: (ctx) => ctx.ids?.areaThumb ?? `color-picker:${ctx.id}:area-thumb`,
|
|
43
|
-
|
|
55
|
+
getChannelSliderId: (ctx, channel) => ctx.ids?.channelSliderTrack?.(channel) ?? `color-picker:${ctx.id}:slider-track:${channel}`,
|
|
44
56
|
getChannelInputId: (ctx, channel) => ctx.ids?.channelInput?.(channel) ?? `color-picker:${ctx.id}:input:${channel}`,
|
|
45
57
|
getChannelSliderThumbId: (ctx, channel) => ctx.ids?.channelSliderThumb?.(channel) ?? `color-picker:${ctx.id}:slider-thumb:${channel}`,
|
|
46
|
-
getHiddenInputId: (ctx) => `color-picker:${ctx.id}:hidden-input`,
|
|
47
58
|
getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
|
|
48
59
|
getAreaThumbEl: (ctx) => dom.getById(ctx, dom.getAreaThumbId(ctx)),
|
|
49
60
|
getChannelSliderThumbEl: (ctx, channel) => dom.getById(ctx, dom.getChannelSliderThumbId(ctx, channel)),
|
|
@@ -57,8 +68,11 @@ var dom = createScope({
|
|
|
57
68
|
const { percent } = getRelativePoint(point, areaEl);
|
|
58
69
|
return percent;
|
|
59
70
|
},
|
|
71
|
+
getControlEl: (ctx) => dom.getById(ctx, dom.getControlId(ctx)),
|
|
72
|
+
getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
|
|
73
|
+
getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
|
|
60
74
|
getChannelSliderTrackEl: (ctx, channel) => {
|
|
61
|
-
return dom.getById(ctx, dom.
|
|
75
|
+
return dom.getById(ctx, dom.getChannelSliderId(ctx, channel));
|
|
62
76
|
},
|
|
63
77
|
getChannelSliderValueFromPoint(ctx, point, channel) {
|
|
64
78
|
const trackEl = dom.getChannelSliderTrackEl(ctx, channel);
|
|
@@ -69,61 +83,18 @@ var dom = createScope({
|
|
|
69
83
|
},
|
|
70
84
|
getChannelInputEls: (ctx) => {
|
|
71
85
|
return queryAll(dom.getContentEl(ctx), "input[data-channel]");
|
|
86
|
+
},
|
|
87
|
+
getFirstFocusableEl: (ctx) => getFirstFocusable(dom.getContentEl(ctx), "if-empty"),
|
|
88
|
+
getInitialFocusEl: (ctx) => {
|
|
89
|
+
let el = runIfFn(ctx.initialFocusEl);
|
|
90
|
+
if (!el && ctx.autoFocus)
|
|
91
|
+
el = dom.getFirstFocusableEl(ctx);
|
|
92
|
+
if (!el)
|
|
93
|
+
el = dom.getContentEl(ctx);
|
|
94
|
+
return el;
|
|
72
95
|
}
|
|
73
96
|
});
|
|
74
97
|
|
|
75
|
-
// src/utils/get-channel-details.ts
|
|
76
|
-
import { getPercentValue, snapValueToStep } from "@zag-js/numeric-range";
|
|
77
|
-
function getChannelDetails(color, xChannel, yChannel) {
|
|
78
|
-
const channels = color.getColorSpaceAxes({ xChannel, yChannel });
|
|
79
|
-
const xChannelRange = color.getChannelRange(channels.xChannel);
|
|
80
|
-
const yChannelRange = color.getChannelRange(channels.yChannel);
|
|
81
|
-
const { minValue: minValueX, maxValue: maxValueX, step: stepX, pageSize: pageSizeX } = xChannelRange;
|
|
82
|
-
const { minValue: minValueY, maxValue: maxValueY, step: stepY, pageSize: pageSizeY } = yChannelRange;
|
|
83
|
-
const xValue = color.getChannelValue(channels.xChannel);
|
|
84
|
-
const yValue = color.getChannelValue(channels.yChannel);
|
|
85
|
-
return {
|
|
86
|
-
channels,
|
|
87
|
-
xChannelStep: stepX,
|
|
88
|
-
yChannelStep: stepY,
|
|
89
|
-
xChannelPageStep: pageSizeX,
|
|
90
|
-
yChannelPageStep: pageSizeY,
|
|
91
|
-
xValue,
|
|
92
|
-
yValue,
|
|
93
|
-
getThumbPosition() {
|
|
94
|
-
let x = (xValue - minValueX) / (maxValueX - minValueX);
|
|
95
|
-
let y = 1 - (yValue - minValueY) / (maxValueY - minValueY);
|
|
96
|
-
return { x, y };
|
|
97
|
-
},
|
|
98
|
-
incrementX(stepSize) {
|
|
99
|
-
return xValue + stepSize > maxValueX ? maxValueX : snapValueToStep(xValue + stepSize, minValueX, maxValueX, stepX);
|
|
100
|
-
},
|
|
101
|
-
incrementY(stepSize) {
|
|
102
|
-
return yValue + stepSize > maxValueY ? maxValueY : snapValueToStep(yValue + stepSize, minValueY, maxValueY, stepY);
|
|
103
|
-
},
|
|
104
|
-
decrementX(stepSize) {
|
|
105
|
-
return snapValueToStep(xValue - stepSize, minValueX, maxValueX, stepX);
|
|
106
|
-
},
|
|
107
|
-
decrementY(stepSize) {
|
|
108
|
-
return snapValueToStep(yValue - stepSize, minValueY, maxValueY, stepY);
|
|
109
|
-
},
|
|
110
|
-
getColorFromPoint(x, y) {
|
|
111
|
-
let newXValue = getPercentValue(x, minValueX, maxValueX, stepX);
|
|
112
|
-
let newYValue = getPercentValue(1 - y, minValueY, maxValueY, stepY);
|
|
113
|
-
let newColor;
|
|
114
|
-
if (newXValue !== xValue) {
|
|
115
|
-
newXValue = snapValueToStep(newXValue, minValueX, maxValueX, stepX);
|
|
116
|
-
newColor = color.withChannelValue(channels.xChannel, newXValue);
|
|
117
|
-
}
|
|
118
|
-
if (newYValue !== yValue) {
|
|
119
|
-
newYValue = snapValueToStep(newYValue, minValueY, maxValueY, stepY);
|
|
120
|
-
newColor = (newColor || color).withChannelValue(channels.yChannel, newYValue);
|
|
121
|
-
}
|
|
122
|
-
return newColor;
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
98
|
// src/utils/get-channel-display-color.ts
|
|
128
99
|
import { parseColor } from "@zag-js/color-utils";
|
|
129
100
|
function getChannelDisplayColor(color, channel) {
|
|
@@ -146,31 +117,48 @@ function getChannelDisplayColor(color, channel) {
|
|
|
146
117
|
}
|
|
147
118
|
|
|
148
119
|
// src/utils/get-channel-input-value.ts
|
|
149
|
-
|
|
120
|
+
import { parseColor as parseColor2 } from "@zag-js/color-utils";
|
|
121
|
+
function getChannelValue(color, channel) {
|
|
150
122
|
if (channel == null)
|
|
151
|
-
return;
|
|
123
|
+
return "";
|
|
124
|
+
if (channel === "hex") {
|
|
125
|
+
return color.toString("hex");
|
|
126
|
+
}
|
|
127
|
+
if (channel === "css") {
|
|
128
|
+
return color.toString("css");
|
|
129
|
+
}
|
|
130
|
+
if (channel in color) {
|
|
131
|
+
return color.getChannelValue(channel).toString();
|
|
132
|
+
}
|
|
133
|
+
const isHSL = color.getFormat() === "hsl";
|
|
152
134
|
switch (channel) {
|
|
153
|
-
case "hex":
|
|
154
|
-
return color.toString("hex");
|
|
155
|
-
case "css":
|
|
156
|
-
return color.toString("css");
|
|
157
135
|
case "hue":
|
|
136
|
+
return isHSL ? color.toFormat("hsla").getChannelValue("hue").toString() : color.toFormat("hsba").getChannelValue("hue").toString();
|
|
158
137
|
case "saturation":
|
|
138
|
+
return isHSL ? color.toFormat("hsl").getChannelValue("saturation").toString() : color.toFormat("hsb").getChannelValue("saturation").toString();
|
|
159
139
|
case "lightness":
|
|
160
|
-
return color.toFormat("
|
|
140
|
+
return color.toFormat("hsla").getChannelValue("lightness").toString();
|
|
161
141
|
case "brightness":
|
|
162
|
-
return color.toFormat("
|
|
142
|
+
return color.toFormat("hsba").getChannelValue("brightness").toString();
|
|
163
143
|
case "red":
|
|
164
144
|
case "green":
|
|
165
145
|
case "blue":
|
|
166
|
-
return color.toFormat("
|
|
146
|
+
return color.toFormat("rgba").getChannelValue(channel).toString();
|
|
167
147
|
default:
|
|
168
148
|
return color.getChannelValue(channel).toString();
|
|
169
149
|
}
|
|
170
150
|
}
|
|
171
|
-
function
|
|
151
|
+
function getChannelRange(color, channel) {
|
|
172
152
|
switch (channel) {
|
|
173
153
|
case "hex":
|
|
154
|
+
const minColor = parseColor2("#000000");
|
|
155
|
+
const maxColor = parseColor2("#FFFFFF");
|
|
156
|
+
return {
|
|
157
|
+
minValue: minColor.toHexInt(),
|
|
158
|
+
maxValue: maxColor.toHexInt(),
|
|
159
|
+
pageSize: 10,
|
|
160
|
+
step: 1
|
|
161
|
+
};
|
|
174
162
|
case "css":
|
|
175
163
|
return void 0;
|
|
176
164
|
case "hue":
|
|
@@ -189,7 +177,7 @@ function getChannelInputRange(color, channel) {
|
|
|
189
177
|
}
|
|
190
178
|
|
|
191
179
|
// src/utils/get-slider-background.ts
|
|
192
|
-
function
|
|
180
|
+
function getSliderBackgroundDirection(orientation, dir) {
|
|
193
181
|
if (orientation === "vertical") {
|
|
194
182
|
return "top";
|
|
195
183
|
} else if (dir === "ltr") {
|
|
@@ -198,16 +186,16 @@ function getSliderBgDirection(orientation, dir) {
|
|
|
198
186
|
return "left";
|
|
199
187
|
}
|
|
200
188
|
}
|
|
201
|
-
var
|
|
189
|
+
var getSliderBackground = (ctx, props) => {
|
|
202
190
|
const { channel } = props;
|
|
203
|
-
const dir =
|
|
204
|
-
const value = ctx.
|
|
205
|
-
const { minValue, maxValue } =
|
|
191
|
+
const dir = getSliderBackgroundDirection(props.orientation, ctx.dir);
|
|
192
|
+
const value = ctx.value;
|
|
193
|
+
const { minValue, maxValue } = value.getChannelRange(channel);
|
|
206
194
|
switch (channel) {
|
|
207
195
|
case "hue":
|
|
208
196
|
return `linear-gradient(to ${dir}, rgb(255, 0, 0) 0%, rgb(255, 255, 0) 17%, rgb(0, 255, 0) 33%, rgb(0, 255, 255) 50%, rgb(0, 0, 255) 67%, rgb(255, 0, 255) 83%, rgb(255, 0, 0) 100%)`;
|
|
209
197
|
case "lightness": {
|
|
210
|
-
let start =
|
|
198
|
+
let start = value.withChannelValue(channel, minValue).toString("css");
|
|
211
199
|
let middle = value.withChannelValue(channel, (maxValue - minValue) / 2).toString("css");
|
|
212
200
|
let end = value.withChannelValue(channel, maxValue).toString("css");
|
|
213
201
|
return `linear-gradient(to ${dir}, ${start}, ${middle}, ${end})`;
|
|
@@ -229,41 +217,112 @@ var getSliderBgImage = (ctx, props) => {
|
|
|
229
217
|
|
|
230
218
|
// src/color-picker.connect.ts
|
|
231
219
|
function connect(state, send, normalize) {
|
|
232
|
-
const valueAsColor = state.context.valueAsColor;
|
|
233
220
|
const value = state.context.value;
|
|
221
|
+
const valueAsString = state.context.valueAsString;
|
|
234
222
|
const isDisabled = state.context.isDisabled;
|
|
235
223
|
const isInteractive = state.context.isInteractive;
|
|
236
|
-
const isDragging = state.
|
|
237
|
-
const
|
|
224
|
+
const isDragging = state.hasTag("dragging");
|
|
225
|
+
const isOpen = state.hasTag("open");
|
|
226
|
+
const channels = value.getChannels();
|
|
227
|
+
const getAreaChannels = (props) => ({
|
|
228
|
+
value: value.toFormat("hsl"),
|
|
229
|
+
xChannel: props.xChannel ?? "saturation",
|
|
230
|
+
yChannel: props.yChannel ?? "lightness"
|
|
231
|
+
});
|
|
232
|
+
const currentPlacement = state.context.currentPlacement;
|
|
233
|
+
const popperStyles = getPlacementStyles({
|
|
234
|
+
...state.context.positioning,
|
|
235
|
+
placement: currentPlacement
|
|
236
|
+
});
|
|
238
237
|
return {
|
|
239
238
|
isDragging,
|
|
239
|
+
isOpen,
|
|
240
|
+
valueAsString,
|
|
240
241
|
value,
|
|
241
|
-
valueAsColor,
|
|
242
|
-
alpha: valueAsColor.getChannelValue("alpha"),
|
|
243
242
|
channels,
|
|
244
243
|
setColor(value2) {
|
|
245
244
|
send({ type: "VALUE.SET", value: normalizeColor(value2), src: "set-color" });
|
|
246
245
|
},
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
getChannelValue(channel) {
|
|
247
|
+
return getChannelValue(value, channel);
|
|
248
|
+
},
|
|
249
|
+
setChannelValue(channel, channelValue) {
|
|
250
|
+
const color = value.withChannelValue(channel, channelValue);
|
|
249
251
|
send({ type: "VALUE.SET", value: color, src: "set-channel" });
|
|
250
252
|
},
|
|
251
253
|
setFormat(format) {
|
|
252
|
-
const
|
|
253
|
-
send({ type: "VALUE.SET", value:
|
|
254
|
+
const formatValue = value.toFormat(format);
|
|
255
|
+
send({ type: "VALUE.SET", value: formatValue, src: "set-format" });
|
|
256
|
+
},
|
|
257
|
+
getAlpha() {
|
|
258
|
+
return value.getChannelValue("alpha");
|
|
254
259
|
},
|
|
255
|
-
setAlpha(
|
|
256
|
-
const color =
|
|
260
|
+
setAlpha(alphaValue) {
|
|
261
|
+
const color = value.withChannelValue("alpha", alphaValue);
|
|
257
262
|
send({ type: "VALUE.SET", value: color, src: "set-alpha" });
|
|
258
263
|
},
|
|
264
|
+
rootProps: normalize.element({
|
|
265
|
+
...parts.root.attrs,
|
|
266
|
+
dir: state.context.dir,
|
|
267
|
+
id: dom.getRootId(state.context),
|
|
268
|
+
"data-disabled": dataAttr(isDisabled),
|
|
269
|
+
"data-readonly": dataAttr(state.context.readOnly),
|
|
270
|
+
style: {
|
|
271
|
+
"--value": value.toString("css")
|
|
272
|
+
}
|
|
273
|
+
}),
|
|
274
|
+
labelProps: normalize.element({
|
|
275
|
+
...parts.label.attrs,
|
|
276
|
+
dir: state.context.dir,
|
|
277
|
+
id: dom.getLabelId(state.context),
|
|
278
|
+
htmlFor: dom.getHiddenInputId(state.context),
|
|
279
|
+
"data-disabled": dataAttr(isDisabled),
|
|
280
|
+
"data-readonly": dataAttr(state.context.readOnly),
|
|
281
|
+
onClick(event) {
|
|
282
|
+
event.preventDefault();
|
|
283
|
+
const inputEl = query(dom.getControlEl(state.context), "[data-channel=hex]");
|
|
284
|
+
inputEl?.focus({ preventScroll: true });
|
|
285
|
+
}
|
|
286
|
+
}),
|
|
287
|
+
controlProps: normalize.element({
|
|
288
|
+
...parts.control.attrs,
|
|
289
|
+
id: dom.getControlId(state.context),
|
|
290
|
+
dir: state.context.dir,
|
|
291
|
+
"data-disabled": dataAttr(isDisabled),
|
|
292
|
+
"data-readonly": dataAttr(state.context.readOnly)
|
|
293
|
+
}),
|
|
294
|
+
triggerProps: normalize.button({
|
|
295
|
+
...parts.trigger.attrs,
|
|
296
|
+
id: dom.getTriggerId(state.context),
|
|
297
|
+
dir: state.context.dir,
|
|
298
|
+
"aria-labelledby": dom.getLabelId(state.context),
|
|
299
|
+
"data-disabled": dataAttr(isDisabled),
|
|
300
|
+
"data-readonly": dataAttr(state.context.readOnly),
|
|
301
|
+
"data-placement": currentPlacement,
|
|
302
|
+
type: "button",
|
|
303
|
+
onClick() {
|
|
304
|
+
send({ type: "TRIGGER.CLICK" });
|
|
305
|
+
},
|
|
306
|
+
style: {
|
|
307
|
+
position: "relative"
|
|
308
|
+
}
|
|
309
|
+
}),
|
|
310
|
+
positionerProps: normalize.element({
|
|
311
|
+
...parts.positioner.attrs,
|
|
312
|
+
id: dom.getPositionerId(state.context),
|
|
313
|
+
dir: state.context.dir,
|
|
314
|
+
style: popperStyles.floating
|
|
315
|
+
}),
|
|
259
316
|
contentProps: normalize.element({
|
|
260
317
|
...parts.content.attrs,
|
|
261
318
|
id: dom.getContentId(state.context),
|
|
262
|
-
dir: state.context.dir
|
|
319
|
+
dir: state.context.dir,
|
|
320
|
+
"data-placement": currentPlacement,
|
|
321
|
+
hidden: !isOpen
|
|
263
322
|
}),
|
|
264
|
-
getAreaProps(props) {
|
|
265
|
-
const { xChannel, yChannel } = props;
|
|
266
|
-
const { areaStyles } = getColorAreaGradient(
|
|
323
|
+
getAreaProps(props = {}) {
|
|
324
|
+
const { xChannel, yChannel } = getAreaChannels(props);
|
|
325
|
+
const { areaStyles } = getColorAreaGradient(value, {
|
|
267
326
|
xChannel,
|
|
268
327
|
yChannel,
|
|
269
328
|
dir: state.context.dir
|
|
@@ -281,6 +340,7 @@ function connect(state, send, normalize) {
|
|
|
281
340
|
const point = getEventPoint(evt);
|
|
282
341
|
const channel = { xChannel, yChannel };
|
|
283
342
|
send({ type: "AREA.POINTER_DOWN", point, channel, id: "area" });
|
|
343
|
+
event.preventDefault();
|
|
284
344
|
},
|
|
285
345
|
style: {
|
|
286
346
|
position: "relative",
|
|
@@ -290,15 +350,15 @@ function connect(state, send, normalize) {
|
|
|
290
350
|
}
|
|
291
351
|
});
|
|
292
352
|
},
|
|
293
|
-
|
|
294
|
-
const { xChannel, yChannel } = props;
|
|
295
|
-
const { areaGradientStyles } = getColorAreaGradient(
|
|
353
|
+
getAreaBackgroundProps(props = {}) {
|
|
354
|
+
const { xChannel, yChannel } = getAreaChannels(props);
|
|
355
|
+
const { areaGradientStyles } = getColorAreaGradient(value, {
|
|
296
356
|
xChannel,
|
|
297
357
|
yChannel,
|
|
298
358
|
dir: state.context.dir
|
|
299
359
|
});
|
|
300
360
|
return normalize.element({
|
|
301
|
-
...parts.
|
|
361
|
+
...parts.areaBackground.attrs,
|
|
302
362
|
id: dom.getAreaGradientId(state.context),
|
|
303
363
|
style: {
|
|
304
364
|
position: "relative",
|
|
@@ -308,14 +368,15 @@ function connect(state, send, normalize) {
|
|
|
308
368
|
}
|
|
309
369
|
});
|
|
310
370
|
},
|
|
311
|
-
getAreaThumbProps(props) {
|
|
312
|
-
const { xChannel, yChannel } = props;
|
|
313
|
-
const { getThumbPosition } = getChannelDetails(valueAsColor, xChannel, yChannel);
|
|
314
|
-
const { x, y } = getThumbPosition();
|
|
371
|
+
getAreaThumbProps(props = {}) {
|
|
372
|
+
const { xChannel, yChannel, value: valueAsHSL } = getAreaChannels(props);
|
|
315
373
|
const channel = { xChannel, yChannel };
|
|
374
|
+
const x = valueAsHSL.getChannelValuePercent(xChannel);
|
|
375
|
+
const y = 1 - valueAsHSL.getChannelValuePercent(yChannel);
|
|
316
376
|
return normalize.element({
|
|
317
377
|
...parts.areaThumb.attrs,
|
|
318
378
|
id: dom.getAreaThumbId(state.context),
|
|
379
|
+
dir: state.context.dir,
|
|
319
380
|
tabIndex: isDisabled ? void 0 : 0,
|
|
320
381
|
"data-disabled": dataAttr(isDisabled),
|
|
321
382
|
role: "presentation",
|
|
@@ -326,13 +387,10 @@ function connect(state, send, normalize) {
|
|
|
326
387
|
transform: "translate(-50%, -50%)",
|
|
327
388
|
touchAction: "none",
|
|
328
389
|
forcedColorAdjust: "none",
|
|
329
|
-
background:
|
|
330
|
-
},
|
|
331
|
-
onBlur() {
|
|
332
|
-
send("AREA.BLUR");
|
|
390
|
+
background: value.withChannelValue("alpha", 1).toString("css")
|
|
333
391
|
},
|
|
334
392
|
onFocus() {
|
|
335
|
-
send({ type: "AREA.FOCUS", id: "area" });
|
|
393
|
+
send({ type: "AREA.FOCUS", id: "area", channel });
|
|
336
394
|
},
|
|
337
395
|
onKeyDown(event) {
|
|
338
396
|
if (!isInteractive)
|
|
@@ -356,6 +414,9 @@ function connect(state, send, normalize) {
|
|
|
356
414
|
},
|
|
357
415
|
PageDown() {
|
|
358
416
|
send({ type: "AREA.PAGE_DOWN", channel, step });
|
|
417
|
+
},
|
|
418
|
+
Escape(event2) {
|
|
419
|
+
event2.stopPropagation();
|
|
359
420
|
}
|
|
360
421
|
};
|
|
361
422
|
const exec = keyMap[getEventKey(event, state.context)];
|
|
@@ -366,14 +427,31 @@ function connect(state, send, normalize) {
|
|
|
366
427
|
}
|
|
367
428
|
});
|
|
368
429
|
},
|
|
369
|
-
|
|
430
|
+
getTransparencyGridProps(props) {
|
|
431
|
+
const { size } = props;
|
|
432
|
+
return normalize.element({
|
|
433
|
+
...parts.transparancyGrid.attrs,
|
|
434
|
+
style: {
|
|
435
|
+
"--size": size,
|
|
436
|
+
width: "100%",
|
|
437
|
+
height: "100%",
|
|
438
|
+
position: "absolute",
|
|
439
|
+
backgroundColor: "#fff",
|
|
440
|
+
backgroundImage: "conic-gradient(#eeeeee 0 25%, transparent 0 50%, #eeeeee 0 75%, transparent 0)",
|
|
441
|
+
backgroundSize: "var(--size) var(--size)",
|
|
442
|
+
inset: "0px",
|
|
443
|
+
zIndex: "auto",
|
|
444
|
+
pointerEvents: "none"
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
},
|
|
448
|
+
getChannelSliderProps(props) {
|
|
370
449
|
const { orientation = "horizontal", channel } = props;
|
|
371
450
|
return normalize.element({
|
|
372
|
-
...parts.
|
|
373
|
-
id: dom.getChannelSliderTrackId(state.context, channel),
|
|
374
|
-
role: "group",
|
|
451
|
+
...parts.channelSlider.attrs,
|
|
375
452
|
"data-channel": channel,
|
|
376
453
|
"data-orientation": orientation,
|
|
454
|
+
role: "presentation",
|
|
377
455
|
onPointerDown(event) {
|
|
378
456
|
if (!isInteractive)
|
|
379
457
|
return;
|
|
@@ -382,41 +460,33 @@ function connect(state, send, normalize) {
|
|
|
382
460
|
return;
|
|
383
461
|
const point = getEventPoint(evt);
|
|
384
462
|
send({ type: "CHANNEL_SLIDER.POINTER_DOWN", channel, point, id: channel, orientation });
|
|
463
|
+
event.preventDefault();
|
|
385
464
|
},
|
|
386
465
|
style: {
|
|
387
466
|
position: "relative",
|
|
388
|
-
touchAction: "none"
|
|
389
|
-
forcedColorAdjust: "none",
|
|
390
|
-
backgroundImage: getSliderBgImage(state.context, { orientation, channel })
|
|
467
|
+
touchAction: "none"
|
|
391
468
|
}
|
|
392
469
|
});
|
|
393
470
|
},
|
|
394
|
-
|
|
471
|
+
getChannelSliderTrackProps(props) {
|
|
395
472
|
const { orientation = "horizontal", channel } = props;
|
|
396
473
|
return normalize.element({
|
|
397
|
-
...parts.
|
|
398
|
-
|
|
474
|
+
...parts.channelSliderTrack.attrs,
|
|
475
|
+
id: dom.getChannelSliderId(state.context, channel),
|
|
476
|
+
role: "group",
|
|
399
477
|
"data-channel": channel,
|
|
478
|
+
"data-orientation": orientation,
|
|
400
479
|
style: {
|
|
401
|
-
position: "
|
|
402
|
-
|
|
403
|
-
backgroundImage:
|
|
404
|
-
"linear-gradient(-45deg,#0000 75.5%,#bcbcbc 75.5%)",
|
|
405
|
-
"linear-gradient(45deg,#0000 75.5%,#bcbcbc 75.5%)",
|
|
406
|
-
"linear-gradient(-45deg,#bcbcbc 25.5%,#0000 25.5%)",
|
|
407
|
-
"linear-gradient(45deg,#bcbcbc 25.5%,#0000 25.5%)"
|
|
408
|
-
].join(","),
|
|
409
|
-
backgroundSize: "16px 16px",
|
|
410
|
-
backgroundPosition: "-2px -2px,-2px 6px,6px -10px,-10px -2px",
|
|
411
|
-
inset: 0,
|
|
412
|
-
zIndex: -1
|
|
480
|
+
position: "relative",
|
|
481
|
+
forcedColorAdjust: "none",
|
|
482
|
+
backgroundImage: getSliderBackground(state.context, { orientation, channel })
|
|
413
483
|
}
|
|
414
484
|
});
|
|
415
485
|
},
|
|
416
486
|
getChannelSliderThumbProps(props) {
|
|
417
487
|
const { orientation = "horizontal", channel } = props;
|
|
418
|
-
const { minValue, maxValue, step: stepValue } =
|
|
419
|
-
const channelValue =
|
|
488
|
+
const { minValue, maxValue, step: stepValue } = value.getChannelRange(channel);
|
|
489
|
+
const channelValue = value.getChannelValue(channel);
|
|
420
490
|
const offset = (channelValue - minValue) / (maxValue - minValue);
|
|
421
491
|
const placementStyles = orientation === "horizontal" ? { left: `${offset * 100}%`, top: "50%" } : { top: `${offset * 100}%`, left: "50%" };
|
|
422
492
|
return normalize.element({
|
|
@@ -436,7 +506,7 @@ function connect(state, send, normalize) {
|
|
|
436
506
|
style: {
|
|
437
507
|
forcedColorAdjust: "none",
|
|
438
508
|
position: "absolute",
|
|
439
|
-
background: getChannelDisplayColor(
|
|
509
|
+
background: getChannelDisplayColor(value, channel).toString("css"),
|
|
440
510
|
...placementStyles
|
|
441
511
|
},
|
|
442
512
|
onFocus() {
|
|
@@ -444,11 +514,6 @@ function connect(state, send, normalize) {
|
|
|
444
514
|
return;
|
|
445
515
|
send({ type: "CHANNEL_SLIDER.FOCUS", channel });
|
|
446
516
|
},
|
|
447
|
-
onBlur() {
|
|
448
|
-
if (!isInteractive)
|
|
449
|
-
return;
|
|
450
|
-
send({ type: "CHANNEL_SLIDER.BLUR", channel });
|
|
451
|
-
},
|
|
452
517
|
onKeyDown(event) {
|
|
453
518
|
if (!isInteractive)
|
|
454
519
|
return;
|
|
@@ -477,6 +542,9 @@ function connect(state, send, normalize) {
|
|
|
477
542
|
},
|
|
478
543
|
End() {
|
|
479
544
|
send({ type: "CHANNEL_SLIDER.END", channel });
|
|
545
|
+
},
|
|
546
|
+
Escape(event2) {
|
|
547
|
+
event2.stopPropagation();
|
|
480
548
|
}
|
|
481
549
|
};
|
|
482
550
|
const exec = keyMap[getEventKey(event, state.context)];
|
|
@@ -490,7 +558,7 @@ function connect(state, send, normalize) {
|
|
|
490
558
|
getChannelInputProps(props) {
|
|
491
559
|
const { channel } = props;
|
|
492
560
|
const isTextField = channel === "hex" || channel === "css";
|
|
493
|
-
const range =
|
|
561
|
+
const range = getChannelRange(value, channel);
|
|
494
562
|
return normalize.input({
|
|
495
563
|
...parts.channelInput.attrs,
|
|
496
564
|
type: isTextField ? "text" : "number",
|
|
@@ -500,22 +568,31 @@ function connect(state, send, normalize) {
|
|
|
500
568
|
"data-disabled": dataAttr(isDisabled),
|
|
501
569
|
readOnly: state.context.readOnly,
|
|
502
570
|
id: dom.getChannelInputId(state.context, channel),
|
|
503
|
-
defaultValue:
|
|
571
|
+
defaultValue: getChannelValue(value, channel),
|
|
504
572
|
min: range?.minValue,
|
|
505
573
|
max: range?.maxValue,
|
|
506
574
|
step: range?.step,
|
|
575
|
+
onBeforeInput(event) {
|
|
576
|
+
if (isTextField)
|
|
577
|
+
return;
|
|
578
|
+
const value2 = event.currentTarget.value;
|
|
579
|
+
if (value2.match(/[^0-9.]/g)) {
|
|
580
|
+
event.preventDefault();
|
|
581
|
+
}
|
|
582
|
+
},
|
|
507
583
|
onFocus(event) {
|
|
508
584
|
send({ type: "CHANNEL_INPUT.FOCUS", channel });
|
|
509
|
-
|
|
585
|
+
event.target.select();
|
|
510
586
|
},
|
|
511
587
|
onBlur(event) {
|
|
512
|
-
const value2 = event.currentTarget.value;
|
|
513
|
-
send({ type: "CHANNEL_INPUT.
|
|
588
|
+
const value2 = isTextField ? event.currentTarget.value : event.currentTarget.valueAsNumber;
|
|
589
|
+
send({ type: "CHANNEL_INPUT.BLUR", channel, value: value2, isTextField });
|
|
514
590
|
},
|
|
515
591
|
onKeyDown(event) {
|
|
516
592
|
if (event.key === "Enter") {
|
|
517
|
-
const value2 = event.currentTarget.value;
|
|
593
|
+
const value2 = isTextField ? event.currentTarget.value : event.currentTarget.valueAsNumber;
|
|
518
594
|
send({ type: "CHANNEL_INPUT.CHANGE", channel, value: value2, isTextField });
|
|
595
|
+
event.preventDefault();
|
|
519
596
|
}
|
|
520
597
|
},
|
|
521
598
|
style: {
|
|
@@ -531,14 +608,11 @@ function connect(state, send, normalize) {
|
|
|
531
608
|
name: state.context.name,
|
|
532
609
|
id: dom.getHiddenInputId(state.context),
|
|
533
610
|
style: visuallyHiddenStyle,
|
|
534
|
-
defaultValue:
|
|
535
|
-
onChange(event) {
|
|
536
|
-
const value2 = event.currentTarget.value;
|
|
537
|
-
send({ type: "VALUE.SET", value: value2, src: "input.change" });
|
|
538
|
-
}
|
|
611
|
+
defaultValue: valueAsString
|
|
539
612
|
}),
|
|
540
613
|
eyeDropperTriggerProps: normalize.button({
|
|
541
614
|
...parts.eyeDropperTrigger.attrs,
|
|
615
|
+
type: "button",
|
|
542
616
|
disabled: isDisabled,
|
|
543
617
|
"data-disabled": dataAttr(isDisabled),
|
|
544
618
|
"aria-label": "Pick a color from the screen",
|
|
@@ -548,43 +622,39 @@ function connect(state, send, normalize) {
|
|
|
548
622
|
send("EYEDROPPER.CLICK");
|
|
549
623
|
}
|
|
550
624
|
}),
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
625
|
+
swatchGroupProps: normalize.element({
|
|
626
|
+
...parts.swatchGroup.attrs,
|
|
627
|
+
role: "group"
|
|
628
|
+
}),
|
|
629
|
+
getSwatchTriggerProps(props) {
|
|
630
|
+
const { value: valueProp } = props;
|
|
631
|
+
const color = normalizeColor(valueProp).toFormat(value.getFormat());
|
|
632
|
+
return normalize.button({
|
|
633
|
+
...parts.swatchTrigger.attrs,
|
|
634
|
+
disabled: isDisabled,
|
|
635
|
+
type: "button",
|
|
636
|
+
"data-value": color.toString("hex"),
|
|
637
|
+
onClick() {
|
|
638
|
+
if (!isInteractive)
|
|
639
|
+
return;
|
|
640
|
+
send({ type: "VALUE.SET", value: color });
|
|
641
|
+
},
|
|
557
642
|
style: {
|
|
558
|
-
|
|
559
|
-
height: "100%",
|
|
560
|
-
background: "#fff",
|
|
561
|
-
backgroundImage: [
|
|
562
|
-
"linear-gradient(-45deg,#0000 75.5%,#bcbcbc 75.5%)",
|
|
563
|
-
"linear-gradient(45deg,#0000 75.5%,#bcbcbc 75.5%)",
|
|
564
|
-
"linear-gradient(-45deg,#bcbcbc 25.5%,#0000 25.5%)",
|
|
565
|
-
"linear-gradient(45deg,#bcbcbc 25.5%,#0000 25.5%)"
|
|
566
|
-
].join(","),
|
|
567
|
-
backgroundPosition: "-2px -2px,-2px 6px,6px -10px,-10px -2px",
|
|
568
|
-
backgroundSize: "16px 16px",
|
|
569
|
-
position: "absolute",
|
|
570
|
-
inset: "0px",
|
|
571
|
-
zIndex: -1
|
|
643
|
+
position: "relative"
|
|
572
644
|
}
|
|
573
645
|
});
|
|
574
646
|
},
|
|
575
647
|
getSwatchProps(props) {
|
|
576
|
-
const { value:
|
|
577
|
-
const
|
|
648
|
+
const { value: valueProp, respectAlpha = true } = props;
|
|
649
|
+
const colorValue = normalizeColor(valueProp);
|
|
650
|
+
const color = colorValue.toFormat(value.getFormat());
|
|
578
651
|
return normalize.element({
|
|
579
652
|
...parts.swatch.attrs,
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
return;
|
|
583
|
-
send({ type: "VALUE.SET", value: color });
|
|
584
|
-
},
|
|
653
|
+
"data-state": colorValue.isEqual(value) ? "selected" : "unselected",
|
|
654
|
+
"data-value": color.toString("hex"),
|
|
585
655
|
style: {
|
|
586
656
|
position: "relative",
|
|
587
|
-
background: color.toString("css")
|
|
657
|
+
background: color.toString(respectAlpha ? "css" : "hex")
|
|
588
658
|
}
|
|
589
659
|
});
|
|
590
660
|
}
|
|
@@ -592,86 +662,135 @@ function connect(state, send, normalize) {
|
|
|
592
662
|
}
|
|
593
663
|
|
|
594
664
|
// src/color-picker.machine.ts
|
|
595
|
-
import { parseColor as
|
|
596
|
-
import { createMachine } from "@zag-js/core";
|
|
665
|
+
import { parseColor as parseColor4 } from "@zag-js/color-utils";
|
|
666
|
+
import { createMachine, guards, ref as ref2 } from "@zag-js/core";
|
|
667
|
+
import { trackDismissableElement } from "@zag-js/dismissable";
|
|
597
668
|
import { trackPointerMove } from "@zag-js/dom-event";
|
|
598
|
-
import { raf
|
|
599
|
-
import { trackFormControl } from "@zag-js/form-utils";
|
|
600
|
-
import {
|
|
669
|
+
import { raf } from "@zag-js/dom-query";
|
|
670
|
+
import { dispatchInputValueEvent, trackFormControl } from "@zag-js/form-utils";
|
|
671
|
+
import { getPlacement } from "@zag-js/popper";
|
|
601
672
|
import { disableTextSelection } from "@zag-js/text-selection";
|
|
602
673
|
import { compact, tryCatch } from "@zag-js/utils";
|
|
674
|
+
|
|
675
|
+
// src/color-picker.parse.ts
|
|
676
|
+
import { parseColor as parseColor3 } from "@zag-js/color-utils";
|
|
677
|
+
import { ref } from "@zag-js/core";
|
|
678
|
+
var parse = (color) => ref(parseColor3(color));
|
|
679
|
+
|
|
680
|
+
// src/color-picker.machine.ts
|
|
681
|
+
var { stateIn } = guards;
|
|
603
682
|
function machine(userContext) {
|
|
604
683
|
const ctx = compact(userContext);
|
|
605
684
|
return createMachine(
|
|
606
685
|
{
|
|
607
686
|
id: "color-picker",
|
|
608
|
-
initial: "idle",
|
|
687
|
+
initial: ctx.open ? "open" : "idle",
|
|
609
688
|
context: {
|
|
610
689
|
dir: "ltr",
|
|
611
|
-
value: "#
|
|
690
|
+
value: parse("#000000"),
|
|
612
691
|
disabled: false,
|
|
613
692
|
...ctx,
|
|
614
693
|
activeId: null,
|
|
615
694
|
activeChannel: null,
|
|
616
695
|
activeOrientation: null,
|
|
617
|
-
fieldsetDisabled: false
|
|
696
|
+
fieldsetDisabled: false,
|
|
697
|
+
autoFocus: true,
|
|
698
|
+
positioning: {
|
|
699
|
+
...ctx.positioning,
|
|
700
|
+
placement: "bottom"
|
|
701
|
+
}
|
|
618
702
|
},
|
|
619
703
|
computed: {
|
|
620
704
|
isRtl: (ctx2) => ctx2.dir === "rtl",
|
|
621
705
|
isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled,
|
|
622
706
|
isInteractive: (ctx2) => !(ctx2.isDisabled || ctx2.readOnly),
|
|
623
|
-
|
|
707
|
+
valueAsString: (ctx2) => ctx2.value.toString("css")
|
|
708
|
+
},
|
|
709
|
+
activities: ["trackFormControl"],
|
|
710
|
+
watch: {
|
|
711
|
+
valueAsString: ["syncInputElements"],
|
|
712
|
+
open: ["toggleVisibility"]
|
|
624
713
|
},
|
|
625
714
|
on: {
|
|
626
715
|
"VALUE.SET": {
|
|
627
716
|
actions: ["setValue"]
|
|
717
|
+
},
|
|
718
|
+
"CHANNEL_INPUT.FOCUS": [
|
|
719
|
+
{
|
|
720
|
+
guard: stateIn("idle"),
|
|
721
|
+
target: "focused",
|
|
722
|
+
actions: ["setActiveChannel"]
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
actions: ["setActiveChannel"]
|
|
726
|
+
}
|
|
727
|
+
],
|
|
728
|
+
"CHANNEL_INPUT.BLUR": [
|
|
729
|
+
{
|
|
730
|
+
guard: stateIn("focused"),
|
|
731
|
+
target: "idle",
|
|
732
|
+
actions: ["setChannelColorFromInput"]
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
actions: ["setChannelColorFromInput"]
|
|
736
|
+
}
|
|
737
|
+
],
|
|
738
|
+
"CHANNEL_INPUT.CHANGE": {
|
|
739
|
+
actions: ["setChannelColorFromInput"]
|
|
628
740
|
}
|
|
629
741
|
},
|
|
630
|
-
activities: ["trackFormControl"],
|
|
631
|
-
watch: {
|
|
632
|
-
value: ["syncInputElements"]
|
|
633
|
-
},
|
|
634
742
|
states: {
|
|
635
743
|
idle: {
|
|
744
|
+
tags: ["closed"],
|
|
636
745
|
on: {
|
|
746
|
+
OPEN: {
|
|
747
|
+
target: "open",
|
|
748
|
+
actions: ["setInitialFocus", "invokeOnOpen"]
|
|
749
|
+
},
|
|
750
|
+
"TRIGGER.CLICK": {
|
|
751
|
+
target: "open",
|
|
752
|
+
actions: ["setInitialFocus", "invokeOnOpen"]
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
},
|
|
756
|
+
focused: {
|
|
757
|
+
tags: ["closed", "focused"],
|
|
758
|
+
on: {
|
|
759
|
+
OPEN: {
|
|
760
|
+
target: "open",
|
|
761
|
+
actions: ["setInitialFocus", "invokeOnOpen"]
|
|
762
|
+
},
|
|
763
|
+
"TRIGGER.CLICK": {
|
|
764
|
+
target: "open",
|
|
765
|
+
actions: ["setInitialFocus", "invokeOnOpen"]
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
open: {
|
|
770
|
+
tags: ["open"],
|
|
771
|
+
activities: ["trackPositioning", "trackDismissableElement"],
|
|
772
|
+
on: {
|
|
773
|
+
"TRIGGER.CLICK": {
|
|
774
|
+
target: "idle",
|
|
775
|
+
actions: ["invokeOnClose"]
|
|
776
|
+
},
|
|
637
777
|
"EYEDROPPER.CLICK": {
|
|
638
778
|
actions: ["openEyeDropper"]
|
|
639
779
|
},
|
|
640
780
|
"AREA.POINTER_DOWN": {
|
|
641
|
-
target: "dragging",
|
|
781
|
+
target: "open:dragging",
|
|
642
782
|
actions: ["setActiveChannel", "setAreaColorFromPoint", "focusAreaThumb"]
|
|
643
783
|
},
|
|
644
784
|
"AREA.FOCUS": {
|
|
645
|
-
target: "focused",
|
|
646
785
|
actions: ["setActiveChannel"]
|
|
647
786
|
},
|
|
648
787
|
"CHANNEL_SLIDER.POINTER_DOWN": {
|
|
649
|
-
target: "dragging",
|
|
788
|
+
target: "open:dragging",
|
|
650
789
|
actions: ["setActiveChannel", "setChannelColorFromPoint", "focusChannelThumb"]
|
|
651
790
|
},
|
|
652
791
|
"CHANNEL_SLIDER.FOCUS": {
|
|
653
|
-
target: "focused",
|
|
654
|
-
actions: ["setActiveChannel"]
|
|
655
|
-
},
|
|
656
|
-
"CHANNEL_INPUT.FOCUS": {
|
|
657
|
-
target: "focused",
|
|
658
792
|
actions: ["setActiveChannel"]
|
|
659
793
|
},
|
|
660
|
-
"CHANNEL_INPUT.CHANGE": {
|
|
661
|
-
actions: ["setChannelColorFromInput"]
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
},
|
|
665
|
-
focused: {
|
|
666
|
-
on: {
|
|
667
|
-
"AREA.POINTER_DOWN": {
|
|
668
|
-
target: "dragging",
|
|
669
|
-
actions: ["setActiveChannel", "setAreaColorFromPoint", "focusAreaThumb"]
|
|
670
|
-
},
|
|
671
|
-
"CHANNEL_SLIDER.POINTER_DOWN": {
|
|
672
|
-
target: "dragging",
|
|
673
|
-
actions: ["setActiveChannel", "setChannelColorFromPoint", "focusChannelThumb"]
|
|
674
|
-
},
|
|
675
794
|
"AREA.ARROW_LEFT": {
|
|
676
795
|
actions: ["decrementXChannel"]
|
|
677
796
|
},
|
|
@@ -714,44 +833,100 @@ function machine(userContext) {
|
|
|
714
833
|
"CHANNEL_SLIDER.END": {
|
|
715
834
|
actions: ["setChannelToMax"]
|
|
716
835
|
},
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
836
|
+
INTERACT_OUTSIDE: [
|
|
837
|
+
{
|
|
838
|
+
guard: "shouldRestoreFocus",
|
|
839
|
+
target: "focused",
|
|
840
|
+
actions: ["setReturnFocus", "invokeOnClose"]
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
target: "idle",
|
|
844
|
+
actions: ["invokeOnClose"]
|
|
845
|
+
}
|
|
846
|
+
],
|
|
847
|
+
CLOSE: {
|
|
848
|
+
target: "idle",
|
|
849
|
+
actions: ["invokeOnClose"]
|
|
728
850
|
}
|
|
729
851
|
}
|
|
730
852
|
},
|
|
731
|
-
dragging: {
|
|
853
|
+
"open:dragging": {
|
|
854
|
+
tags: ["open"],
|
|
732
855
|
exit: ["clearActiveChannel"],
|
|
733
|
-
activities: ["trackPointerMove", "disableTextSelection"],
|
|
856
|
+
activities: ["trackPointerMove", "disableTextSelection", "trackPositioning", "trackDismissableElement"],
|
|
734
857
|
on: {
|
|
735
858
|
"AREA.POINTER_MOVE": {
|
|
736
|
-
actions: ["setAreaColorFromPoint"]
|
|
859
|
+
actions: ["setAreaColorFromPoint", "focusAreaThumb"]
|
|
737
860
|
},
|
|
738
861
|
"AREA.POINTER_UP": {
|
|
739
|
-
target: "
|
|
862
|
+
target: "open",
|
|
740
863
|
actions: ["invokeOnChangeEnd"]
|
|
741
864
|
},
|
|
742
865
|
"CHANNEL_SLIDER.POINTER_MOVE": {
|
|
743
|
-
actions: ["setChannelColorFromPoint"]
|
|
866
|
+
actions: ["setChannelColorFromPoint", "focusChannelThumb"]
|
|
744
867
|
},
|
|
745
868
|
"CHANNEL_SLIDER.POINTER_UP": {
|
|
746
|
-
target: "
|
|
869
|
+
target: "open",
|
|
747
870
|
actions: ["invokeOnChangeEnd"]
|
|
871
|
+
},
|
|
872
|
+
INTERACT_OUTSIDE: [
|
|
873
|
+
{
|
|
874
|
+
guard: "shouldRestoreFocus",
|
|
875
|
+
target: "focused",
|
|
876
|
+
actions: ["setReturnFocus", "invokeOnClose"]
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
target: "idle",
|
|
880
|
+
actions: ["invokeOnClose"]
|
|
881
|
+
}
|
|
882
|
+
],
|
|
883
|
+
CLOSE: {
|
|
884
|
+
target: "idle",
|
|
885
|
+
actions: ["invokeOnClose"]
|
|
748
886
|
}
|
|
749
887
|
}
|
|
750
888
|
}
|
|
751
889
|
}
|
|
752
890
|
},
|
|
753
891
|
{
|
|
892
|
+
guards: {
|
|
893
|
+
isTargetFocusable: (_ctx, evt) => evt.restoreFocus
|
|
894
|
+
},
|
|
754
895
|
activities: {
|
|
896
|
+
trackPositioning(ctx2) {
|
|
897
|
+
ctx2.currentPlacement = ctx2.positioning.placement;
|
|
898
|
+
const anchorEl = dom.getTriggerEl(ctx2);
|
|
899
|
+
const getPositionerEl = () => dom.getPositionerEl(ctx2);
|
|
900
|
+
return getPlacement(anchorEl, getPositionerEl, {
|
|
901
|
+
...ctx2.positioning,
|
|
902
|
+
defer: true,
|
|
903
|
+
onComplete(data) {
|
|
904
|
+
ctx2.currentPlacement = data.placement;
|
|
905
|
+
},
|
|
906
|
+
onCleanup() {
|
|
907
|
+
ctx2.currentPlacement = void 0;
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
},
|
|
911
|
+
trackDismissableElement(ctx2, _evt, { send }) {
|
|
912
|
+
const getContentEl = () => dom.getContentEl(ctx2);
|
|
913
|
+
let restoreFocus = true;
|
|
914
|
+
return trackDismissableElement(getContentEl, {
|
|
915
|
+
exclude: dom.getTriggerEl(ctx2),
|
|
916
|
+
defer: true,
|
|
917
|
+
onInteractOutside(event) {
|
|
918
|
+
ctx2.onInteractOutside?.(event);
|
|
919
|
+
if (event.defaultPrevented)
|
|
920
|
+
return;
|
|
921
|
+
restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
|
|
922
|
+
},
|
|
923
|
+
onPointerDownOutside: ctx2.onPointerDownOutside,
|
|
924
|
+
onFocusOutside: ctx2.onFocusOutside,
|
|
925
|
+
onDismiss() {
|
|
926
|
+
send({ type: "INTERACT_OUTSIDE", restoreFocus });
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
},
|
|
755
930
|
trackFormControl(ctx2, _evt, { send, initialContext }) {
|
|
756
931
|
const inputEl = dom.getHiddenInputEl(ctx2);
|
|
757
932
|
return trackFormControl(inputEl, {
|
|
@@ -787,20 +962,18 @@ function machine(userContext) {
|
|
|
787
962
|
const win = dom.getWin(ctx2);
|
|
788
963
|
const picker = new win.EyeDropper();
|
|
789
964
|
picker.open().then(({ sRGBHex }) => {
|
|
790
|
-
const format = ctx2.
|
|
791
|
-
const color =
|
|
965
|
+
const format = ctx2.value.getFormat();
|
|
966
|
+
const color = parseColor4(sRGBHex).toFormat(format);
|
|
792
967
|
set.value(ctx2, color);
|
|
793
|
-
ctx2.onValueChangeEnd?.({ value: ctx2.value,
|
|
968
|
+
ctx2.onValueChangeEnd?.({ value: ctx2.value, valueAsString: ctx2.valueAsString });
|
|
794
969
|
}).catch(() => void 0);
|
|
795
970
|
},
|
|
796
971
|
setActiveChannel(ctx2, evt) {
|
|
797
972
|
ctx2.activeId = evt.id;
|
|
798
|
-
if (evt.channel)
|
|
973
|
+
if (evt.channel)
|
|
799
974
|
ctx2.activeChannel = evt.channel;
|
|
800
|
-
|
|
801
|
-
if (evt.orientation) {
|
|
975
|
+
if (evt.orientation)
|
|
802
976
|
ctx2.activeOrientation = evt.orientation;
|
|
803
|
-
}
|
|
804
977
|
},
|
|
805
978
|
clearActiveChannel(ctx2) {
|
|
806
979
|
ctx2.activeChannel = null;
|
|
@@ -812,10 +985,9 @@ function machine(userContext) {
|
|
|
812
985
|
const percent = dom.getAreaValueFromPoint(ctx2, evt.point);
|
|
813
986
|
if (!percent)
|
|
814
987
|
return;
|
|
815
|
-
const
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
return;
|
|
988
|
+
const xValue = ctx2.value.getChannelPercentValue(xChannel, percent.x);
|
|
989
|
+
const yValue = ctx2.value.getChannelPercentValue(yChannel, 1 - percent.y);
|
|
990
|
+
const color = ctx2.value.withChannelValue(xChannel, xValue).withChannelValue(yChannel, yValue);
|
|
819
991
|
set.value(ctx2, color);
|
|
820
992
|
},
|
|
821
993
|
setChannelColorFromPoint(ctx2, evt) {
|
|
@@ -823,24 +995,17 @@ function machine(userContext) {
|
|
|
823
995
|
const percent = dom.getChannelSliderValueFromPoint(ctx2, evt.point, channel);
|
|
824
996
|
if (!percent)
|
|
825
997
|
return;
|
|
826
|
-
const { minValue, maxValue, step } = ctx2.valueAsColor.getChannelRange(channel);
|
|
827
998
|
const orientation = ctx2.activeOrientation || "horizontal";
|
|
828
|
-
const
|
|
829
|
-
const
|
|
830
|
-
const
|
|
831
|
-
|
|
832
|
-
set.value(ctx2, newColor);
|
|
999
|
+
const channelPercent = orientation === "horizontal" ? percent.x : percent.y;
|
|
1000
|
+
const value = ctx2.value.getChannelPercentValue(channel, channelPercent);
|
|
1001
|
+
const color = ctx2.value.withChannelValue(channel, value);
|
|
1002
|
+
set.value(ctx2, color);
|
|
833
1003
|
},
|
|
834
1004
|
setValue(ctx2, evt) {
|
|
835
1005
|
set.value(ctx2, evt.value);
|
|
836
1006
|
},
|
|
837
1007
|
syncInputElements(ctx2) {
|
|
838
|
-
|
|
839
|
-
inputs.forEach((input) => {
|
|
840
|
-
const channel = input.dataset.channel;
|
|
841
|
-
dom.setValue(input, getChannelInputValue(ctx2.valueAsColor, channel));
|
|
842
|
-
});
|
|
843
|
-
dom.setValue(dom.getHiddenInputEl(ctx2), ctx2.value);
|
|
1008
|
+
sync.inputs(ctx2);
|
|
844
1009
|
},
|
|
845
1010
|
invokeOnChangeEnd(ctx2) {
|
|
846
1011
|
invoke.changeEnd(ctx2);
|
|
@@ -848,112 +1013,133 @@ function machine(userContext) {
|
|
|
848
1013
|
setChannelColorFromInput(ctx2, evt) {
|
|
849
1014
|
const { channel, isTextField, value } = evt;
|
|
850
1015
|
if (channel === "alpha") {
|
|
851
|
-
const
|
|
852
|
-
set.value(ctx2,
|
|
1016
|
+
const newColor = ctx2.value.withChannelValue("alpha", parseFloat(value));
|
|
1017
|
+
set.value(ctx2, newColor);
|
|
853
1018
|
return;
|
|
854
1019
|
}
|
|
855
1020
|
if (isTextField) {
|
|
856
1021
|
const format = "hsl";
|
|
857
|
-
const currentAlpha = ctx2.
|
|
858
|
-
const
|
|
859
|
-
() =>
|
|
860
|
-
() => ctx2.
|
|
1022
|
+
const currentAlpha = ctx2.value.getChannelValue("alpha");
|
|
1023
|
+
const color2 = tryCatch(
|
|
1024
|
+
() => parseColor4(value).toFormat(format).withChannelValue("alpha", currentAlpha),
|
|
1025
|
+
() => ctx2.value
|
|
861
1026
|
);
|
|
862
1027
|
const inputEl = dom.getChannelInputEl(ctx2, channel);
|
|
863
|
-
dom.setValue(inputEl,
|
|
864
|
-
set.value(ctx2,
|
|
1028
|
+
dom.setValue(inputEl, getChannelValue(color2, channel));
|
|
1029
|
+
set.value(ctx2, color2);
|
|
865
1030
|
return;
|
|
866
1031
|
}
|
|
867
|
-
const
|
|
868
|
-
set.value(ctx2,
|
|
1032
|
+
const color = ctx2.value.withChannelValue(channel, value);
|
|
1033
|
+
set.value(ctx2, color);
|
|
869
1034
|
},
|
|
870
1035
|
incrementChannel(ctx2, evt) {
|
|
871
|
-
const
|
|
872
|
-
const channelValue = ctx2.valueAsColor.getChannelValue(evt.channel);
|
|
873
|
-
const value = snapValueToStep2(channelValue + evt.step, minValue, maxValue, step);
|
|
874
|
-
const color = ctx2.valueAsColor.withChannelValue(evt.channel, clampValue(value, minValue, maxValue));
|
|
1036
|
+
const color = ctx2.value.incrementChannel(evt.channel, evt.step);
|
|
875
1037
|
set.value(ctx2, color);
|
|
876
1038
|
},
|
|
877
1039
|
decrementChannel(ctx2, evt) {
|
|
878
|
-
const
|
|
879
|
-
const channelValue = ctx2.valueAsColor.getChannelValue(evt.channel);
|
|
880
|
-
const value = snapValueToStep2(channelValue - evt.step, minValue, maxValue, step);
|
|
881
|
-
const color = ctx2.valueAsColor.withChannelValue(evt.channel, clampValue(value, minValue, maxValue));
|
|
1040
|
+
const color = ctx2.value.decrementChannel(evt.channel, evt.step);
|
|
882
1041
|
set.value(ctx2, color);
|
|
883
1042
|
},
|
|
884
1043
|
incrementXChannel(ctx2, evt) {
|
|
885
|
-
const { xChannel
|
|
886
|
-
const
|
|
887
|
-
const color = ctx2.valueAsColor.withChannelValue(xChannel, incrementX(evt.step));
|
|
1044
|
+
const { xChannel } = evt.channel;
|
|
1045
|
+
const color = ctx2.value.incrementChannel(xChannel, evt.step);
|
|
888
1046
|
set.value(ctx2, color);
|
|
889
1047
|
},
|
|
890
1048
|
decrementXChannel(ctx2, evt) {
|
|
891
|
-
const { xChannel
|
|
892
|
-
const
|
|
893
|
-
const color = ctx2.valueAsColor.withChannelValue(xChannel, decrementX(evt.step));
|
|
1049
|
+
const { xChannel } = evt.channel;
|
|
1050
|
+
const color = ctx2.value.decrementChannel(xChannel, evt.step);
|
|
894
1051
|
set.value(ctx2, color);
|
|
895
1052
|
},
|
|
896
1053
|
incrementYChannel(ctx2, evt) {
|
|
897
|
-
const {
|
|
898
|
-
const
|
|
899
|
-
const color = ctx2.valueAsColor.withChannelValue(yChannel, incrementY(evt.step));
|
|
1054
|
+
const { yChannel } = evt.channel;
|
|
1055
|
+
const color = ctx2.value.incrementChannel(yChannel, evt.step);
|
|
900
1056
|
set.value(ctx2, color);
|
|
901
1057
|
},
|
|
902
1058
|
decrementYChannel(ctx2, evt) {
|
|
903
|
-
const {
|
|
904
|
-
const
|
|
905
|
-
const color = ctx2.valueAsColor.withChannelValue(yChannel, decrementY(evt.step));
|
|
1059
|
+
const { yChannel } = evt.channel;
|
|
1060
|
+
const color = ctx2.value.decrementChannel(yChannel, evt.step);
|
|
906
1061
|
set.value(ctx2, color);
|
|
907
1062
|
},
|
|
908
1063
|
setChannelToMax(ctx2, evt) {
|
|
909
|
-
const
|
|
910
|
-
const color = ctx2.
|
|
1064
|
+
const range = ctx2.value.getChannelRange(evt.channel);
|
|
1065
|
+
const color = ctx2.value.withChannelValue(evt.channel, range.maxValue);
|
|
911
1066
|
set.value(ctx2, color);
|
|
912
1067
|
},
|
|
913
1068
|
setChannelToMin(ctx2, evt) {
|
|
914
|
-
const
|
|
915
|
-
const color = ctx2.
|
|
1069
|
+
const range = ctx2.value.getChannelRange(evt.channel);
|
|
1070
|
+
const color = ctx2.value.withChannelValue(evt.channel, range.minValue);
|
|
916
1071
|
set.value(ctx2, color);
|
|
917
1072
|
},
|
|
918
1073
|
focusAreaThumb(ctx2) {
|
|
919
|
-
|
|
920
|
-
dom.getAreaThumbEl(ctx2)
|
|
1074
|
+
raf(() => {
|
|
1075
|
+
dom?.focus(ctx2, dom.getAreaThumbEl(ctx2));
|
|
921
1076
|
});
|
|
922
1077
|
},
|
|
923
1078
|
focusChannelThumb(ctx2, evt) {
|
|
924
|
-
|
|
925
|
-
dom.getChannelSliderThumbEl(ctx2, evt.channel)
|
|
1079
|
+
raf(() => {
|
|
1080
|
+
dom?.focus(ctx2, dom.getChannelSliderThumbEl(ctx2, evt.channel));
|
|
926
1081
|
});
|
|
1082
|
+
},
|
|
1083
|
+
setInitialFocus(ctx2) {
|
|
1084
|
+
raf(() => {
|
|
1085
|
+
dom.getInitialFocusEl(ctx2)?.focus({ preventScroll: true });
|
|
1086
|
+
});
|
|
1087
|
+
},
|
|
1088
|
+
setReturnFocus(ctx2) {
|
|
1089
|
+
raf(() => {
|
|
1090
|
+
dom?.focus(ctx2, dom.getTriggerEl(ctx2));
|
|
1091
|
+
});
|
|
1092
|
+
},
|
|
1093
|
+
invokeOnOpen(ctx2) {
|
|
1094
|
+
ctx2.onOpenChange?.({ open: true });
|
|
1095
|
+
},
|
|
1096
|
+
invokeOnClose(ctx2) {
|
|
1097
|
+
ctx2.onOpenChange?.({ open: false });
|
|
1098
|
+
},
|
|
1099
|
+
toggleVisibility(ctx2, _evt, { send }) {
|
|
1100
|
+
send({ type: ctx2.open ? "OPEN" : "CLOSE", src: "controlled" });
|
|
927
1101
|
}
|
|
928
1102
|
}
|
|
929
1103
|
}
|
|
930
1104
|
);
|
|
931
1105
|
}
|
|
1106
|
+
var sync = {
|
|
1107
|
+
inputs(ctx) {
|
|
1108
|
+
const channelInputs = dom.getChannelInputEls(ctx);
|
|
1109
|
+
channelInputs.forEach((inputEl) => {
|
|
1110
|
+
const channel = inputEl.dataset.channel;
|
|
1111
|
+
dom.setValue(inputEl, getChannelValue(ctx.value, channel));
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
932
1115
|
var invoke = {
|
|
933
1116
|
changeEnd(ctx) {
|
|
934
1117
|
ctx.onValueChangeEnd?.({
|
|
935
1118
|
value: ctx.value,
|
|
936
|
-
|
|
1119
|
+
valueAsString: ctx.valueAsString
|
|
937
1120
|
});
|
|
938
1121
|
},
|
|
939
1122
|
change(ctx) {
|
|
940
1123
|
ctx.onValueChange?.({
|
|
941
1124
|
value: ctx.value,
|
|
942
|
-
|
|
1125
|
+
valueAsString: ctx.valueAsString
|
|
943
1126
|
});
|
|
1127
|
+
dispatchInputValueEvent(dom.getHiddenInputEl(ctx), { value: ctx.valueAsString });
|
|
944
1128
|
}
|
|
945
1129
|
};
|
|
946
1130
|
var set = {
|
|
947
1131
|
value(ctx, color) {
|
|
948
|
-
|
|
1132
|
+
sync.inputs(ctx);
|
|
1133
|
+
if (!color || ctx.value.isEqual(color))
|
|
949
1134
|
return;
|
|
950
|
-
ctx.value = color
|
|
1135
|
+
ctx.value = ref2(color);
|
|
951
1136
|
invoke.change(ctx);
|
|
952
1137
|
}
|
|
953
1138
|
};
|
|
954
1139
|
export {
|
|
955
1140
|
anatomy,
|
|
956
1141
|
connect,
|
|
957
|
-
machine
|
|
1142
|
+
machine,
|
|
1143
|
+
parse
|
|
958
1144
|
};
|
|
959
1145
|
//# sourceMappingURL=index.mjs.map
|