@ladder-ui/checkbox 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/checkbox.css CHANGED
@@ -51,7 +51,7 @@
51
51
  .lui-checkbox:has(.lui-checkbox__input:focus-visible) .lui-checkbox__control {
52
52
  outline: none;
53
53
  border-color: var(--lui-checkbox-focus-border);
54
- box-shadow: 0 0 0 2px var(--lui-surface), 0 0 0 4px var(--lui-checkbox-focus-ring-color);
54
+ box-shadow: 0 0 0 2px var(--lui-bg-surface), 0 0 0 4px var(--lui-checkbox-focus-ring-color);
55
55
  }
56
56
  .lui-checkbox:has(.lui-checkbox__input:checked:not(:indeterminate)) .lui-checkbox__control {
57
57
  background-color: var(--lui-checkbox-checked-bg);
@@ -75,7 +75,7 @@
75
75
  }
76
76
  .lui-checkbox--error:has(.lui-checkbox__input:focus-visible) .lui-checkbox__control {
77
77
  border-color: var(--lui-error);
78
- box-shadow: 0 0 0 2px var(--lui-surface), 0 0 0 4px color-mix(in srgb, var(--lui-error) 40%, transparent);
78
+ box-shadow: 0 0 0 2px var(--lui-bg-surface), 0 0 0 4px color-mix(in srgb, var(--lui-error) 40%, transparent);
79
79
  }
