@geckou/ui-react 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.
@@ -1,72 +1,68 @@
1
1
  "use client";
2
- import { jsx as C } from "react/jsx-runtime";
3
- import { useRef as a, useState as L, useCallback as E, useEffect as v } from "react";
4
- import { INPUT_BOX_DEFAULT_STYLES as k } from "@geckou/ui-core";
2
+ import { jsx as y } from "react/jsx-runtime";
3
+ import { useRef as u, useState as C, useCallback as L, useEffect as v } from "react";
4
+ import { INPUT_BOX_DEFAULT_STYLES as E } from "@geckou/ui-core";
5
5
  function $({
6
6
  cssStyle: m,
7
- isErrored: u,
8
- isDisabled: n,
7
+ isErrored: l,
8
+ isDisabled: s,
9
9
  className: _,
10
- children: w
10
+ children: S
11
11
  }) {
12
- var b, p, h;
13
- const l = a(null), [S, t] = L("default"), c = a(u);
14
- c.current = u;
15
- const r = E(() => {
16
- var s;
17
- const e = (s = l.current) == null ? void 0 : s.querySelector("input, textarea, select");
18
- if (!e)
12
+ var p, x, h;
13
+ const c = u(null), [g, t] = C("default"), i = u(l);
14
+ i.current = l;
15
+ const r = L(() => {
16
+ var a;
17
+ const e = Array.from(
18
+ ((a = c.current) == null ? void 0 : a.querySelectorAll("input, textarea, select")) ?? []
19
+ );
20
+ if (e.length === 0)
19
21
  return t("default");
20
- if (e.matches(":disabled"))
22
+ if (e.every((n) => n.matches(":disabled")))
21
23
  return t("disabled");
22
- if (e.matches(":focus"))
24
+ if (e.some((n) => n.matches(":focus")))
23
25
  return t("focus");
24
- if (e.tagName.toLowerCase() === "select") {
25
- const x = e;
26
- return t(
27
- x.required && !x.value ? "error" : "valid"
28
- );
29
- }
30
- if (c.current || e.matches(":invalid"))
26
+ if (i.current || e.some((n) => n.matches(":invalid")))
31
27
  return t("error");
32
- if (e.matches(":valid") && e.matches(":not(:placeholder-shown)") && e.matches(":not(:invalid)"))
28
+ if (e.every((n) => n.value !== ""))
33
29
  return t("valid");
34
30
  t("default");
35
31
  }, []);
36
32
  v(() => {
37
- const e = l.current;
33
+ const e = c.current;
38
34
  if (!e)
39
35
  return;
40
- const s = new MutationObserver(r);
41
- return s.observe(e, { childList: !0, subtree: !0 }), e.addEventListener("focusin", r, !0), e.addEventListener("blur", r, !0), () => {
42
- s.disconnect(), e.removeEventListener("focusin", r, !0), e.removeEventListener("blur", r, !0);
36
+ const a = new MutationObserver(r);
37
+ return a.observe(e, { childList: !0, subtree: !0 }), e.addEventListener("focusin", r, !0), e.addEventListener("blur", r, !0), () => {
38
+ a.disconnect(), e.removeEventListener("focusin", r, !0), e.removeEventListener("blur", r, !0);
43
39
  };
44
40
  }, [r]);
45
- const i = a(!0), d = a(n);
41
+ const d = u(!0), f = u(s);
46
42
  v(() => {
47
- const e = d.current !== n;
48
- if (d.current = n, i.current) {
49
- i.current = !1, n && t("disabled");
43
+ const e = f.current !== s;
44
+ if (f.current = s, d.current) {
45
+ d.current = !1, s && t("disabled");
50
46
  return;
51
47
  }
52
48
  if (e)
53
- return t(n ? "disabled" : "default");
49
+ return t(s ? "disabled" : "default");
54
50
  r();
55
- }, [n, u, r]);
56
- const f = { ...k, ...m }, o = f[S] ?? f.default, g = {
51
+ }, [s, l, r]);
52
+ const b = { ...E, ...m }, o = b[g] ?? b.default, w = {
57
53
  "--text-color": o.textColor,
58
54
  "--placeholder-color": o.placeholderColor,
59
55
  "--background-color": o.backgroundColor,
60
- "--radius-size": ((b = o.border) == null ? void 0 : b.radius) || ".25rem",
61
- "--input-box-shadow": `0 0 0 ${((p = o.border) == null ? void 0 : p.size) || "1px"} ${(h = o.border) == null ? void 0 : h.color} inset, ${o.boxShadow || "0 0 0 0 rgba(0, 0, 0, 0)"}`
56
+ "--radius-size": ((p = o.border) == null ? void 0 : p.radius) || ".25rem",
57
+ "--input-box-shadow": `0 0 0 ${((x = o.border) == null ? void 0 : x.size) || "1px"} ${(h = o.border) == null ? void 0 : h.color} inset, ${o.boxShadow || "0 0 0 0 rgba(0, 0, 0, 0)"}`
62
58
  };
63
- return /* @__PURE__ */ C(
59
+ return /* @__PURE__ */ y(
64
60
  "div",
65
61
  {
66
- ref: l,
62
+ ref: c,
67
63
  className: `relative inline-flex max-w-full rounded-(--radius-size) bg-(--background-color) text-(--text-color) shadow-(--input-box-shadow) has-[:disabled]:pointer-events-none has-[:disabled]:before:pointer-events-auto has-[:disabled]:before:absolute has-[:disabled]:before:inset-0 has-[:disabled]:before:cursor-not-allowed has-[:disabled]:before:content-[''] [&_*::placeholder]:font-normal [&_*::placeholder]:text-(--placeholder-color) [&_*:focus]:outline-none [&_:is(input,textarea,select)]:w-full [&_:is(input,textarea,select)]:appearance-none [&_:is(input,textarea,select)]:border-none [&_:is(input,textarea,select)]:bg-transparent [&_:is(input,textarea,select)]:p-4 [&_:is(input,textarea,select)]:outline-none ${_ || ""}`,
68
- style: g,
69
- children: w
64
+ style: w,
65
+ children: S
70
66
  }
71
67
  );
72
68
  }
@@ -1,46 +1,49 @@
1
1
  "use client";
2
- import { jsxs as m, jsx as n } from "react/jsx-runtime";
3
- import { CheckBox as h } from "./CheckBox.js";
2
+ import { jsxs as p, jsx as t } from "react/jsx-runtime";
3
+ import { useId as h } from "react";
4
+ import { CheckBox as b } from "./CheckBox.js";
4
5
  import { COLOR as r } from "@geckou/ui-core";
5
- function f({
6
- name: c,
7
- label: l,
8
- checked: d,
9
- onChange: u,
10
- isDisabled: e,
11
- cssStyle: o,
12
- isDisableAnimation: x
6
+ function L({
7
+ name: l,
8
+ label: d,
9
+ checked: i,
10
+ onChange: m,
11
+ isDisabled: o,
12
+ cssStyle: e,
13
+ isDisableAnimation: u
13
14
  }) {
14
- const t = d ?? !1, i = e ? o == null ? void 0 : o.disabled : o == null ? void 0 : o.default, a = {
15
- textColor: e ? r.darkGray : r.black,
16
- backgroundColor: e ? r.darkGray : r.blue,
17
- ...i ?? {}
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,
18
+ ...x ?? {}
18
19
  }, k = {
19
- "--text-color": a.textColor,
20
- "--checked-color": a.backgroundColor
20
+ "--text-color": c.textColor,
21
+ "--checked-color": c.backgroundColor
21
22
  };
22
- return /* @__PURE__ */ m("label", { className: "inline-flex cursor-pointer items-center gap-[.5em] has-[input:disabled]:cursor-auto", children: [
23
- /* @__PURE__ */ n("span", { className: "pointer-events-none", children: /* @__PURE__ */ n(
24
- h,
23
+ return /* @__PURE__ */ p("label", { className: "inline-flex cursor-pointer items-center gap-[.5em] has-[input:disabled]:cursor-auto", children: [
24
+ /* @__PURE__ */ t("span", { className: "pointer-events-none", children: /* @__PURE__ */ t(
25
+ b,
25
26
  {
26
- name: c,
27
- checked: t,
28
- onChange: u,
29
- isDisabled: e,
30
- cssStyle: o,
31
- isDisableAnimation: x
27
+ name: l,
28
+ checked: a,
29
+ onChange: m,
30
+ isDisabled: o,
31
+ cssStyle: e,
32
+ isDisableAnimation: u,
33
+ ariaLabelledBy: n
32
34
  }
33
35
  ) }),
34
- /* @__PURE__ */ n(
36
+ /* @__PURE__ */ t(
35
37
  "span",
36
38
  {
39
+ id: n,
37
40
  style: k,
38
- className: t ? "text-(--text-color)" : "text-(--checked-color)",
39
- children: l
41
+ className: a ? "text-(--text-color)" : "text-(--checked-color)",
42
+ children: d
40
43
  }
41
44
  )
42
45
  ] });
43
46
  }
44
47
  export {
45
- f as LabeledCheckbox
48
+ L as LabeledCheckbox
46
49
  };
@@ -1,75 +1,90 @@
1
1
  "use client";
2
- import { jsx as e, jsxs as c } from "react/jsx-runtime";
3
- import { useId as p, useRef as f, useEffect as d } from "react";
4
- const v = {
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 = {
5
6
  small: "max-w-[var(--mobile-lower-width,430px)]",
6
7
  medium: "max-w-[var(--desktop-lower-width,1025px)]",
7
8
  large: "max-w-[var(--contents-max-width,1440px)]"
8
9
  };
9
- function x() {
10
- return /* @__PURE__ */ e(
10
+ function h() {
11
+ return /* @__PURE__ */ t(
11
12
  "svg",
12
13
  {
13
14
  xmlns: "http://www.w3.org/2000/svg",
14
15
  viewBox: "0 -960 960 960",
15
16
  fill: "currentColor",
16
- children: /* @__PURE__ */ e("path", { d: "m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z" })
17
+ children: /* @__PURE__ */ t("path", { d: "m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z" })
17
18
  }
18
19
  );
19
20
  }
20
- function w({
21
+ function N({
21
22
  isShown: r,
22
- size: s = "medium",
23
- onClose: t,
23
+ size: c = "medium",
24
+ onClose: a,
24
25
  header: l,
25
- footer: o,
26
- children: u,
27
- ariaLabel: n
26
+ footer: d,
27
+ children: p,
28
+ ariaLabel: f
28
29
  }) {
29
- const i = p(), m = f(null);
30
- return d(() => (r ? document.body.style.overflow = "hidden" : document.body.style.overflow = "", () => {
31
- document.body.style.overflow = "";
32
- }), [r]), d(() => {
33
- var a;
34
- r && ((a = m.current) == null || a.focus());
35
- }, [r]), /* @__PURE__ */ e(
30
+ const u = b(), s = m(null), v = m(g());
31
+ n(() => {
32
+ const e = v.current;
33
+ return e.toggle(r), () => e.release();
34
+ }, [r]);
35
+ const i = m(null);
36
+ return n(() => {
37
+ var e, o;
38
+ if (r) {
39
+ i.current = document.activeElement, (e = s.current) == null || e.focus();
40
+ return;
41
+ }
42
+ (o = i.current) == null || o.focus(), i.current = null;
43
+ }, [r]), n(() => {
44
+ if (!r)
45
+ return;
46
+ const e = (o) => {
47
+ o.key === "Escape" && a();
48
+ };
49
+ return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
50
+ }, [r, a]), /* @__PURE__ */ t(
36
51
  "div",
37
52
  {
38
53
  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"}`,
39
54
  "aria-hidden": !r,
40
55
  inert: !r,
41
- onClick: (a) => {
42
- a.target === a.currentTarget && t();
56
+ onClick: (e) => {
57
+ e.target === e.currentTarget && a();
43
58
  },
44
- children: /* @__PURE__ */ c(
59
+ children: /* @__PURE__ */ x(
45
60
  "div",
46
61
  {
47
- ref: m,
62
+ ref: s,
48
63
  role: "dialog",
49
64
  "aria-modal": "true",
50
- "aria-labelledby": l ? i : void 0,
51
- "aria-label": l ? void 0 : n ?? "ダイアログ",
65
+ "aria-labelledby": l ? u : void 0,
66
+ "aria-label": l ? void 0 : f ?? "ダイアログ",
52
67
  tabIndex: -1,
53
- 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] ${v[s]}`,
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]}`,
54
69
  children: [
55
- l && /* @__PURE__ */ e(
70
+ l && /* @__PURE__ */ t(
56
71
  "header",
57
72
  {
58
- id: i,
73
+ id: u,
59
74
  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)]",
60
75
  children: l
61
76
  }
62
77
  ),
63
- /* @__PURE__ */ e("div", { className: "flex-auto overflow-auto p-[var(--sp-large,1.5rem)] max-md:p-[var(--sp-medium,0.75rem)]", children: u }),
64
- o && /* @__PURE__ */ e("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: o }),
65
- /* @__PURE__ */ e(
78
+ /* @__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 }),
80
+ /* @__PURE__ */ t(
66
81
  "button",
67
82
  {
68
83
  type: "button",
69
84
  "aria-label": "閉じる",
70
85
  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",
71
- onClick: t,
72
- children: /* @__PURE__ */ e(x, {})
86
+ onClick: a,
87
+ children: /* @__PURE__ */ t(h, {})
73
88
  }
74
89
  )
75
90
  ]
@@ -79,5 +94,5 @@ function w({
79
94
  );
80
95
  }
81
96
  export {
82
- w as ModalBox
97
+ N as ModalBox
83
98
  };
@@ -1,64 +1,70 @@
1
1
  "use client";
2
- import { jsxs as n, jsx as c } from "react/jsx-runtime";
3
- import { useId as h } from "react";
4
- import { COLOR as r } from "@geckou/ui-core";
5
- function R({
6
- value: s,
7
- onChange: t,
8
- options: b,
9
- name: f,
10
- isDisabled: o,
11
- isRequired: p,
2
+ import { jsxs as f, jsx as u } from "react/jsx-runtime";
3
+ import { useState as N, useRef as G, useEffect as R, useId as z } from "react";
4
+ import { isEmptyValue as M, MESSAGES as V, COLOR as o } from "@geckou/ui-core";
5
+ import { ErrorMessage as j } from "./ErrorMessage.js";
6
+ function A({
7
+ value: p,
8
+ onChange: s,
9
+ options: m,
10
+ name: _,
11
+ isDisabled: a,
12
+ isRequired: n,
12
13
  cssStyle: e,
13
- isDisableAnimation: m
14
+ isDisableAnimation: v
14
15
  }) {
15
- var d, i;
16
- const _ = s ?? "", x = h(), v = f ?? x, k = o ? e == null ? void 0 : e.disabled : e == null ? void 0 : e.default, l = {
17
- textColor: o ? r.darkGray : r.black,
18
- backgroundColor: o ? r.lightGray : r.white,
16
+ var i, d;
17
+ const r = p ?? "", [g, x] = N(!1), c = G(r);
18
+ R(() => {
19
+ c.current !== r && (c.current = r, x(!0));
20
+ }, [r]);
21
+ const h = g && n && M(r) ? [V.required] : void 0, k = z(), w = _ ?? k, C = a ? e == null ? void 0 : e.disabled : e == null ? void 0 : e.default, l = {
22
+ textColor: a ? o.darkGray : o.black,
23
+ backgroundColor: a ? o.lightGray : o.white,
19
24
  border: {
20
- color: o ? r.darkGray : r.blue,
25
+ color: a ? o.darkGray : o.blue,
21
26
  size: "1px"
22
27
  },
23
- ...k ?? {}
24
- }, g = {
28
+ ...C ?? {}
29
+ }, E = {
25
30
  "--text-color": l.textColor,
26
- "--border-color": (d = l.border) == null ? void 0 : d.color,
27
- "--border-size": (i = l.border) == null ? void 0 : i.size,
31
+ "--border-color": (i = l.border) == null ? void 0 : i.color,
32
+ "--border-size": (d = l.border) == null ? void 0 : d.size,
28
33
  "--background-color": l.backgroundColor,
29
- "--duration": m ? "0s" : ".3s"
34
+ "--duration": v ? "0s" : ".3s"
30
35
  };
31
- return /* @__PURE__ */ n("div", { className: "flex flex-wrap items-center gap-4", children: [
32
- /* @__PURE__ */ c("style", { children: "@keyframes uiRadioPop{0%{scale:1}10%{scale:.8}50%{scale:1.2}100%{scale:1}}" }),
33
- b.map((a) => {
34
- const u = a.value === _;
35
- return /* @__PURE__ */ n(
36
+ return /* @__PURE__ */ f("div", { className: "relative flex flex-wrap items-center gap-4", children: [
37
+ /* @__PURE__ */ u("style", { children: "@keyframes uiRadioPop{0%{scale:1}10%{scale:.8}50%{scale:1.2}100%{scale:1}}" }),
38
+ m.map((t) => {
39
+ const b = t.value === r;
40
+ return /* @__PURE__ */ f(
36
41
  "label",
37
42
  {
38
- style: g,
39
- className: `relative grid cursor-pointer grid-cols-[auto_1fr] items-center gap-2 before:inline-block before:aspect-square before:w-4 before:rounded-full before:transition-all before:duration-(--duration) before:ease-linear before:content-[''] has-[input:disabled]:cursor-not-allowed has-[input:focus-visible]:outline-2 has-[input:focus-visible]:outline-offset-2 has-[input:focus-visible]:outline-(--border-color) ${u ? "text-(--text-color) before:animate-[uiRadioPop_var(--duration)_ease-out] before:bg-(--border-color) before:shadow-[0_0_0_2px_var(--background-color)_inset,0_0_0_1px_var(--border-color)]" : "text-(--border-color) before:bg-(--background-color) before:shadow-[0_0_0_1px_var(--border-color)_inset]"}`,
43
+ style: E,
44
+ className: `relative grid cursor-pointer grid-cols-[auto_1fr] items-center gap-2 before:inline-block before:aspect-square before:w-4 before:rounded-full before:transition-all before:duration-(--duration) before:ease-linear before:content-[''] has-[input:disabled]:cursor-not-allowed has-[input:focus-visible]:outline-2 has-[input:focus-visible]:outline-offset-2 has-[input:focus-visible]:outline-(--border-color) ${b ? "text-(--text-color) before:animate-[uiRadioPop_var(--duration)_ease-out] before:bg-(--border-color) before:shadow-[0_0_0_2px_var(--background-color)_inset,0_0_0_1px_var(--border-color)]" : "text-(--border-color) before:bg-(--background-color) before:shadow-[0_0_0_1px_var(--border-color)_inset]"}`,
40
45
  children: [
41
- /* @__PURE__ */ c(
46
+ /* @__PURE__ */ u(
42
47
  "input",
43
48
  {
44
49
  type: "radio",
45
- name: v,
46
- value: a.value,
47
- disabled: o,
48
- required: p,
49
- checked: u,
50
- onChange: () => t == null ? void 0 : t(a.value),
50
+ name: w,
51
+ value: t.value,
52
+ disabled: a,
53
+ required: n,
54
+ checked: b,
55
+ onChange: () => s == null ? void 0 : s(t.value),
51
56
  className: "sr-only"
52
57
  }
53
58
  ),
54
- /* @__PURE__ */ c("span", { children: a.label })
59
+ /* @__PURE__ */ u("span", { children: t.label })
55
60
  ]
56
61
  },
57
- a.value
62
+ t.value
58
63
  );
59
- })
64
+ }),
65
+ /* @__PURE__ */ u(j, { errorMessages: h })
60
66
  ] });
61
67
  }
62
68
  export {
63
- R as RadioButtons
69
+ A as RadioButtons
64
70
  };
@@ -10,7 +10,6 @@ type Props = {
10
10
  background: string;
11
11
  text: string;
12
12
  };
13
- type?: 'tab' | 'button' | 'border';
14
13
  initialIndex?: number;
15
14
  tabSlots?: Record<string, ReactNode>;
16
15
  panelSlots?: Record<string, ReactNode>;
@@ -1,70 +1,71 @@
1
1
  "use client";
2
- import { jsxs as I, jsx as k } from "react/jsx-runtime";
3
- import { useState as $, useRef as v, useId as w } from "react";
2
+ import { jsxs as I, jsx as a } from "react/jsx-runtime";
3
+ import { useState as v, useRef as $, useId as w } from "react";
4
4
  import { COLOR as T } from "@geckou/ui-core";
5
5
  function C({
6
- tabs: r,
7
- color: t,
6
+ tabs: t,
7
+ color: r,
8
8
  initialIndex: p = 0,
9
9
  tabSlots: d,
10
10
  panelSlots: y
11
11
  }) {
12
- const [c, o] = $(
12
+ const [i, k] = v(
13
13
  () => {
14
14
  var e, n;
15
- return ((e = r[p]) == null ? void 0 : e.key) ?? ((n = r[0]) == null ? void 0 : n.key) ?? "";
15
+ return ((e = t[p]) == null ? void 0 : e.key) ?? ((n = t[0]) == null ? void 0 : n.key) ?? "";
16
16
  }
17
- ), s = v([]), a = w(), u = (e) => `${a}-tab-${e}`, f = (e) => `${a}-panel-${e}`, m = (e) => o(e), l = (e) => {
17
+ ), s = $([]), u = w(), o = (e) => `${u}-tab-${e}`, f = (e) => `${u}-panel-${e}`, l = (e) => k(e), x = (e) => {
18
18
  var n;
19
- o(r[e].key), (n = s.current[e]) == null || n.focus();
19
+ k(t[e].key), (n = s.current[e]) == null || n.focus();
20
20
  }, h = (e) => {
21
21
  if (e.key !== "ArrowLeft" && e.key !== "ArrowRight")
22
22
  return;
23
- const n = r.findIndex((g) => g.key === c);
23
+ const n = t.findIndex((g) => g.key === i);
24
24
  if (n === -1)
25
25
  return;
26
26
  e.preventDefault();
27
- const i = r.length - 1;
28
- e.key === "ArrowLeft" ? l(n > 0 ? n - 1 : i) : l(n < i ? n + 1 : 0);
29
- }, x = {
30
- "--active-color": (t == null ? void 0 : t.active) || T.blue,
31
- "--background-color": (t == null ? void 0 : t.background) || "transparent"
27
+ const c = t.length - 1;
28
+ e.key === "ArrowLeft" ? x(n > 0 ? n - 1 : c) : x(n < c ? n + 1 : 0);
29
+ }, m = {
30
+ "--active-color": (r == null ? void 0 : r.active) || T.blue,
31
+ "--background-color": (r == null ? void 0 : r.background) || "transparent",
32
+ "--text-color": (r == null ? void 0 : r.text) || "inherit"
32
33
  };
33
34
  return /* @__PURE__ */ I("div", { children: [
34
- /* @__PURE__ */ k(
35
+ /* @__PURE__ */ a(
35
36
  "div",
36
37
  {
37
- style: x,
38
+ style: m,
38
39
  className: "flex bg-(--background-color)",
39
40
  role: "tablist",
40
41
  onKeyDown: h,
41
- children: r.map((e, n) => /* @__PURE__ */ k(
42
+ children: t.map((e, n) => /* @__PURE__ */ a(
42
43
  "button",
43
44
  {
44
- id: u(e.key),
45
- ref: (i) => {
46
- s.current[n] = i;
45
+ id: o(e.key),
46
+ ref: (c) => {
47
+ s.current[n] = c;
47
48
  },
48
49
  type: "button",
49
50
  role: "tab",
50
51
  "aria-controls": f(e.key),
51
- "aria-selected": c === e.key,
52
- tabIndex: c === e.key ? 0 : -1,
53
- className: `border-none bg-transparent px-4 py-2 text-base ${c === e.key ? "cursor-auto" : "cursor-pointer"}`,
54
- onClick: () => m(e.key),
52
+ "aria-selected": i === e.key,
53
+ tabIndex: i === e.key ? 0 : -1,
54
+ className: `border-none bg-transparent px-4 py-2 text-base ${i === e.key ? "cursor-auto text-(--active-color)" : "cursor-pointer text-(--text-color)"}`,
55
+ onClick: () => l(e.key),
55
56
  children: (d == null ? void 0 : d[e.key]) ?? e.label
56
57
  },
57
58
  e.key
58
59
  ))
59
60
  }
60
61
  ),
61
- r.map((e) => /* @__PURE__ */ k(
62
+ t.map((e) => /* @__PURE__ */ a(
62
63
  "div",
63
64
  {
64
65
  id: f(e.key),
65
66
  role: "tabpanel",
66
- "aria-labelledby": u(e.key),
67
- hidden: c !== e.key,
67
+ "aria-labelledby": o(e.key),
68
+ hidden: i !== e.key,
68
69
  children: y == null ? void 0 : y[`${e.key}Contents`]
69
70
  },
70
71
  `${e.key}_panel`
@@ -10,6 +10,9 @@ type Props = {
10
10
  onChange?: (newValue: boolean) => void;
11
11
  isDisabled?: boolean;
12
12
  cssStyle?: StyleForEachStatus<ToggleStyle>;
13
+ /** アクセシブル名。可視ラベルがあるなら ariaLabelledBy でその要素を指すこと */
14
+ ariaLabel?: string;
15
+ ariaLabelledBy?: string;
13
16
  };
14
- export declare function ToggleButton({ name, label, checked, onChange, isDisabled, cssStyle, }: Props): import("react").JSX.Element;
17
+ export declare function ToggleButton({ name, label, checked, onChange, isDisabled, cssStyle, ariaLabel, ariaLabelledBy, }: Props): import("react").JSX.Element;
15
18
  export {};
@@ -1,16 +1,18 @@
1
1
  "use client";
2
- import { jsxs as x, jsx as f } from "react/jsx-runtime";
2
+ import { jsxs as v, jsx as f } from "react/jsx-runtime";
3
3
  import { COLOR as e } from "@geckou/ui-core";
4
- function m({
4
+ function k({
5
5
  name: l,
6
6
  label: n = { on: "ON", off: "OFF" },
7
- checked: b,
7
+ checked: h,
8
8
  onChange: d,
9
9
  isDisabled: o,
10
- cssStyle: r
10
+ cssStyle: r,
11
+ ariaLabel: p,
12
+ ariaLabelledBy: c
11
13
  }) {
12
- var c, u, s;
13
- const a = b ?? !1, p = Math.max(n.on.length, n.off.length), t = o ? r == null ? void 0 : r.disabled : r == null ? void 0 : r.default, i = {
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 = {
14
16
  on: {
15
17
  textColor: o ? e.lightGray : e.white,
16
18
  backgroundColor: o ? e.gray : e.blue,
@@ -33,28 +35,30 @@ function m({
33
35
  boxShadow: "0 0 0 0 rgba(0, 0, 0, 0)",
34
36
  ...t == null ? void 0 : t.off
35
37
  }
36
- }[a ? "on" : "off"], h = {
38
+ }[a ? "on" : "off"], x = {
37
39
  "--text-color": i.textColor,
38
- "--border-color": (c = i.border) == null ? void 0 : c.color,
39
- "--border-size": (u = i.border) == null ? void 0 : u.size,
40
- "--radius-size": (s = i.border) == null ? void 0 : s.radius,
40
+ "--border-color": (u = i.border) == null ? void 0 : u.color,
41
+ "--border-size": (s = i.border) == null ? void 0 : s.size,
42
+ "--radius-size": (b = i.border) == null ? void 0 : b.radius,
41
43
  "--background-color": i.backgroundColor,
42
44
  "--box-shadow": i.boxShadow,
43
- "--inline-size": `${p * 2}ch`,
45
+ "--inline-size": `${g * 2}ch`,
44
46
  "--handle-size": "1.5rem",
45
47
  "--padding-size": "calc(var(--border-size) + 2px)",
46
48
  "--duration": ".15s"
47
49
  };
48
- return /* @__PURE__ */ x(
50
+ return /* @__PURE__ */ v(
49
51
  "button",
50
52
  {
51
53
  type: "button",
52
- style: h,
54
+ style: x,
53
55
  disabled: o,
54
- "aria-pressed": a,
55
- "aria-label": l,
56
- onClick: (g) => {
57
- g.stopPropagation(), o || d == null || d(!a);
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);
58
62
  },
59
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)",
60
64
  children: [
@@ -88,5 +92,5 @@ function m({
88
92
  );
89
93
  }
90
94
  export {
91
- m as ToggleButton
95
+ k as ToggleButton
92
96
  };