@geckou/ui-react 0.3.0 → 0.5.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/README.md +33 -0
- package/dist/components/CheckBox.d.ts +7 -1
- package/dist/components/CheckBox.js +37 -46
- package/dist/components/DatePicker.d.ts +8 -1
- package/dist/components/DatePicker.js +86 -79
- package/dist/components/DateRangePicker.js +60 -50
- package/dist/components/DateSelector.d.ts +11 -1
- package/dist/components/DateSelector.js +74 -62
- package/dist/components/ErrorMessage.js +7 -6
- package/dist/components/InputBox.js +36 -40
- package/dist/components/LabeledCheckbox.js +26 -23
- package/dist/components/ModalBox.js +54 -35
- package/dist/components/RadioButtons.js +45 -39
- package/dist/components/SearchableSelectBox.d.ts +3 -1
- package/dist/components/SearchableSelectBox.js +86 -43
- package/dist/components/TabUI.js +28 -27
- package/dist/components/TextBox.d.ts +15 -2
- package/dist/components/TextBox.js +54 -38
- package/dist/components/ToggleButton.d.ts +4 -1
- package/dist/components/ToggleButton.js +50 -53
- package/package.json +8 -6
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,29 @@ 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
|
+
|
|
122
|
+
## 0.4.0 の変更
|
|
123
|
+
|
|
124
|
+
- `RadioButtons` が必須エラー(「必須項目です」)を描画する。Vue 版と同じく、
|
|
125
|
+
値が空へ変化したときに出る
|
|
126
|
+
- `CheckBox` / `ToggleButton` のロールが `aria-pressed` から
|
|
127
|
+
`role="checkbox" + aria-checked` / `role="switch" + aria-checked` に変わった。
|
|
128
|
+
アクセシブル名は `ariaLabel` / `ariaLabelledBy` で渡せる(未指定なら従来どおり `name`)
|
|
129
|
+
- `DateSelector` に `minYear` / `maxYear` を追加(既定は従来どおり「今年 -100 〜 今年 -14」)
|
|
130
|
+
- `DateRangePicker` が範囲(開始 > 終了)を検証し、`<name>Range` という名前で
|
|
131
|
+
`FormValidationStore` に登録する。`invalidNames` を見ている場合は増える
|
|
132
|
+
- `TabUI` の `color.text` を配線した
|
|
133
|
+
|
|
101
134
|
## License
|
|
102
135
|
|
|
103
136
|
[MIT](../../LICENSE)
|
|
@@ -8,6 +8,12 @@ type Props = {
|
|
|
8
8
|
cssStyle?: CheckBoxStyleForEachStatus;
|
|
9
9
|
isDisableAnimation?: boolean;
|
|
10
10
|
check?: ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* アクセシブル名。可視ラベルがあるなら ariaLabelledBy でその要素を指すこと。
|
|
13
|
+
* どちらも無いときだけ name を名前として使う(機械名でも無いよりはマシ)
|
|
14
|
+
*/
|
|
15
|
+
ariaLabel?: string;
|
|
16
|
+
ariaLabelledBy?: string;
|
|
11
17
|
};
|
|
12
|
-
export declare function CheckBox({ name, checked, onChange, isDisabled, cssStyle, isDisableAnimation, check, }: Props): import("react").JSX.Element;
|
|
18
|
+
export declare function CheckBox({ name, checked, onChange, isDisabled, cssStyle, isDisableAnimation, check, ariaLabel, ariaLabelledBy, }: Props): import("react").JSX.Element;
|
|
13
19
|
export {};
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as
|
|
3
|
-
import { CheckIcon as
|
|
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
5
|
function j({
|
|
6
6
|
name: l,
|
|
7
|
-
checked:
|
|
8
|
-
onChange:
|
|
7
|
+
checked: s,
|
|
8
|
+
onChange: c,
|
|
9
9
|
isDisabled: e,
|
|
10
|
-
cssStyle:
|
|
11
|
-
isDisableAnimation:
|
|
12
|
-
check: k
|
|
10
|
+
cssStyle: r,
|
|
11
|
+
isDisableAnimation: f,
|
|
12
|
+
check: k,
|
|
13
|
+
ariaLabel: p,
|
|
14
|
+
ariaLabelledBy: a
|
|
13
15
|
}) {
|
|
14
|
-
var
|
|
15
|
-
const
|
|
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 = {
|
|
16
18
|
textColor: e ? t.darkGray : t.blue,
|
|
17
19
|
backgroundColor: e ? t.lightGray : t.white,
|
|
18
20
|
border: {
|
|
@@ -21,52 +23,41 @@ function j({
|
|
|
21
23
|
radius: ".25rem"
|
|
22
24
|
},
|
|
23
25
|
...h
|
|
24
|
-
},
|
|
26
|
+
}, x = {
|
|
25
27
|
"--text-color": d.textColor,
|
|
26
|
-
"--border-color": (
|
|
27
|
-
"--border-size": (
|
|
28
|
-
"--radius-size": (
|
|
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,
|
|
29
31
|
"--background-color": d.backgroundColor,
|
|
30
|
-
"--duration":
|
|
32
|
+
"--duration": f ? "0s" : ".3s"
|
|
31
33
|
};
|
|
32
|
-
return /* @__PURE__ */
|
|
33
|
-
/* @__PURE__ */
|
|
34
|
-
/* @__PURE__ */
|
|
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(
|
|
35
37
|
"button",
|
|
36
38
|
{
|
|
37
39
|
type: "button",
|
|
38
|
-
style:
|
|
39
|
-
"
|
|
40
|
-
"aria-
|
|
40
|
+
style: x,
|
|
41
|
+
role: "checkbox",
|
|
42
|
+
"aria-checked": o,
|
|
43
|
+
"data-checked": o,
|
|
44
|
+
"aria-labelledby": a,
|
|
45
|
+
"aria-label": a ? void 0 : p ?? l,
|
|
41
46
|
disabled: e,
|
|
42
|
-
onClick: (
|
|
43
|
-
|
|
47
|
+
onClick: (m) => {
|
|
48
|
+
m.stopPropagation(), e || c == null || c(!o);
|
|
44
49
|
},
|
|
45
|
-
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)
|
|
46
|
-
children:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
disabled: e,
|
|
54
|
-
onChange: (a) => {
|
|
55
|
-
e || r == null || r(a.target.checked);
|
|
56
|
-
},
|
|
57
|
-
className: "hidden"
|
|
58
|
-
}
|
|
59
|
-
),
|
|
60
|
-
/* @__PURE__ */ c(
|
|
61
|
-
"div",
|
|
62
|
-
{
|
|
63
|
-
className: `flex h-4 w-4 items-center justify-center [&>*]:fill-current [&>*]:text-current ${i ? "text-(--background-color)" : "text-(--border-color)"}`,
|
|
64
|
-
children: k ?? /* @__PURE__ */ c(v, {})
|
|
65
|
-
}
|
|
66
|
-
)
|
|
67
|
-
]
|
|
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
|
+
)
|
|
68
58
|
}
|
|
69
|
-
)
|
|
59
|
+
),
|
|
60
|
+
o && /* @__PURE__ */ i("input", { type: "hidden", name: l, value: "on", disabled: e })
|
|
70
61
|
] });
|
|
71
62
|
}
|
|
72
63
|
export {
|
|
@@ -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
|
|
3
|
-
import { formatDateValue as
|
|
4
|
-
import { useState as
|
|
5
|
-
import { InputBox as
|
|
6
|
-
import { ErrorMessage as
|
|
7
|
-
import { CalendarIcon as
|
|
8
|
-
import { useRegisterValidation as
|
|
9
|
-
function
|
|
10
|
-
name:
|
|
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:
|
|
13
|
+
cssStyle: M,
|
|
14
14
|
isDisabled: i,
|
|
15
|
-
isRequired:
|
|
16
|
-
formValidationStore:
|
|
17
|
-
minDate:
|
|
18
|
-
maxDate:
|
|
19
|
-
size:
|
|
20
|
-
type:
|
|
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 [
|
|
23
|
-
() => a ?
|
|
24
|
-
), [
|
|
25
|
-
() => a ?
|
|
26
|
-
), [
|
|
27
|
-
|
|
28
|
-
if (
|
|
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
|
-
|
|
31
|
-
const e = a ?
|
|
32
|
-
|
|
33
|
-
}, [a,
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
const { message:
|
|
37
|
-
$(
|
|
38
|
-
},
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
const { isValid:
|
|
42
|
-
if (
|
|
43
|
-
const
|
|
44
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
y
|
|
49
|
+
_(
|
|
50
|
+
D,
|
|
51
|
+
o,
|
|
52
|
+
I(y).isValid && G
|
|
51
53
|
);
|
|
52
|
-
const
|
|
53
|
-
return /* @__PURE__ */
|
|
54
|
-
|
|
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:
|
|
58
|
+
cssStyle: M,
|
|
57
59
|
isDisabled: i,
|
|
58
|
-
isErrored: !!
|
|
59
|
-
className: `flex w-full items-center leading-none ${
|
|
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__ */
|
|
62
|
-
/* @__PURE__ */
|
|
63
|
-
|
|
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) ${
|
|
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__ */
|
|
70
|
+
/* @__PURE__ */ r(
|
|
69
71
|
"input",
|
|
70
72
|
{
|
|
71
|
-
type:
|
|
72
|
-
name:
|
|
73
|
-
value:
|
|
74
|
-
max:
|
|
75
|
-
min:
|
|
76
|
-
required:
|
|
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) =>
|
|
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 ${
|
|
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__ */
|
|
85
|
+
/* @__PURE__ */ r(
|
|
84
86
|
"input",
|
|
85
87
|
{
|
|
86
|
-
value:
|
|
88
|
+
value: l.year,
|
|
87
89
|
placeholder: "年",
|
|
88
|
-
"
|
|
90
|
+
...x("年"),
|
|
89
91
|
maxLength: 4,
|
|
90
92
|
type: "text",
|
|
91
93
|
disabled: i,
|
|
92
|
-
onChange: (e) =>
|
|
93
|
-
className: `w-[calc(var(--sp-medium,0.75rem)*2+5ch)]! ${
|
|
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__ */
|
|
99
|
+
/* @__PURE__ */ r(
|
|
98
100
|
"input",
|
|
99
101
|
{
|
|
100
|
-
value:
|
|
102
|
+
value: l.month,
|
|
101
103
|
placeholder: "月",
|
|
102
|
-
"
|
|
104
|
+
...x("月"),
|
|
103
105
|
maxLength: 2,
|
|
104
106
|
type: "text",
|
|
105
107
|
disabled: i,
|
|
106
|
-
onChange: (e) =>
|
|
107
|
-
className: `w-[calc(var(--sp-medium,0.75rem)*2+3ch)]! ${
|
|
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
|
-
|
|
111
|
-
|
|
112
|
+
t === "date" && /* @__PURE__ */ r("span", { children: "/" }),
|
|
113
|
+
t === "date" && /* @__PURE__ */ r(
|
|
112
114
|
"input",
|
|
113
115
|
{
|
|
114
|
-
value:
|
|
116
|
+
value: l.day,
|
|
115
117
|
placeholder: "日",
|
|
116
|
-
"
|
|
118
|
+
...x("日"),
|
|
117
119
|
maxLength: 2,
|
|
118
120
|
type: "text",
|
|
119
121
|
disabled: i,
|
|
120
|
-
onChange: (e) =>
|
|
121
|
-
className: `w-[calc(var(--sp-medium,0.75rem)*2+3ch)]! ${
|
|
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__ */
|
|
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
|
-
|
|
137
|
+
le as DatePicker
|
|
131
138
|
};
|
|
@@ -1,65 +1,75 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
import { jsxs as b, jsx as t } from "react/jsx-runtime";
|
|
3
|
+
import { COLOR as g, MESSAGES as R } from "@geckou/ui-core";
|
|
4
|
+
import { DatePicker as x } from "./DatePicker.js";
|
|
5
|
+
import { ErrorMessage as k } from "./ErrorMessage.js";
|
|
6
|
+
import { useRegisterValidation as u } from "../hooks/useFormValidation.js";
|
|
7
|
+
const M = { start: "", end: "" };
|
|
8
|
+
function $({
|
|
9
|
+
name: d,
|
|
10
|
+
value: r = M,
|
|
11
|
+
onChange: e,
|
|
12
|
+
isDisabled: a,
|
|
13
|
+
isRequired: c,
|
|
14
|
+
formValidationStore: s,
|
|
15
|
+
minDate: o = "",
|
|
16
|
+
maxDate: i = "",
|
|
17
|
+
size: l = "medium",
|
|
18
|
+
type: m = "date"
|
|
17
19
|
}) {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
const f = !(r.start && r.end && r.start > r.end);
|
|
21
|
+
u(s, `${d}Range`, f);
|
|
22
|
+
const E = (n) => e == null ? void 0 : e({ start: n, end: r.end }), p = (n) => e == null ? void 0 : e({ start: r.start, end: n }), h = {
|
|
23
|
+
"--range-background-color": g.white,
|
|
24
|
+
"--range-border-color": g.gray
|
|
21
25
|
};
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
children: [
|
|
28
|
-
/* @__PURE__ */
|
|
29
|
-
|
|
26
|
+
return (
|
|
27
|
+
// 角丸・区切り線は :first-child / :last-child で割り当てるため、
|
|
28
|
+
// ErrorMessage を同じ階層に置くとエラー表示時だけ枠の見た目が変わる。
|
|
29
|
+
// 入力群を内側にまとめ、ErrorMessage は外側(relative)に置く
|
|
30
|
+
/* @__PURE__ */ b("div", { style: h, className: "relative", children: [
|
|
31
|
+
/* @__PURE__ */ b("div", { className: "flex bg-(--range-background-color) [&>*]:flex-auto [&>*]:rounded-none! [&>*:first-child]:rounded-s-[calc(var(--bv,0.375rem)/2)]! [&>*:last-child]:rounded-e-[calc(var(--bv,0.375rem)/2)]! [&>*:not(:last-child)]:border-e [&>*:not(:last-child)]:border-(--range-border-color)", children: [
|
|
32
|
+
/* @__PURE__ */ t(
|
|
33
|
+
x,
|
|
30
34
|
{
|
|
31
|
-
name: `${
|
|
35
|
+
name: `${d}Start`,
|
|
32
36
|
value: r.start,
|
|
33
|
-
isDisabled:
|
|
34
|
-
isRequired:
|
|
35
|
-
formValidationStore:
|
|
36
|
-
minDate:
|
|
37
|
-
maxDate: r.end ||
|
|
38
|
-
size:
|
|
39
|
-
type:
|
|
40
|
-
onChange:
|
|
37
|
+
isDisabled: a,
|
|
38
|
+
isRequired: c,
|
|
39
|
+
formValidationStore: s,
|
|
40
|
+
minDate: o,
|
|
41
|
+
maxDate: r.end || i,
|
|
42
|
+
size: l,
|
|
43
|
+
type: m,
|
|
44
|
+
onChange: E
|
|
41
45
|
}
|
|
42
46
|
),
|
|
43
|
-
/* @__PURE__ */
|
|
44
|
-
/* @__PURE__ */
|
|
45
|
-
|
|
47
|
+
/* @__PURE__ */ t("div", { className: "flex flex-none! items-center px-[var(--bv,0.375rem)]", children: "〜" }),
|
|
48
|
+
/* @__PURE__ */ t(
|
|
49
|
+
x,
|
|
46
50
|
{
|
|
47
|
-
name: `${
|
|
51
|
+
name: `${d}End`,
|
|
48
52
|
value: r.end,
|
|
49
|
-
isDisabled:
|
|
50
|
-
isRequired:
|
|
51
|
-
formValidationStore:
|
|
52
|
-
minDate: r.start ||
|
|
53
|
-
maxDate:
|
|
54
|
-
size:
|
|
55
|
-
type:
|
|
56
|
-
onChange:
|
|
53
|
+
isDisabled: a,
|
|
54
|
+
isRequired: c,
|
|
55
|
+
formValidationStore: s,
|
|
56
|
+
minDate: r.start || o,
|
|
57
|
+
maxDate: i,
|
|
58
|
+
size: l,
|
|
59
|
+
type: m,
|
|
60
|
+
onChange: p
|
|
57
61
|
}
|
|
58
62
|
)
|
|
59
|
-
]
|
|
60
|
-
|
|
63
|
+
] }),
|
|
64
|
+
/* @__PURE__ */ t(
|
|
65
|
+
k,
|
|
66
|
+
{
|
|
67
|
+
errorMessages: f ? void 0 : [R.startAfterEnd]
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
] })
|
|
61
71
|
);
|
|
62
72
|
}
|
|
63
73
|
export {
|
|
64
|
-
|
|
74
|
+
$ as DateRangePicker
|
|
65
75
|
};
|
|
@@ -8,6 +8,16 @@ type Props = {
|
|
|
8
8
|
formValidationStore?: FormValidationStore | null;
|
|
9
9
|
/** 'month' なら日の選択を出さない(Vue 版と揃える) */
|
|
10
10
|
type?: 'date' | 'month';
|
|
11
|
+
/** 選べる年の下限・上限。既定は「今年 -100 〜 今年 -14」(生年月日向け) */
|
|
12
|
+
minYear?: number;
|
|
13
|
+
maxYear?: number;
|
|
14
|
+
/**
|
|
15
|
+
* 年月日それぞれの読み上げ名の土台。「の年」「の月」「の日」を後ろに繋げる。
|
|
16
|
+
* 可視ラベルがあるなら ariaLabelledBy でその要素を指すこと。
|
|
17
|
+
* どちらも無いときだけ name を使う(機械名でも無いよりはマシ)
|
|
18
|
+
*/
|
|
19
|
+
ariaLabel?: string;
|
|
20
|
+
ariaLabelledBy?: string;
|
|
11
21
|
};
|
|
12
|
-
export declare function DateSelector({ name, value, onChange, isRequired, formValidationStore, type, }: 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;
|
|
13
23
|
export {};
|