@geckou/ui-react 0.4.0 → 0.5.1

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.
@@ -1,34 +1,34 @@
1
1
  "use client";
2
- import { jsxs as p, jsx as t } from "react/jsx-runtime";
2
+ import { jsxs as b, jsx as t } from "react/jsx-runtime";
3
3
  import { useId as h } from "react";
4
- import { CheckBox as b } from "./CheckBox.js";
4
+ import { CheckBox as p } from "./CheckBox.js";
5
5
  import { COLOR as r } from "@geckou/ui-core";
6
6
  function L({
7
7
  name: l,
8
8
  label: d,
9
9
  checked: i,
10
10
  onChange: m,
11
- isDisabled: o,
12
- cssStyle: e,
11
+ isDisabled: e,
12
+ cssStyle: o,
13
13
  isDisableAnimation: u
14
14
  }) {
15
- const a = i ?? !1, n = h(), x = o ? e == null ? void 0 : e.disabled : e == null ? void 0 : e.default, c = {
16
- textColor: o ? r.darkGray : r.black,
17
- backgroundColor: o ? r.darkGray : r.blue,
15
+ const a = i ?? !1, n = h(), x = e ? o == null ? void 0 : o.disabled : o == null ? void 0 : o.default, c = {
16
+ textColor: e ? r.darkGray : r.black,
17
+ backgroundColor: e ? r.darkGray : r.blue,
18
18
  ...x ?? {}
19
19
  }, k = {
20
20
  "--text-color": c.textColor,
21
21
  "--checked-color": c.backgroundColor
22
22
  };
23
- return /* @__PURE__ */ p("label", { className: "inline-flex cursor-pointer items-center gap-[.5em] has-[input:disabled]:cursor-auto", children: [
23
+ return /* @__PURE__ */ b("label", { className: "inline-flex cursor-pointer items-center gap-[.5em] has-[button:disabled]:cursor-auto", children: [
24
24
  /* @__PURE__ */ t("span", { className: "pointer-events-none", children: /* @__PURE__ */ t(
25
- b,
25
+ p,
26
26
  {
27
27
  name: l,
28
28
  checked: a,
29
29
  onChange: m,
30
- isDisabled: o,
31
- cssStyle: e,
30
+ isDisabled: e,
31
+ cssStyle: o,
32
32
  isDisableAnimation: u,
33
33
  ariaLabelledBy: n
34
34
  }
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  import { jsx as t, jsxs as x } from "react/jsx-runtime";
3
- import { useId as b, useRef as m, useEffect as n } from "react";
4
- import { createScrollLock as g } from "@geckou/ui-core";
5
- const w = {
3
+ import { useId as b, useRef as n, useEffect as d } from "react";
4
+ import { createScrollLock as g, handleTabKey as w } from "@geckou/ui-core";
5
+ const h = {
6
6
  small: "max-w-[var(--mobile-lower-width,430px)]",
7
7
  medium: "max-w-[var(--desktop-lower-width,1025px)]",
8
8
  large: "max-w-[var(--contents-max-width,1440px)]"
9
9
  };
10
- function h() {
10
+ function y() {
11
11
  return /* @__PURE__ */ t(
12
12
  "svg",
13
13
  {
@@ -18,73 +18,79 @@ function h() {
18
18
  }
19
19
  );
20
20
  }
21
- function N({
21
+ function I({
22
22
  isShown: r,
23
- size: c = "medium",
24
- onClose: a,
25
- header: l,
26
- footer: d,
23
+ size: s = "medium",
24
+ onClose: o,
25
+ header: i,
26
+ footer: u,
27
27
  children: p,
28
28
  ariaLabel: f
29
29
  }) {
30
- const u = b(), s = m(null), v = m(g());
31
- n(() => {
30
+ const c = b(), m = n(null), v = n(g());
31
+ d(() => {
32
32
  const e = v.current;
33
33
  return e.toggle(r), () => e.release();
34
34
  }, [r]);
35
- const i = m(null);
36
- return n(() => {
37
- var e, o;
35
+ const l = n(null);
36
+ return d(() => {
37
+ var e, a;
38
38
  if (r) {
39
- i.current = document.activeElement, (e = s.current) == null || e.focus();
39
+ l.current ?? (l.current = document.activeElement), (e = m.current) == null || e.focus();
40
40
  return;
41
41
  }
42
- (o = i.current) == null || o.focus(), i.current = null;
43
- }, [r]), n(() => {
42
+ (a = l.current) == null || a.focus(), l.current = null;
43
+ }, [r]), d(() => {
44
44
  if (!r)
45
45
  return;
46
- const e = (o) => {
47
- o.key === "Escape" && a();
46
+ const e = (a) => {
47
+ if (!a.defaultPrevented) {
48
+ if (a.key === "Escape") {
49
+ o();
50
+ return;
51
+ }
52
+ w(m.current, a, document.activeElement);
53
+ }
48
54
  };
49
55
  return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
50
- }, [r, a]), /* @__PURE__ */ t(
56
+ }, [r, o]), /* @__PURE__ */ t(
51
57
  "div",
52
58
  {
53
59
  className: `fixed top-0 left-0 z-50 flex h-dvh w-dvw cursor-pointer items-center justify-center overflow-hidden bg-[#33333380] p-[var(--sp-larger,3rem)] backdrop-blur-sm transition-opacity duration-100 max-md:px-[var(--sp-large,1.5rem)] ${r ? "pointer-events-auto opacity-100" : "pointer-events-none opacity-0"}`,
54
60
  "aria-hidden": !r,
55
61
  inert: !r,
56
62
  onClick: (e) => {
57
- e.target === e.currentTarget && a();
63
+ e.target === e.currentTarget && o();
58
64
  },
59
65
  children: /* @__PURE__ */ x(
60
66
  "div",
61
67
  {
62
- ref: s,
68
+ ref: m,
63
69
  role: "dialog",
64
70
  "aria-modal": "true",
65
- "aria-labelledby": l ? u : void 0,
66
- "aria-label": l ? void 0 : f ?? "ダイアログ",
71
+ "aria-labelledby": i ? c : void 0,
72
+ "aria-label": i ? void 0 : f ?? "ダイアログ",
67
73
  tabIndex: -1,
68
- className: `relative flex max-h-full w-full cursor-auto flex-col rounded-[var(--radius-small,0.1875rem)] bg-white drop-shadow-[0_0_6px_#33333355] ${w[c]}`,
74
+ className: `relative flex max-h-full w-full cursor-auto flex-col rounded-[var(--radius-small,0.1875rem)] bg-white drop-shadow-[0_0_6px_#33333355] ${h[s]}`,
69
75
  children: [
70
- l && /* @__PURE__ */ t(
76
+ i && /* @__PURE__ */ t(
71
77
  "header",
72
78
  {
73
- id: u,
79
+ id: c,
74
80
  className: "border-b border-[#eee] px-[var(--sp-large,1.5rem)] py-[var(--sp-medium,0.75rem)] max-md:p-[var(--sp-medium,0.75rem)] [&>h2]:font-bold [&>h2]:text-[var(--fs-large,0.875rem)]",
75
- children: l
81
+ children: i
76
82
  }
77
83
  ),
78
84
  /* @__PURE__ */ t("div", { className: "flex-auto overflow-auto p-[var(--sp-large,1.5rem)] max-md:p-[var(--sp-medium,0.75rem)]", children: p }),
79
- d && /* @__PURE__ */ t("footer", { className: "flex justify-center gap-[var(--sp-large,1.5rem)] border-t border-[#eee] px-[var(--sp-large,1.5rem)] py-[var(--sp-medium,0.75rem)] max-md:gap-[var(--sp-medium,0.75rem)] max-md:p-[var(--sp-medium,0.75rem)] max-md:[&>*]:flex-auto", children: d }),
85
+ u && /* @__PURE__ */ t("footer", { className: "flex justify-center gap-[var(--sp-large,1.5rem)] border-t border-[#eee] px-[var(--sp-large,1.5rem)] py-[var(--sp-medium,0.75rem)] max-md:gap-[var(--sp-medium,0.75rem)] max-md:p-[var(--sp-medium,0.75rem)] max-md:[&>*]:flex-auto", children: u }),
80
86
  /* @__PURE__ */ t(
81
87
  "button",
82
88
  {
83
89
  type: "button",
84
90
  "aria-label": "閉じる",
85
91
  className: "absolute bottom-full left-full size-[var(--icon-medium,1.125rem)] cursor-pointer leading-none text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white [&>*]:size-full",
86
- onClick: a,
87
- children: /* @__PURE__ */ t(h, {})
92
+ onClick: o,
93
+ children: /* @__PURE__ */ t(y, {})
88
94
  }
89
95
  )
90
96
  ]
@@ -94,5 +100,5 @@ function N({
94
100
  );
95
101
  }
96
102
  export {
97
- N as ModalBox
103
+ I as ModalBox
98
104
  };
@@ -9,6 +9,8 @@ type Props = {
9
9
  isDisabled?: boolean;
10
10
  searchTarget?: 'label' | 'value';
11
11
  cssStyle?: InputBoxStyleForEachStatus;
12
+ /** combobox のアクセシブル名。可視ラベルがあるならそちらを ariaLabelledBy で指すこと */
13
+ ariaLabel?: string;
12
14
  };
13
- export declare function SearchableSelectBox({ options, value, onChange, onSelect, name, placeholder, isDisabled, searchTarget, cssStyle, }: Props): import("react").JSX.Element;
15
+ export declare function SearchableSelectBox({ options, value, onChange, onSelect, name, placeholder, isDisabled, searchTarget, cssStyle, ariaLabel, }: Props): import("react").JSX.Element;
14
16
  export {};
@@ -1,61 +1,104 @@
1
1
  "use client";
2
- import { jsxs as N, jsx as n } from "react/jsx-runtime";
3
- import { useState as p, useRef as v, useEffect as w } from "react";
4
- import { TextBox as S } from "./TextBox.js";
5
- function F({
6
- options: i,
7
- value: t,
2
+ import { jsxs as N, jsx as w } from "react/jsx-runtime";
3
+ import { useState as v, useRef as k, useId as _, useEffect as y } from "react";
4
+ import { TextBox as $ } from "./TextBox.js";
5
+ function R({
6
+ options: h,
7
+ value: o,
8
8
  onChange: s,
9
- onSelect: o,
10
- name: x,
11
- placeholder: b = "入力してください",
12
- isDisabled: h,
13
- searchTarget: E = "label",
14
- cssStyle: O
9
+ onSelect: d,
10
+ name: A,
11
+ placeholder: I = "入力してください",
12
+ isDisabled: g,
13
+ searchTarget: B = "label",
14
+ cssStyle: L,
15
+ ariaLabel: O
15
16
  }) {
16
- const [l, a] = p(t), [k, c] = p(!1), u = v(null), d = v(t);
17
- w(() => {
18
- d.current !== t && (d.current = t, a(t));
19
- }, [t]), w(() => {
17
+ const [u, f] = v(o), [p, a] = v(!1), [i, n] = v(-1), x = k(null), m = _(), b = (e) => `${m}-option-${e}`, E = k(o);
18
+ y(() => {
19
+ E.current !== o && (E.current = o, f(o));
20
+ }, [o]), y(() => {
20
21
  const e = (r) => {
21
- const f = u.current;
22
- f && !f.contains(r.target) && c(!1);
22
+ const t = x.current;
23
+ t && !t.contains(r.target) && a(!1);
23
24
  };
24
25
  return document.addEventListener("pointerdown", e), () => document.removeEventListener("pointerdown", e);
25
26
  }, []);
26
- const m = l ? i.filter(
27
- (e) => String(e[E]).toLowerCase().includes(l.toLowerCase())
28
- ) : i, B = (e) => {
27
+ const l = u ? h.filter(
28
+ (e) => String(e[B]).toLowerCase().includes(u.toLowerCase())
29
+ ) : h, F = (e) => {
29
30
  const r = String(e);
30
- a(r), c(!!r), s == null || s(r);
31
- }, L = (e) => {
31
+ f(r), a(!!r), n(-1), s == null || s(r);
32
+ }, D = (e) => {
32
33
  const r = e.value.toString();
33
- a(r), c(!1), s == null || s(r), o == null || o(r);
34
+ f(r), a(!1), n(-1), s == null || s(r), d == null || d(r);
35
+ }, c = p && l.length > 0, S = (e) => {
36
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
37
+ if (e.preventDefault(), !p) {
38
+ a(!0), n(
39
+ e.key === "ArrowDown" ? 0 : l.length - 1
40
+ );
41
+ return;
42
+ }
43
+ if (l.length === 0)
44
+ return;
45
+ n((r) => {
46
+ const t = l.length - 1;
47
+ return e.key === "ArrowDown" ? r >= t ? 0 : r + 1 : r <= 0 ? t : r - 1;
48
+ });
49
+ return;
50
+ }
51
+ if (e.key === "Enter") {
52
+ const r = c ? l[i] : void 0;
53
+ r && (e.preventDefault(), D(r));
54
+ return;
55
+ }
56
+ e.key === "Escape" && p && (e.preventDefault(), a(!1), n(-1));
34
57
  };
35
- return /* @__PURE__ */ N("div", { ref: u, className: "relative", children: [
36
- /* @__PURE__ */ n(
37
- S,
58
+ return /* @__PURE__ */ N("div", { ref: x, className: "relative", children: [
59
+ /* @__PURE__ */ w(
60
+ $,
38
61
  {
39
- name: x,
40
- value: l,
41
- onChange: B,
42
- isDisabled: h,
43
- placeholder: b,
44
- cssStyle: O
62
+ name: A,
63
+ value: u,
64
+ onChange: F,
65
+ isDisabled: g,
66
+ placeholder: I,
67
+ cssStyle: L,
68
+ role: "combobox",
69
+ ariaLabel: O,
70
+ ariaAutocomplete: "list",
71
+ ariaExpanded: c,
72
+ ariaControls: m,
73
+ ariaActivedescendant: c && i >= 0 ? b(i) : void 0,
74
+ onKeyDown: S
45
75
  }
46
76
  ),
47
- k && m.length > 0 && /* @__PURE__ */ n("div", { className: "absolute top-[calc(100%-var(--sp-min,0.1875rem))] left-0 z-[2] max-h-[calc(var(--bv,0.375rem)*56)] min-w-full overflow-auto rounded-[var(--radius-small,0.1875rem)] bg-white py-[var(--sp-small,0.375rem)] shadow-[0_0_6px_#33333333]", children: m.map((e) => /* @__PURE__ */ n(
48
- "button",
77
+ c && /* @__PURE__ */ w(
78
+ "div",
49
79
  {
50
- type: "button",
51
- className: "block w-full cursor-pointer p-[var(--sp-medium,0.75rem)] text-left text-[length:var(--fs-small,0.6875rem)] text-[var(--link-color,#1c4ac9)] hover:bg-[var(--hover-color,#EEF7FB)] hover:transition-all hover:duration-100",
52
- onClick: () => L(e),
53
- children: e.label
54
- },
55
- e.value
56
- )) })
80
+ id: m,
81
+ role: "listbox",
82
+ className: "absolute top-[calc(100%-var(--sp-min,0.1875rem))] left-0 z-[2] max-h-[calc(var(--bv,0.375rem)*56)] min-w-full overflow-auto rounded-[var(--radius-small,0.1875rem)] bg-white py-[var(--sp-small,0.375rem)] shadow-[0_0_6px_#33333333]",
83
+ children: l.map((e, r) => /* @__PURE__ */ w(
84
+ "div",
85
+ {
86
+ id: b(r),
87
+ role: "option",
88
+ "aria-selected": r === i,
89
+ className: `block w-full cursor-pointer p-[var(--sp-medium,0.75rem)] text-left text-[length:var(--fs-small,0.6875rem)] text-[var(--link-color,#1c4ac9)] hover:bg-[var(--hover-color,#EEF7FB)] hover:transition-all hover:duration-100 ${r === i ? "bg-[var(--hover-color,#EEF7FB)]" : ""}`,
90
+ onPointerDown: (t) => {
91
+ t.preventDefault(), D(e);
92
+ },
93
+ onMouseEnter: () => n(r),
94
+ children: e.label
95
+ },
96
+ e.value
97
+ ))
98
+ }
99
+ )
57
100
  ] });
58
101
  }
59
102
  export {
60
- F as SearchableSelectBox
103
+ R as SearchableSelectBox
61
104
  };
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import { KeyboardEvent, ReactNode } from 'react';
2
2
  import { InputBoxStyleForEachStatus, Validates } from '../types';
3
3
  type InputValue = string | number;
4
4
  type Props = {
@@ -15,6 +15,19 @@ type Props = {
15
15
  validates?: Validates;
16
16
  before?: ReactNode;
17
17
  after?: ReactNode;
18
+ /** input の id。combobox のように外から参照する必要があるときに渡す */
19
+ id?: string;
20
+ /**
21
+ * input へそのまま渡す ARIA 属性とキー操作。
22
+ * SearchableSelectBox のような複合ウィジェットから使う(通常は指定しない)
23
+ */
24
+ role?: string;
25
+ ariaLabel?: string;
26
+ ariaExpanded?: boolean;
27
+ ariaControls?: string;
28
+ ariaActivedescendant?: string;
29
+ ariaAutocomplete?: 'none' | 'inline' | 'list' | 'both';
30
+ onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
18
31
  };
19
- export declare function TextBox({ name, value, onChange, cssStyle, inputType, placeholder, isDisabled, isRequired, maxLength, autocomplete, validates, before, after, }: Props): import("react").JSX.Element;
32
+ export declare function TextBox({ name, value, onChange, cssStyle, inputType, placeholder, isDisabled, isRequired, maxLength, autocomplete, validates, before, after, id, role, ariaLabel, ariaExpanded, ariaControls, ariaActivedescendant, ariaAutocomplete, onKeyDown, }: Props): import("react").JSX.Element;
20
33
  export {};
@@ -1,83 +1,99 @@
1
1
  "use client";
2
- import { jsxs as W, jsx as c } from "react/jsx-runtime";
3
- import { isEmptyValue as w, convertFullWidthToHalfWidth as x, validateInputValue as C } from "@geckou/ui-core";
4
- import { useState as F, useRef as n, useEffect as H } from "react";
5
- import { InputBox as N } from "./InputBox.js";
6
- import { ErrorMessage as q } from "./ErrorMessage.js";
7
- function L({
2
+ import { jsxs as A, jsx as s } from "react/jsx-runtime";
3
+ import { isEmptyValue as G, convertFullWidthToHalfWidth as x, validateInputValue as J } from "@geckou/ui-core";
4
+ import { useState as K, useRef as n, useEffect as L } from "react";
5
+ import { InputBox as O } from "./InputBox.js";
6
+ import { ErrorMessage as P } from "./ErrorMessage.js";
7
+ function Z({
8
8
  name: v,
9
9
  value: E,
10
10
  onChange: t,
11
11
  cssStyle: r,
12
12
  inputType: V = "text",
13
- placeholder: g = "入力してください",
13
+ placeholder: b = "入力してください",
14
14
  isDisabled: l,
15
15
  isRequired: f,
16
- maxLength: B = 30,
17
- autocomplete: M = "off",
18
- validates: T = [],
19
- before: b,
20
- after: j
16
+ maxLength: g = 30,
17
+ autocomplete: B = "off",
18
+ validates: M = [],
19
+ before: T,
20
+ after: j,
21
+ id: k,
22
+ role: I,
23
+ ariaLabel: W,
24
+ ariaExpanded: w,
25
+ ariaControls: C,
26
+ ariaActivedescendant: F,
27
+ ariaAutocomplete: H,
28
+ onKeyDown: N
21
29
  }) {
22
- var m, s;
23
- const [o, k] = F([]), e = E ?? "", u = () => {
24
- k(C(e, { isRequired: f, validates: T }));
25
- }, I = n(e), p = n(!1);
26
- H(() => {
30
+ var d, c;
31
+ const [o, q] = K([]), e = E ?? "", a = () => {
32
+ q(J(e, { isRequired: f, validates: M }));
33
+ }, z = n(e), p = n(!1);
34
+ L(() => {
27
35
  if (!p.current) {
28
- if (e === I.current) {
29
- w(e) || u();
36
+ if (e === z.current) {
37
+ G(e) || a();
30
38
  return;
31
39
  }
32
40
  p.current = !0;
33
41
  }
34
- u();
42
+ a();
35
43
  }, [e]);
36
44
  const i = n(!1);
37
- return /* @__PURE__ */ W(
38
- N,
45
+ return /* @__PURE__ */ A(
46
+ O,
39
47
  {
40
48
  cssStyle: r,
41
49
  className: "inline-flex [&>input]:flex-auto",
42
50
  isErrored: !!o.length,
43
51
  isDisabled: l,
44
52
  children: [
45
- b,
46
- /* @__PURE__ */ c(
53
+ T,
54
+ /* @__PURE__ */ s(
47
55
  "input",
48
56
  {
49
57
  type: V,
58
+ id: k,
50
59
  name: v,
60
+ role: I,
61
+ "aria-label": W,
62
+ "aria-expanded": w,
63
+ "aria-controls": C,
64
+ "aria-activedescendant": F,
65
+ "aria-autocomplete": H,
66
+ onKeyDown: N,
51
67
  value: e,
52
68
  required: f,
53
- placeholder: g,
69
+ placeholder: b,
54
70
  disabled: l,
55
- autoComplete: M,
56
- maxLength: B,
71
+ autoComplete: B,
72
+ maxLength: g,
57
73
  "aria-invalid": o.length ? "true" : void 0,
58
- onChange: (a) => {
59
- const d = a.target.value;
74
+ onChange: (u) => {
75
+ const m = u.target.value;
60
76
  t == null || t(
61
- i.current ? d : x(d)
77
+ i.current ? m : x(m)
62
78
  );
63
79
  },
64
80
  onCompositionStart: () => {
65
81
  i.current = !0;
66
82
  },
67
- onCompositionEnd: (a) => {
68
- i.current = !1, t == null || t(x(a.currentTarget.value));
83
+ onCompositionEnd: (u) => {
84
+ i.current = !1, t == null || t(x(u.currentTarget.value));
69
85
  },
70
- onBlur: () => u()
86
+ onBlur: () => a()
71
87
  }
72
88
  ),
73
89
  j,
74
- /* @__PURE__ */ c(
75
- q,
90
+ /* @__PURE__ */ s(
91
+ P,
76
92
  {
77
93
  errorMessages: o,
78
94
  cssStyle: {
79
- textColor: (m = r == null ? void 0 : r.error) == null ? void 0 : m.backgroundColor,
80
- backgroundColor: (s = r == null ? void 0 : r.error) == null ? void 0 : s.textColor
95
+ textColor: (d = r == null ? void 0 : r.error) == null ? void 0 : d.backgroundColor,
96
+ backgroundColor: (c = r == null ? void 0 : r.error) == null ? void 0 : c.textColor
81
97
  }
82
98
  }
83
99
  )
@@ -86,5 +102,5 @@ function L({
86
102
  );
87
103
  }
88
104
  export {
89
- L as TextBox
105
+ Z as TextBox
90
106
  };
@@ -1,18 +1,18 @@
1
1
  "use client";
2
- import { jsxs as v, jsx as f } from "react/jsx-runtime";
2
+ import { jsxs as h, Fragment as m, jsx as f } from "react/jsx-runtime";
3
3
  import { COLOR as e } from "@geckou/ui-core";
4
- function k({
4
+ function y({
5
5
  name: l,
6
6
  label: n = { on: "ON", off: "OFF" },
7
- checked: h,
7
+ checked: p,
8
8
  onChange: d,
9
9
  isDisabled: o,
10
- cssStyle: r,
11
- ariaLabel: p,
10
+ cssStyle: a,
11
+ ariaLabel: g,
12
12
  ariaLabelledBy: c
13
13
  }) {
14
14
  var u, s, b;
15
- const a = h ?? !1, g = Math.max(n.on.length, n.off.length), t = o ? r == null ? void 0 : r.disabled : r == null ? void 0 : r.default, i = {
15
+ const r = p ?? !1, x = Math.max(n.on.length, n.off.length), t = o ? a == null ? void 0 : a.disabled : a == null ? void 0 : a.default, i = {
16
16
  on: {
17
17
  textColor: o ? e.lightGray : e.white,
18
18
  backgroundColor: o ? e.gray : e.blue,
@@ -35,62 +35,55 @@ function k({
35
35
  boxShadow: "0 0 0 0 rgba(0, 0, 0, 0)",
36
36
  ...t == null ? void 0 : t.off
37
37
  }
38
- }[a ? "on" : "off"], x = {
38
+ }[r ? "on" : "off"], z = {
39
39
  "--text-color": i.textColor,
40
40
  "--border-color": (u = i.border) == null ? void 0 : u.color,
41
41
  "--border-size": (s = i.border) == null ? void 0 : s.size,
42
42
  "--radius-size": (b = i.border) == null ? void 0 : b.radius,
43
43
  "--background-color": i.backgroundColor,
44
44
  "--box-shadow": i.boxShadow,
45
- "--inline-size": `${g * 2}ch`,
45
+ "--inline-size": `${x * 2}ch`,
46
46
  "--handle-size": "1.5rem",
47
47
  "--padding-size": "calc(var(--border-size) + 2px)",
48
48
  "--duration": ".15s"
49
49
  };
50
- return /* @__PURE__ */ v(
51
- "button",
52
- {
53
- type: "button",
54
- style: x,
55
- disabled: o,
56
- role: "switch",
57
- "aria-checked": a,
58
- "aria-labelledby": c,
59
- "aria-label": c ? void 0 : p ?? l,
60
- onClick: (z) => {
61
- z.stopPropagation(), o || d == null || d(!a);
62
- },
63
- className: "relative inline-block w-[calc(var(--inline-size)+var(--handle-size)+(var(--padding-size)*2))] cursor-pointer rounded-(--radius-size) border-none bg-(--background-color) p-(--padding-size) shadow-[0_0_0_var(--border-size)_var(--border-color)_inset,var(--box-shadow)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--border-color)",
64
- children: [
65
- /* @__PURE__ */ f(
66
- "input",
67
- {
68
- type: "checkbox",
69
- name: l,
70
- checked: a,
71
- disabled: o,
72
- readOnly: !0,
73
- className: "hidden"
74
- }
75
- ),
76
- /* @__PURE__ */ f(
77
- "div",
78
- {
79
- "data-on": n.on,
80
- "data-off": n.off,
81
- className: `absolute top-0 left-0 h-full w-full text-(--text-color) uppercase before:absolute before:right-0 before:m-auto before:inline-flex before:h-full before:w-[calc(100%-var(--handle-size)-var(--padding-size))] before:items-center before:justify-center before:leading-none before:transition-opacity before:duration-(--duration) before:ease-out before:content-[attr(data-off)] after:absolute after:left-0 after:m-auto after:inline-flex after:h-full after:w-[calc(100%-var(--handle-size)-var(--padding-size))] after:items-center after:justify-center after:leading-none after:transition-opacity after:duration-(--duration) after:ease-out after:content-[attr(data-on)] ${a ? "before:opacity-0 after:opacity-100" : "before:opacity-100 after:opacity-0"}`
82
- }
83
- ),
84
- /* @__PURE__ */ f(
85
- "div",
86
- {
87
- className: `relative m-0 aspect-square w-(--handle-size) rounded-[calc(var(--radius-size)-(var(--padding-size)/2))] bg-(--text-color) shadow-(--box-shadow) transition-[left] duration-(--duration) ease-out ${a ? "left-[calc(100%-var(--handle-size))]" : "left-0"}`
88
- }
89
- )
90
- ]
91
- }
92
- );
50
+ return /* @__PURE__ */ h(m, { children: [
51
+ /* @__PURE__ */ h(
52
+ "button",
53
+ {
54
+ type: "button",
55
+ style: z,
56
+ disabled: o,
57
+ role: "switch",
58
+ "aria-checked": r,
59
+ "data-checked": r,
60
+ "aria-labelledby": c,
61
+ "aria-label": c ? void 0 : g ?? l,
62
+ onClick: (v) => {
63
+ v.stopPropagation(), o || d == null || d(!r);
64
+ },
65
+ className: "relative inline-block w-[calc(var(--inline-size)+var(--handle-size)+(var(--padding-size)*2))] cursor-pointer rounded-(--radius-size) border-none bg-(--background-color) p-(--padding-size) shadow-[0_0_0_var(--border-size)_var(--border-color)_inset,var(--box-shadow)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--border-color)",
66
+ children: [
67
+ /* @__PURE__ */ f(
68
+ "div",
69
+ {
70
+ "data-on": n.on,
71
+ "data-off": n.off,
72
+ className: `absolute top-0 left-0 h-full w-full text-(--text-color) uppercase before:absolute before:right-0 before:m-auto before:inline-flex before:h-full before:w-[calc(100%-var(--handle-size)-var(--padding-size))] before:items-center before:justify-center before:leading-none before:transition-opacity before:duration-(--duration) before:ease-out before:content-[attr(data-off)] after:absolute after:left-0 after:m-auto after:inline-flex after:h-full after:w-[calc(100%-var(--handle-size)-var(--padding-size))] after:items-center after:justify-center after:leading-none after:transition-opacity after:duration-(--duration) after:ease-out after:content-[attr(data-on)] ${r ? "before:opacity-0 after:opacity-100" : "before:opacity-100 after:opacity-0"}`
73
+ }
74
+ ),
75
+ /* @__PURE__ */ f(
76
+ "div",
77
+ {
78
+ className: `relative m-0 aspect-square w-(--handle-size) rounded-[calc(var(--radius-size)-(var(--padding-size)/2))] bg-(--text-color) shadow-(--box-shadow) transition-[left] duration-(--duration) ease-out ${r ? "left-[calc(100%-var(--handle-size))]" : "left-0"}`
79
+ }
80
+ )
81
+ ]
82
+ }
83
+ ),
84
+ r && /* @__PURE__ */ f("input", { type: "hidden", name: l, value: "on", disabled: o })
85
+ ] });
93
86
  }
94
87
  export {
95
- k as ToggleButton
88
+ y as ToggleButton
96
89
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geckou/ui-react",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "A set of reusable React UI components (forms) by Geckou",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -40,7 +40,7 @@
40
40
  "react-dom": "^19.0.0"
41
41
  },
42
42
  "dependencies": {
43
- "@geckou/ui-core": "^0.3.0"
43
+ "@geckou/ui-core": "^0.5.0"
44
44
  },
45
45
  "scripts": {
46
46
  "build": "vite build && node scripts/copy-assets.mjs",