@zag-js/color-picker 0.12.0 → 0.14.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 +51 -37
- package/dist/index.d.ts +51 -37
- package/dist/index.js +98 -51
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -51
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -10
- package/src/color-picker.anatomy.ts +4 -3
- package/src/color-picker.connect.ts +31 -5
- package/src/color-picker.dom.ts +14 -8
- package/src/color-picker.machine.ts +33 -16
- package/src/color-picker.types.ts +57 -44
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { type Color
|
|
1
|
+
import { parseColor, type Color } from "@zag-js/color-utils"
|
|
2
2
|
import { createMachine } from "@zag-js/core"
|
|
3
3
|
import { trackPointerMove } from "@zag-js/dom-event"
|
|
4
4
|
import { raf } from "@zag-js/dom-query"
|
|
5
|
+
import { trackFormControl } from "@zag-js/form-utils"
|
|
5
6
|
import { clampValue, getPercentValue, snapValueToStep } from "@zag-js/numeric-range"
|
|
6
7
|
import { disableTextSelection } from "@zag-js/text-selection"
|
|
7
8
|
import { compact } from "@zag-js/utils"
|
|
@@ -24,12 +25,12 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
24
25
|
activeOrientation: null,
|
|
25
26
|
value: "#D9D9D9",
|
|
26
27
|
...ctx,
|
|
27
|
-
valueAsColor: parseColor(ctx.value || "#D9D9D9"),
|
|
28
28
|
},
|
|
29
29
|
|
|
30
30
|
computed: {
|
|
31
31
|
isRtl: (ctx) => ctx.dir === "rtl",
|
|
32
32
|
isInteractive: (ctx) => !(ctx.disabled || ctx.readOnly),
|
|
33
|
+
valueAsColor: (ctx) => parseColor(ctx.value),
|
|
33
34
|
},
|
|
34
35
|
|
|
35
36
|
on: {
|
|
@@ -38,10 +39,10 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
38
39
|
},
|
|
39
40
|
},
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
activities: ["trackFormControl"],
|
|
42
43
|
|
|
43
44
|
watch: {
|
|
44
|
-
value: ["
|
|
45
|
+
value: ["syncInputElements", "invokeOnChange"],
|
|
45
46
|
},
|
|
46
47
|
|
|
47
48
|
states: {
|
|
@@ -62,6 +63,10 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
62
63
|
target: "dragging",
|
|
63
64
|
actions: ["setActiveChannel", "setChannelColorFromPoint", "focusChannelThumb"],
|
|
64
65
|
},
|
|
66
|
+
"CHANNEL_SLIDER.FOCUS": {
|
|
67
|
+
target: "focused",
|
|
68
|
+
actions: ["setActiveChannel"],
|
|
69
|
+
},
|
|
65
70
|
"CHANNEL_INPUT.FOCUS": {
|
|
66
71
|
target: "focused",
|
|
67
72
|
actions: ["setActiveChannel"],
|
|
@@ -174,6 +179,17 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
174
179
|
isTextField: (_ctx, evt) => !!evt.isTextField,
|
|
175
180
|
},
|
|
176
181
|
activities: {
|
|
182
|
+
trackFormControl(ctx, _evt, { send, initialContext }) {
|
|
183
|
+
const inputEl = dom.getHiddenInputEl(ctx)
|
|
184
|
+
return trackFormControl(inputEl, {
|
|
185
|
+
onFieldsetDisabled() {
|
|
186
|
+
ctx.disabled = true
|
|
187
|
+
},
|
|
188
|
+
onFormReset() {
|
|
189
|
+
send({ type: "VALUE.SET", value: initialContext.value, src: "form.reset" })
|
|
190
|
+
},
|
|
191
|
+
})
|
|
192
|
+
},
|
|
177
193
|
trackPointerMove(ctx, _evt, { send }) {
|
|
178
194
|
return trackPointerMove(dom.getDoc(ctx), {
|
|
179
195
|
onPointerMove({ point }) {
|
|
@@ -224,6 +240,8 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
224
240
|
const { xChannel, yChannel } = evt.channel || ctx.activeChannel
|
|
225
241
|
|
|
226
242
|
const percent = dom.getAreaValueFromPoint(ctx, evt.point)
|
|
243
|
+
if (!percent) return
|
|
244
|
+
|
|
227
245
|
const { getColorFromPoint } = getChannelDetails(ctx.valueAsColor, xChannel, yChannel)
|
|
228
246
|
const color = getColorFromPoint(percent.x, percent.y)
|
|
229
247
|
|
|
@@ -232,7 +250,9 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
232
250
|
},
|
|
233
251
|
setChannelColorFromPoint(ctx, evt) {
|
|
234
252
|
const channel = evt.channel || ctx.activeId
|
|
253
|
+
|
|
235
254
|
const percent = dom.getChannelSliderValueFromPoint(ctx, evt.point, channel)
|
|
255
|
+
if (!percent) return
|
|
236
256
|
|
|
237
257
|
const { minValue, maxValue, step } = ctx.valueAsColor.getChannelRange(channel)
|
|
238
258
|
const orientation = ctx.activeOrientation || "horizontal"
|
|
@@ -248,21 +268,19 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
248
268
|
setValue(ctx, evt) {
|
|
249
269
|
setColor(ctx, evt.value)
|
|
250
270
|
},
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const color = parseColor(ctx.value)
|
|
254
|
-
if (color.isEqual(ctx.valueAsColor)) return
|
|
255
|
-
ctx.valueAsColor = color
|
|
256
|
-
} catch {}
|
|
257
|
-
},
|
|
258
|
-
syncChannelInputs(ctx) {
|
|
271
|
+
syncInputElements(ctx) {
|
|
272
|
+
// sync channel inputs
|
|
259
273
|
const inputs = dom.getChannelInputEls(ctx)
|
|
260
274
|
inputs.forEach((input) => {
|
|
261
|
-
const channel = input.
|
|
275
|
+
const channel = input.dataset.channel as ExtendedColorChannel | null
|
|
262
276
|
if (!channel) return
|
|
263
|
-
|
|
264
|
-
input.value = value.toString()
|
|
277
|
+
input.value = getChannelInputValue(ctx.valueAsColor, channel)
|
|
265
278
|
})
|
|
279
|
+
|
|
280
|
+
// sync hidden input
|
|
281
|
+
const hiddenInput = dom.getHiddenInputEl(ctx)
|
|
282
|
+
if (!hiddenInput) return
|
|
283
|
+
hiddenInput.value = ctx.value
|
|
266
284
|
},
|
|
267
285
|
setChannelColorFromInput(ctx, evt) {
|
|
268
286
|
const { channel, isTextField, value } = evt
|
|
@@ -358,5 +376,4 @@ export function machine(userContext: UserDefinedContext) {
|
|
|
358
376
|
|
|
359
377
|
const setColor = (ctx: MachineContext, color: Color) => {
|
|
360
378
|
ctx.value = color.toString("css")
|
|
361
|
-
ctx.valueAsColor = color
|
|
362
379
|
}
|
|
@@ -39,6 +39,8 @@ type ElementIds = Partial<{
|
|
|
39
39
|
channelSliderThumb(id: ColorChannel): string
|
|
40
40
|
}>
|
|
41
41
|
|
|
42
|
+
export type { Color, ColorAxes, ColorChannel, ColorFormat, ColorType }
|
|
43
|
+
|
|
42
44
|
type PublicContext = CommonProperties & {
|
|
43
45
|
/**
|
|
44
46
|
* The ids of the elements in the color picker. Useful for composition.
|
|
@@ -68,8 +70,54 @@ type PublicContext = CommonProperties & {
|
|
|
68
70
|
* Handler that is called when the user stops dragging.
|
|
69
71
|
*/
|
|
70
72
|
onChangeEnd?: (details: ChangeDetails) => void
|
|
73
|
+
/**
|
|
74
|
+
* The name for the form input
|
|
75
|
+
*/
|
|
76
|
+
name?: string
|
|
71
77
|
}
|
|
72
78
|
|
|
79
|
+
type PrivateContext = Context<{
|
|
80
|
+
/**
|
|
81
|
+
* The id of the thumb that is currently being dragged
|
|
82
|
+
*/
|
|
83
|
+
activeId: string | null
|
|
84
|
+
/**
|
|
85
|
+
* The channel that is currently being interacted with
|
|
86
|
+
*/
|
|
87
|
+
activeChannel: Partial<ColorAxes> | null
|
|
88
|
+
/**
|
|
89
|
+
* The orientation of the channel that is currently being interacted with
|
|
90
|
+
*/
|
|
91
|
+
activeOrientation: Orientation | null
|
|
92
|
+
}>
|
|
93
|
+
|
|
94
|
+
type ComputedContext = Readonly<{
|
|
95
|
+
/**
|
|
96
|
+
* Whether the color picker is in RTL mode
|
|
97
|
+
*/
|
|
98
|
+
isRtl: boolean
|
|
99
|
+
/**
|
|
100
|
+
* Whether the color picker is interactive
|
|
101
|
+
*/
|
|
102
|
+
isInteractive: boolean
|
|
103
|
+
/**
|
|
104
|
+
* The color value as a Color object
|
|
105
|
+
*/
|
|
106
|
+
valueAsColor: Color
|
|
107
|
+
}>
|
|
108
|
+
|
|
109
|
+
export type UserDefinedContext = RequiredBy<PublicContext, "id">
|
|
110
|
+
|
|
111
|
+
export type MachineContext = PublicContext & PrivateContext & ComputedContext
|
|
112
|
+
|
|
113
|
+
export type MachineState = {
|
|
114
|
+
value: "idle" | "focused" | "dragging"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export type State = S.State<MachineContext, MachineState>
|
|
118
|
+
|
|
119
|
+
export type Send = S.Send<S.AnyEventObject>
|
|
120
|
+
|
|
73
121
|
export type PublicApi<T extends PropTypes = PropTypes> = {
|
|
74
122
|
/**
|
|
75
123
|
* Whether the color picker is being dragged
|
|
@@ -83,6 +131,10 @@ export type PublicApi<T extends PropTypes = PropTypes> = {
|
|
|
83
131
|
* The current color value (as a Color object)
|
|
84
132
|
*/
|
|
85
133
|
valueAsColor: Color
|
|
134
|
+
/**
|
|
135
|
+
* The alpha value of the color
|
|
136
|
+
*/
|
|
137
|
+
alpha: number
|
|
86
138
|
/**
|
|
87
139
|
* The current color channels of the color
|
|
88
140
|
*/
|
|
@@ -99,7 +151,12 @@ export type PublicApi<T extends PropTypes = PropTypes> = {
|
|
|
99
151
|
* Function to set the color format
|
|
100
152
|
*/
|
|
101
153
|
setFormat(format: ColorFormat): void
|
|
154
|
+
/**
|
|
155
|
+
* Function to set the color alpha
|
|
156
|
+
*/
|
|
157
|
+
setAlpha(value: number): void
|
|
102
158
|
contentProps: T["element"]
|
|
159
|
+
hiddenInputProps: T["input"]
|
|
103
160
|
getAreaProps(props: ColorAreaProps): T["element"]
|
|
104
161
|
getAreaGradientProps(props: ColorAreaProps): T["element"]
|
|
105
162
|
getAreaThumbProps(props: ColorAreaProps): T["element"]
|
|
@@ -111,47 +168,3 @@ export type PublicApi<T extends PropTypes = PropTypes> = {
|
|
|
111
168
|
getSwatchBackgroundProps(props: ColorSwatchProps): T["element"]
|
|
112
169
|
getSwatchProps(props: ColorSwatchProps): T["element"]
|
|
113
170
|
}
|
|
114
|
-
|
|
115
|
-
type PrivateContext = Context<{
|
|
116
|
-
/**
|
|
117
|
-
* The id of the thumb that is currently being dragged
|
|
118
|
-
*/
|
|
119
|
-
activeId: string | null
|
|
120
|
-
/**
|
|
121
|
-
* The color value as a Color object
|
|
122
|
-
*/
|
|
123
|
-
valueAsColor: Color
|
|
124
|
-
/**
|
|
125
|
-
* The channel that is currently being interacted with
|
|
126
|
-
*/
|
|
127
|
-
activeChannel: Partial<ColorAxes> | null
|
|
128
|
-
/**
|
|
129
|
-
* The orientation of the channel that is currently being interacted with
|
|
130
|
-
*/
|
|
131
|
-
activeOrientation: Orientation | null
|
|
132
|
-
}>
|
|
133
|
-
|
|
134
|
-
type ComputedContext = Readonly<{
|
|
135
|
-
/**
|
|
136
|
-
* Whether the color picker is in RTL mode
|
|
137
|
-
*/
|
|
138
|
-
isRtl: boolean
|
|
139
|
-
/**
|
|
140
|
-
* Whether the color picker is interactive
|
|
141
|
-
*/
|
|
142
|
-
isInteractive: boolean
|
|
143
|
-
}>
|
|
144
|
-
|
|
145
|
-
export type UserDefinedContext = RequiredBy<PublicContext, "id">
|
|
146
|
-
|
|
147
|
-
export type MachineContext = PublicContext & PrivateContext & ComputedContext
|
|
148
|
-
|
|
149
|
-
export type MachineState = {
|
|
150
|
-
value: "idle" | "focused" | "dragging"
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export type State = S.State<MachineContext, MachineState>
|
|
154
|
-
|
|
155
|
-
export type Send = S.Send<S.AnyEventObject>
|
|
156
|
-
|
|
157
|
-
export type { Color, ColorAxes, ColorChannel, ColorFormat, ColorType }
|