@udixio/ui-react 2.9.12 → 2.9.14

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/index.cjs +3 -3
  3. package/dist/index.js +2261 -1808
  4. package/dist/lib/components/Button.d.ts.map +1 -1
  5. package/dist/lib/components/Card.d.ts +2 -2
  6. package/dist/lib/components/Card.d.ts.map +1 -1
  7. package/dist/lib/components/Checkbox.d.ts +15 -0
  8. package/dist/lib/components/Checkbox.d.ts.map +1 -0
  9. package/dist/lib/components/DatePicker.d.ts +9 -0
  10. package/dist/lib/components/DatePicker.d.ts.map +1 -0
  11. package/dist/lib/components/FabMenu.d.ts.map +1 -1
  12. package/dist/lib/components/IconButton.d.ts.map +1 -1
  13. package/dist/lib/components/Slider.d.ts.map +1 -1
  14. package/dist/lib/components/Switch.d.ts.map +1 -1
  15. package/dist/lib/components/TabGroup.d.ts +1 -0
  16. package/dist/lib/components/TabGroup.d.ts.map +1 -1
  17. package/dist/lib/components/TabGroupContext.d.ts +1 -0
  18. package/dist/lib/components/TabGroupContext.d.ts.map +1 -1
  19. package/dist/lib/components/TabPanel.d.ts +1 -0
  20. package/dist/lib/components/TabPanel.d.ts.map +1 -1
  21. package/dist/lib/components/TabPanels.d.ts +1 -0
  22. package/dist/lib/components/TabPanels.d.ts.map +1 -1
  23. package/dist/lib/components/TextField.d.ts +4 -4
  24. package/dist/lib/components/TextField.d.ts.map +1 -1
  25. package/dist/lib/components/index.d.ts +2 -0
  26. package/dist/lib/components/index.d.ts.map +1 -1
  27. package/dist/lib/effects/State.d.ts +3 -1
  28. package/dist/lib/effects/State.d.ts.map +1 -1
  29. package/dist/lib/interfaces/card.interface.d.ts +1 -1
  30. package/dist/lib/interfaces/card.interface.d.ts.map +1 -1
  31. package/dist/lib/interfaces/checkbox.interface.d.ts +38 -0
  32. package/dist/lib/interfaces/checkbox.interface.d.ts.map +1 -0
  33. package/dist/lib/interfaces/date-picker.interface.d.ts +67 -0
  34. package/dist/lib/interfaces/date-picker.interface.d.ts.map +1 -0
  35. package/dist/lib/interfaces/icon-button.interface.d.ts +2 -1
  36. package/dist/lib/interfaces/icon-button.interface.d.ts.map +1 -1
  37. package/dist/lib/interfaces/index.d.ts +1 -0
  38. package/dist/lib/interfaces/index.d.ts.map +1 -1
  39. package/dist/lib/interfaces/text-field.interface.d.ts +7 -4
  40. package/dist/lib/interfaces/text-field.interface.d.ts.map +1 -1
  41. package/dist/lib/styles/card.style.d.ts +3 -3
  42. package/dist/lib/styles/checkbox.style.d.ts +45 -0
  43. package/dist/lib/styles/checkbox.style.d.ts.map +1 -0
  44. package/dist/lib/styles/date-picker.style.d.ts +45 -0
  45. package/dist/lib/styles/date-picker.style.d.ts.map +1 -0
  46. package/dist/lib/styles/icon-button.style.d.ts +10 -4
  47. package/dist/lib/styles/icon-button.style.d.ts.map +1 -1
  48. package/dist/lib/styles/index.d.ts +1 -0
  49. package/dist/lib/styles/index.d.ts.map +1 -1
  50. package/dist/lib/styles/text-field.style.d.ts +18 -9
  51. package/dist/lib/styles/text-field.style.d.ts.map +1 -1
  52. package/package.json +3 -3
  53. package/src/lib/components/Button.tsx +1 -0
  54. package/src/lib/components/Card.tsx +9 -4
  55. package/src/lib/components/Checkbox.tsx +120 -0
  56. package/src/lib/components/DatePicker.tsx +432 -0
  57. package/src/lib/components/FabMenu.tsx +4 -5
  58. package/src/lib/components/IconButton.tsx +9 -7
  59. package/src/lib/components/Slider.tsx +6 -0
  60. package/src/lib/components/Switch.tsx +5 -1
  61. package/src/lib/components/TabGroup.tsx +8 -6
  62. package/src/lib/components/TabGroupContext.tsx +1 -1
  63. package/src/lib/components/TabPanel.tsx +1 -0
  64. package/src/lib/components/TabPanels.tsx +1 -0
  65. package/src/lib/components/TextField.tsx +95 -108
  66. package/src/lib/components/index.ts +2 -0
  67. package/src/lib/effects/State.tsx +4 -1
  68. package/src/lib/interfaces/card.interface.ts +1 -1
  69. package/src/lib/interfaces/checkbox.interface.ts +39 -0
  70. package/src/lib/interfaces/date-picker.interface.ts +79 -0
  71. package/src/lib/interfaces/icon-button.interface.ts +2 -1
  72. package/src/lib/interfaces/index.ts +1 -0
  73. package/src/lib/interfaces/text-field.interface.ts +7 -4
  74. package/src/lib/styles/checkbox.style.ts +64 -0
  75. package/src/lib/styles/date-picker.style.ts +43 -0
  76. package/src/lib/styles/index.ts +1 -0
  77. package/src/lib/styles/text-field.style.ts +2 -2
  78. package/src/stories/containment/card.stories.tsx +1 -1
