@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.
package/README.md CHANGED
@@ -84,6 +84,16 @@ props は Vue 版(`@geckou/ui-vue`)と揃えている。`v-model` にあた
84
84
  | `DateRangePicker` | `{ start: string; end: string }` | `DatePicker` と同じ(開始日と終了日の min / max が自動連動)。各入力の name は `<name>Start` / `<name>End` |
85
85
  | `DateSelector` | `string`(`YYYY-MM-DD` / `type="month"` なら `YYYY-MM`) | `name` / `isRequired` / `type` / `formValidationStore` |
86
86
 
87
+ `DatePicker` / `DateSelector` の年月日欄の読み上げ名は、既定では `name` から作られます
88
+ (`name="startedOn"` なら「startedOnの年」)。`CheckBox` と同じ `ariaLabel` / `ariaLabelledBy`
89
+ を渡すと、そちらを土台に「の年」「の月」「の日」を繋げます。可視ラベルがあるなら
90
+ `ariaLabelledBy` でその要素を指してください(WCAG 2.5.3 Label in Name)。
91
+
92
+ ```tsx
93
+ <DatePicker name="startedOn" ariaLabel="開始日" /> {/* 「開始日の年」 */}
94
+ <DatePicker name="startedOn" ariaLabelledBy={labelId} /> {/* 可視ラベル + 「の年」 */}
95
+ ```
96
+
87
97
  ## 収録コンポーネント
88
98
 
