@choice-ui/checkbox 0.0.4 → 0.0.6
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.ts +10 -12
- package/dist/index.js +54 -12
- package/dist/index.js.map +1 -1
- package/package.json +10 -12
- package/dist/index.cjs +0 -255
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -39
- package/src/checkbox-label.tsx +0 -33
- package/src/checkbox.tsx +0 -120
- package/src/context.ts +0 -21
- package/src/index.ts +0 -5
- package/src/tv.ts +0 -128
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLProps, ReactNode } from 'react';
|
|
3
3
|
|
|
4
|
+
interface CheckboxIconProps extends Omit<HTMLProps<HTMLDivElement>, "children"> {
|
|
5
|
+
children?: ReactNode | ((props: {
|
|
6
|
+
value?: boolean;
|
|
7
|
+
mixed?: boolean;
|
|
8
|
+
}) => ReactNode);
|
|
9
|
+
}
|
|
10
|
+
declare const CheckboxIcon: react.MemoExoticComponent<react.ForwardRefExoticComponent<Omit<CheckboxIconProps, "ref"> & react.RefAttributes<HTMLDivElement>>>;
|
|
11
|
+
|
|
4
12
|
interface CheckboxLabelProps extends Omit<HTMLProps<HTMLLabelElement>, "htmlFor" | "id" | "disabled"> {
|
|
5
13
|
children: ReactNode;
|
|
6
14
|
}
|
|
@@ -20,20 +28,10 @@ interface CheckboxType {
|
|
|
20
28
|
(props: CheckboxProps & {
|
|
21
29
|
ref?: React.Ref<HTMLInputElement>;
|
|
22
30
|
}): JSX.Element;
|
|
31
|
+
Icon: typeof CheckboxIcon;
|
|
23
32
|
Label: typeof CheckboxLabel;
|
|
24
33
|
displayName?: string;
|
|
25
34
|
}
|
|
26
35
|
declare const Checkbox: CheckboxType;
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
descriptionId?: string;
|
|
30
|
-
disabled?: boolean;
|
|
31
|
-
id: string;
|
|
32
|
-
mixed?: boolean;
|
|
33
|
-
onChange: (value: boolean) => void;
|
|
34
|
-
value?: boolean;
|
|
35
|
-
variant?: "default" | "accent" | "outline";
|
|
36
|
-
}
|
|
37
|
-
declare function useCheckboxContext(): CheckboxContextValue;
|
|
38
|
-
|
|
39
|
-
export { Checkbox, type CheckboxContextValue, type CheckboxLabelProps, type CheckboxProps, useCheckboxContext };
|
|
37
|
+
export { Checkbox, type CheckboxIconProps, type CheckboxLabelProps, type CheckboxProps };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { tcv, tcx } from '@choice-ui/shared';
|
|
2
2
|
import { Indeterminate, Check } from '@choiceform/icons-react';
|
|
3
|
-
import { createContext, memo, forwardRef, useId, useContext } from 'react';
|
|
3
|
+
import { createContext, memo, forwardRef, useId, Children, isValidElement, useContext } from 'react';
|
|
4
4
|
import { useEventCallback } from 'usehooks-ts';
|
|
5
5
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -139,18 +139,50 @@ var checkboxTv = tcv({
|
|
|
139
139
|
focused: false
|
|
140
140
|
}
|
|
141
141
|
});
|
|
142
|
+
var CheckboxIcon = memo(
|
|
143
|
+
forwardRef(function CheckboxIcon2(props, ref) {
|
|
144
|
+
const { className, children, ...rest } = props;
|
|
145
|
+
const { value, mixed, disabled, variant } = useCheckboxContext();
|
|
146
|
+
const tv = checkboxTv({
|
|
147
|
+
type: "checkbox",
|
|
148
|
+
variant,
|
|
149
|
+
disabled,
|
|
150
|
+
checked: value || mixed
|
|
151
|
+
});
|
|
152
|
+
const renderIcon = () => {
|
|
153
|
+
if (typeof children === "function") {
|
|
154
|
+
return children({ value, mixed });
|
|
155
|
+
}
|
|
156
|
+
if (children !== void 0) {
|
|
157
|
+
return children;
|
|
158
|
+
}
|
|
159
|
+
return mixed ? /* @__PURE__ */ jsx(Indeterminate, {}) : value ? /* @__PURE__ */ jsx(Check, {}) : null;
|
|
160
|
+
};
|
|
161
|
+
return /* @__PURE__ */ jsx(
|
|
162
|
+
"div",
|
|
163
|
+
{
|
|
164
|
+
ref,
|
|
165
|
+
className: tcx(tv.box(), className),
|
|
166
|
+
"data-active": value,
|
|
167
|
+
...rest,
|
|
168
|
+
children: renderIcon()
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
})
|
|
172
|
+
);
|
|
173
|
+
CheckboxIcon.displayName = "Checkbox.Icon";
|
|
142
174
|
var CheckboxLabel = memo(
|
|
143
175
|
forwardRef(function CheckboxLabel2(props, ref) {
|
|
144
176
|
const { children, className, ...rest } = props;
|
|
145
177
|
const { id, descriptionId, disabled } = useCheckboxContext();
|
|
146
|
-
const
|
|
178
|
+
const tv = checkboxTv({ disabled });
|
|
147
179
|
return /* @__PURE__ */ jsx(
|
|
148
180
|
"label",
|
|
149
181
|
{
|
|
150
182
|
ref,
|
|
151
183
|
id: descriptionId,
|
|
152
184
|
htmlFor: id,
|
|
153
|
-
className: tcx(
|
|
185
|
+
className: tcx(tv.label(), className),
|
|
154
186
|
...rest,
|
|
155
187
|
children
|
|
156
188
|
}
|
|
@@ -177,11 +209,12 @@ var CheckboxBase = forwardRef(function Checkbox(props, ref) {
|
|
|
177
209
|
} = props;
|
|
178
210
|
const internalId = useId();
|
|
179
211
|
const descriptionId = useId();
|
|
180
|
-
const
|
|
212
|
+
const tv = checkboxTv({
|
|
181
213
|
type: "checkbox",
|
|
182
214
|
variant,
|
|
183
215
|
disabled,
|
|
184
|
-
checked: value,
|
|
216
|
+
checked: value || mixed,
|
|
217
|
+
// mixed state should have same style as checked
|
|
185
218
|
focused
|
|
186
219
|
});
|
|
187
220
|
const handleChange = useEventCallback((e) => {
|
|
@@ -196,12 +229,20 @@ var CheckboxBase = forwardRef(function Checkbox(props, ref) {
|
|
|
196
229
|
}
|
|
197
230
|
onKeyDown?.(e);
|
|
198
231
|
});
|
|
232
|
+
const isIconElement = (child) => isValidElement(child) && (child.type === CheckboxIcon || child.type?.displayName === "Checkbox.Icon");
|
|
233
|
+
const childArray = Children.toArray(children);
|
|
234
|
+
const iconChild = childArray.find(isIconElement);
|
|
235
|
+
const otherChildren = childArray.filter((child) => !isIconElement(child));
|
|
199
236
|
const renderChildren = () => {
|
|
200
|
-
if (
|
|
201
|
-
|
|
237
|
+
if (otherChildren.length === 1) {
|
|
238
|
+
const child = otherChildren[0];
|
|
239
|
+
if (typeof child === "string" || typeof child === "number") {
|
|
240
|
+
return /* @__PURE__ */ jsx(CheckboxLabel, { children: child });
|
|
241
|
+
}
|
|
202
242
|
}
|
|
203
|
-
return
|
|
243
|
+
return otherChildren;
|
|
204
244
|
};
|
|
245
|
+
const renderDefaultIcon = () => /* @__PURE__ */ jsx("div", { className: tv.box(), children: mixed ? /* @__PURE__ */ jsx(Indeterminate, {}) : value ? /* @__PURE__ */ jsx(Check, {}) : null });
|
|
205
246
|
return /* @__PURE__ */ jsx(
|
|
206
247
|
CheckboxContext.Provider,
|
|
207
248
|
{
|
|
@@ -214,13 +255,13 @@ var CheckboxBase = forwardRef(function Checkbox(props, ref) {
|
|
|
214
255
|
variant,
|
|
215
256
|
mixed
|
|
216
257
|
},
|
|
217
|
-
children: /* @__PURE__ */ jsxs("div", { className: tcx(
|
|
258
|
+
children: /* @__PURE__ */ jsxs("div", { className: tcx(tv.root(), className), children: [
|
|
218
259
|
/* @__PURE__ */ jsxs("div", { className: "pointer-events-none relative", children: [
|
|
219
260
|
/* @__PURE__ */ jsx(
|
|
220
261
|
"input",
|
|
221
262
|
{
|
|
222
263
|
ref,
|
|
223
|
-
className:
|
|
264
|
+
className: tv.input(),
|
|
224
265
|
type: "checkbox",
|
|
225
266
|
id: id || internalId,
|
|
226
267
|
checked: value,
|
|
@@ -235,7 +276,7 @@ var CheckboxBase = forwardRef(function Checkbox(props, ref) {
|
|
|
235
276
|
...rest
|
|
236
277
|
}
|
|
237
278
|
),
|
|
238
|
-
|
|
279
|
+
iconChild ?? renderDefaultIcon()
|
|
239
280
|
] }),
|
|
240
281
|
renderChildren()
|
|
241
282
|
] })
|
|
@@ -244,9 +285,10 @@ var CheckboxBase = forwardRef(function Checkbox(props, ref) {
|
|
|
244
285
|
});
|
|
245
286
|
var MemoizedCheckbox = memo(CheckboxBase);
|
|
246
287
|
var Checkbox2 = MemoizedCheckbox;
|
|
288
|
+
Checkbox2.Icon = CheckboxIcon;
|
|
247
289
|
Checkbox2.Label = CheckboxLabel;
|
|
248
290
|
Checkbox2.displayName = "Checkbox";
|
|
249
291
|
|
|
250
|
-
export { Checkbox2 as Checkbox
|
|
292
|
+
export { Checkbox2 as Checkbox };
|
|
251
293
|
//# sourceMappingURL=index.js.map
|
|
252
294
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context.ts","../src/tv.ts","../src/checkbox-label.tsx","../src/checkbox.tsx"],"names":["CheckboxLabel","forwardRef","jsx","tcx","memo","Checkbox"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext } from \"react\"\n\nexport interface CheckboxContextValue {\n descriptionId?: string\n disabled?: boolean\n id: string\n mixed?: boolean\n onChange: (value: boolean) => void\n value?: boolean\n variant?: \"default\" | \"accent\" | \"outline\"\n}\n\nexport const CheckboxContext = createContext<CheckboxContextValue | null>(null)\n\nexport function useCheckboxContext() {\n const context = useContext(CheckboxContext)\n if (!context) {\n throw new Error(\"Checkbox components must be used within a Checkbox component\")\n }\n return context\n}\n","import { tcv } from \"@choice-ui/shared\"\n\nexport const checkboxTv = tcv({\n slots: {\n root: \"flex items-center select-none\",\n box: [\"relative flex size-4 items-center justify-center\", \"border border-solid\"],\n input: \"peer pointer-events-auto absolute inset-0 appearance-none opacity-0\",\n label: \"pl-2\",\n },\n variants: {\n type: {\n checkbox: {\n box: \"rounded-md\",\n },\n radio: {\n box: \"rounded-full\",\n },\n },\n variant: {\n default: {},\n accent: {},\n outline: {},\n },\n checked: {\n true: {},\n false: {},\n },\n disabled: {\n true: {},\n false: {},\n },\n focused: {\n true: {},\n false: {},\n },\n },\n compoundVariants: [\n // 未选中状态\n {\n variant: [\"default\", \"accent\"],\n checked: false,\n disabled: false,\n focused: false,\n class: {\n box: \"bg-secondary-background border-default-boundary\",\n },\n },\n {\n variant: \"outline\",\n checked: false,\n disabled: false,\n focused: false,\n class: {\n box: [\"border-default-foreground\", \"peer-focus-visible:border-selected-boundary\"],\n },\n },\n // 选中状态 - default\n {\n variant: \"default\",\n checked: true,\n disabled: false,\n focused: false,\n class: {\n box: [\n \"bg-secondary-background border-default-boundary\",\n \"peer-focus-visible:border-selected-strong-boundary\",\n ],\n },\n },\n // 选中状态 - accent & outline\n {\n variant: [\"accent\", \"outline\"],\n checked: true,\n disabled: false,\n focused: false,\n class: {\n box: [\n \"bg-accent-background border-selected-strong-boundary text-on-accent-foreground\",\n \"peer-focus-visible:border-selected-strong-boundary\",\n \"peer-focus-visible:text-on-accent-foreground\",\n \"peer-focus-visible:shadow-checked-focused\",\n ],\n },\n },\n {\n variant: [\"default\", \"accent\", \"outline\"],\n checked: false,\n disabled: false,\n focused: true,\n class: {\n box: \"border-selected-boundary\",\n },\n },\n {\n variant: \"default\",\n checked: true,\n disabled: false,\n focused: true,\n class: {\n box: \"border-selected-strong-boundary\",\n },\n },\n {\n variant: [\"accent\", \"outline\"],\n checked: true,\n disabled: false,\n focused: true,\n class: {\n box: \"text-on-accent-foreground border-selected-strong-boundary shadow-checked-focused\",\n },\n },\n {\n variant: [\"accent\", \"outline\", \"default\"],\n disabled: true,\n class: {\n root: \"text-default-background\",\n box: \"border-disabled-background bg-disabled-background\",\n label: \"text-disabled-foreground\",\n },\n },\n ],\n defaultVariants: {\n variant: \"default\",\n checked: false,\n disabled: false,\n focused: false,\n },\n})\n","import { tcx } from \"@choice-ui/shared\"\nimport { forwardRef, HTMLProps, memo, ReactNode } from \"react\"\nimport { useCheckboxContext } from \"./context\"\nimport { checkboxTv } from \"./tv\"\n\nexport interface CheckboxLabelProps extends Omit<\n HTMLProps<HTMLLabelElement>,\n \"htmlFor\" | \"id\" | \"disabled\"\n> {\n children: ReactNode\n}\n\nexport const CheckboxLabel = memo(\n forwardRef<HTMLLabelElement, CheckboxLabelProps>(function CheckboxLabel(props, ref) {\n const { children, className, ...rest } = props\n const { id, descriptionId, disabled } = useCheckboxContext()\n const styles = checkboxTv({ disabled })\n\n return (\n <label\n ref={ref}\n id={descriptionId}\n htmlFor={id}\n className={tcx(styles.label(), className)}\n {...rest}\n >\n {children}\n </label>\n )\n }),\n)\n\nCheckboxLabel.displayName = \"Checkbox.Label\"\n","import { tcx } from \"@choice-ui/shared\"\nimport { Check, Indeterminate } from \"@choiceform/icons-react\"\nimport { forwardRef, HTMLProps, memo, ReactNode, useId } from \"react\"\nimport { useEventCallback } from \"usehooks-ts\"\nimport { CheckboxLabel } from \"./checkbox-label\"\nimport { CheckboxContext } from \"./context\"\nimport { checkboxTv } from \"./tv\"\n\nexport interface CheckboxProps extends Omit<HTMLProps<HTMLInputElement>, \"value\" | \"onChange\"> {\n children?: ReactNode\n className?: string\n focused?: boolean\n mixed?: boolean\n onChange?: (value: boolean) => void\n readOnly?: boolean\n value?: boolean\n variant?: \"default\" | \"accent\" | \"outline\"\n}\n\nconst CheckboxBase = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(props, ref) {\n const {\n value,\n onChange,\n disabled,\n readOnly = false,\n variant = \"default\",\n className,\n focused,\n mixed,\n children,\n id,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedby,\n onKeyDown,\n ...rest\n } = props\n const internalId = useId()\n const descriptionId = useId()\n\n const styles = checkboxTv({\n type: \"checkbox\",\n variant,\n disabled,\n checked: value,\n focused: focused,\n })\n\n const handleChange = useEventCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n if (readOnly) return\n onChange?.(e.target.checked)\n })\n\n const handleKeyDown = useEventCallback((e: React.KeyboardEvent<HTMLInputElement>) => {\n if (readOnly) return\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault()\n onChange?.(!value)\n }\n onKeyDown?.(e)\n })\n\n // 自动将字符串类型的 children 包装成 CheckboxLabel\n const renderChildren = () => {\n if (typeof children === \"string\" || typeof children === \"number\") {\n return <CheckboxLabel>{children}</CheckboxLabel>\n }\n return children\n }\n\n return (\n <CheckboxContext.Provider\n value={{\n value,\n onChange: (val) => onChange?.(val),\n disabled,\n id: id || internalId,\n descriptionId,\n variant,\n mixed,\n }}\n >\n <div className={tcx(styles.root(), className)}>\n <div className=\"pointer-events-none relative\">\n <input\n ref={ref}\n className={styles.input()}\n type=\"checkbox\"\n id={id || internalId}\n checked={value}\n disabled={disabled || readOnly}\n onChange={handleChange}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedby || descriptionId}\n aria-checked={mixed ? \"mixed\" : value}\n aria-disabled={disabled || readOnly}\n role=\"checkbox\"\n onKeyDown={handleKeyDown}\n {...rest}\n />\n\n <div className={styles.box()}>{value && (mixed ? <Indeterminate /> : <Check />)}</div>\n </div>\n\n {renderChildren()}\n </div>\n </CheckboxContext.Provider>\n )\n})\n\nconst MemoizedCheckbox = memo(CheckboxBase) as unknown as CheckboxType\n\ninterface CheckboxType {\n (props: CheckboxProps & { ref?: React.Ref<HTMLInputElement> }): JSX.Element\n Label: typeof CheckboxLabel\n displayName?: string\n}\n\nexport const Checkbox = MemoizedCheckbox as CheckboxType\nCheckbox.Label = CheckboxLabel\nCheckbox.displayName = \"Checkbox\"\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/tv.ts","../src/checkbox-icon.tsx","../src/checkbox-label.tsx","../src/checkbox.tsx"],"names":["CheckboxIcon","memo","forwardRef","CheckboxLabel","jsx","tcx","Indeterminate","Check","Checkbox"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext } from \"react\"\n\nexport interface CheckboxContextValue {\n descriptionId?: string\n disabled?: boolean\n id: string\n mixed?: boolean\n onChange: (value: boolean) => void\n value?: boolean\n variant?: \"default\" | \"accent\" | \"outline\"\n}\n\nexport const CheckboxContext = createContext<CheckboxContextValue | null>(null)\n\nexport function useCheckboxContext() {\n const context = useContext(CheckboxContext)\n if (!context) {\n throw new Error(\"Checkbox components must be used within a Checkbox component\")\n }\n return context\n}\n","import { tcv } from \"@choice-ui/shared\"\n\nexport const checkboxTv = tcv({\n slots: {\n root: \"flex items-center select-none\",\n box: [\"relative flex size-4 items-center justify-center\", \"border border-solid\"],\n input: \"peer pointer-events-auto absolute inset-0 appearance-none opacity-0\",\n label: \"pl-2\",\n },\n variants: {\n type: {\n checkbox: {\n box: \"rounded-md\",\n },\n radio: {\n box: \"rounded-full\",\n },\n },\n variant: {\n default: {},\n accent: {},\n outline: {},\n },\n checked: {\n true: {},\n false: {},\n },\n disabled: {\n true: {},\n false: {},\n },\n focused: {\n true: {},\n false: {},\n },\n },\n compoundVariants: [\n // 未选中状态\n {\n variant: [\"default\", \"accent\"],\n checked: false,\n disabled: false,\n focused: false,\n class: {\n box: \"bg-secondary-background border-default-boundary\",\n },\n },\n {\n variant: \"outline\",\n checked: false,\n disabled: false,\n focused: false,\n class: {\n box: [\"border-default-foreground\", \"peer-focus-visible:border-selected-boundary\"],\n },\n },\n // 选中状态 - default\n {\n variant: \"default\",\n checked: true,\n disabled: false,\n focused: false,\n class: {\n box: [\n \"bg-secondary-background border-default-boundary\",\n \"peer-focus-visible:border-selected-strong-boundary\",\n ],\n },\n },\n // 选中状态 - accent & outline\n {\n variant: [\"accent\", \"outline\"],\n checked: true,\n disabled: false,\n focused: false,\n class: {\n box: [\n \"bg-accent-background border-selected-strong-boundary text-on-accent-foreground\",\n \"peer-focus-visible:border-selected-strong-boundary\",\n \"peer-focus-visible:text-on-accent-foreground\",\n \"peer-focus-visible:shadow-checked-focused\",\n ],\n },\n },\n {\n variant: [\"default\", \"accent\", \"outline\"],\n checked: false,\n disabled: false,\n focused: true,\n class: {\n box: \"border-selected-boundary\",\n },\n },\n {\n variant: \"default\",\n checked: true,\n disabled: false,\n focused: true,\n class: {\n box: \"border-selected-strong-boundary\",\n },\n },\n {\n variant: [\"accent\", \"outline\"],\n checked: true,\n disabled: false,\n focused: true,\n class: {\n box: \"text-on-accent-foreground border-selected-strong-boundary shadow-checked-focused\",\n },\n },\n {\n variant: [\"accent\", \"outline\", \"default\"],\n disabled: true,\n class: {\n root: \"text-default-background\",\n box: \"border-disabled-background bg-disabled-background\",\n label: \"text-disabled-foreground\",\n },\n },\n ],\n defaultVariants: {\n variant: \"default\",\n checked: false,\n disabled: false,\n focused: false,\n },\n})\n","import { tcx } from \"@choice-ui/shared\"\nimport { Check, Indeterminate } from \"@choiceform/icons-react\"\nimport { forwardRef, HTMLProps, memo, ReactNode } from \"react\"\nimport { useCheckboxContext } from \"./context\"\nimport { checkboxTv } from \"./tv\"\n\nexport interface CheckboxIconProps extends Omit<HTMLProps<HTMLDivElement>, \"children\"> {\n children?: ReactNode | ((props: { value?: boolean; mixed?: boolean }) => ReactNode)\n}\n\nexport const CheckboxIcon = memo(\n forwardRef<HTMLDivElement, CheckboxIconProps>(function CheckboxIcon(props, ref) {\n const { className, children, ...rest } = props\n const { value, mixed, disabled, variant } = useCheckboxContext()\n const tv = checkboxTv({\n type: \"checkbox\",\n variant,\n disabled,\n checked: value || mixed,\n })\n\n const renderIcon = () => {\n if (typeof children === \"function\") {\n return children({ value, mixed })\n }\n if (children !== undefined) {\n return children\n }\n return mixed ? <Indeterminate /> : value ? <Check /> : null\n }\n\n return (\n <div\n ref={ref}\n className={tcx(tv.box(), className)}\n data-active={value}\n {...rest}\n >\n {renderIcon()}\n </div>\n )\n }),\n)\n\nCheckboxIcon.displayName = \"Checkbox.Icon\"\n","import { tcx } from \"@choice-ui/shared\"\nimport { forwardRef, HTMLProps, memo, ReactNode } from \"react\"\nimport { useCheckboxContext } from \"./context\"\nimport { checkboxTv } from \"./tv\"\n\nexport interface CheckboxLabelProps extends Omit<\n HTMLProps<HTMLLabelElement>,\n \"htmlFor\" | \"id\" | \"disabled\"\n> {\n children: ReactNode\n}\n\nexport const CheckboxLabel = memo(\n forwardRef<HTMLLabelElement, CheckboxLabelProps>(function CheckboxLabel(props, ref) {\n const { children, className, ...rest } = props\n const { id, descriptionId, disabled } = useCheckboxContext()\n const tv = checkboxTv({ disabled })\n\n return (\n <label\n ref={ref}\n id={descriptionId}\n htmlFor={id}\n className={tcx(tv.label(), className)}\n {...rest}\n >\n {children}\n </label>\n )\n }),\n)\n\nCheckboxLabel.displayName = \"Checkbox.Label\"\n","import { tcx } from \"@choice-ui/shared\"\nimport { Check, Indeterminate } from \"@choiceform/icons-react\"\nimport { Children, forwardRef, HTMLProps, isValidElement, memo, ReactNode, useId } from \"react\"\nimport { useEventCallback } from \"usehooks-ts\"\nimport { CheckboxIcon } from \"./checkbox-icon\"\nimport { CheckboxLabel } from \"./checkbox-label\"\nimport { CheckboxContext } from \"./context\"\nimport { checkboxTv } from \"./tv\"\n\nexport interface CheckboxProps extends Omit<HTMLProps<HTMLInputElement>, \"value\" | \"onChange\"> {\n children?: ReactNode\n className?: string\n focused?: boolean\n mixed?: boolean\n onChange?: (value: boolean) => void\n readOnly?: boolean\n value?: boolean\n variant?: \"default\" | \"accent\" | \"outline\"\n}\n\nconst CheckboxBase = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(props, ref) {\n const {\n value,\n onChange,\n disabled,\n readOnly = false,\n variant = \"default\",\n className,\n focused,\n mixed,\n children,\n id,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedby,\n onKeyDown,\n ...rest\n } = props\n const internalId = useId()\n const descriptionId = useId()\n\n const tv = checkboxTv({\n type: \"checkbox\",\n variant,\n disabled,\n checked: value || mixed, // mixed state should have same style as checked\n focused: focused,\n })\n\n const handleChange = useEventCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n if (readOnly) return\n onChange?.(e.target.checked)\n })\n\n const handleKeyDown = useEventCallback((e: React.KeyboardEvent<HTMLInputElement>) => {\n if (readOnly) return\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault()\n onChange?.(!value)\n }\n onKeyDown?.(e)\n })\n\n // Separate Icon from other children\n const isIconElement = (child: unknown): child is React.ReactElement =>\n isValidElement(child) &&\n (child.type === CheckboxIcon ||\n (child.type as { displayName?: string })?.displayName === \"Checkbox.Icon\")\n\n const childArray = Children.toArray(children)\n const iconChild = childArray.find(isIconElement)\n const otherChildren = childArray.filter((child) => !isIconElement(child))\n\n // Automatically wrap string-type children into CheckboxLabel\n const renderChildren = () => {\n if (otherChildren.length === 1) {\n const child = otherChildren[0]\n if (typeof child === \"string\" || typeof child === \"number\") {\n return <CheckboxLabel>{child}</CheckboxLabel>\n }\n }\n return otherChildren\n }\n\n // Render default icon (used when no custom Checkbox.Icon is provided)\n const renderDefaultIcon = () => (\n <div className={tv.box()}>{mixed ? <Indeterminate /> : value ? <Check /> : null}</div>\n )\n\n return (\n <CheckboxContext.Provider\n value={{\n value,\n onChange: (val) => onChange?.(val),\n disabled,\n id: id || internalId,\n descriptionId,\n variant,\n mixed,\n }}\n >\n <div className={tcx(tv.root(), className)}>\n <div className=\"pointer-events-none relative\">\n <input\n ref={ref}\n className={tv.input()}\n type=\"checkbox\"\n id={id || internalId}\n checked={value}\n disabled={disabled || readOnly}\n onChange={handleChange}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedby || descriptionId}\n aria-checked={mixed ? \"mixed\" : value}\n aria-disabled={disabled || readOnly}\n role=\"checkbox\"\n onKeyDown={handleKeyDown}\n {...rest}\n />\n\n {iconChild ?? renderDefaultIcon()}\n </div>\n\n {renderChildren()}\n </div>\n </CheckboxContext.Provider>\n )\n})\n\nconst MemoizedCheckbox = memo(CheckboxBase) as unknown as CheckboxType\n\ninterface CheckboxType {\n (props: CheckboxProps & { ref?: React.Ref<HTMLInputElement> }): JSX.Element\n Icon: typeof CheckboxIcon\n Label: typeof CheckboxLabel\n displayName?: string\n}\n\nexport const Checkbox = MemoizedCheckbox as CheckboxType\nCheckbox.Icon = CheckboxIcon\nCheckbox.Label = CheckboxLabel\nCheckbox.displayName = \"Checkbox\"\n"]}
|
package/package.json
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@choice-ui/checkbox",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.6",
|
|
4
|
+
"description": "A checkbox component for binary selection with support for checked, unchecked, and indeterminate states",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
7
|
-
"main": "./dist/index.
|
|
8
|
-
"
|
|
9
|
-
"types": "./src/index.ts",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
10
9
|
"files": [
|
|
11
|
-
"dist"
|
|
12
|
-
"src"
|
|
10
|
+
"dist"
|
|
13
11
|
],
|
|
14
12
|
"exports": {
|
|
15
13
|
".": {
|
|
16
|
-
"types": "./
|
|
17
|
-
"import": "./dist/index.js"
|
|
18
|
-
"require": "./dist/index.cjs"
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
19
16
|
}
|
|
20
17
|
},
|
|
21
18
|
"publishConfig": {
|
|
22
19
|
"access": "public"
|
|
23
20
|
},
|
|
24
21
|
"dependencies": {
|
|
22
|
+
"@choice-ui/shared": "^0.0.1",
|
|
25
23
|
"@choiceform/icons-react": "^1.3.8",
|
|
26
|
-
"usehooks-ts": "^3.1.0"
|
|
27
|
-
"@choice-ui/shared": "0.0.1"
|
|
24
|
+
"usehooks-ts": "^3.1.0"
|
|
28
25
|
},
|
|
29
26
|
"devDependencies": {
|
|
30
27
|
"@types/react": "^18.3.12",
|
|
@@ -39,6 +36,7 @@
|
|
|
39
36
|
"react": ">=18.0.0",
|
|
40
37
|
"react-dom": ">=18.0.0"
|
|
41
38
|
},
|
|
39
|
+
"source": "./src/index.ts",
|
|
42
40
|
"scripts": {
|
|
43
41
|
"build": "tsup",
|
|
44
42
|
"build:watch": "tsup --watch",
|
package/dist/index.cjs
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var shared = require('@choice-ui/shared');
|
|
4
|
-
var iconsReact = require('@choiceform/icons-react');
|
|
5
|
-
var react = require('react');
|
|
6
|
-
var usehooksTs = require('usehooks-ts');
|
|
7
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
-
|
|
9
|
-
// src/checkbox.tsx
|
|
10
|
-
var CheckboxContext = react.createContext(null);
|
|
11
|
-
function useCheckboxContext() {
|
|
12
|
-
const context = react.useContext(CheckboxContext);
|
|
13
|
-
if (!context) {
|
|
14
|
-
throw new Error("Checkbox components must be used within a Checkbox component");
|
|
15
|
-
}
|
|
16
|
-
return context;
|
|
17
|
-
}
|
|
18
|
-
var checkboxTv = shared.tcv({
|
|
19
|
-
slots: {
|
|
20
|
-
root: "flex items-center select-none",
|
|
21
|
-
box: ["relative flex size-4 items-center justify-center", "border border-solid"],
|
|
22
|
-
input: "peer pointer-events-auto absolute inset-0 appearance-none opacity-0",
|
|
23
|
-
label: "pl-2"
|
|
24
|
-
},
|
|
25
|
-
variants: {
|
|
26
|
-
type: {
|
|
27
|
-
checkbox: {
|
|
28
|
-
box: "rounded-md"
|
|
29
|
-
},
|
|
30
|
-
radio: {
|
|
31
|
-
box: "rounded-full"
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
variant: {
|
|
35
|
-
default: {},
|
|
36
|
-
accent: {},
|
|
37
|
-
outline: {}
|
|
38
|
-
},
|
|
39
|
-
checked: {
|
|
40
|
-
true: {},
|
|
41
|
-
false: {}
|
|
42
|
-
},
|
|
43
|
-
disabled: {
|
|
44
|
-
true: {},
|
|
45
|
-
false: {}
|
|
46
|
-
},
|
|
47
|
-
focused: {
|
|
48
|
-
true: {},
|
|
49
|
-
false: {}
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
compoundVariants: [
|
|
53
|
-
// 未选中状态
|
|
54
|
-
{
|
|
55
|
-
variant: ["default", "accent"],
|
|
56
|
-
checked: false,
|
|
57
|
-
disabled: false,
|
|
58
|
-
focused: false,
|
|
59
|
-
class: {
|
|
60
|
-
box: "bg-secondary-background border-default-boundary"
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
variant: "outline",
|
|
65
|
-
checked: false,
|
|
66
|
-
disabled: false,
|
|
67
|
-
focused: false,
|
|
68
|
-
class: {
|
|
69
|
-
box: ["border-default-foreground", "peer-focus-visible:border-selected-boundary"]
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
// 选中状态 - default
|
|
73
|
-
{
|
|
74
|
-
variant: "default",
|
|
75
|
-
checked: true,
|
|
76
|
-
disabled: false,
|
|
77
|
-
focused: false,
|
|
78
|
-
class: {
|
|
79
|
-
box: [
|
|
80
|
-
"bg-secondary-background border-default-boundary",
|
|
81
|
-
"peer-focus-visible:border-selected-strong-boundary"
|
|
82
|
-
]
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
// 选中状态 - accent & outline
|
|
86
|
-
{
|
|
87
|
-
variant: ["accent", "outline"],
|
|
88
|
-
checked: true,
|
|
89
|
-
disabled: false,
|
|
90
|
-
focused: false,
|
|
91
|
-
class: {
|
|
92
|
-
box: [
|
|
93
|
-
"bg-accent-background border-selected-strong-boundary text-on-accent-foreground",
|
|
94
|
-
"peer-focus-visible:border-selected-strong-boundary",
|
|
95
|
-
"peer-focus-visible:text-on-accent-foreground",
|
|
96
|
-
"peer-focus-visible:shadow-checked-focused"
|
|
97
|
-
]
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
variant: ["default", "accent", "outline"],
|
|
102
|
-
checked: false,
|
|
103
|
-
disabled: false,
|
|
104
|
-
focused: true,
|
|
105
|
-
class: {
|
|
106
|
-
box: "border-selected-boundary"
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
variant: "default",
|
|
111
|
-
checked: true,
|
|
112
|
-
disabled: false,
|
|
113
|
-
focused: true,
|
|
114
|
-
class: {
|
|
115
|
-
box: "border-selected-strong-boundary"
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
variant: ["accent", "outline"],
|
|
120
|
-
checked: true,
|
|
121
|
-
disabled: false,
|
|
122
|
-
focused: true,
|
|
123
|
-
class: {
|
|
124
|
-
box: "text-on-accent-foreground border-selected-strong-boundary shadow-checked-focused"
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
variant: ["accent", "outline", "default"],
|
|
129
|
-
disabled: true,
|
|
130
|
-
class: {
|
|
131
|
-
root: "text-default-background",
|
|
132
|
-
box: "border-disabled-background bg-disabled-background",
|
|
133
|
-
label: "text-disabled-foreground"
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
],
|
|
137
|
-
defaultVariants: {
|
|
138
|
-
variant: "default",
|
|
139
|
-
checked: false,
|
|
140
|
-
disabled: false,
|
|
141
|
-
focused: false
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
var CheckboxLabel = react.memo(
|
|
145
|
-
react.forwardRef(function CheckboxLabel2(props, ref) {
|
|
146
|
-
const { children, className, ...rest } = props;
|
|
147
|
-
const { id, descriptionId, disabled } = useCheckboxContext();
|
|
148
|
-
const styles = checkboxTv({ disabled });
|
|
149
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
150
|
-
"label",
|
|
151
|
-
{
|
|
152
|
-
ref,
|
|
153
|
-
id: descriptionId,
|
|
154
|
-
htmlFor: id,
|
|
155
|
-
className: shared.tcx(styles.label(), className),
|
|
156
|
-
...rest,
|
|
157
|
-
children
|
|
158
|
-
}
|
|
159
|
-
);
|
|
160
|
-
})
|
|
161
|
-
);
|
|
162
|
-
CheckboxLabel.displayName = "Checkbox.Label";
|
|
163
|
-
var CheckboxBase = react.forwardRef(function Checkbox(props, ref) {
|
|
164
|
-
const {
|
|
165
|
-
value,
|
|
166
|
-
onChange,
|
|
167
|
-
disabled,
|
|
168
|
-
readOnly = false,
|
|
169
|
-
variant = "default",
|
|
170
|
-
className,
|
|
171
|
-
focused,
|
|
172
|
-
mixed,
|
|
173
|
-
children,
|
|
174
|
-
id,
|
|
175
|
-
"aria-label": ariaLabel,
|
|
176
|
-
"aria-describedby": ariaDescribedby,
|
|
177
|
-
onKeyDown,
|
|
178
|
-
...rest
|
|
179
|
-
} = props;
|
|
180
|
-
const internalId = react.useId();
|
|
181
|
-
const descriptionId = react.useId();
|
|
182
|
-
const styles = checkboxTv({
|
|
183
|
-
type: "checkbox",
|
|
184
|
-
variant,
|
|
185
|
-
disabled,
|
|
186
|
-
checked: value,
|
|
187
|
-
focused
|
|
188
|
-
});
|
|
189
|
-
const handleChange = usehooksTs.useEventCallback((e) => {
|
|
190
|
-
if (readOnly) return;
|
|
191
|
-
onChange?.(e.target.checked);
|
|
192
|
-
});
|
|
193
|
-
const handleKeyDown = usehooksTs.useEventCallback((e) => {
|
|
194
|
-
if (readOnly) return;
|
|
195
|
-
if (e.key === " " || e.key === "Enter") {
|
|
196
|
-
e.preventDefault();
|
|
197
|
-
onChange?.(!value);
|
|
198
|
-
}
|
|
199
|
-
onKeyDown?.(e);
|
|
200
|
-
});
|
|
201
|
-
const renderChildren = () => {
|
|
202
|
-
if (typeof children === "string" || typeof children === "number") {
|
|
203
|
-
return /* @__PURE__ */ jsxRuntime.jsx(CheckboxLabel, { children });
|
|
204
|
-
}
|
|
205
|
-
return children;
|
|
206
|
-
};
|
|
207
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
208
|
-
CheckboxContext.Provider,
|
|
209
|
-
{
|
|
210
|
-
value: {
|
|
211
|
-
value,
|
|
212
|
-
onChange: (val) => onChange?.(val),
|
|
213
|
-
disabled,
|
|
214
|
-
id: id || internalId,
|
|
215
|
-
descriptionId,
|
|
216
|
-
variant,
|
|
217
|
-
mixed
|
|
218
|
-
},
|
|
219
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: shared.tcx(styles.root(), className), children: [
|
|
220
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pointer-events-none relative", children: [
|
|
221
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
222
|
-
"input",
|
|
223
|
-
{
|
|
224
|
-
ref,
|
|
225
|
-
className: styles.input(),
|
|
226
|
-
type: "checkbox",
|
|
227
|
-
id: id || internalId,
|
|
228
|
-
checked: value,
|
|
229
|
-
disabled: disabled || readOnly,
|
|
230
|
-
onChange: handleChange,
|
|
231
|
-
"aria-label": ariaLabel,
|
|
232
|
-
"aria-describedby": ariaDescribedby || descriptionId,
|
|
233
|
-
"aria-checked": mixed ? "mixed" : value,
|
|
234
|
-
"aria-disabled": disabled || readOnly,
|
|
235
|
-
role: "checkbox",
|
|
236
|
-
onKeyDown: handleKeyDown,
|
|
237
|
-
...rest
|
|
238
|
-
}
|
|
239
|
-
),
|
|
240
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: styles.box(), children: value && (mixed ? /* @__PURE__ */ jsxRuntime.jsx(iconsReact.Indeterminate, {}) : /* @__PURE__ */ jsxRuntime.jsx(iconsReact.Check, {})) })
|
|
241
|
-
] }),
|
|
242
|
-
renderChildren()
|
|
243
|
-
] })
|
|
244
|
-
}
|
|
245
|
-
);
|
|
246
|
-
});
|
|
247
|
-
var MemoizedCheckbox = react.memo(CheckboxBase);
|
|
248
|
-
var Checkbox2 = MemoizedCheckbox;
|
|
249
|
-
Checkbox2.Label = CheckboxLabel;
|
|
250
|
-
Checkbox2.displayName = "Checkbox";
|
|
251
|
-
|
|
252
|
-
exports.Checkbox = Checkbox2;
|
|
253
|
-
exports.useCheckboxContext = useCheckboxContext;
|
|
254
|
-
//# sourceMappingURL=index.cjs.map
|
|
255
|
-
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context.ts","../src/tv.ts","../src/checkbox-label.tsx","../src/checkbox.tsx"],"names":["createContext","useContext","tcv","memo","forwardRef","CheckboxLabel","jsx","tcx","useId","useEventCallback","jsxs","Indeterminate","Check","Checkbox"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createContext, useContext } from \"react\"\n\nexport interface CheckboxContextValue {\n descriptionId?: string\n disabled?: boolean\n id: string\n mixed?: boolean\n onChange: (value: boolean) => void\n value?: boolean\n variant?: \"default\" | \"accent\" | \"outline\"\n}\n\nexport const CheckboxContext = createContext<CheckboxContextValue | null>(null)\n\nexport function useCheckboxContext() {\n const context = useContext(CheckboxContext)\n if (!context) {\n throw new Error(\"Checkbox components must be used within a Checkbox component\")\n }\n return context\n}\n","import { tcv } from \"@choice-ui/shared\"\n\nexport const checkboxTv = tcv({\n slots: {\n root: \"flex items-center select-none\",\n box: [\"relative flex size-4 items-center justify-center\", \"border border-solid\"],\n input: \"peer pointer-events-auto absolute inset-0 appearance-none opacity-0\",\n label: \"pl-2\",\n },\n variants: {\n type: {\n checkbox: {\n box: \"rounded-md\",\n },\n radio: {\n box: \"rounded-full\",\n },\n },\n variant: {\n default: {},\n accent: {},\n outline: {},\n },\n checked: {\n true: {},\n false: {},\n },\n disabled: {\n true: {},\n false: {},\n },\n focused: {\n true: {},\n false: {},\n },\n },\n compoundVariants: [\n // 未选中状态\n {\n variant: [\"default\", \"accent\"],\n checked: false,\n disabled: false,\n focused: false,\n class: {\n box: \"bg-secondary-background border-default-boundary\",\n },\n },\n {\n variant: \"outline\",\n checked: false,\n disabled: false,\n focused: false,\n class: {\n box: [\"border-default-foreground\", \"peer-focus-visible:border-selected-boundary\"],\n },\n },\n // 选中状态 - default\n {\n variant: \"default\",\n checked: true,\n disabled: false,\n focused: false,\n class: {\n box: [\n \"bg-secondary-background border-default-boundary\",\n \"peer-focus-visible:border-selected-strong-boundary\",\n ],\n },\n },\n // 选中状态 - accent & outline\n {\n variant: [\"accent\", \"outline\"],\n checked: true,\n disabled: false,\n focused: false,\n class: {\n box: [\n \"bg-accent-background border-selected-strong-boundary text-on-accent-foreground\",\n \"peer-focus-visible:border-selected-strong-boundary\",\n \"peer-focus-visible:text-on-accent-foreground\",\n \"peer-focus-visible:shadow-checked-focused\",\n ],\n },\n },\n {\n variant: [\"default\", \"accent\", \"outline\"],\n checked: false,\n disabled: false,\n focused: true,\n class: {\n box: \"border-selected-boundary\",\n },\n },\n {\n variant: \"default\",\n checked: true,\n disabled: false,\n focused: true,\n class: {\n box: \"border-selected-strong-boundary\",\n },\n },\n {\n variant: [\"accent\", \"outline\"],\n checked: true,\n disabled: false,\n focused: true,\n class: {\n box: \"text-on-accent-foreground border-selected-strong-boundary shadow-checked-focused\",\n },\n },\n {\n variant: [\"accent\", \"outline\", \"default\"],\n disabled: true,\n class: {\n root: \"text-default-background\",\n box: \"border-disabled-background bg-disabled-background\",\n label: \"text-disabled-foreground\",\n },\n },\n ],\n defaultVariants: {\n variant: \"default\",\n checked: false,\n disabled: false,\n focused: false,\n },\n})\n","import { tcx } from \"@choice-ui/shared\"\nimport { forwardRef, HTMLProps, memo, ReactNode } from \"react\"\nimport { useCheckboxContext } from \"./context\"\nimport { checkboxTv } from \"./tv\"\n\nexport interface CheckboxLabelProps extends Omit<\n HTMLProps<HTMLLabelElement>,\n \"htmlFor\" | \"id\" | \"disabled\"\n> {\n children: ReactNode\n}\n\nexport const CheckboxLabel = memo(\n forwardRef<HTMLLabelElement, CheckboxLabelProps>(function CheckboxLabel(props, ref) {\n const { children, className, ...rest } = props\n const { id, descriptionId, disabled } = useCheckboxContext()\n const styles = checkboxTv({ disabled })\n\n return (\n <label\n ref={ref}\n id={descriptionId}\n htmlFor={id}\n className={tcx(styles.label(), className)}\n {...rest}\n >\n {children}\n </label>\n )\n }),\n)\n\nCheckboxLabel.displayName = \"Checkbox.Label\"\n","import { tcx } from \"@choice-ui/shared\"\nimport { Check, Indeterminate } from \"@choiceform/icons-react\"\nimport { forwardRef, HTMLProps, memo, ReactNode, useId } from \"react\"\nimport { useEventCallback } from \"usehooks-ts\"\nimport { CheckboxLabel } from \"./checkbox-label\"\nimport { CheckboxContext } from \"./context\"\nimport { checkboxTv } from \"./tv\"\n\nexport interface CheckboxProps extends Omit<HTMLProps<HTMLInputElement>, \"value\" | \"onChange\"> {\n children?: ReactNode\n className?: string\n focused?: boolean\n mixed?: boolean\n onChange?: (value: boolean) => void\n readOnly?: boolean\n value?: boolean\n variant?: \"default\" | \"accent\" | \"outline\"\n}\n\nconst CheckboxBase = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(props, ref) {\n const {\n value,\n onChange,\n disabled,\n readOnly = false,\n variant = \"default\",\n className,\n focused,\n mixed,\n children,\n id,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": ariaDescribedby,\n onKeyDown,\n ...rest\n } = props\n const internalId = useId()\n const descriptionId = useId()\n\n const styles = checkboxTv({\n type: \"checkbox\",\n variant,\n disabled,\n checked: value,\n focused: focused,\n })\n\n const handleChange = useEventCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n if (readOnly) return\n onChange?.(e.target.checked)\n })\n\n const handleKeyDown = useEventCallback((e: React.KeyboardEvent<HTMLInputElement>) => {\n if (readOnly) return\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault()\n onChange?.(!value)\n }\n onKeyDown?.(e)\n })\n\n // 自动将字符串类型的 children 包装成 CheckboxLabel\n const renderChildren = () => {\n if (typeof children === \"string\" || typeof children === \"number\") {\n return <CheckboxLabel>{children}</CheckboxLabel>\n }\n return children\n }\n\n return (\n <CheckboxContext.Provider\n value={{\n value,\n onChange: (val) => onChange?.(val),\n disabled,\n id: id || internalId,\n descriptionId,\n variant,\n mixed,\n }}\n >\n <div className={tcx(styles.root(), className)}>\n <div className=\"pointer-events-none relative\">\n <input\n ref={ref}\n className={styles.input()}\n type=\"checkbox\"\n id={id || internalId}\n checked={value}\n disabled={disabled || readOnly}\n onChange={handleChange}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedby || descriptionId}\n aria-checked={mixed ? \"mixed\" : value}\n aria-disabled={disabled || readOnly}\n role=\"checkbox\"\n onKeyDown={handleKeyDown}\n {...rest}\n />\n\n <div className={styles.box()}>{value && (mixed ? <Indeterminate /> : <Check />)}</div>\n </div>\n\n {renderChildren()}\n </div>\n </CheckboxContext.Provider>\n )\n})\n\nconst MemoizedCheckbox = memo(CheckboxBase) as unknown as CheckboxType\n\ninterface CheckboxType {\n (props: CheckboxProps & { ref?: React.Ref<HTMLInputElement> }): JSX.Element\n Label: typeof CheckboxLabel\n displayName?: string\n}\n\nexport const Checkbox = MemoizedCheckbox as CheckboxType\nCheckbox.Label = CheckboxLabel\nCheckbox.displayName = \"Checkbox\"\n"]}
|
package/dist/index.d.cts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import * as react from 'react';
|
|
2
|
-
import { HTMLProps, ReactNode } from 'react';
|
|
3
|
-
|
|
4
|
-
interface CheckboxLabelProps extends Omit<HTMLProps<HTMLLabelElement>, "htmlFor" | "id" | "disabled"> {
|
|
5
|
-
children: ReactNode;
|
|
6
|
-
}
|
|
7
|
-
declare const CheckboxLabel: react.MemoExoticComponent<react.ForwardRefExoticComponent<Omit<CheckboxLabelProps, "ref"> & react.RefAttributes<HTMLLabelElement>>>;
|
|
8
|
-
|
|
9
|
-
interface CheckboxProps extends Omit<HTMLProps<HTMLInputElement>, "value" | "onChange"> {
|
|
10
|
-
children?: ReactNode;
|
|
11
|
-
className?: string;
|
|
12
|
-
focused?: boolean;
|
|
13
|
-
mixed?: boolean;
|
|
14
|
-
onChange?: (value: boolean) => void;
|
|
15
|
-
readOnly?: boolean;
|
|
16
|
-
value?: boolean;
|
|
17
|
-
variant?: "default" | "accent" | "outline";
|
|
18
|
-
}
|
|
19
|
-
interface CheckboxType {
|
|
20
|
-
(props: CheckboxProps & {
|
|
21
|
-
ref?: React.Ref<HTMLInputElement>;
|
|
22
|
-
}): JSX.Element;
|
|
23
|
-
Label: typeof CheckboxLabel;
|
|
24
|
-
displayName?: string;
|
|
25
|
-
}
|
|
26
|
-
declare const Checkbox: CheckboxType;
|
|
27
|
-
|
|
28
|
-
interface CheckboxContextValue {
|
|
29
|
-
descriptionId?: string;
|
|
30
|
-
disabled?: boolean;
|
|
31
|
-
id: string;
|
|
32
|
-
mixed?: boolean;
|
|
33
|
-
onChange: (value: boolean) => void;
|
|
34
|
-
value?: boolean;
|
|
35
|
-
variant?: "default" | "accent" | "outline";
|
|
36
|
-
}
|
|
37
|
-
declare function useCheckboxContext(): CheckboxContextValue;
|
|
38
|
-
|
|
39
|
-
export { Checkbox, type CheckboxContextValue, type CheckboxLabelProps, type CheckboxProps, useCheckboxContext };
|
package/src/checkbox-label.tsx
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { tcx } from "@choice-ui/shared"
|
|
2
|
-
import { forwardRef, HTMLProps, memo, ReactNode } from "react"
|
|
3
|
-
import { useCheckboxContext } from "./context"
|
|
4
|
-
import { checkboxTv } from "./tv"
|
|
5
|
-
|
|
6
|
-
export interface CheckboxLabelProps extends Omit<
|
|
7
|
-
HTMLProps<HTMLLabelElement>,
|
|
8
|
-
"htmlFor" | "id" | "disabled"
|
|
9
|
-
> {
|
|
10
|
-
children: ReactNode
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const CheckboxLabel = memo(
|
|
14
|
-
forwardRef<HTMLLabelElement, CheckboxLabelProps>(function CheckboxLabel(props, ref) {
|
|
15
|
-
const { children, className, ...rest } = props
|
|
16
|
-
const { id, descriptionId, disabled } = useCheckboxContext()
|
|
17
|
-
const styles = checkboxTv({ disabled })
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<label
|
|
21
|
-
ref={ref}
|
|
22
|
-
id={descriptionId}
|
|
23
|
-
htmlFor={id}
|
|
24
|
-
className={tcx(styles.label(), className)}
|
|
25
|
-
{...rest}
|
|
26
|
-
>
|
|
27
|
-
{children}
|
|
28
|
-
</label>
|
|
29
|
-
)
|
|
30
|
-
}),
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
CheckboxLabel.displayName = "Checkbox.Label"
|
package/src/checkbox.tsx
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { tcx } from "@choice-ui/shared"
|
|
2
|
-
import { Check, Indeterminate } from "@choiceform/icons-react"
|
|
3
|
-
import { forwardRef, HTMLProps, memo, ReactNode, useId } from "react"
|
|
4
|
-
import { useEventCallback } from "usehooks-ts"
|
|
5
|
-
import { CheckboxLabel } from "./checkbox-label"
|
|
6
|
-
import { CheckboxContext } from "./context"
|
|
7
|
-
import { checkboxTv } from "./tv"
|
|
8
|
-
|
|
9
|
-
export interface CheckboxProps extends Omit<HTMLProps<HTMLInputElement>, "value" | "onChange"> {
|
|
10
|
-
children?: ReactNode
|
|
11
|
-
className?: string
|
|
12
|
-
focused?: boolean
|
|
13
|
-
mixed?: boolean
|
|
14
|
-
onChange?: (value: boolean) => void
|
|
15
|
-
readOnly?: boolean
|
|
16
|
-
value?: boolean
|
|
17
|
-
variant?: "default" | "accent" | "outline"
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const CheckboxBase = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(props, ref) {
|
|
21
|
-
const {
|
|
22
|
-
value,
|
|
23
|
-
onChange,
|
|
24
|
-
disabled,
|
|
25
|
-
readOnly = false,
|
|
26
|
-
variant = "default",
|
|
27
|
-
className,
|
|
28
|
-
focused,
|
|
29
|
-
mixed,
|
|
30
|
-
children,
|
|
31
|
-
id,
|
|
32
|
-
"aria-label": ariaLabel,
|
|
33
|
-
"aria-describedby": ariaDescribedby,
|
|
34
|
-
onKeyDown,
|
|
35
|
-
...rest
|
|
36
|
-
} = props
|
|
37
|
-
const internalId = useId()
|
|
38
|
-
const descriptionId = useId()
|
|
39
|
-
|
|
40
|
-
const styles = checkboxTv({
|
|
41
|
-
type: "checkbox",
|
|
42
|
-
variant,
|
|
43
|
-
disabled,
|
|
44
|
-
checked: value,
|
|
45
|
-
focused: focused,
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
const handleChange = useEventCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
|
49
|
-
if (readOnly) return
|
|
50
|
-
onChange?.(e.target.checked)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
const handleKeyDown = useEventCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
54
|
-
if (readOnly) return
|
|
55
|
-
if (e.key === " " || e.key === "Enter") {
|
|
56
|
-
e.preventDefault()
|
|
57
|
-
onChange?.(!value)
|
|
58
|
-
}
|
|
59
|
-
onKeyDown?.(e)
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
// 自动将字符串类型的 children 包装成 CheckboxLabel
|
|
63
|
-
const renderChildren = () => {
|
|
64
|
-
if (typeof children === "string" || typeof children === "number") {
|
|
65
|
-
return <CheckboxLabel>{children}</CheckboxLabel>
|
|
66
|
-
}
|
|
67
|
-
return children
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return (
|
|
71
|
-
<CheckboxContext.Provider
|
|
72
|
-
value={{
|
|
73
|
-
value,
|
|
74
|
-
onChange: (val) => onChange?.(val),
|
|
75
|
-
disabled,
|
|
76
|
-
id: id || internalId,
|
|
77
|
-
descriptionId,
|
|
78
|
-
variant,
|
|
79
|
-
mixed,
|
|
80
|
-
}}
|
|
81
|
-
>
|
|
82
|
-
<div className={tcx(styles.root(), className)}>
|
|
83
|
-
<div className="pointer-events-none relative">
|
|
84
|
-
<input
|
|
85
|
-
ref={ref}
|
|
86
|
-
className={styles.input()}
|
|
87
|
-
type="checkbox"
|
|
88
|
-
id={id || internalId}
|
|
89
|
-
checked={value}
|
|
90
|
-
disabled={disabled || readOnly}
|
|
91
|
-
onChange={handleChange}
|
|
92
|
-
aria-label={ariaLabel}
|
|
93
|
-
aria-describedby={ariaDescribedby || descriptionId}
|
|
94
|
-
aria-checked={mixed ? "mixed" : value}
|
|
95
|
-
aria-disabled={disabled || readOnly}
|
|
96
|
-
role="checkbox"
|
|
97
|
-
onKeyDown={handleKeyDown}
|
|
98
|
-
{...rest}
|
|
99
|
-
/>
|
|
100
|
-
|
|
101
|
-
<div className={styles.box()}>{value && (mixed ? <Indeterminate /> : <Check />)}</div>
|
|
102
|
-
</div>
|
|
103
|
-
|
|
104
|
-
{renderChildren()}
|
|
105
|
-
</div>
|
|
106
|
-
</CheckboxContext.Provider>
|
|
107
|
-
)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
const MemoizedCheckbox = memo(CheckboxBase) as unknown as CheckboxType
|
|
111
|
-
|
|
112
|
-
interface CheckboxType {
|
|
113
|
-
(props: CheckboxProps & { ref?: React.Ref<HTMLInputElement> }): JSX.Element
|
|
114
|
-
Label: typeof CheckboxLabel
|
|
115
|
-
displayName?: string
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export const Checkbox = MemoizedCheckbox as CheckboxType
|
|
119
|
-
Checkbox.Label = CheckboxLabel
|
|
120
|
-
Checkbox.displayName = "Checkbox"
|
package/src/context.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from "react"
|
|
2
|
-
|
|
3
|
-
export interface CheckboxContextValue {
|
|
4
|
-
descriptionId?: string
|
|
5
|
-
disabled?: boolean
|
|
6
|
-
id: string
|
|
7
|
-
mixed?: boolean
|
|
8
|
-
onChange: (value: boolean) => void
|
|
9
|
-
value?: boolean
|
|
10
|
-
variant?: "default" | "accent" | "outline"
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const CheckboxContext = createContext<CheckboxContextValue | null>(null)
|
|
14
|
-
|
|
15
|
-
export function useCheckboxContext() {
|
|
16
|
-
const context = useContext(CheckboxContext)
|
|
17
|
-
if (!context) {
|
|
18
|
-
throw new Error("Checkbox components must be used within a Checkbox component")
|
|
19
|
-
}
|
|
20
|
-
return context
|
|
21
|
-
}
|
package/src/index.ts
DELETED
package/src/tv.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { tcv } from "@choice-ui/shared"
|
|
2
|
-
|
|
3
|
-
export const checkboxTv = tcv({
|
|
4
|
-
slots: {
|
|
5
|
-
root: "flex items-center select-none",
|
|
6
|
-
box: ["relative flex size-4 items-center justify-center", "border border-solid"],
|
|
7
|
-
input: "peer pointer-events-auto absolute inset-0 appearance-none opacity-0",
|
|
8
|
-
label: "pl-2",
|
|
9
|
-
},
|
|
10
|
-
variants: {
|
|
11
|
-
type: {
|
|
12
|
-
checkbox: {
|
|
13
|
-
box: "rounded-md",
|
|
14
|
-
},
|
|
15
|
-
radio: {
|
|
16
|
-
box: "rounded-full",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
variant: {
|
|
20
|
-
default: {},
|
|
21
|
-
accent: {},
|
|
22
|
-
outline: {},
|
|
23
|
-
},
|
|
24
|
-
checked: {
|
|
25
|
-
true: {},
|
|
26
|
-
false: {},
|
|
27
|
-
},
|
|
28
|
-
disabled: {
|
|
29
|
-
true: {},
|
|
30
|
-
false: {},
|
|
31
|
-
},
|
|
32
|
-
focused: {
|
|
33
|
-
true: {},
|
|
34
|
-
false: {},
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
compoundVariants: [
|
|
38
|
-
// 未选中状态
|
|
39
|
-
{
|
|
40
|
-
variant: ["default", "accent"],
|
|
41
|
-
checked: false,
|
|
42
|
-
disabled: false,
|
|
43
|
-
focused: false,
|
|
44
|
-
class: {
|
|
45
|
-
box: "bg-secondary-background border-default-boundary",
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
variant: "outline",
|
|
50
|
-
checked: false,
|
|
51
|
-
disabled: false,
|
|
52
|
-
focused: false,
|
|
53
|
-
class: {
|
|
54
|
-
box: ["border-default-foreground", "peer-focus-visible:border-selected-boundary"],
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
// 选中状态 - default
|
|
58
|
-
{
|
|
59
|
-
variant: "default",
|
|
60
|
-
checked: true,
|
|
61
|
-
disabled: false,
|
|
62
|
-
focused: false,
|
|
63
|
-
class: {
|
|
64
|
-
box: [
|
|
65
|
-
"bg-secondary-background border-default-boundary",
|
|
66
|
-
"peer-focus-visible:border-selected-strong-boundary",
|
|
67
|
-
],
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
// 选中状态 - accent & outline
|
|
71
|
-
{
|
|
72
|
-
variant: ["accent", "outline"],
|
|
73
|
-
checked: true,
|
|
74
|
-
disabled: false,
|
|
75
|
-
focused: false,
|
|
76
|
-
class: {
|
|
77
|
-
box: [
|
|
78
|
-
"bg-accent-background border-selected-strong-boundary text-on-accent-foreground",
|
|
79
|
-
"peer-focus-visible:border-selected-strong-boundary",
|
|
80
|
-
"peer-focus-visible:text-on-accent-foreground",
|
|
81
|
-
"peer-focus-visible:shadow-checked-focused",
|
|
82
|
-
],
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
variant: ["default", "accent", "outline"],
|
|
87
|
-
checked: false,
|
|
88
|
-
disabled: false,
|
|
89
|
-
focused: true,
|
|
90
|
-
class: {
|
|
91
|
-
box: "border-selected-boundary",
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
variant: "default",
|
|
96
|
-
checked: true,
|
|
97
|
-
disabled: false,
|
|
98
|
-
focused: true,
|
|
99
|
-
class: {
|
|
100
|
-
box: "border-selected-strong-boundary",
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
variant: ["accent", "outline"],
|
|
105
|
-
checked: true,
|
|
106
|
-
disabled: false,
|
|
107
|
-
focused: true,
|
|
108
|
-
class: {
|
|
109
|
-
box: "text-on-accent-foreground border-selected-strong-boundary shadow-checked-focused",
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
variant: ["accent", "outline", "default"],
|
|
114
|
-
disabled: true,
|
|
115
|
-
class: {
|
|
116
|
-
root: "text-default-background",
|
|
117
|
-
box: "border-disabled-background bg-disabled-background",
|
|
118
|
-
label: "text-disabled-foreground",
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
],
|
|
122
|
-
defaultVariants: {
|
|
123
|
-
variant: "default",
|
|
124
|
-
checked: false,
|
|
125
|
-
disabled: false,
|
|
126
|
-
focused: false,
|
|
127
|
-
},
|
|
128
|
-
})
|