@geckou/ui-react 0.7.0 → 0.8.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 +18 -0
- package/dist/components/BasicButton.js +50 -35
- package/dist/components/ErrorMessage.d.ts +3 -1
- package/dist/components/ErrorMessage.js +6 -5
- package/dist/components/LoadingSpinner.js +28 -16
- package/dist/components/ModalBox.js +49 -45
- package/dist/components/PopupBox.js +9 -9
- package/dist/components/RadioButtons.d.ts +7 -1
- package/dist/components/RadioButtons.js +66 -53
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -108,6 +108,24 @@ props は Vue 版(`@geckou/ui-vue`)と揃えている。`v-model` にあた
|
|
|
108
108
|
yarn workspace @geckou/ui-react test
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
## 0.8.0 の変更
|
|
112
|
+
|
|
113
|
+
- `BasicButton` はローディング中に `disabled` にしない(押した瞬間にフォーカスが
|
|
114
|
+
`body` へ落ちるため)。代わりに `aria-disabled` / `aria-busy` を付け、
|
|
115
|
+
`pointer-events` と `onClick` ガードで押せなくする。**`:disabled` を前提に
|
|
116
|
+
スタイルを当てている場合は `[aria-disabled]` の追従が要る**
|
|
117
|
+
- `BasicButton` のローディング中もアクセシブル名を保つ(`invisible` → `opacity-0`)。
|
|
118
|
+
`LoadingSpinner` は `aria-hidden="true"`
|
|
119
|
+
- `BasicButton` の hover 色が `color-mix()` になった。`${色}cc` の文字列連結だったため、
|
|
120
|
+
3 桁 hex(`'#fff'`)・`rgb()`・名前色・`var()` では不正値になっていた
|
|
121
|
+
- `PopupBox` は**表示している間だけ**子要素を描画する。常時 DOM にあると
|
|
122
|
+
`opacity` の切り替えでは支援技術に通知されず、非表示中も文言が読めていた
|
|
123
|
+
- `ModalBox` は開いたままアンマウントされてもフォーカスを戻す
|
|
124
|
+
- `ModalBox` の背景クリック判定が「押し始めも背景だったとき」だけになった。
|
|
125
|
+
ダイアログ内でテキスト選択を始めて背景で離すと閉じていた
|
|
126
|
+
- `RadioButtons` が `role="radiogroup"` になり、`ariaLabel` / `ariaLabelledBy` を受ける。
|
|
127
|
+
エラーは `aria-describedby` で結び付く
|
|
128
|
+
- `ErrorMessage` が `id` を受ける(`aria-describedby` から参照するため)
|
|
111
129
|
## 0.7.0 の変更
|
|
112
130
|
|
|
113
131
|
- `CheckBox` / `LabeledCheckbox` に `value` を追加。`CheckBoxes` は各選択肢の
|
|
@@ -1,57 +1,72 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as
|
|
3
|
-
import { LoadingSpinner as
|
|
4
|
-
import { COLOR as
|
|
5
|
-
function
|
|
2
|
+
import { jsxs as j, jsx as i } from "react/jsx-runtime";
|
|
3
|
+
import { LoadingSpinner as I } from "./LoadingSpinner.js";
|
|
4
|
+
import { COLOR as d } from "@geckou/ui-core";
|
|
5
|
+
function O({
|
|
6
6
|
cssStyle: r,
|
|
7
|
-
duration:
|
|
8
|
-
isLoading:
|
|
9
|
-
isDisabled:
|
|
7
|
+
duration: p = 0.3,
|
|
8
|
+
isLoading: a,
|
|
9
|
+
isDisabled: n,
|
|
10
10
|
buttonType: v = "button",
|
|
11
|
-
onClick:
|
|
12
|
-
loading:
|
|
13
|
-
children:
|
|
11
|
+
onClick: b,
|
|
12
|
+
loading: w,
|
|
13
|
+
children: k
|
|
14
14
|
}) {
|
|
15
|
-
var
|
|
16
|
-
const
|
|
17
|
-
textColor:
|
|
18
|
-
backgroundColor:
|
|
15
|
+
var u, l, s, c, h, f, x, m, g;
|
|
16
|
+
const z = n ? r == null ? void 0 : r.disabled : r == null ? void 0 : r.default, e = {
|
|
17
|
+
textColor: d.white,
|
|
18
|
+
backgroundColor: n ? d.darkGray : d.blue,
|
|
19
19
|
backgroundImage: "none",
|
|
20
20
|
border: {
|
|
21
|
-
color:
|
|
21
|
+
color: n ? d.darkGray : d.blue,
|
|
22
22
|
size: "1px",
|
|
23
23
|
radius: ".25rem"
|
|
24
24
|
},
|
|
25
25
|
boxShadow: "0 0 0 0 transparent",
|
|
26
|
-
...
|
|
27
|
-
},
|
|
28
|
-
"--text-color":
|
|
29
|
-
"--background-color":
|
|
30
|
-
"--background-image":
|
|
31
|
-
"--radius-size": (
|
|
32
|
-
"--button-shadow": `0 0 0 ${(
|
|
33
|
-
"--hover-text-color":
|
|
34
|
-
"--hover-background-color":
|
|
35
|
-
"--hover-background-image":
|
|
36
|
-
"--hover-radius-size": ((
|
|
37
|
-
"--hover-button-shadow": `0 0 0 ${((
|
|
38
|
-
"--duration": `${
|
|
26
|
+
...z
|
|
27
|
+
}, o = (r == null ? void 0 : r.hover) || {}, $ = (t) => t && `color-mix(in srgb, ${t} 80%, transparent)`, C = {
|
|
28
|
+
"--text-color": e.textColor,
|
|
29
|
+
"--background-color": e.backgroundColor,
|
|
30
|
+
"--background-image": e.backgroundImage,
|
|
31
|
+
"--radius-size": (u = e.border) == null ? void 0 : u.radius,
|
|
32
|
+
"--button-shadow": `0 0 0 ${(l = e.border) == null ? void 0 : l.size} ${(s = e.border) == null ? void 0 : s.color} inset, ${e.boxShadow}`,
|
|
33
|
+
"--hover-text-color": o.textColor || e.textColor,
|
|
34
|
+
"--hover-background-color": o.backgroundColor || $(e.backgroundColor),
|
|
35
|
+
"--hover-background-image": o.backgroundImage || e.backgroundImage,
|
|
36
|
+
"--hover-radius-size": ((c = o.border) == null ? void 0 : c.radius) || ((h = e.border) == null ? void 0 : h.radius),
|
|
37
|
+
"--hover-button-shadow": `0 0 0 ${((f = o.border) == null ? void 0 : f.size) || ((x = e.border) == null ? void 0 : x.size)} ${((m = o.border) == null ? void 0 : m.color) || ((g = e.border) == null ? void 0 : g.color)} inset, ${o.boxShadow || e.boxShadow}`,
|
|
38
|
+
"--duration": `${p}s`
|
|
39
39
|
};
|
|
40
|
-
return /* @__PURE__ */
|
|
40
|
+
return /* @__PURE__ */ j(
|
|
41
41
|
"button",
|
|
42
42
|
{
|
|
43
43
|
type: v,
|
|
44
|
-
disabled:
|
|
45
|
-
|
|
44
|
+
disabled: n,
|
|
45
|
+
"aria-disabled": n || a || void 0,
|
|
46
|
+
"aria-busy": a || void 0,
|
|
47
|
+
onClick: (t) => {
|
|
48
|
+
if (a) {
|
|
49
|
+
t.preventDefault();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
b == null || b(t);
|
|
53
|
+
},
|
|
46
54
|
style: C,
|
|
47
|
-
className: "relative inline-flex w-max cursor-pointer items-center justify-center rounded-(--radius-size) border-none bg-(--background-color) px-8 py-4 leading-none text-(--text-color) shadow-(--button-shadow) transition-all duration-(--duration) enabled:hover:rounded-(--hover-radius-size) enabled:hover:bg-(--hover-background-color) enabled:hover:text-(--hover-text-color) enabled:hover:shadow-(--hover-button-shadow) disabled:pointer-events-none disabled:before:pointer-events-auto disabled:before:absolute disabled:before:inset-0 disabled:before:cursor-not-allowed disabled:before:content-['']",
|
|
55
|
+
className: "relative inline-flex w-max cursor-pointer items-center justify-center rounded-(--radius-size) border-none bg-(--background-color) px-8 py-4 leading-none text-(--text-color) shadow-(--button-shadow) transition-all duration-(--duration) enabled:hover:rounded-(--hover-radius-size) enabled:hover:bg-(--hover-background-color) enabled:hover:text-(--hover-text-color) enabled:hover:shadow-(--hover-button-shadow) disabled:pointer-events-none disabled:before:pointer-events-auto disabled:before:absolute disabled:before:inset-0 disabled:before:cursor-not-allowed disabled:before:content-[''] aria-disabled:pointer-events-none aria-disabled:before:pointer-events-auto aria-disabled:before:absolute aria-disabled:before:inset-0 aria-disabled:before:cursor-not-allowed aria-disabled:before:content-['']",
|
|
48
56
|
children: [
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
a && /* @__PURE__ */ i(
|
|
58
|
+
"span",
|
|
59
|
+
{
|
|
60
|
+
"aria-hidden": "true",
|
|
61
|
+
className: "absolute inset-0 m-auto flex max-h-[calc(100%-1.5rem)] items-center justify-center fill-current text-current [&_*]:max-h-full [&_*]:fill-current",
|
|
62
|
+
children: w ?? /* @__PURE__ */ i(I, {})
|
|
63
|
+
}
|
|
64
|
+
),
|
|
65
|
+
/* @__PURE__ */ i("span", { className: a ? "opacity-0" : void 0, children: k })
|
|
51
66
|
]
|
|
52
67
|
}
|
|
53
68
|
);
|
|
54
69
|
}
|
|
55
70
|
export {
|
|
56
|
-
|
|
71
|
+
O as BasicButton
|
|
57
72
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
type Props = {
|
|
2
|
+
/** aria-describedby から参照させたいときに渡す */
|
|
3
|
+
id?: string;
|
|
2
4
|
errorMessages?: string[];
|
|
3
5
|
cssStyle?: {
|
|
4
6
|
textColor?: string;
|
|
5
7
|
backgroundColor?: string;
|
|
6
8
|
};
|
|
7
9
|
};
|
|
8
|
-
export declare function ErrorMessage({ errorMessages, cssStyle }: Props): import("react").JSX.Element | null;
|
|
10
|
+
export declare function ErrorMessage({ id, errorMessages, cssStyle }: Props): import("react").JSX.Element | null;
|
|
9
11
|
export {};
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { jsx as e } from "react/jsx-runtime";
|
|
2
2
|
import { COLOR as n } from "@geckou/ui-core";
|
|
3
|
-
function
|
|
3
|
+
function c({ id: t, errorMessages: o, cssStyle: r }) {
|
|
4
4
|
if (!o || !o.length)
|
|
5
5
|
return null;
|
|
6
|
-
const
|
|
6
|
+
const b = {
|
|
7
7
|
"--error-text-color": (r == null ? void 0 : r.textColor) || n.white,
|
|
8
8
|
"--error-background-color": (r == null ? void 0 : r.backgroundColor) || n.red
|
|
9
9
|
};
|
|
10
10
|
return /* @__PURE__ */ e(
|
|
11
11
|
"div",
|
|
12
12
|
{
|
|
13
|
+
id: t,
|
|
13
14
|
role: "alert",
|
|
14
15
|
className: "absolute top-[calc(100%+0.25rem)] flex w-max flex-col gap-2 rounded-sm bg-(--error-background-color) px-3 py-2 text-sm leading-none text-(--error-text-color) shadow-[0_0_0.5rem_0.25rem_#33333322] before:absolute before:bottom-[calc(100%-1px)] before:left-[0.85rem] before:block before:h-[0.53rem] before:w-[0.85rem] before:bg-(--error-background-color) before:content-[''] before:[clip-path:polygon(50%_0%,100%_100%,0%_100%)]",
|
|
15
|
-
style:
|
|
16
|
-
children: o.map((
|
|
16
|
+
style: b,
|
|
17
|
+
children: o.map((l, a) => /* @__PURE__ */ e("span", { children: l }, a))
|
|
17
18
|
}
|
|
18
19
|
);
|
|
19
20
|
}
|
|
20
21
|
export {
|
|
21
|
-
|
|
22
|
+
c as ErrorMessage
|
|
22
23
|
};
|
|
@@ -1,25 +1,37 @@
|
|
|
1
1
|
import { jsx as c, jsxs as r } from "react/jsx-runtime";
|
|
2
2
|
function i() {
|
|
3
|
-
return
|
|
4
|
-
|
|
5
|
-
/* @__PURE__ */ c("circle", { cx: "16.75", cy: "3.77", r: "1.5", opacity: ".29" }),
|
|
6
|
-
/* @__PURE__ */ c("circle", { cx: "20.23", cy: "7.25", r: "1.5", opacity: ".43" }),
|
|
7
|
-
/* @__PURE__ */ c("circle", { cx: "21.50", cy: "12.00", r: "1.5", opacity: ".57" }),
|
|
8
|
-
/* @__PURE__ */ c("circle", { cx: "20.23", cy: "16.75", r: "1.5", opacity: ".71" }),
|
|
9
|
-
/* @__PURE__ */ c("circle", { cx: "16.75", cy: "20.23", r: "1.5", opacity: ".86" }),
|
|
10
|
-
/* @__PURE__ */ c("circle", { cx: "12", cy: "21.5", r: "1.5" }),
|
|
3
|
+
return (
|
|
4
|
+
// 装飾。読み上げ対象にしない(状態は呼び出し側の aria-busy で伝える)
|
|
11
5
|
/* @__PURE__ */ c(
|
|
12
|
-
"
|
|
6
|
+
"svg",
|
|
13
7
|
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
8
|
+
viewBox: "0 0 24 24",
|
|
9
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
10
|
+
"aria-hidden": "true",
|
|
11
|
+
focusable: "false",
|
|
12
|
+
children: /* @__PURE__ */ r("g", { children: [
|
|
13
|
+
/* @__PURE__ */ c("circle", { cx: "12", cy: "2.5", r: "1.5", opacity: ".14" }),
|
|
14
|
+
/* @__PURE__ */ c("circle", { cx: "16.75", cy: "3.77", r: "1.5", opacity: ".29" }),
|
|
15
|
+
/* @__PURE__ */ c("circle", { cx: "20.23", cy: "7.25", r: "1.5", opacity: ".43" }),
|
|
16
|
+
/* @__PURE__ */ c("circle", { cx: "21.50", cy: "12.00", r: "1.5", opacity: ".57" }),
|
|
17
|
+
/* @__PURE__ */ c("circle", { cx: "20.23", cy: "16.75", r: "1.5", opacity: ".71" }),
|
|
18
|
+
/* @__PURE__ */ c("circle", { cx: "16.75", cy: "20.23", r: "1.5", opacity: ".86" }),
|
|
19
|
+
/* @__PURE__ */ c("circle", { cx: "12", cy: "21.5", r: "1.5" }),
|
|
20
|
+
/* @__PURE__ */ c(
|
|
21
|
+
"animateTransform",
|
|
22
|
+
{
|
|
23
|
+
attributeName: "transform",
|
|
24
|
+
type: "rotate",
|
|
25
|
+
calcMode: "discrete",
|
|
26
|
+
dur: "0.75s",
|
|
27
|
+
values: "0 12 12;30 12 12;60 12 12;90 12 12;120 12 12;150 12 12;180 12 12;210 12 12;240 12 12;270 12 12;300 12 12;330 12 12;360 12 12",
|
|
28
|
+
repeatCount: "indefinite"
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
] })
|
|
20
32
|
}
|
|
21
33
|
)
|
|
22
|
-
|
|
34
|
+
);
|
|
23
35
|
}
|
|
24
36
|
export {
|
|
25
37
|
i as LoadingSpinner
|
|
@@ -1,71 +1,75 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as
|
|
3
|
-
import { useId as
|
|
4
|
-
import { createScrollLock as
|
|
5
|
-
const
|
|
2
|
+
import { jsx as a, jsxs as b } from "react/jsx-runtime";
|
|
3
|
+
import { useId as y, useRef as o, useEffect as i } from "react";
|
|
4
|
+
import { createScrollLock as w, createModalLayer as h, handleTabKey as k } from "@geckou/ui-core";
|
|
5
|
+
const E = {
|
|
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
|
|
11
|
-
return /* @__PURE__ */
|
|
10
|
+
function L() {
|
|
11
|
+
return /* @__PURE__ */ a(
|
|
12
12
|
"svg",
|
|
13
13
|
{
|
|
14
14
|
xmlns: "http://www.w3.org/2000/svg",
|
|
15
15
|
viewBox: "0 -960 960 960",
|
|
16
16
|
fill: "currentColor",
|
|
17
|
-
children: /* @__PURE__ */
|
|
17
|
+
children: /* @__PURE__ */ a("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" })
|
|
18
18
|
}
|
|
19
19
|
);
|
|
20
20
|
}
|
|
21
21
|
function _({
|
|
22
22
|
isShown: r,
|
|
23
|
-
size:
|
|
24
|
-
onClose:
|
|
25
|
-
header:
|
|
23
|
+
size: f = "medium",
|
|
24
|
+
onClose: n,
|
|
25
|
+
header: u,
|
|
26
26
|
footer: d,
|
|
27
|
-
children:
|
|
28
|
-
ariaLabel:
|
|
27
|
+
children: v,
|
|
28
|
+
ariaLabel: x
|
|
29
29
|
}) {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
const e =
|
|
30
|
+
const s = y(), m = o(null), g = o(w());
|
|
31
|
+
i(() => {
|
|
32
|
+
const e = g.current;
|
|
33
33
|
return e.toggle(r), () => e.release();
|
|
34
34
|
}, [r]);
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
const e =
|
|
35
|
+
const p = o(h());
|
|
36
|
+
i(() => {
|
|
37
|
+
const e = p.current;
|
|
38
38
|
return e.toggle(r, m.current), () => e.release();
|
|
39
39
|
}, [r]);
|
|
40
|
-
const l =
|
|
41
|
-
return
|
|
42
|
-
var e
|
|
43
|
-
if (r)
|
|
44
|
-
l.current ?? (l.current = document.activeElement), (e = m.current) == null || e.focus()
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}, [r]),
|
|
40
|
+
const l = o(null), c = o(!1);
|
|
41
|
+
return i(() => {
|
|
42
|
+
var e;
|
|
43
|
+
if (r)
|
|
44
|
+
return l.current ?? (l.current = document.activeElement), (e = m.current) == null || e.focus(), () => {
|
|
45
|
+
var t;
|
|
46
|
+
(t = l.current) == null || t.focus(), l.current = null;
|
|
47
|
+
};
|
|
48
|
+
}, [r]), i(() => {
|
|
49
49
|
if (!r)
|
|
50
50
|
return;
|
|
51
|
-
const e = (
|
|
52
|
-
if (
|
|
53
|
-
if (
|
|
54
|
-
|
|
51
|
+
const e = (t) => {
|
|
52
|
+
if (p.current.isTopmost() && !t.defaultPrevented) {
|
|
53
|
+
if (t.key === "Escape") {
|
|
54
|
+
t.preventDefault(), n();
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
k(m.current, t, document.activeElement);
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
|
|
61
|
-
}, [r,
|
|
61
|
+
}, [r, n]), /* @__PURE__ */ a(
|
|
62
62
|
"div",
|
|
63
63
|
{
|
|
64
64
|
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"}`,
|
|
65
65
|
"aria-hidden": !r,
|
|
66
66
|
inert: !r,
|
|
67
|
+
onPointerDown: (e) => {
|
|
68
|
+
c.current = e.target === e.currentTarget;
|
|
69
|
+
},
|
|
67
70
|
onClick: (e) => {
|
|
68
|
-
|
|
71
|
+
const t = c.current;
|
|
72
|
+
c.current = !1, t && e.target === e.currentTarget && n();
|
|
69
73
|
},
|
|
70
74
|
children: /* @__PURE__ */ b(
|
|
71
75
|
"div",
|
|
@@ -73,29 +77,29 @@ function _({
|
|
|
73
77
|
ref: m,
|
|
74
78
|
role: "dialog",
|
|
75
79
|
"aria-modal": "true",
|
|
76
|
-
"aria-labelledby":
|
|
77
|
-
"aria-label":
|
|
80
|
+
"aria-labelledby": u ? s : void 0,
|
|
81
|
+
"aria-label": u ? void 0 : x ?? "ダイアログ",
|
|
78
82
|
tabIndex: -1,
|
|
79
|
-
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] ${
|
|
83
|
+
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] ${E[f]}`,
|
|
80
84
|
children: [
|
|
81
|
-
|
|
85
|
+
u && /* @__PURE__ */ a(
|
|
82
86
|
"header",
|
|
83
87
|
{
|
|
84
|
-
id:
|
|
88
|
+
id: s,
|
|
85
89
|
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)]",
|
|
86
|
-
children:
|
|
90
|
+
children: u
|
|
87
91
|
}
|
|
88
92
|
),
|
|
89
|
-
/* @__PURE__ */
|
|
90
|
-
d && /* @__PURE__ */
|
|
91
|
-
/* @__PURE__ */
|
|
93
|
+
/* @__PURE__ */ a("div", { className: "flex-auto overflow-auto p-[var(--sp-large,1.5rem)] max-md:p-[var(--sp-medium,0.75rem)]", children: v }),
|
|
94
|
+
d && /* @__PURE__ */ a("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 }),
|
|
95
|
+
/* @__PURE__ */ a(
|
|
92
96
|
"button",
|
|
93
97
|
{
|
|
94
98
|
type: "button",
|
|
95
99
|
"aria-label": "閉じる",
|
|
96
100
|
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",
|
|
97
|
-
onClick:
|
|
98
|
-
children: /* @__PURE__ */
|
|
101
|
+
onClick: n,
|
|
102
|
+
children: /* @__PURE__ */ a(L, {})
|
|
99
103
|
}
|
|
100
104
|
)
|
|
101
105
|
]
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as i } from "react/jsx-runtime";
|
|
3
|
-
import { useState as
|
|
3
|
+
import { useState as n, useRef as c, useEffect as l, useImperativeHandle as f } from "react";
|
|
4
4
|
import { createPortal as p } from "react-dom";
|
|
5
5
|
import { COLOR as d } from "@geckou/ui-core";
|
|
6
6
|
const x = {
|
|
7
7
|
left: "left-[max(calc((100vw-64rem)/2),1rem)]",
|
|
8
8
|
right: "right-[max(calc((100vw-64rem)/2),1rem)]",
|
|
9
9
|
center: "inset-0 m-auto"
|
|
10
|
-
},
|
|
10
|
+
}, h = {
|
|
11
11
|
top: "top-14",
|
|
12
12
|
bottom: "bottom-4",
|
|
13
13
|
center: "inset-0 m-auto"
|
|
14
14
|
};
|
|
15
15
|
function y({
|
|
16
16
|
position: t = { x: "right", y: "top" },
|
|
17
|
-
ref:
|
|
18
|
-
children:
|
|
17
|
+
ref: m,
|
|
18
|
+
children: s
|
|
19
19
|
}) {
|
|
20
|
-
const [
|
|
20
|
+
const [r, o] = n(!1), [u, a] = n(!1), e = c(null);
|
|
21
21
|
return l(() => (a(!0), () => {
|
|
22
22
|
e.current && clearTimeout(e.current);
|
|
23
|
-
}), []), f(
|
|
23
|
+
}), []), f(m, () => ({
|
|
24
24
|
showPopup: () => {
|
|
25
|
-
|
|
25
|
+
o(!0), e.current && clearTimeout(e.current), e.current = setTimeout(() => o(!1), 3e3);
|
|
26
26
|
}
|
|
27
27
|
})), u ? p(
|
|
28
28
|
/* @__PURE__ */ i(
|
|
@@ -30,8 +30,8 @@ function y({
|
|
|
30
30
|
{
|
|
31
31
|
role: "status",
|
|
32
32
|
style: { borderColor: d.blue },
|
|
33
|
-
className: `pointer-events-none fixed z-50 h-max w-max max-w-40 rounded-[var(--radius-small,0.1875rem)] border bg-white p-[var(--sp-medium,0.75rem)] transition-[transform,opacity] duration-300 ${x[t.x]} ${
|
|
34
|
-
children:
|
|
33
|
+
className: `pointer-events-none fixed z-50 h-max w-max max-w-40 rounded-[var(--radius-small,0.1875rem)] border bg-white p-[var(--sp-medium,0.75rem)] transition-[transform,opacity] duration-300 ${x[t.x]} ${h[t.y]} ${r ? "opacity-100" : "opacity-0"}`,
|
|
34
|
+
children: r && s
|
|
35
35
|
}
|
|
36
36
|
),
|
|
37
37
|
document.body
|
|
@@ -8,6 +8,12 @@ type Props = {
|
|
|
8
8
|
isRequired?: boolean;
|
|
9
9
|
cssStyle?: RadioButtonStyleForEachStatus;
|
|
10
10
|
isDisableAnimation?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* ラジオグループ自体のアクセシブル名。
|
|
13
|
+
* 可視ラベル(見出し等)があるなら ariaLabelledBy でその要素を指すこと
|
|
14
|
+
*/
|
|
15
|
+
ariaLabel?: string;
|
|
16
|
+
ariaLabelledBy?: string;
|
|
11
17
|
};
|
|
12
|
-
export declare function RadioButtons({ value, onChange, options, name, isDisabled, isRequired, cssStyle, isDisableAnimation, }: Props): import("react").JSX.Element;
|
|
18
|
+
export declare function RadioButtons({ value, onChange, options, name, isDisabled, isRequired, cssStyle, isDisableAnimation, ariaLabel, ariaLabelledBy, }: Props): import("react").JSX.Element;
|
|
13
19
|
export {};
|
|
@@ -1,70 +1,83 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as
|
|
3
|
-
import { useState as
|
|
4
|
-
import { isEmptyValue as
|
|
5
|
-
import { ErrorMessage as
|
|
6
|
-
function
|
|
7
|
-
value:
|
|
8
|
-
onChange:
|
|
9
|
-
options:
|
|
10
|
-
name:
|
|
2
|
+
import { jsxs as _, jsx as d } from "react/jsx-runtime";
|
|
3
|
+
import { useState as M, useRef as R, useEffect as V, useId as g } from "react";
|
|
4
|
+
import { isEmptyValue as j, MESSAGES as q, COLOR as o } from "@geckou/ui-core";
|
|
5
|
+
import { ErrorMessage as I } from "./ErrorMessage.js";
|
|
6
|
+
function $({
|
|
7
|
+
value: v,
|
|
8
|
+
onChange: n,
|
|
9
|
+
options: x,
|
|
10
|
+
name: h,
|
|
11
11
|
isDisabled: a,
|
|
12
|
-
isRequired:
|
|
12
|
+
isRequired: u,
|
|
13
13
|
cssStyle: e,
|
|
14
|
-
isDisableAnimation:
|
|
14
|
+
isDisableAnimation: k,
|
|
15
|
+
ariaLabel: w,
|
|
16
|
+
ariaLabelledBy: i
|
|
15
17
|
}) {
|
|
16
|
-
var
|
|
17
|
-
const r =
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
var f, p;
|
|
19
|
+
const r = v ?? "", [C, E] = M(!1), s = R(r);
|
|
20
|
+
V(() => {
|
|
21
|
+
s.current !== r && (s.current = r, E(!0));
|
|
20
22
|
}, [r]);
|
|
21
|
-
const
|
|
23
|
+
const c = C && u && j(r) ? [q.required] : void 0, N = g(), G = h ?? N, b = g(), y = a ? e == null ? void 0 : e.disabled : e == null ? void 0 : e.default, l = {
|
|
22
24
|
textColor: a ? o.darkGray : o.black,
|
|
23
25
|
backgroundColor: a ? o.lightGray : o.white,
|
|
24
26
|
border: {
|
|
25
27
|
color: a ? o.darkGray : o.blue,
|
|
26
28
|
size: "1px"
|
|
27
29
|
},
|
|
28
|
-
...
|
|
29
|
-
},
|
|
30
|
+
...y ?? {}
|
|
31
|
+
}, z = {
|
|
30
32
|
"--text-color": l.textColor,
|
|
31
|
-
"--border-color": (
|
|
32
|
-
"--border-size": (
|
|
33
|
+
"--border-color": (f = l.border) == null ? void 0 : f.color,
|
|
34
|
+
"--border-size": (p = l.border) == null ? void 0 : p.size,
|
|
33
35
|
"--background-color": l.backgroundColor,
|
|
34
|
-
"--duration":
|
|
36
|
+
"--duration": k ? "0s" : ".3s"
|
|
35
37
|
};
|
|
36
|
-
return /* @__PURE__ */
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
38
|
+
return /* @__PURE__ */ _(
|
|
39
|
+
"div",
|
|
40
|
+
{
|
|
41
|
+
role: "radiogroup",
|
|
42
|
+
"aria-label": i ? void 0 : w,
|
|
43
|
+
"aria-labelledby": i,
|
|
44
|
+
"aria-required": u || void 0,
|
|
45
|
+
"aria-describedby": c ? b : void 0,
|
|
46
|
+
className: "relative flex flex-wrap items-center gap-4",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ d("style", { children: "@keyframes uiRadioPop{0%{scale:1}10%{scale:.8}50%{scale:1.2}100%{scale:1}}" }),
|
|
49
|
+
x.map((t) => {
|
|
50
|
+
const m = t.value === r;
|
|
51
|
+
return /* @__PURE__ */ _(
|
|
52
|
+
"label",
|
|
53
|
+
{
|
|
54
|
+
style: z,
|
|
55
|
+
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) ${m ? "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]"}`,
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ d(
|
|
58
|
+
"input",
|
|
59
|
+
{
|
|
60
|
+
type: "radio",
|
|
61
|
+
name: G,
|
|
62
|
+
value: t.value,
|
|
63
|
+
disabled: a,
|
|
64
|
+
required: u,
|
|
65
|
+
checked: m,
|
|
66
|
+
onChange: () => n == null ? void 0 : n(t.value),
|
|
67
|
+
className: "sr-only"
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
/* @__PURE__ */ d("span", { children: t.label })
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
t.value
|
|
74
|
+
);
|
|
75
|
+
}),
|
|
76
|
+
/* @__PURE__ */ d(I, { id: b, errorMessages: c })
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
);
|
|
67
80
|
}
|
|
68
81
|
export {
|
|
69
|
-
|
|
82
|
+
$ as RadioButtons
|
|
70
83
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geckou/ui-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
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.
|
|
43
|
+
"@geckou/ui-core": "^0.8.0"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "vite build && node scripts/copy-assets.mjs",
|