@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 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
- 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 };
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 styles = checkboxTv({ disabled });
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(styles.label(), className),
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 styles = checkboxTv({
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 (typeof children === "string" || typeof children === "number") {
201
- return /* @__PURE__ */ jsx(CheckboxLabel, { children });
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 children;
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(styles.root(), className), children: [
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: styles.input(),
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
- /* @__PURE__ */ jsx("div", { className: styles.box(), children: value && (mixed ? /* @__PURE__ */ jsx(Indeterminate, {}) : /* @__PURE__ */ jsx(Check, {})) })
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, useCheckboxContext };
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",
4
- "description": "Checkbox component for Choiceform Design System",
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.cjs",
8
- "module": "./dist/index.js",
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": "./src/index.ts",
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
@@ -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 };
@@ -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
@@ -1,5 +0,0 @@
1
- export { Checkbox } from "./checkbox"
2
- export type { CheckboxProps } from "./checkbox"
3
- export type { CheckboxLabelProps } from "./checkbox-label"
4
- export { useCheckboxContext } from "./context"
5
- export type { CheckboxContextValue } from "./context"
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
- })