@@ -11,6 +11,7 @@ export declare const iconButtonStyle: (states: (({
11
11
  variant: any;
12
12
  disabled: any;
13
13
  activated: any;
14
+ title: any;
14
15
  shape: any;
15
16
  allowShapeTransformation: any;
16
17
  transition: any;
@@ -26,6 +27,7 @@ export declare const iconButtonStyle: (states: (({
26
27
  variant: any;
27
28
  disabled: any;
28
29
  activated: any;
30
+ title: any;
29
31
  shape: any;
30
32
  allowShapeTransformation: any;
31
33
  transition: any;
@@ -33,7 +35,7 @@ export declare const iconButtonStyle: (states: (({
33
35
  }) & (({
34
36
  label?: string;
35
37
  children?: string;
36
- icon: import('..').Icon;
38
+ icon?: import('..').Icon;
37
39
  size?: "xSmall" | "small" | "medium" | "large" | "xLarge";
38
40
  width?: "default" | "narrow" | "wide";
39
41
  iconSelected?: import('@fortawesome/fontawesome-svg-core').IconDefinition;
@@ -41,6 +43,7 @@ export declare const iconButtonStyle: (states: (({
41
43
  variant?: import('..').IconButtonVariant;
42
44
  disabled?: boolean;
43
45
  activated?: boolean;
46
+ title?: string | null;
44
47
  shape?: "squared" | "rounded";
45
48
  allowShapeTransformation?: boolean;
46
49
  transition?: import('motion').Transition;
@@ -49,7 +52,7 @@ export declare const iconButtonStyle: (states: (({
49
52
  }) | ({
50
53
  label?: string;
51
54
  children?: string;
52
- icon: import('..').Icon;
55
+ icon?: import('..').Icon;
53
56
  size?: "xSmall" | "small" | "medium" | "large" | "xLarge";
54
57
  width?: "default" | "narrow" | "wide";
55
58
  iconSelected?: import('@fortawesome/fontawesome-svg-core').IconDefinition;
@@ -57,6 +60,7 @@ export declare const iconButtonStyle: (states: (({
57
60
  variant?: import('..').IconButtonVariant;
58
61
  disabled?: boolean;
59
62
  activated?: boolean;
63
+ title?: string | null;
60
64
  shape?: "squared" | "rounded";
61
65
  allowShapeTransformation?: boolean;
62
66
  transition?: import('motion').Transition;
@@ -68,7 +72,7 @@ export declare const iconButtonStyle: (states: (({
68
72
  export declare const useIconButtonStyle: (states: import('..').IconButtonStates & ((({
69
73
  label?: string;
70
74
  children?: string;
71
- icon: import('..').Icon;
75
+ icon?: import('..').Icon;
72
76
  size?: "xSmall" | "small" | "medium" | "large" | "xLarge";
73
77
  width?: "default" | "narrow" | "wide";
74
78
  iconSelected?: import('@fortawesome/fontawesome-svg-core').IconDefinition;
@@ -76,6 +80,7 @@ export declare const useIconButtonStyle: (states: import('..').IconButtonStates
76
80
  variant?: import('..').IconButtonVariant;
77
81
  disabled?: boolean;
78
82
  activated?: boolean;
83
+ title?: string | null;
79
84
  shape?: "squared" | "rounded";
80
85
  allowShapeTransformation?: boolean;
81
86
  transition?: import('motion').Transition;
@@ -84,7 +89,7 @@ export declare const useIconButtonStyle: (states: import('..').IconButtonStates
84
89
  }) | ({
85
90
  label?: string;
86
91
  children?: string;
87
- icon: import('..').Icon;
92
+ icon?: import('..').Icon;
88
93
  size?: "xSmall" | "small" | "medium" | "large" | "xLarge";
89
94
  width?: "default" | "narrow" | "wide";
90
95
  iconSelected?: import('@fortawesome/fontawesome-svg-core').IconDefinition;
@@ -92,6 +97,7 @@ export declare const useIconButtonStyle: (states: import('..').IconButtonStates
92
97
  variant?: import('..').IconButtonVariant;
93
98
  disabled?: boolean;
94
99
  activated?: boolean;
100
+ title?: string | null;
95
101
  shape?: "squared" | "rounded";
96
102
  allowShapeTransformation?: boolean;
97
103
  transition?: import('motion').Transition;
@@ -1 +1 @@
1
- {"version":3,"file":"icon-button.style.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/icon-button.style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,UAAU,CAAC;AAyJlB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0EAG3B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2EAG9B,CAAC"}
1
+ {"version":3,"file":"icon-button.style.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/icon-button.style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,UAAU,CAAC;AAyJlB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0EAG3B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2EAG9B,CAAC"}
@@ -2,6 +2,7 @@ export * from './button.style';
2
2
  export * from './card.style';
3
3
  export * from './carousel-item.style';
4
4
  export * from './carousel.style';
5
+ export * from './checkbox.style';
5
6
  export * from './chip.style';
6
7
  export * from './chips.style';
7
8
  export * from './divider.style';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
@@ -14,47 +14,56 @@ export declare const textFieldStyle: (states: {
14
14
  showSupportingText: any;
15
15
  suffix: any;
16
16
  value: any;
17
+ defaultValue: any;
18
+ id: any;
19
+ style: any;
17
20
  variant: any;
18
21
  type: any;
19
22
  autoComplete: any;
20
- textLine: any;
23
+ multiline: any;
21
24
  } & {
22
25
  placeholder?: string;
23
- name: string;
26
+ name?: string;
24
27
  label: string;
25
28
  disabled?: boolean;
26
29
  errorText?: string | null;
27
30
  supportingText?: string;
28
31
  trailingIcon?: React.ReactElement<typeof import('..').IconButton> | import('..').Icon;
29
32
  leadingIcon?: React.ReactElement<typeof import('..').IconButton> | import('..').Icon;
30
- onChange?: (value: string) => void;
33
+ onChange?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>;
31
34
  showSupportingText?: boolean;
32
35
  suffix?: string;
33
- value: string;
36
+ value?: string;
37
+ defaultValue?: string;
38
+ id?: string;
39
+ style?: React.CSSProperties;
34
40
  variant?: import('..').TextFieldVariant;
35
41
  type?: "text" | "password" | "number";
36
42
  autoComplete?: "on" | "off" | string;
37
- textLine?: "singleLine" | "multiLine" | "textAreas";
43
+ multiline?: boolean;
38
44
  } & import('..').TextFieldStates & {
39
45
  className: string | ClassNameComponent<TextFieldInterface> | undefined;
40
46
  }) => Record<"content" | "input" | "label" | "stateLayer" | "leadingIcon" | "trailingIcon" | "activeIndicator" | "supportingText" | "textField" | "suffix", string>;
41
47
  export declare const useTextFieldStyle: (states: import('..').TextFieldStates & {
42
48
  placeholder?: string;
43
- name: string;
49
+ name?: string;
44
50
  label: string;
45
51
  disabled?: boolean;
46
52
  errorText?: string | null;
47
53
  supportingText?: string;
48
54
  trailingIcon?: React.ReactElement<typeof import('..').IconButton> | import('..').Icon;
49
55
  leadingIcon?: React.ReactElement<typeof import('..').IconButton> | import('..').Icon;
50
- onChange?: (value: string) => void;
56
+ onChange?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>;
51
57
  showSupportingText?: boolean;
52
58
  suffix?: string;
53
- value: string;
59
+ value?: string;
60
+ defaultValue?: string;
61
+ id?: string;
62
+ style?: React.CSSProperties;
54
63
  variant?: import('..').TextFieldVariant;
55
64
  type?: "text" | "password" | "number";
56
65
  autoComplete?: "on" | "off" | string;
57
- textLine?: "singleLine" | "multiLine" | "textAreas";
66
+ multiline?: boolean;
58
67
  } & {
59
68
  className?: string | ClassNameComponent<TextFieldInterface> | undefined;
60
69
  }) => Record<"content" | "input" | "label" | "stateLayer" | "leadingIcon" | "trailingIcon" | "activeIndicator" | "supportingText" | "textField" | "suffix", string>;
@@ -1 +1 @@
1
- {"version":3,"file":"text-field.style.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/text-field.style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAmGnD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mKAG1B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;mKAG7B,CAAC"}
1
+ {"version":3,"file":"text-field.style.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/text-field.style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAmGnD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mKAG1B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;mKAG7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@udixio/ui-react",
3
- "version": "2.9.12",
3
+ "version": "2.9.14",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -37,8 +37,8 @@
37
37
  "devDependencies": {
38
38
  "react": "^19.1.1",
39
39
  "react-dom": "^19.1.1",
40
- "@udixio/theme": "2.1.11",
41
- "@udixio/tailwind": "2.4.11"
40
+ "@udixio/theme": "2.1.13",
41
+ "@udixio/tailwind": "2.4.13"
42
42
  },
43
43
  "repository": {
44
44
  "type": "git",
@@ -1,3 +1,4 @@
1
+
1
2
  import { classNames, ReactProps } from '../utils';
2
3
  import { ButtonInterface } from '../interfaces';
3
4
  import { useButtonStyle } from '../styles';
@@ -9,7 +9,7 @@ import { State } from '../effects';
9
9
  * @status beta
10
10
  * @category Layout
11
11
  * @devx
12
- * - `isInteractive` only adds a state layer; add your own click/role semantics.
12
+ * - `interactive` only adds a state layer; add your own click/role semantics.
13
13
  * @limitations
14
14
  * - No built-in header/actions slots; layout is fully custom via children.
15
15
  */
@@ -17,18 +17,23 @@ export const Card = ({
17
17
  variant = 'outlined',
18
18
  className,
19
19
  children,
20
- isInteractive = false,
20
+ interactive = false,
21
21
  ref,
22
22
  ...rest
23
23
  }: ReactProps<CardInterface>) => {
24
- const styles = useCardStyle({ className, isInteractive, variant, children });
24
+ const styles = useCardStyle({
25
+ className,
26
+ isInteractive: interactive,
27
+ variant,
28
+ children,
29
+ });
25
30
 
26
31
  const defaultRef = useRef<HTMLDivElement>(null);
27
32
  const resolvedRef = ref || defaultRef;
28
33
 
29
34
  return (
30
35
  <div {...rest} ref={resolvedRef} className={styles.card}>
31
- {isInteractive && (
36
+ {interactive && (
32
37
  <State
33
38
  className={styles.stateLayer}
34
39
  colorName={'on-surface'}
@@ -0,0 +1,120 @@
1
+ import React, { useEffect, useId, useState } from 'react';
2
+ import { AnimatePresence, motion } from 'motion/react';
3
+ import { useCheckboxStyle } from '../styles/checkbox.style';
4
+ import { classNames } from '../utils';
5
+ import { ReactProps } from '../utils/component';
6
+ import { CheckboxInterface } from '../interfaces/checkbox.interface';
7
+ import { Icon } from '../icon';
8
+ import { faCheck, faMinus } from '@fortawesome/free-solid-svg-icons';
9
+ import { State } from '../effects';
10
+
11
+ /**
12
+ * Checkboxes allow the user to select one or more items from a set.
13
+ * @status beta
14
+ * @category Selection
15
+ * @devx
16
+ * - Supports controlled (`checked`) and uncontrolled (`defaultChecked`) modes.
17
+ * - Handles `indeterminate` state strictly as visual (updates UI, but underlying input is checked/unchecked based on logic).
18
+ * @a11y
19
+ * - Uses native input for accessibility.
20
+ * - Supports standard keyboard interaction.
21
+ */
22
+ export const Checkbox = ({
23
+ checked: checkedProp,
24
+ defaultChecked,
25
+ indeterminate = false,
26
+ disabled = false,
27
+ error = false,
28
+ onChange,
29
+ id: idProp,
30
+ name,
31
+ value,
32
+ style,
33
+ className,
34
+ ...restProps
35
+ }: ReactProps<CheckboxInterface>) => {
36
+ const generatedId = useId();
37
+ const id = idProp || generatedId;
38
+
39
+ const isControlled = checkedProp !== undefined;
40
+ const [internalChecked, setInternalChecked] = useState(
41
+ defaultChecked ?? false,
42
+ );
43
+ const isChecked = isControlled ? checkedProp : internalChecked;
44
+
45
+ const [isFocused, setIsFocused] = useState(false);
46
+
47
+ const inputRef = React.useRef<HTMLInputElement>(null);
48
+
49
+ // Sync indeterminate state to input element for a11y
50
+ useEffect(() => {
51
+ if (inputRef.current) {
52
+ inputRef.current.indeterminate = indeterminate;
53
+ }
54
+ }, [indeterminate]);
55
+
56
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
57
+ if (disabled) return;
58
+
59
+ if (!isControlled) {
60
+ setInternalChecked(e.target.checked);
61
+ }
62
+
63
+ if (onChange) {
64
+ onChange(e);
65
+ }
66
+ };
67
+
68
+ const styles = useCheckboxStyle({
69
+ isChecked: !!isChecked,
70
+ isIndeterminate: indeterminate,
71
+ isDisabled: disabled,
72
+ isError: error,
73
+ isFocused,
74
+ isHovered: false, // Not used in style logic but requested by strict type if defined in interface? style config keys are flexible usually.
75
+ });
76
+
77
+ return (
78
+ <div
79
+ className={classNames(styles.checkbox, className, 'group/checkbox')}
80
+ style={style}
81
+ >
82
+ <State
83
+ stateClassName={styles.stateLayer}
84
+ colorName={isChecked || indeterminate ? 'primary' : 'on-surface'}
85
+ >
86
+ <input
87
+ ref={inputRef}
88
+ type="checkbox"
89
+ id={id}
90
+ name={name}
91
+ value={value}
92
+ checked={isChecked}
93
+ disabled={disabled}
94
+ onChange={handleChange}
95
+ onFocus={() => setIsFocused(true)}
96
+ onBlur={() => setIsFocused(false)}
97
+ className={styles.input}
98
+ {...(restProps as any)}
99
+ />
100
+ <div className={styles.box}></div>
101
+ <AnimatePresence>
102
+ {(isChecked || indeterminate) && (
103
+ <motion.div
104
+ initial={{ opacity: 0, scale: 0.5 }}
105
+ animate={{ opacity: 1, scale: 1 }}
106
+ exit={{ opacity: 0, scale: 0.5 }}
107
+ transition={{ duration: 0.15 }}
108
+ className={styles.icon}
109
+ >
110
+ <Icon
111
+ icon={indeterminate ? faMinus : faCheck}
112
+ className="size-3.5" // ~14px icon
113
+ />
114
+ </motion.div>
115
+ )}
116
+ </AnimatePresence>
117
+ </State>
118
+ </div>
119
+ );
120
+ };