89
99
  フォーム系 25 種(`TextBox` / `TextArea` / `SelectBox` / `SearchableSelectBox` / `CheckBox` 系 /
@@ -98,6 +108,17 @@ props は Vue 版(`@geckou/ui-vue`)と揃えている。`v-model` にあた
98
108
  yarn workspace @geckou/ui-react test
99
109
  ```
100
110
 
111
+ ## 0.5.0 の変更
112
+
113
+ - `DatePicker` / `DateSelector` が `ariaLabel` / `ariaLabelledBy` を受ける
114
+ (未指定なら従来どおり `name` から読み上げ名を作る)
115
+ - `CheckBox` / `ToggleButton` が `<button>` の中に `<input>` を置かなくなった。
116
+ 状態は `<button>` の `data-checked` / `disabled` で表し、送信用の入力は
117
+ チェック時だけ `<input type="hidden">` として `<button>` の外に描かれる。
118
+ DOM を辿っているテストやスタイルがあれば追従が要る
119
+ - `ModalBox` が開いている間、Tab / Shift+Tab をダイアログ内で循環させる(フォーカストラップ)
120
+ - `SearchableSelectBox` が WAI-ARIA の Combobox パターンに沿い、↑↓ / Enter / Escape で操作できる
121
+
101
122
  ## 0.4.0 の変更
102
123
 
103
124
  - `RadioButtons` が必須エラー(「必須項目です」)を描画する。Vue 版と同じく、
@@ -1,20 +1,20 @@
1
1
  "use client";
2
- import { jsxs as f, Fragment as _, jsx as d } from "react/jsx-runtime";
3
- import { CheckIcon as z } from "./icons/CheckIcon.js";
2
+ import { jsxs as v, Fragment as C, jsx as i } from "react/jsx-runtime";
3
+ import { CheckIcon as _ } from "./icons/CheckIcon.js";
4
4
  import { COLOR as t } from "@geckou/ui-core";
5
- function g({
5
+ function j({
6
6
  name: l,
7
- checked: p,
8
- onChange: r,
7
+ checked: s,
8
+ onChange: c,
9
9
  isDisabled: e,
10
- cssStyle: o,
11
- isDisableAnimation: k,
12
- check: h,
13
- ariaLabel: x,
14
- ariaLabelledBy: u
10
+ cssStyle: r,
11
+ isDisableAnimation: f,
12
+ check: k,
13
+ ariaLabel: p,
14
+ ariaLabelledBy: a
15
15
  }) {
16
- var n, s, b;
17
- const i = p ?? !1, m = e ? o == null ? void 0 : o.disabled : o == null ? void 0 : o.default, c = {
16
+ var n, u, b;
17
+ const o = s ?? !1, h = e ? r == null ? void 0 : r.disabled : r == null ? void 0 : r.default, d = {
18
18
  textColor: e ? t.darkGray : t.blue,
19
19
  backgroundColor: e ? t.lightGray : t.white,
20
20
  border: {
@@ -22,57 +22,44 @@ function g({
22
22
  size: "1px",
23
23
  radius: ".25rem"
24
24
  },
25
- ...m
26
- }, v = {
27
- "--text-color": c.textColor,
28
- "--border-color": (n = c.border) == null ? void 0 : n.color,
29
- "--border-size": (s = c.border) == null ? void 0 : s.size,
30
- "--radius-size": (b = c.border) == null ? void 0 : b.radius,
31
- "--background-color": c.backgroundColor,
32
- "--duration": k ? "0s" : ".3s"
25
+ ...h
26
+ }, x = {
27
+ "--text-color": d.textColor,
28
+ "--border-color": (n = d.border) == null ? void 0 : n.color,
29
+ "--border-size": (u = d.border) == null ? void 0 : u.size,
30
+ "--radius-size": (b = d.border) == null ? void 0 : b.radius,
31
+ "--background-color": d.backgroundColor,
32
+ "--duration": f ? "0s" : ".3s"
33
33
  };
34
- return /* @__PURE__ */ f(_, { children: [
35
- /* @__PURE__ */ d("style", { children: "@keyframes uiCheckPop{0%{scale:1}10%{scale:.8}50%{scale:1.1}100%{scale:1}}" }),
36
- /* @__PURE__ */ f(
34
+ return /* @__PURE__ */ v(C, { children: [
35
+ /* @__PURE__ */ i("style", { children: "@keyframes uiCheckPop{0%{scale:1}10%{scale:.8}50%{scale:1.1}100%{scale:1}}" }),
36
+ /* @__PURE__ */ i(
37
37
  "button",
38
38
  {
39
39
  type: "button",
40
- style: v,
40
+ style: x,
41
41
  role: "checkbox",
42
- "aria-checked": i,
43
- "aria-labelledby": u,
44
- "aria-label": u ? void 0 : x ?? l,
42
+ "aria-checked": o,
43
+ "data-checked": o,
44
+ "aria-labelledby": a,
45
+ "aria-label": a ? void 0 : p ?? l,
45
46
  disabled: e,
46
- onClick: (a) => {
47
- a.stopPropagation(), e || r == null || r(!i);
47
+ onClick: (m) => {
48
+ m.stopPropagation(), e || c == null || c(!o);
48
49
  },
49
- className: `relative flex h-6 w-6 cursor-pointer items-center justify-center rounded-(--radius-size) border-none shadow-[0_0_0_var(--border-size)_var(--border-color)_inset] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--border-color) has-[input:disabled]:pointer-events-none has-[input:disabled]:before:pointer-events-auto has-[input:disabled]:before:absolute has-[input:disabled]:before:inset-0 has-[input:disabled]:before:cursor-not-allowed has-[input:disabled]:before:content-[''] ${i ? "animate-[uiCheckPop_var(--duration)_ease-out] bg-(--border-color)" : "bg-(--background-color)"}`,
50
- children: [
51
- /* @__PURE__ */ d(
52
- "input",
53
- {
54
- type: "checkbox",
55
- name: l,
56
- checked: i,
57
- disabled: e,
58
- onChange: (a) => {
59
- e || r == null || r(a.target.checked);
60
- },
61
- className: "hidden"
62
- }
63
- ),
64
- /* @__PURE__ */ d(
65
- "div",
66
- {
67
- className: `flex h-4 w-4 items-center justify-center [&>*]:fill-current [&>*]:text-current ${i ? "text-(--background-color)" : "text-(--border-color)"}`,
68
- children: h ?? /* @__PURE__ */ d(z, {})
69
- }
70
- )
71
- ]
50
+ className: `relative flex h-6 w-6 cursor-pointer items-center justify-center rounded-(--radius-size) border-none shadow-[0_0_0_var(--border-size)_var(--border-color)_inset] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--border-color) disabled:pointer-events-none disabled:before:pointer-events-auto disabled:before:absolute disabled:before:inset-0 disabled:before:cursor-not-allowed disabled:before:content-[''] ${o ? "animate-[uiCheckPop_var(--duration)_ease-out] bg-(--border-color)" : "bg-(--background-color)"}`,
51
+ children: /* @__PURE__ */ i(
52
+ "div",
53
+ {
54
+ className: `flex h-4 w-4 items-center justify-center [&>*]:fill-current [&>*]:text-current ${o ? "text-(--background-color)" : "text-(--border-color)"}`,
55
+ children: k ?? /* @__PURE__ */ i(_, {})
56
+ }
57
+ )
72
58
  }
73
- )
59
+ ),
60
+ o && /* @__PURE__ */ i("input", { type: "hidden", name: l, value: "on", disabled: e })
74
61
  ] });
75
62
  }
76
63
  export {
77
- g as CheckBox
64
+ j as CheckBox
78
65
  };
@@ -13,6 +13,13 @@ type Props = {
13
13
  maxDate?: string;
14
14
  size?: 'small' | 'medium';
15
15
  type?: 'date' | 'month';
16
+ /**
17
+ * 年月日それぞれの読み上げ名の土台。「の年」「の月」「の日」を後ろに繋げる。
18
+ * 可視ラベルがあるなら ariaLabelledBy でその要素を指すこと。
19
+ * どちらも無いときだけ name を使う(機械名でも無いよりはマシ)
20
+ */
21
+ ariaLabel?: string;
22
+ ariaLabelledBy?: string;
16
23
  };
17
- export declare function DatePicker({ name, value, onChange, cssStyle, isDisabled, isRequired, formValidationStore, minDate, maxDate, size, type, }: Props): import("react").JSX.Element;
24
+ export declare function DatePicker({ name, value, onChange, cssStyle, isDisabled, isRequired, formValidationStore, minDate, maxDate, size, type, ariaLabel, ariaLabelledBy, }: Props): import("react").JSX.Element;
18
25
  export {};
@@ -1,131 +1,138 @@
1
1
  "use client";
2
- import { jsxs as N, jsx as t } from "react/jsx-runtime";
3
- import { formatDateValue as g, splitDate as k, COLOR as G, MESSAGES as R, composeDateValue as q, validateDateObject as C } from "@geckou/ui-core";
4
- import { useState as o, useRef as F, useEffect as H } from "react";
5
- import { InputBox as J } from "./InputBox.js";
6
- import { ErrorMessage as K } from "./ErrorMessage.js";
7
- import { CalendarIcon as Q } from "./icons/CalendarIcon.js";
8
- import { useRegisterValidation as T } from "../hooks/useFormValidation.js";
9
- function ae({
10
- name: l,
2
+ import { jsxs as j, jsx as r } from "react/jsx-runtime";
3
+ import { formatDateValue as V, splitDate as w, COLOR as H, MESSAGES as J, composeDateValue as K, validateDateObject as Q } from "@geckou/ui-core";
4
+ import { useState as m, useRef as T, useEffect as U, useId as W } from "react";
5
+ import { InputBox as X } from "./InputBox.js";
6
+ import { ErrorMessage as Y } from "./ErrorMessage.js";
7
+ import { CalendarIcon as Z } from "./icons/CalendarIcon.js";
8
+ import { useRegisterValidation as _ } from "../hooks/useFormValidation.js";
9
+ function le({
10
+ name: o,
11
11
  value: a,
12
12
  onChange: s,
13
- cssStyle: E,
13
+ cssStyle: M,
14
14
  isDisabled: i,
15
- isRequired: n,
16
- formValidationStore: S,
17
- minDate: I = "",
18
- maxDate: M = "",
19
- size: D = "medium",
20
- type: r = "date"
15
+ isRequired: d,
16
+ formValidationStore: D,
17
+ minDate: L = "",
18
+ maxDate: z = "",
19
+ size: P = "medium",
20
+ type: t = "date",
21
+ ariaLabel: A,
22
+ ariaLabelledBy: p
21
23
  }) {
22
- const [j, d] = o(
23
- () => a ? g(a, r) : ""
24
- ), [c, p] = o(
25
- () => a ? k(g(a, r)) : { year: "", month: "", day: "" }
26
- ), [u, V] = o(""), [L, f] = o(!0), $ = F(a);
27
- H(() => {
28
- if ($.current === a)
24
+ const [y, u] = m(
25
+ () => a ? V(a, t) : ""
26
+ ), [l, f] = m(
27
+ () => a ? w(V(a, t)) : { year: "", month: "", day: "" }
28
+ ), [v, O] = m(""), [G, h] = m(!0), N = T(a);
29
+ U(() => {
30
+ if (N.current === a)
29
31
  return;
30
- $.current = a;
31
- const e = a ? g(a, r) : "";
32
- d(e), p(k(e)), f(!0);
33
- }, [a, r]);
34
- const w = (e) => !e && n ? { isValid: !1, message: R.required } : { isValid: !0, message: "" }, z = (e) => C(e, { type: r, isRequired: n }), P = (e) => {
35
- d(e), p(k(e));
36
- const { message: x } = w(e);
37
- V(x), f(!0), s == null || s(e);
38
- }, v = (e, x) => {
39
- const h = { ...c, [e]: x };
40
- p(h);
41
- const { isValid: y, message: B } = z(h);
42
- if (V(B), f(y), y) {
43
- const O = q(h, r);
44
- d(O), s == null || s(O);
32
+ N.current = a;
33
+ const e = a ? V(a, t) : "";
34
+ u(e), f(w(e)), h(!0);
35
+ }, [a, t]);
36
+ const I = (e) => !e && d ? { isValid: !1, message: J.required } : { isValid: !0, message: "" }, R = (e) => Q(e, { type: t, isRequired: d }), q = (e) => {
37
+ u(e), f(w(e));
38
+ const { message: $ } = I(e);
39
+ O($), h(!0), s == null || s(e);
40
+ }, b = (e, $) => {
41
+ const k = { ...l, [e]: $ };
42
+ f(k);
43
+ const { isValid: E, message: F } = R(k);
44
+ if (O(F), h(E), E) {
45
+ const S = K(k, t);
46
+ u(S), s == null || s(S);
45
47
  }
46
48
  };
47
- T(
48
- S,
49
- l,
50
- w(j).isValid && L
49
+ _(
50
+ D,
51
+ o,
52
+ I(y).isValid && G
51
53
  );
52
- const m = D === "small", b = `flex-none! ${m ? "px-[var(--sp-small,0.375rem)]! py-[var(--sp-min,0.1875rem)]! text-[length:var(--fs-small,0.6875rem)]" : "p-[var(--sp-medium,0.75rem)]!"}`, A = { "--icon-color": G.blue };
53
- return /* @__PURE__ */ N(
54
- J,
54
+ const c = W(), x = (e) => p ? { "aria-labelledby": `${p} ${c}-${e}` } : { "aria-label": `${A ?? o}の${e}` }, n = P === "small", g = `flex-none! ${n ? "px-[var(--sp-small,0.375rem)]! py-[var(--sp-min,0.1875rem)]! text-[length:var(--fs-small,0.6875rem)]" : "p-[var(--sp-medium,0.75rem)]!"}`, C = { "--icon-color": H.blue };
55
+ return /* @__PURE__ */ j(
56
+ X,
55
57
  {
56
- cssStyle: E,
58
+ cssStyle: M,
57
59
  isDisabled: i,
58
- isErrored: !!u,
59
- className: `flex w-full items-center leading-none ${m ? "h-[calc(var(--bv,0.375rem)*5)] px-[var(--sp-min,0.1875rem)]" : "h-[calc(var(--bv,0.375rem)*6)] px-[var(--sp-small,0.375rem)]"}`,
60
+ isErrored: !!v,
61
+ className: `flex w-full items-center leading-none ${n ? "h-[calc(var(--bv,0.375rem)*5)] px-[var(--sp-min,0.1875rem)]" : "h-[calc(var(--bv,0.375rem)*6)] px-[var(--sp-small,0.375rem)]"}`,
60
62
  children: [
61
- /* @__PURE__ */ N("div", { className: "relative flex-none", style: A, children: [
62
- /* @__PURE__ */ t(
63
- Q,
63
+ /* @__PURE__ */ j("div", { className: "relative flex-none", style: C, children: [
64
+ /* @__PURE__ */ r(
65
+ Z,
64
66
  {
65
- className: `pointer-events-none absolute inset-y-0 left-[var(--sp-small,0.375rem)] m-auto fill-(--icon-color) ${m ? "size-[var(--icon-small,0.9375rem)]" : "size-[var(--icon-medium,1.125rem)]"}`
67
+ className: `pointer-events-none absolute inset-y-0 left-[var(--sp-small,0.375rem)] m-auto fill-(--icon-color) ${n ? "size-[var(--icon-small,0.9375rem)]" : "size-[var(--icon-medium,1.125rem)]"}`
66
68
  }
67
69
  ),
68
- /* @__PURE__ */ t(
70
+ /* @__PURE__ */ r(
69
71
  "input",
70
72
  {
71
- type: r,
72
- name: l,
73
- value: j,
74
- max: M,
75
- min: I,
76
- required: n,
73
+ type: t,
74
+ name: o,
75
+ value: y,
76
+ max: z,
77
+ min: L,
78
+ required: d,
77
79
  disabled: i,
78
- onChange: (e) => P(e.target.value),
79
- className: `w-[calc(var(--icon-medium,1.125rem)+var(--sp-small,0.375rem)*2)]! cursor-pointer px-[var(--sp-small,0.375rem)]! opacity-0 [&::-webkit-calendar-picker-indicator]:absolute [&::-webkit-calendar-picker-indicator]:left-0 [&::-webkit-calendar-picker-indicator]:h-full [&::-webkit-calendar-picker-indicator]:w-full [&::-webkit-calendar-picker-indicator]:cursor-pointer [&::-webkit-calendar-picker-indicator]:opacity-0 ${m ? "py-[var(--sp-min,0.1875rem)]!" : "py-[var(--sp-medium,0.75rem)]!"}`
80
+ onChange: (e) => q(e.target.value),
81
+ className: `w-[calc(var(--icon-medium,1.125rem)+var(--sp-small,0.375rem)*2)]! cursor-pointer px-[var(--sp-small,0.375rem)]! opacity-0 [&::-webkit-calendar-picker-indicator]:absolute [&::-webkit-calendar-picker-indicator]:left-0 [&::-webkit-calendar-picker-indicator]:h-full [&::-webkit-calendar-picker-indicator]:w-full [&::-webkit-calendar-picker-indicator]:cursor-pointer [&::-webkit-calendar-picker-indicator]:opacity-0 ${n ? "py-[var(--sp-min,0.1875rem)]!" : "py-[var(--sp-medium,0.75rem)]!"}`
80
82
  }
81
83
  )
82
84
  ] }),
83
- /* @__PURE__ */ t(
85
+ /* @__PURE__ */ r(
84
86
  "input",
85
87
  {
86
- value: c.year,
88
+ value: l.year,
87
89
  placeholder: "年",
88
- "aria-label": `${l}の年`,
90
+ ...x(""),
89
91
  maxLength: 4,
90
92
  type: "text",
91
93
  disabled: i,
92
- onChange: (e) => v("year", e.target.value),
93
- className: `w-[calc(var(--sp-medium,0.75rem)*2+5ch)]! ${b}`
94
+ onChange: (e) => b("year", e.target.value),
95
+ className: `w-[calc(var(--sp-medium,0.75rem)*2+5ch)]! ${g}`
94
96
  }
95
97
  ),
96
98
  "/",
97
- /* @__PURE__ */ t(
99
+ /* @__PURE__ */ r(
98
100
  "input",
99
101
  {
100
- value: c.month,
102
+ value: l.month,
101
103
  placeholder: "月",
102
- "aria-label": `${l}の月`,
104
+ ...x(""),
103
105
  maxLength: 2,
104
106
  type: "text",
105
107
  disabled: i,
106
- onChange: (e) => v("month", e.target.value),
107
- className: `w-[calc(var(--sp-medium,0.75rem)*2+3ch)]! ${b}`
108
+ onChange: (e) => b("month", e.target.value),
109
+ className: `w-[calc(var(--sp-medium,0.75rem)*2+3ch)]! ${g}`
108
110
  }
109
111
  ),
110
- r === "date" && /* @__PURE__ */ t("span", { children: "/" }),
111
- r === "date" && /* @__PURE__ */ t(
112
+ t === "date" && /* @__PURE__ */ r("span", { children: "/" }),
113
+ t === "date" && /* @__PURE__ */ r(
112
114
  "input",
113
115
  {
114
- value: c.day,
116
+ value: l.day,
115
117
  placeholder: "日",
116
- "aria-label": `${l}の日`,
118
+ ...x(""),
117
119
  maxLength: 2,
118
120
  type: "text",
119
121
  disabled: i,
120
- onChange: (e) => v("day", e.target.value),
121
- className: `w-[calc(var(--sp-medium,0.75rem)*2+3ch)]! ${b}`
122
+ onChange: (e) => b("day", e.target.value),
123
+ className: `w-[calc(var(--sp-medium,0.75rem)*2+3ch)]! ${g}`
122
124
  }
123
125
  ),
124
- /* @__PURE__ */ t(K, { errorMessages: u ? [u] : void 0 })
126
+ p && /* @__PURE__ */ j("span", { className: "sr-only", children: [
127
+ /* @__PURE__ */ r("span", { id: `${c}-年`, children: "の年" }),
128
+ /* @__PURE__ */ r("span", { id: `${c}-月`, children: "の月" }),
129
+ /* @__PURE__ */ r("span", { id: `${c}-日`, children: "の日" })
130
+ ] }),
131
+ /* @__PURE__ */ r(Y, { errorMessages: v ? [v] : void 0 })
125
132
  ]
126
133
  }
127
134
  );
128
135
  }
129
136
  export {
130
- ae as DatePicker
137
+ le as DatePicker
131
138
  };
@@ -11,6 +11,13 @@ type Props = {
11
11
  /** 選べる年の下限・上限。既定は「今年 -100 〜 今年 -14」(生年月日向け) */
12
12
  minYear?: number;
13
13
  maxYear?: number;
14
+ /**
15
+ * 年月日それぞれの読み上げ名の土台。「の年」「の月」「の日」を後ろに繋げる。
16
+ * 可視ラベルがあるなら ariaLabelledBy でその要素を指すこと。
17
+ * どちらも無いときだけ name を使う(機械名でも無いよりはマシ)
18
+ */
19
+ ariaLabel?: string;
20
+ ariaLabelledBy?: string;
14
21
  };
15
- export declare function DateSelector({ name, value, onChange, isRequired, formValidationStore, type, minYear, maxYear, }: Props): import("react").JSX.Element;
22
+ export declare function DateSelector({ name, value, onChange, isRequired, formValidationStore, type, minYear, maxYear, ariaLabel, ariaLabelledBy, }: Props): import("react").JSX.Element;
16
23
  export {};
@@ -1,134 +1,141 @@
1
1
  "use client";
2
- import { jsxs as s, jsx as l } from "react/jsx-runtime";
3
- import { useState as C, useEffect as F } from "react";
4
- import { splitDate as z, COLOR as I, daysInMonth as H } from "@geckou/ui-core";
5
- import { InputBox as K } from "./InputBox.js";
6
- import { KeyboardArrowDownIcon as f } from "./icons/KeyboardArrowDownIcon.js";
7
- import { useRegisterValidation as L } from "../hooks/useFormValidation.js";
8
- const b = { year: "", month: "", day: "" };
9
- function R({
10
- name: o,
11
- value: i,
12
- onChange: n,
2
+ import { jsxs as o, jsx as r } from "react/jsx-runtime";
3
+ import { useState as H, useEffect as K, useId as L } from "react";
4
+ import { splitDate as V, COLOR as O, daysInMonth as q } from "@geckou/ui-core";
5
+ import { InputBox as G } from "./InputBox.js";
6
+ import { KeyboardArrowDownIcon as g } from "./icons/KeyboardArrowDownIcon.js";
7
+ import { useRegisterValidation as J } from "../hooks/useFormValidation.js";
8
+ const S = { year: "", month: "", day: "" };
9
+ function ee({
10
+ name: n,
11
+ value: m,
12
+ onChange: s,
13
13
  isRequired: c,
14
- formValidationStore: $,
15
- type: m = "date",
16
- minYear: A,
17
- maxYear: M
14
+ formValidationStore: k,
15
+ type: d = "date",
16
+ minYear: B,
17
+ maxYear: E,
18
+ ariaLabel: T,
19
+ ariaLabelledBy: u
18
20
  }) {
19
- const [r, d] = C(b), g = !!(r.year && r.month && (m === "month" || r.day)), O = !r.year && !r.month && !r.day;
20
- L(
21
- $,
22
- o,
23
- c ? g : g || O
24
- ), F(() => {
25
- d(i ? z(i) : b);
26
- }, [i]);
27
- const N = (/* @__PURE__ */ new Date()).getFullYear(), S = A ?? N - 100, k = M ?? N - 14, E = Array.from(
28
- { length: Math.max(k - S + 1, 0) },
29
- (e, a) => (S + a).toString()
30
- ).map((e) => ({ label: e, value: e })), T = Array.from({ length: 12 }, (e, a) => {
21
+ const [l, p] = H(S), $ = !!(l.year && l.month && (d === "month" || l.day)), Y = !l.year && !l.month && !l.day;
22
+ J(
23
+ k,
24
+ n,
25
+ c ? $ : $ || Y
26
+ ), K(() => {
27
+ p(m ? V(m) : S);
28
+ }, [m]);
29
+ const w = (/* @__PURE__ */ new Date()).getFullYear(), D = B ?? w - 100, _ = E ?? w - 14, j = Array.from(
30
+ { length: Math.max(_ - D + 1, 0) },
31
+ (e, a) => (D + a).toString()
32
+ ).map((e) => ({ label: e, value: e })), C = Array.from({ length: 12 }, (e, a) => {
31
33
  const t = (a + 1).toString();
32
34
  return { label: t, value: t.padStart(2, "0") };
33
- }), w = (e, a) => H(Number(e) || 2e3, Number(a)), Y = w(r.year, r.month), _ = Array.from({ length: Y }, (e, a) => {
35
+ }), I = (e, a) => q(Number(e) || 2e3, Number(a)), F = I(l.year, l.month), P = Array.from({ length: F }, (e, a) => {
34
36
  const t = (a + 1).toString();
35
37
  return { label: t, value: t.padStart(2, "0") };
36
- }), D = (e) => {
37
- d(e);
38
- const a = m === "month" ? [e.year, e.month] : [e.year, e.month, e.day];
38
+ }), x = (e) => {
39
+ p(e);
40
+ const a = d === "month" ? [e.year, e.month] : [e.year, e.month, e.day];
39
41
  if (!e.year && !e.month && !e.day)
40
- n == null || n("");
42
+ s == null || s("");
41
43
  else {
42
44
  if (a.some((t) => !t))
43
45
  return;
44
- n == null || n(a.join("-"));
46
+ s == null || s(a.join("-"));
45
47
  }
46
- }, u = (e, a) => {
47
- const t = { ...r, [e]: a };
48
+ }, h = (e, a) => {
49
+ const t = { ...l, [e]: a };
48
50
  if (e !== "day" && t.day && t.month) {
49
- const B = w(t.year, t.month);
50
- Number(t.day) > B && (t.day = String(B).padStart(2, "0"));
51
+ const M = I(t.year, t.month);
52
+ Number(t.day) > M && (t.day = String(M).padStart(2, "0"));
51
53
  }
52
- D(t);
53
- }, p = (e) => {
54
+ x(t);
55
+ }, y = (e) => {
54
56
  const t = e.currentTarget.firstElementChild;
55
57
  t && t.click();
56
- }, y = "relative w-max [&:has(select:focus)>svg]:rotate-180", v = "pointer-events-none absolute inset-y-0 right-[var(--sp-small,0.375rem)] m-auto size-[var(--icon-medium,1.125rem)] fill-(--icon-color)", x = "w-[calc(3ch+var(--sp-medium,0.75rem)*2+var(--icon-medium,1.125rem))]! p-[var(--sp-medium,0.75rem)]! pe-[calc(var(--sp-small,0.375rem)*2+var(--icon-medium,1.125rem))]! cursor-pointer", h = { "--icon-color": I.blue }, j = { "--caution-color": I.red };
57
- return /* @__PURE__ */ s(K, { className: "flex w-max items-center [&>*:not(:last-of-type)]:after:content-['/']", children: [
58
- /* @__PURE__ */ s("div", { className: y, style: h, onClick: p, children: [
59
- /* @__PURE__ */ s(
58
+ }, i = L(), v = (e) => u ? { "aria-labelledby": `${u} ${i}-${e}` } : { "aria-label": `${T ?? n}の${e}` }, f = "relative w-max [&:has(select:focus)>svg]:rotate-180", b = "pointer-events-none absolute inset-y-0 right-[var(--sp-small,0.375rem)] m-auto size-[var(--icon-medium,1.125rem)] fill-(--icon-color)", A = "w-[calc(3ch+var(--sp-medium,0.75rem)*2+var(--icon-medium,1.125rem))]! p-[var(--sp-medium,0.75rem)]! pe-[calc(var(--sp-small,0.375rem)*2+var(--icon-medium,1.125rem))]! cursor-pointer", N = { "--icon-color": O.blue }, z = { "--caution-color": O.red };
59
+ return /* @__PURE__ */ o(G, { className: "flex w-max items-center [&>*:not(:last-of-type)]:after:content-['/']", children: [
60
+ /* @__PURE__ */ o("div", { className: f, style: N, onClick: y, children: [
61
+ /* @__PURE__ */ o(
60
62
  "select",
61
63
  {
62
- value: r.year,
63
- name: `${o}-year`,
64
- "aria-label": `${o}の年`,
64
+ value: l.year,
65
+ name: `${n}-year`,
66
+ ...v(""),
65
67
  required: c,
66
- onChange: (e) => u("year", e.target.value),
68
+ onChange: (e) => h("year", e.target.value),
67
69
  className: "w-[calc(5ch+var(--sp-medium,0.75rem)*2+var(--icon-medium,1.125rem))]! cursor-pointer p-[var(--sp-medium,0.75rem)]! pe-[calc(var(--sp-small,0.375rem)*2+var(--icon-medium,1.125rem))]!",
68
70
  children: [
69
- /* @__PURE__ */ l("option", { disabled: !0, value: "", children: "年" }),
70
- E.map((e) => /* @__PURE__ */ l("option", { value: e.value, children: e.label }, e.value))
71
+ /* @__PURE__ */ r("option", { disabled: !0, value: "", children: "年" }),
72
+ j.map((e) => /* @__PURE__ */ r("option", { value: e.value, children: e.label }, e.value))
71
73
  ]
72
74
  }
73
75
  ),
74
- /* @__PURE__ */ l(f, { className: v })
76
+ /* @__PURE__ */ r(g, { className: b })
75
77
  ] }),
76
- /* @__PURE__ */ s("div", { className: y, style: h, onClick: p, children: [
77
- /* @__PURE__ */ s(
78
+ /* @__PURE__ */ o("div", { className: f, style: N, onClick: y, children: [
79
+ /* @__PURE__ */ o(
78
80
  "select",
79
81
  {
80
- value: r.month,
81
- name: `${o}-month`,
82
- "aria-label": `${o}の月`,
82
+ value: l.month,
83
+ name: `${n}-month`,
84
+ ...v(""),
83
85
  required: c,
84
- onChange: (e) => u("month", e.target.value),
85
- className: x,
86
+ onChange: (e) => h("month", e.target.value),
87
+ className: A,
86
88
  children: [
87
- /* @__PURE__ */ l("option", { disabled: !0, value: "", children: "月" }),
88
- T.map((e) => /* @__PURE__ */ l("option", { value: e.value, children: e.label }, e.value))
89
+ /* @__PURE__ */ r("option", { disabled: !0, value: "", children: "月" }),
90
+ C.map((e) => /* @__PURE__ */ r("option", { value: e.value, children: e.label }, e.value))
89
91
  ]
90
92
  }
91
93
  ),
92
- /* @__PURE__ */ l(f, { className: v })
94
+ /* @__PURE__ */ r(g, { className: b })
93
95
  ] }),
94
- m === "date" && /* @__PURE__ */ s(
96
+ d === "date" && /* @__PURE__ */ o(
95
97
  "div",
96
98
  {
97
- className: y,
98
- style: h,
99
- onClick: p,
99
+ className: f,
100
+ style: N,
101
+ onClick: y,
100
102
  children: [
101
- /* @__PURE__ */ s(
103
+ /* @__PURE__ */ o(
102
104
  "select",
103
105
  {
104
- value: r.day,
105
- name: `${o}-day`,
106
- "aria-label": `${o}の日`,
106
+ value: l.day,
107
+ name: `${n}-day`,
108
+ ...v(""),
107
109
  required: c,
108
- onChange: (e) => u("day", e.target.value),
109
- className: x,
110
+ onChange: (e) => h("day", e.target.value),
111
+ className: A,
110
112
  children: [
111
- /* @__PURE__ */ l("option", { disabled: !0, value: "", children: "日" }),
112
- _.map((e) => /* @__PURE__ */ l("option", { value: e.value, children: e.label }, e.value))
113
+ /* @__PURE__ */ r("option", { disabled: !0, value: "", children: "日" }),
114
+ P.map((e) => /* @__PURE__ */ r("option", { value: e.value, children: e.label }, e.value))
113
115
  ]
114
116
  }
115
117
  ),
116
- /* @__PURE__ */ l(f, { className: v })
118
+ /* @__PURE__ */ r(g, { className: b })
117
119
  ]
118
120
  }
119
121
  ),
120
- /* @__PURE__ */ l(
122
+ u && /* @__PURE__ */ o("span", { className: "sr-only", children: [
123
+ /* @__PURE__ */ r("span", { id: `${i}-年`, children: "の年" }),
124
+ /* @__PURE__ */ r("span", { id: `${i}-月`, children: "の月" }),
125
+ /* @__PURE__ */ r("span", { id: `${i}-日`, children: "の日" })
126
+ ] }),
127
+ /* @__PURE__ */ r(
121
128
  "button",
122
129
  {
123
130
  type: "button",
124
- style: j,
131
+ style: z,
125
132
  className: "mx-[var(--sp-medium,0.75rem)] inline-flex cursor-pointer items-center gap-[var(--sp-min,0.1875rem)] text-[length:var(--fs-small,0.6875rem)] text-(--caution-color)",
126
- onClick: () => D(b),
133
+ onClick: () => x(S),
127
134
  children: "削除"
128
135
  }
129
136
  )
130
137
  ] });
131
138
  }
132
139
  export {
133
- R as DateSelector
140
+ ee as DateSelector
134
141
  };