80
80
  .lui-checkbox--sm {
81
81
  width: var(--lui-checkbox-size-sm);
@@ -27,10 +27,8 @@ export interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputE
27
27
  * - Renders a native `<input type="checkbox">` for full browser and AT support.
28
28
  * - `ref` points directly to the native input element.
29
29
  * - Supports `indeterminate` state (shows a dash — useful for "select all" patterns).
30
- * - `status="error"` sets `aria-invalid="true"` automatically.
31
30
  * - No third-party dependencies — checkmark and dash are inline SVGs.
32
- * - All visual state (checked, indeterminate, focus, disabled, error) is driven by
33
- * CSS `:has()` selectors — zero JS involved in rendering.
31
+ * - All visual state is driven by CSS `:has()` selectors zero JS in rendering.
34
32
  */
35
33
  export declare function Checkbox({ ref, className, size, status, indeterminate, disabled, ...props }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
36
34
  export declare namespace Checkbox {
@@ -4,14 +4,14 @@
4
4
  --lui-checkbox-size-md: 1rem; /* 16px */
5
5
  --lui-checkbox-size-lg: 1.25rem; /* 20px */
6
6
  /* Background & border (unchecked) */
7
- --lui-checkbox-bg: var(--lui-surface);
8
- --lui-checkbox-border: color-mix(in srgb, var(--lui-surface-border) 93%, var(--lui-surface-text));
7
+ --lui-checkbox-bg: var(--lui-bg-surface);
8
+ --lui-checkbox-border: color-mix(in srgb, var(--lui-border-default) 93%, var(--lui-text-primary));
9
9
  /* Checked & indeterminate */
10
- --lui-checkbox-checked-bg: var(--lui-primary);
11
- --lui-checkbox-checked-text: var(--lui-primary-text);
10
+ --lui-checkbox-checked-bg: var(--lui-bg-interactive);
11
+ --lui-checkbox-checked-text: var(--lui-text-inverse);
12
12
  /* Focus ring */
13
- --lui-checkbox-focus-border: var(--lui-primary);
14
- --lui-checkbox-focus-ring-color: color-mix(in srgb, var(--lui-primary) 40%, transparent);
13
+ --lui-checkbox-focus-border: var(--lui-bg-interactive);
14
+ --lui-checkbox-focus-ring-color: color-mix(in srgb, var(--lui-bg-interactive) 40%, transparent);
15
15
  /* Shape */
16
16
  --lui-checkbox-radius: var(--lui-radius-sm);
17
17
  }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { Checkbox, type CheckboxProps } from "./checkbox";
2
2
  export { Checkbox as default } from "./checkbox";
3
+ export { useCheckbox, type UseCheckboxProps } from "@ladder-ui/primitives";
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
- var concatClassNames = require('@ladder-ui/core/concatClassNames');
7
- var react = require('react');
6
+ var core = require('@ladder-ui/core');
7
+ var primitives = require('@ladder-ui/primitives');
8
8
 
9
9
  // ── Internal SVG icons (no external dependency) ───────────────────────────────
10
10
  function CheckIcon() {
@@ -13,6 +13,30 @@ function CheckIcon() {
13
13
  function IndeterminateIcon() {
14
14
  return (jsxRuntime.jsx("svg", { viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": "true", children: jsxRuntime.jsx("line", { x1: "2.5", y1: "6", x2: "9.5", y2: "6" }) }));
15
15
  }
16
+ // ── Variants ──────────────────────────────────────────────────────────────────
17
+ const checkboxVariants = core.cva({
18
+ base: "lui-checkbox",
19
+ variants: {
20
+ size: {
21
+ sm: "lui-checkbox--sm",
22
+ md: "lui-checkbox--md",
23
+ lg: "lui-checkbox--lg",
24
+ },
25
+ status: {
26
+ default: "",
27
+ error: "lui-checkbox--error",
28
+ },
29
+ disabled: {
30
+ true: "lui-checkbox--disabled",
31
+ false: "",
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ size: "md",
36
+ status: "default",
37
+ disabled: false,
38
+ },
39
+ });
16
40
  // ── Component ─────────────────────────────────────────────────────────────────
17
41
  /**
18
42
  * Checkbox — a fully accessible, themeable checkbox.
@@ -20,32 +44,24 @@ function IndeterminateIcon() {
20
44
  * - Renders a native `<input type="checkbox">` for full browser and AT support.
21
45
  * - `ref` points directly to the native input element.
22
46
  * - Supports `indeterminate` state (shows a dash — useful for "select all" patterns).
23
- * - `status="error"` sets `aria-invalid="true"` automatically.
24
47
  * - No third-party dependencies — checkmark and dash are inline SVGs.
25
- * - All visual state (checked, indeterminate, focus, disabled, error) is driven by
26
- * CSS `:has()` selectors — zero JS involved in rendering.
48
+ * - All visual state is driven by CSS `:has()` selectors zero JS in rendering.
27
49
  */
28
50
  function Checkbox({ ref, className, size = "md", status = "default", indeterminate = false, disabled, ...props }) {
29
- // Internal ref required to set .indeterminate imperatively (no HTML attribute).
30
- const internalRef = react.useRef(null);
31
- react.useEffect(() => {
32
- if (internalRef.current) {
33
- internalRef.current.indeterminate = indeterminate;
34
- }
35
- }, [indeterminate]);
36
- // Merge external ref (from the consumer) with our internal ref.
37
- function setRef(node) {
38
- internalRef.current = node;
39
- if (typeof ref === "function") {
40
- ref(node);
41
- }
42
- else if (ref) {
43
- ref.current = node;
44
- }
45
- }
46
- return (jsxRuntime.jsxs("span", { "data-slot": "checkbox", "data-disabled": disabled ? "true" : undefined, "data-status": status !== "default" ? status : undefined, className: concatClassNames("lui-checkbox", `lui-checkbox--${size}`, status === "error" && "lui-checkbox--error", disabled && "lui-checkbox--disabled", className), children: [jsxRuntime.jsx("input", { ref: setRef, type: "checkbox", className: "lui-checkbox__input", disabled: disabled, "aria-invalid": props["aria-invalid"] ?? (status === "error" ? true : undefined), ...props }), jsxRuntime.jsxs("span", { className: "lui-checkbox__control", "aria-hidden": "true", children: [jsxRuntime.jsx("span", { className: "lui-checkbox__icon lui-checkbox__icon--check", children: jsxRuntime.jsx(CheckIcon, {}) }), jsxRuntime.jsx("span", { className: "lui-checkbox__icon lui-checkbox__icon--indeterminate", children: jsxRuntime.jsx(IndeterminateIcon, {}) })] })] }));
51
+ const { wrapperProps, inputProps } = primitives.useCheckbox({
52
+ ref,
53
+ indeterminate,
54
+ status,
55
+ disabled,
56
+ "aria-invalid": props["aria-invalid"],
57
+ });
58
+ return (jsxRuntime.jsxs("span", { ...wrapperProps, className: checkboxVariants({ size, status, disabled, className }), children: [jsxRuntime.jsx("input", { className: "lui-checkbox__input", ...inputProps, ...props }), jsxRuntime.jsxs("span", { className: "lui-checkbox__control", "aria-hidden": "true", children: [jsxRuntime.jsx("span", { className: "lui-checkbox__icon lui-checkbox__icon--check", children: jsxRuntime.jsx(CheckIcon, {}) }), jsxRuntime.jsx("span", { className: "lui-checkbox__icon lui-checkbox__icon--indeterminate", children: jsxRuntime.jsx(IndeterminateIcon, {}) })] })] }));
47
59
  }
48
60
  Checkbox.displayName = "Checkbox";
49
61
 
62
+ Object.defineProperty(exports, "useCheckbox", {
63
+ enumerable: true,
64
+ get: function () { return primitives.useCheckbox; }
65
+ });
50
66
  exports.Checkbox = Checkbox;
51
67
  exports.default = Checkbox;
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import concatClassNames from '@ladder-ui/core/concatClassNames';
3
- import { useRef, useEffect } from 'react';
2
+ import { cva } from '@ladder-ui/core';
3
+ import { useCheckbox } from '@ladder-ui/primitives';
4
+ export { useCheckbox } from '@ladder-ui/primitives';
4
5
 
5
6
  // ── Internal SVG icons (no external dependency) ───────────────────────────────
6
7
  function CheckIcon() {
@@ -9,6 +10,30 @@ function CheckIcon() {
9
10
  function IndeterminateIcon() {
10
11
  return (jsx("svg", { viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": "true", children: jsx("line", { x1: "2.5", y1: "6", x2: "9.5", y2: "6" }) }));
11
12
  }
13
+ // ── Variants ──────────────────────────────────────────────────────────────────
14
+ const checkboxVariants = cva({
15
+ base: "lui-checkbox",
16
+ variants: {
17
+ size: {
18
+ sm: "lui-checkbox--sm",
19
+ md: "lui-checkbox--md",
20
+ lg: "lui-checkbox--lg",
21
+ },
22
+ status: {
23
+ default: "",
24
+ error: "lui-checkbox--error",
25
+ },
26
+ disabled: {
27
+ true: "lui-checkbox--disabled",
28
+ false: "",
29
+ },
30
+ },
31
+ defaultVariants: {
32
+ size: "md",
33
+ status: "default",
34
+ disabled: false,
35
+ },
36
+ });
12
37
  // ── Component ─────────────────────────────────────────────────────────────────
13
38
  /**
14
39
  * Checkbox — a fully accessible, themeable checkbox.
@@ -16,30 +41,18 @@ function IndeterminateIcon() {
16
41
  * - Renders a native `<input type="checkbox">` for full browser and AT support.
17
42
  * - `ref` points directly to the native input element.
18
43
  * - Supports `indeterminate` state (shows a dash — useful for "select all" patterns).
19
- * - `status="error"` sets `aria-invalid="true"` automatically.
20
44
  * - No third-party dependencies — checkmark and dash are inline SVGs.
21
- * - All visual state (checked, indeterminate, focus, disabled, error) is driven by
22
- * CSS `:has()` selectors — zero JS involved in rendering.
45
+ * - All visual state is driven by CSS `:has()` selectors zero JS in rendering.
23
46
  */
24
47
  function Checkbox({ ref, className, size = "md", status = "default", indeterminate = false, disabled, ...props }) {
25
- // Internal ref required to set .indeterminate imperatively (no HTML attribute).
26
- const internalRef = useRef(null);
27
- useEffect(() => {
28
- if (internalRef.current) {
29
- internalRef.current.indeterminate = indeterminate;
30
- }
31
- }, [indeterminate]);
32
- // Merge external ref (from the consumer) with our internal ref.
33
- function setRef(node) {
34
- internalRef.current = node;
35
- if (typeof ref === "function") {
36
- ref(node);
37
- }
38
- else if (ref) {
39
- ref.current = node;
40
- }
41
- }
42
- return (jsxs("span", { "data-slot": "checkbox", "data-disabled": disabled ? "true" : undefined, "data-status": status !== "default" ? status : undefined, className: concatClassNames("lui-checkbox", `lui-checkbox--${size}`, status === "error" && "lui-checkbox--error", disabled && "lui-checkbox--disabled", className), children: [jsx("input", { ref: setRef, type: "checkbox", className: "lui-checkbox__input", disabled: disabled, "aria-invalid": props["aria-invalid"] ?? (status === "error" ? true : undefined), ...props }), jsxs("span", { className: "lui-checkbox__control", "aria-hidden": "true", children: [jsx("span", { className: "lui-checkbox__icon lui-checkbox__icon--check", children: jsx(CheckIcon, {}) }), jsx("span", { className: "lui-checkbox__icon lui-checkbox__icon--indeterminate", children: jsx(IndeterminateIcon, {}) })] })] }));
48
+ const { wrapperProps, inputProps } = useCheckbox({
49
+ ref,
50
+ indeterminate,
51
+ status,
52
+ disabled,
53
+ "aria-invalid": props["aria-invalid"],
54
+ });
55
+ return (jsxs("span", { ...wrapperProps, className: checkboxVariants({ size, status, disabled, className }), children: [jsx("input", { className: "lui-checkbox__input", ...inputProps, ...props }), jsxs("span", { className: "lui-checkbox__control", "aria-hidden": "true", children: [jsx("span", { className: "lui-checkbox__icon lui-checkbox__icon--check", children: jsx(CheckIcon, {}) }), jsx("span", { className: "lui-checkbox__icon lui-checkbox__icon--indeterminate", children: jsx(IndeterminateIcon, {}) })] })] }));
43
56
  }
44
57
  Checkbox.displayName = "Checkbox";
45
58
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ladder-ui/checkbox",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -47,7 +47,8 @@
47
47
  "sass": "^1.90.0",
48
48
  "tslib": "^2.6.2",
49
49
  "typescript": "^5.3.3",
50
- "@ladder-ui/core": "0.2.0"
50
+ "@ladder-ui/core": "0.4.0",
51
+ "@ladder-ui/primitives": "0.4.0"
51
52
  },
52
53
  "peerDependencies": {
53
54
  "@ladder-ui/core": ">=0.0.0",