@yamada-ui/checkbox 0.1.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.
@@ -0,0 +1,448 @@
1
+ import {
2
+ useCheckboxGroupContext
3
+ } from "./chunk-3MZZPRTR.mjs";
4
+
5
+ // src/checkbox.tsx
6
+ import {
7
+ ui,
8
+ useMultiComponentStyle,
9
+ omitThemeProps
10
+ } from "@yamada-ui/core";
11
+ import {
12
+ useFormControl,
13
+ useFormControlProps,
14
+ formControlProperties
15
+ } from "@yamada-ui/form-control";
16
+ import { AnimatePresence, motion } from "@yamada-ui/motion";
17
+ import { trackFocusVisible } from "@yamada-ui/use-focus-visible";
18
+ import {
19
+ cx,
20
+ omitObject,
21
+ pickObject,
22
+ useCallbackRef,
23
+ useSafeLayoutEffect,
24
+ useUpdateEffect,
25
+ handlerAll,
26
+ dataAttr,
27
+ mergeRefs,
28
+ funcAll
29
+ } from "@yamada-ui/utils";
30
+ import {
31
+ cloneElement,
32
+ useCallback,
33
+ useEffect,
34
+ useRef,
35
+ useState,
36
+ forwardRef
37
+ } from "react";
38
+ import { jsx, jsxs } from "react/jsx-runtime";
39
+ var useCheckbox = (props) => {
40
+ const {
41
+ id,
42
+ name,
43
+ value,
44
+ defaultChecked,
45
+ tabIndex,
46
+ required,
47
+ disabled,
48
+ readOnly,
49
+ isIndeterminate,
50
+ ...rest
51
+ } = useFormControlProps(props);
52
+ const [isFocusVisible, setIsFocusVisible] = useState(false);
53
+ const [isFocused, setFocused] = useState(false);
54
+ const [isHovered, setHovered] = useState(false);
55
+ const [isActive, setActive] = useState(false);
56
+ const inputRef = useRef(null);
57
+ const [isLabel, setIsLabel] = useState(true);
58
+ const [isChecked, setIsChecked] = useState(!!defaultChecked);
59
+ const isControlled = props.isChecked !== void 0;
60
+ const checked = isControlled ? props.isChecked : isChecked;
61
+ const onChange = useCallbackRef(
62
+ (ev) => {
63
+ var _a;
64
+ if (readOnly || disabled) {
65
+ ev.preventDefault();
66
+ return;
67
+ }
68
+ if (!isControlled)
69
+ setIsChecked(!checked || isIndeterminate ? true : ev.target.checked);
70
+ (_a = rest.onChange) == null ? void 0 : _a.call(rest, ev);
71
+ },
72
+ [readOnly, disabled, isControlled, checked, isIndeterminate]
73
+ );
74
+ const onBlur = useCallbackRef(rest.onBlur);
75
+ const onFocus = useCallbackRef(rest.onFocus);
76
+ const onKeyDown = useCallback(
77
+ ({ key }) => {
78
+ if (key === " ")
79
+ setActive(true);
80
+ },
81
+ [setActive]
82
+ );
83
+ const onKeyUp = useCallback(
84
+ ({ key }) => {
85
+ if (key === " ")
86
+ setActive(false);
87
+ },
88
+ [setActive]
89
+ );
90
+ useEffect(() => {
91
+ return trackFocusVisible(setIsFocusVisible);
92
+ }, []);
93
+ useSafeLayoutEffect(() => {
94
+ if (inputRef.current)
95
+ inputRef.current.indeterminate = Boolean(isIndeterminate);
96
+ }, [isIndeterminate]);
97
+ useUpdateEffect(() => {
98
+ if (disabled)
99
+ setFocused(false);
100
+ }, [disabled, setFocused]);
101
+ useSafeLayoutEffect(() => {
102
+ var _a;
103
+ if (!((_a = inputRef.current) == null ? void 0 : _a.form))
104
+ return;
105
+ inputRef.current.form.onreset = () => setIsChecked(!!defaultChecked);
106
+ }, []);
107
+ useSafeLayoutEffect(() => {
108
+ if (!inputRef.current)
109
+ return;
110
+ if (inputRef.current.checked !== checked)
111
+ setIsChecked(inputRef.current.checked);
112
+ }, [inputRef.current]);
113
+ const getContainerProps = useCallback(
114
+ (props2 = {}, ref = null) => ({
115
+ ...pickObject(rest, formControlProperties),
116
+ ...props2,
117
+ ref: mergeRefs(ref, (el) => {
118
+ if (el)
119
+ setIsLabel(el.tagName === "LABEL");
120
+ }),
121
+ "data-checked": dataAttr(checked),
122
+ onClick: handlerAll(props2.onClick, () => {
123
+ var _a;
124
+ if (isLabel)
125
+ return;
126
+ (_a = inputRef.current) == null ? void 0 : _a.click();
127
+ requestAnimationFrame(() => {
128
+ var _a2;
129
+ return (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
130
+ });
131
+ })
132
+ }),
133
+ [checked, isLabel, rest]
134
+ );
135
+ const getIconProps = useCallback(
136
+ (props2 = {}, ref = null) => ({
137
+ ...pickObject(rest, formControlProperties),
138
+ ...props2,
139
+ ref,
140
+ "data-active": dataAttr(isActive),
141
+ "data-hover": dataAttr(isHovered),
142
+ "data-checked": dataAttr(checked),
143
+ "data-focus": dataAttr(isFocused),
144
+ "data-focus-visible": dataAttr(isFocused && isFocusVisible),
145
+ "data-indeterminate": dataAttr(isIndeterminate),
146
+ "aria-hidden": true,
147
+ onMouseDown: handlerAll(props2.onMouseDown, (ev) => {
148
+ if (isFocused)
149
+ ev.preventDefault();
150
+ setActive(true);
151
+ }),
152
+ onMouseUp: handlerAll(props2.onMouseUp, () => setActive(false)),
153
+ onMouseEnter: handlerAll(props2.onMouseEnter, () => setHovered(true)),
154
+ onMouseLeave: handlerAll(props2.onMouseLeave, () => setHovered(false))
155
+ }),
156
+ [isActive, checked, isFocused, isHovered, isFocusVisible, isIndeterminate, rest]
157
+ );
158
+ const getInputProps = useCallback(
159
+ (props2 = {}, ref = null) => ({
160
+ ...pickObject(rest, formControlProperties),
161
+ ...props2,
162
+ ref: mergeRefs(inputRef, ref),
163
+ id,
164
+ type: "checkbox",
165
+ name,
166
+ value,
167
+ tabIndex,
168
+ required,
169
+ disabled,
170
+ readOnly,
171
+ checked,
172
+ style: {
173
+ border: "0px",
174
+ clip: "rect(0px, 0px, 0px, 0px)",
175
+ height: "1px",
176
+ width: "1px",
177
+ margin: "-1px",
178
+ padding: "0px",
179
+ overflow: "hidden",
180
+ whiteSpace: "nowrap",
181
+ position: "absolute"
182
+ },
183
+ onChange: handlerAll(props2.onChange, onChange),
184
+ onBlur: handlerAll(props2.onBlur, onBlur, () => setFocused(false)),
185
+ onFocus: handlerAll(props2.onFocus, onFocus, () => setFocused(true)),
186
+ onKeyDown: handlerAll(props2.onKeyDown, onKeyDown),
187
+ onKeyUp: handlerAll(props2.onKeyUp, onKeyUp)
188
+ }),
189
+ [
190
+ rest,
191
+ id,
192
+ name,
193
+ value,
194
+ tabIndex,
195
+ required,
196
+ disabled,
197
+ readOnly,
198
+ checked,
199
+ onChange,
200
+ onBlur,
201
+ onFocus,
202
+ onKeyDown,
203
+ onKeyUp
204
+ ]
205
+ );
206
+ const getLabelProps = useCallback(
207
+ (props2 = {}, ref = null) => ({
208
+ ...pickObject(rest, formControlProperties),
209
+ ...props2,
210
+ ref,
211
+ "data-checked": dataAttr(checked),
212
+ onMouseDown: handlerAll(props2.onMouseDown, (ev) => {
213
+ ev.preventDefault();
214
+ ev.stopPropagation();
215
+ }),
216
+ onTouchStart: handlerAll(props2.onTouchStart, (ev) => {
217
+ ev.preventDefault();
218
+ ev.stopPropagation();
219
+ })
220
+ }),
221
+ [checked, rest]
222
+ );
223
+ return {
224
+ isFocusVisible,
225
+ isFocused,
226
+ isHovered,
227
+ isActive,
228
+ isChecked: checked,
229
+ isIndeterminate,
230
+ getContainerProps,
231
+ getIconProps,
232
+ getInputProps,
233
+ getLabelProps
234
+ };
235
+ };
236
+ var Checkbox = forwardRef(
237
+ (props, ref) => {
238
+ var _a, _b, _c, _d, _e;
239
+ const group = useCheckboxGroupContext();
240
+ const control = useFormControl(props);
241
+ const [styles, mergedProps] = useMultiComponentStyle("Checkbox", {
242
+ ...group ? omitObject(group, ["value"]) : {},
243
+ ...props
244
+ });
245
+ const {
246
+ className,
247
+ gap = "0.5rem",
248
+ isRequired = (_a = group == null ? void 0 : group.isRequired) != null ? _a : control.isRequired,
249
+ isReadOnly = (_b = group == null ? void 0 : group.isReadOnly) != null ? _b : control.isReadOnly,
250
+ isDisabled = (_c = group == null ? void 0 : group.isDisabled) != null ? _c : control.isDisabled,
251
+ isInvalid = (_d = group == null ? void 0 : group.isInvalid) != null ? _d : control.isInvalid,
252
+ iconProps,
253
+ inputProps,
254
+ labelProps,
255
+ children,
256
+ ...rest
257
+ } = omitThemeProps(mergedProps);
258
+ const {
259
+ isChecked,
260
+ isIndeterminate,
261
+ getContainerProps,
262
+ getInputProps,
263
+ getIconProps,
264
+ getLabelProps
265
+ } = useCheckbox({
266
+ ...rest,
267
+ isRequired,
268
+ isReadOnly,
269
+ isDisabled,
270
+ isInvalid,
271
+ isChecked: (group == null ? void 0 : group.value) && rest.value ? group.value.includes(rest.value) : rest.isChecked,
272
+ onChange: (group == null ? void 0 : group.onChange) && rest.value ? funcAll(group.onChange, rest.onChange) : rest.onChange
273
+ });
274
+ const cloneIcon = cloneElement((_e = iconProps == null ? void 0 : iconProps.children) != null ? _e : /* @__PURE__ */ jsx(CheckboxIcon, {}), {
275
+ __css: {
276
+ opacity: isChecked || isIndeterminate ? 1 : 0,
277
+ transform: isChecked || isIndeterminate ? "scale(1)" : "scale(0.95)",
278
+ transitionProperty: "transform",
279
+ transitionDuration: "normal"
280
+ },
281
+ isIndeterminate,
282
+ isChecked,
283
+ isRequired,
284
+ isReadOnly,
285
+ isDisabled,
286
+ isInvalid
287
+ });
288
+ return /* @__PURE__ */ jsxs(
289
+ ui.label,
290
+ {
291
+ className: cx("ui-checkbox", className),
292
+ ...getContainerProps(),
293
+ __css: {
294
+ cursor: "pointer",
295
+ position: "relative",
296
+ display: "inline-flex",
297
+ alignItems: "center",
298
+ verticalAlign: "top",
299
+ gap,
300
+ ...styles.container
301
+ },
302
+ ...omitObject(rest, [
303
+ "id",
304
+ "name",
305
+ "value",
306
+ "defaultValue",
307
+ "defaultChecked",
308
+ "isChecked",
309
+ "isIndeterminate",
310
+ "onChange",
311
+ "onBlur",
312
+ "onFocus",
313
+ "tabIndex"
314
+ ]),
315
+ children: [
316
+ /* @__PURE__ */ jsx(ui.input, { className: "ui-checkbox-input", ...getInputProps(inputProps, ref) }),
317
+ /* @__PURE__ */ jsx(
318
+ ui.span,
319
+ {
320
+ className: "ui-checkbox-icon",
321
+ __css: {
322
+ pointerEvents: isReadOnly ? "none" : void 0,
323
+ position: "relative",
324
+ display: "inline-block",
325
+ userSelect: "none",
326
+ ...styles.icon
327
+ },
328
+ ...getIconProps(omitObject(iconProps != null ? iconProps : { children: void 0 }, ["children"])),
329
+ children: cloneIcon
330
+ }
331
+ ),
332
+ /* @__PURE__ */ jsx(
333
+ ui.span,
334
+ {
335
+ className: "ui-checkbox-label",
336
+ __css: { ...styles.label },
337
+ ...getLabelProps(labelProps),
338
+ children
339
+ }
340
+ )
341
+ ]
342
+ }
343
+ );
344
+ }
345
+ );
346
+ Checkbox.displayName = "Checkbox";
347
+ var CheckboxIcon = ({
348
+ isIndeterminate,
349
+ isChecked,
350
+ isRequired,
351
+ isReadOnly,
352
+ isDisabled,
353
+ isInvalid,
354
+ ...rest
355
+ }) => {
356
+ return /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: isIndeterminate || isChecked ? /* @__PURE__ */ jsx(
357
+ ui.div,
358
+ {
359
+ __css: {
360
+ position: "absolute",
361
+ top: "50%",
362
+ left: "50%",
363
+ transform: "translate(-50%, -50%)"
364
+ },
365
+ children: /* @__PURE__ */ jsx(
366
+ ui.div,
367
+ {
368
+ as: motion.div,
369
+ variants: {
370
+ unchecked: { scale: 0.5 },
371
+ checked: { scale: 1 }
372
+ },
373
+ initial: "unchecked",
374
+ animate: "checked",
375
+ exit: "unchecked",
376
+ style: {
377
+ display: "flex",
378
+ alignItems: "center",
379
+ justifyContent: "center"
380
+ },
381
+ children: isIndeterminate ? /* @__PURE__ */ jsx(IndeterminateIcon, { ...rest }) : /* @__PURE__ */ jsx(CheckIcon, { ...rest })
382
+ }
383
+ )
384
+ }
385
+ ) : null });
386
+ };
387
+ var CheckIcon = (props) => {
388
+ return /* @__PURE__ */ jsx(
389
+ ui.svg,
390
+ {
391
+ as: motion.svg,
392
+ width: "1.2em",
393
+ viewBox: "0 0 12 10",
394
+ variants: {
395
+ unchecked: {
396
+ opacity: 0,
397
+ strokeDashoffset: 16
398
+ },
399
+ checked: {
400
+ opacity: 1,
401
+ strokeDashoffset: 0,
402
+ transition: { duration: 0.2 }
403
+ }
404
+ },
405
+ style: {
406
+ fill: "none",
407
+ strokeWidth: 2,
408
+ stroke: "currentColor",
409
+ strokeDasharray: 16
410
+ },
411
+ ...props,
412
+ children: /* @__PURE__ */ jsx("polyline", { points: "1.5 6 4.5 9 10.5 1" })
413
+ }
414
+ );
415
+ };
416
+ var IndeterminateIcon = (props) => {
417
+ return /* @__PURE__ */ jsx(
418
+ ui.svg,
419
+ {
420
+ as: motion.svg,
421
+ width: "1.2em",
422
+ viewBox: "0 0 24 24",
423
+ variants: {
424
+ unchecked: {
425
+ scaleX: 0.65,
426
+ opacity: 0
427
+ },
428
+ checked: {
429
+ scaleX: 1,
430
+ opacity: 1,
431
+ transition: {
432
+ scaleX: { duration: 0 },
433
+ opacity: { duration: 0.02 }
434
+ }
435
+ }
436
+ },
437
+ style: { stroke: "currentColor", strokeWidth: 4 },
438
+ ...props,
439
+ children: /* @__PURE__ */ jsx("line", { x1: "21", x2: "3", y1: "12", y2: "12" })
440
+ }
441
+ );
442
+ };
443
+
444
+ export {
445
+ useCheckbox,
446
+ Checkbox,
447
+ CheckboxIcon
448
+ };
@@ -0,0 +1,8 @@
1
+ export { Checkbox, CheckboxIcon, CheckboxIconProps, CheckboxProps, UseCheckboxProps, useCheckbox } from './checkbox.js';
2
+ export { CheckboxGroup, CheckboxGroupProps, UseCheckboxGroupProps, useCheckboxGroup, useCheckboxGroupContext } from './checkbox-group.js';
3
+ import '@yamada-ui/utils';
4
+ import '@yamada-ui/core';
5
+ import '@yamada-ui/form-control';
6
+ import '@yamada-ui/motion';
7
+ import 'react';
8
+ import '@yamada-ui/layouts';