@insession/design-system 1.3.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/CHANGELOG.md +84 -0
- package/README.md +108 -0
- package/dist/index.d.ts +501 -0
- package/dist/index.js +1962 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
- package/theme.css +325 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1962 @@
|
|
|
1
|
+
// avatar.tsx
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
function initialOf(name, fallback) {
|
|
4
|
+
return [...name || fallback || "?"][0].toUpperCase();
|
|
5
|
+
}
|
|
6
|
+
function Avatar({
|
|
7
|
+
label,
|
|
8
|
+
name,
|
|
9
|
+
src,
|
|
10
|
+
fallback,
|
|
11
|
+
color,
|
|
12
|
+
bgColor,
|
|
13
|
+
size,
|
|
14
|
+
status,
|
|
15
|
+
ring,
|
|
16
|
+
className = "",
|
|
17
|
+
fallbackClassName = "",
|
|
18
|
+
alt = ""
|
|
19
|
+
}) {
|
|
20
|
+
const bg = color ?? bgColor;
|
|
21
|
+
const content = label != null ? label : initialOf(name, fallback);
|
|
22
|
+
const ds = status != null || ring === true;
|
|
23
|
+
if (ds) {
|
|
24
|
+
const dim2 = size ?? 40;
|
|
25
|
+
const circleStyle = {
|
|
26
|
+
width: dim2,
|
|
27
|
+
height: dim2,
|
|
28
|
+
fontSize: dim2 * 0.4,
|
|
29
|
+
...!src && bg ? { background: bg } : void 0
|
|
30
|
+
};
|
|
31
|
+
return /* @__PURE__ */ jsxs(
|
|
32
|
+
"span",
|
|
33
|
+
{
|
|
34
|
+
className: `relative inline-flex shrink-0 ${className}`.trim(),
|
|
35
|
+
style: { width: dim2, height: dim2 },
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ jsx(
|
|
38
|
+
"span",
|
|
39
|
+
{
|
|
40
|
+
className: `inline-flex items-center justify-center overflow-hidden rounded-pill font-bold text-white ${src ? "bg-transparent" : bg ? "" : "bg-info"} ${ring ? "border-2 border-solid border-surface" : ""}`.trim(),
|
|
41
|
+
style: circleStyle,
|
|
42
|
+
children: src ? /* @__PURE__ */ jsx(
|
|
43
|
+
"img",
|
|
44
|
+
{
|
|
45
|
+
src,
|
|
46
|
+
alt: alt || (typeof label === "string" ? label : name || ""),
|
|
47
|
+
referrerPolicy: "no-referrer",
|
|
48
|
+
className: "h-full w-full object-cover"
|
|
49
|
+
}
|
|
50
|
+
) : content
|
|
51
|
+
}
|
|
52
|
+
),
|
|
53
|
+
status != null && /* @__PURE__ */ jsx(
|
|
54
|
+
"span",
|
|
55
|
+
{
|
|
56
|
+
"aria-hidden": "true",
|
|
57
|
+
className: `absolute right-0 bottom-0 rounded-pill border-2 border-solid border-surface ${status === "live" ? "bg-success" : "bg-text-dim"}`,
|
|
58
|
+
style: { width: dim2 * 0.28, height: dim2 * 0.28 }
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
const dim = size != null ? { width: size, height: size } : void 0;
|
|
66
|
+
if (src) {
|
|
67
|
+
return /* @__PURE__ */ jsx("img", { className, src, alt, referrerPolicy: "no-referrer", style: dim });
|
|
68
|
+
}
|
|
69
|
+
return /* @__PURE__ */ jsx(
|
|
70
|
+
"span",
|
|
71
|
+
{
|
|
72
|
+
className: `${className} ${fallbackClassName}`.trim(),
|
|
73
|
+
style: bg ? { ...dim, background: bg } : dim,
|
|
74
|
+
children: content
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
function AvatarStack({ people = [], max = 4, size = 40, className = "" }) {
|
|
79
|
+
const shown = people.slice(0, max);
|
|
80
|
+
const extra = people.length - shown.length;
|
|
81
|
+
const overlap = -(size * 0.3);
|
|
82
|
+
return /* @__PURE__ */ jsxs("span", { className: `inline-flex items-center ${className}`.trim(), children: [
|
|
83
|
+
shown.map((p, i) => /* @__PURE__ */ jsx("span", { style: { marginLeft: i ? overlap : 0 }, className: "inline-flex rounded-pill", children: /* @__PURE__ */ jsx(Avatar, { ...p, size, ring: true }) }, i)),
|
|
84
|
+
extra > 0 && /* @__PURE__ */ jsxs(
|
|
85
|
+
"span",
|
|
86
|
+
{
|
|
87
|
+
style: { marginLeft: overlap, width: size, height: size, fontSize: size * 0.32 },
|
|
88
|
+
className: "inline-flex items-center justify-center rounded-pill border-2 border-solid border-surface bg-surface-3 font-bold text-text-dim",
|
|
89
|
+
children: [
|
|
90
|
+
"+",
|
|
91
|
+
extra
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
] });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// icons/icon.tsx
|
|
99
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
100
|
+
var PATHS = {
|
|
101
|
+
menu: "M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z",
|
|
102
|
+
// サイドナビ用(#463。DS SideNav の home / graphic_eq / history)
|
|
103
|
+
home: "M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z",
|
|
104
|
+
graphic_eq: "M7 18h2V6H7v12zm4 4h2V2h-2v20zm-8-8h2v-4H3v4zm12 4h2V6h-2v12zm4-4h2v-4h-2v4z",
|
|
105
|
+
history: "M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z",
|
|
106
|
+
settings: "M19.14 12.94c.04-.3.06-.61.06-.94s-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z",
|
|
107
|
+
check: "M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z",
|
|
108
|
+
check_circle: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",
|
|
109
|
+
warning: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z",
|
|
110
|
+
edit: "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z",
|
|
111
|
+
link: "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z",
|
|
112
|
+
volume_off: "M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3 3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06a8.99 8.99 0 0 0 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4 9.91 6.09 12 8.18V4z",
|
|
113
|
+
// 音量スライダーのアイコン(レコードプレーヤービュー。#406)
|
|
114
|
+
volume_up: "M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.26 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z",
|
|
115
|
+
extension: "M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7s2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z",
|
|
116
|
+
// ステージスイッチャーのトリガー(#235。3x3グリッドの「アプリ一覧」アイコン)
|
|
117
|
+
apps: "M4 8h4V4H4v4zm6 12h4v-4h-4v4zM4 20h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z",
|
|
118
|
+
timer: "M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.03-6.61 1.42-1.42c-.43-.51-.9-.99-1.41-1.41l-1.42 1.42C16.07 4.74 14.12 4 12 4c-4.97 0-9 4.03-9 9s4.02 9 9 9 9-4.03 9-9c0-2.12-.74-4.07-1.97-5.61zM12 20c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z",
|
|
119
|
+
movie: "M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4h-4z",
|
|
120
|
+
group: "M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z",
|
|
121
|
+
sports_esports: "M15 7.5H9c-2.76 0-5 2.24-5 5v3c0 1.66 1.34 3 3 3 .58 0 1.11-.24 1.5-.62L10.5 16h3l2 1.88c.39.38.92.62 1.5.62 1.66 0 3-1.34 3-3v-3c0-2.76-2.24-5-5-5zM10 13H8.5v1.5H7V13H5.5v-1.5H7V10h1.5v1.5H10V13zm5.5 1c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm2-2.5c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1z",
|
|
122
|
+
auto_awesome: "M19 9l1.25-2.75L23 5l-2.75-1.25L19 1l-1.25 2.75L15 5l2.75 1.25L19 9zM11.5 9.5 9 4l-2.5 5.5L1 12l5.5 2.5L9 20l2.5-5.5L17 12l-5.5-2.5zM19 15l-1.25 2.75L15 19l2.75 1.25L19 23l1.25-2.75L23 19l-2.75-1.25L19 15z",
|
|
123
|
+
// 入室拒否画面(#845。スペースの公開範囲で弾かれたときの空状態アイコン)
|
|
124
|
+
lock: "M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm3 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z",
|
|
125
|
+
play_arrow: "M8 5v14l11-7z",
|
|
126
|
+
// スペース内キュー(モバイル下部ナビ #572)。Material Symbols queue_music 由来。
|
|
127
|
+
queue_music: "M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z",
|
|
128
|
+
// モバイル下部タブバーのマイページ(#580)。Material Symbols account_circle 由来。
|
|
129
|
+
account_circle: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z",
|
|
130
|
+
pause: "M6 19h4V5H6v14zm8-14v14h4V5h-4z",
|
|
131
|
+
fast_forward: "M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z",
|
|
132
|
+
videocam: "M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z",
|
|
133
|
+
videocam_off: "M21 6.5l-4 4V7c0-.55-.45-1-1-1H9.82L21 17.18V6.5zM3.27 2 2 3.27 4.73 6H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73 3.27 2zM7.73 8l6 6H6V8h1.73z",
|
|
134
|
+
mic: "M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5-3c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z",
|
|
135
|
+
mic_off: "M19 11h-1.7c0 .74-.16 1.43-.43 2.05l1.23 1.23c.56-.98.9-2.09.9-3.28zm-4.02.17c0-.06.02-.11.02-.17V5c0-1.66-1.34-3-3-3S9 3.34 9 5v.18l5.98 5.99zM4.27 3 3 4.27l6.01 6.01V11c0 1.66 1.33 3 2.99 3 .22 0 .44-.03.65-.08l1.66 1.66c-.71.33-1.5.52-2.31.52-2.76 0-5.3-2.1-5.3-5.1H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.27c.91-.13 1.77-.45 2.54-.9L19.73 21 21 19.73 4.27 3z",
|
|
136
|
+
call_end: "M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08c-.18-.17-.29-.42-.29-.7 0-.28.11-.53.29-.71C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67c.18.18.29.43.29.71 0 .28-.11.53-.29.7l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28-.79-.74-1.69-1.36-2.67-1.85-.33-.16-.56-.51-.56-.9v-3.1C15.15 9.25 13.6 9 12 9z",
|
|
137
|
+
// 受話器アイコン(発信/参加ボタン用。#187フォローアップ)
|
|
138
|
+
call: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z",
|
|
139
|
+
help: "M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z",
|
|
140
|
+
// 画面共有(#180)。モニター枠 + 上向き矢印(共有中)/× (共有停止)。
|
|
141
|
+
screen_share: "M20 18c1.1 0 1.99-.9 1.99-2L22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 16V6h16v10H4zm7-4h2V9h2.5L12 5.5 8.5 9H11v3z",
|
|
142
|
+
stop_screen_share: "M20 18c1.1 0 1.99-.9 1.99-2L22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 16V6h16v10H4zm3.4-8.6L12 11.6l4.6-4.2 1.4 1.4L13.4 13l4.6 4.2-1.4 1.4L12 14.4l-4.6 4.2-1.4-1.4L10.6 13 6 8.8z",
|
|
143
|
+
// ログアウト(#219 ユーザーメニューのドロップダウン用)
|
|
144
|
+
logout: "M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.59L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z",
|
|
145
|
+
// 追加(+)。チャットメッセージへのリアクション追加トリガー等(#236)。
|
|
146
|
+
add: "M19 13H13V19H11V13H5V11H11V5H13V11H19V13Z",
|
|
147
|
+
// URL/動画ID追加トグル(モバイルの+収納。#581)。Material Symbols add_link 由来。
|
|
148
|
+
add_link: "M8 11h8v2H8zm12.1 1c0-1.71-1.39-3.1-3.1-3.1h-4V7h4c2.76 0 5 2.24 5 5s-2.24 5-5 5h-4v-1.9h4c1.71 0 3.1-1.39 3.1-3.1zM3.9 12c0 1.71 1.39 3.1 3.1 3.1h4V17H7c-2.76 0-5-2.24-5-5s2.24-5 5-5h4v1.9H7c-1.71 0-3.1 1.39-3.1 3.1z",
|
|
149
|
+
// リアクション追加(顔+マーク)。チャットメッセージへのリアクション追加トリガー専用アイコン(#262)。
|
|
150
|
+
add_reaction: "M7,9.5C7,8.67,7.67,8,8.5,8S10,8.67,10,9.5c0,0.83-0.67,1.5-1.5,1.5S7,10.33,7,9.5z M12,17.5c2.33,0,4.31-1.46,5.11-3.5 H6.89C7.69,16.04,9.67,17.5,12,17.5z M15.5,11c0.83,0,1.5-0.67,1.5-1.5C17,8.67,16.33,8,15.5,8S14,8.67,14,9.5 C14,10.33,14.67,11,15.5,11z M22,1h-2v2h-2v2h2v2h2V5h2V3h-2V1z M20,12c0,4.42-3.58,8-8,8s-8-3.58-8-8c0-4.42,3.58-8,8-8 c1.46,0,2.82,0.4,4,1.08V2.84C14.77,2.3,13.42,2,11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12 c0-1.05-0.17-2.05-0.47-3h-2.13C19.78,9.93,20,10.94,20,12z",
|
|
151
|
+
// 別タブで開くリンク。参加者一覧の簡易プロフィール→詳細プロフィールへの導線(#254)。
|
|
152
|
+
open_in_new: "M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z",
|
|
153
|
+
// 参加者一覧の行展開トグル(簡易プロフィール開閉。#254)。
|
|
154
|
+
expand_more: "M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z",
|
|
155
|
+
expand_less: "M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z",
|
|
156
|
+
// モバイルBottom Navのチャット導線用の吹き出しアイコン(#284)
|
|
157
|
+
chat: "M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z",
|
|
158
|
+
// チャットメッセージの「返信」アクション(#324)
|
|
159
|
+
reply: "M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z",
|
|
160
|
+
// 汎用の閉じる(×)。返信プレビューバーのキャンセルボタン等(#324)
|
|
161
|
+
close: "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z",
|
|
162
|
+
// フィードバック送信フォームの常設フローティングボタン(#329)。吹き出し+感嘆符。
|
|
163
|
+
feedback: "M20 2H4c-1.1 0-2 .89-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.11-.9-2-2-2zM13 14h-2v-2h2v2zm0-4h-2V6h2v4z",
|
|
164
|
+
// レコード盤(プレーヤーのレコードビュー切替ボタン用。#376)
|
|
165
|
+
album: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z",
|
|
166
|
+
// 画像スタンプ添付ボタン(チャットの画像アップロード。#394)
|
|
167
|
+
image: "M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4.86 8.86-3 3.87L9 13.14 6 17h12l-3.86-5.14z",
|
|
168
|
+
// チャット送信ボタン(#430。message-input-action-area 整理でテキストラベルからアイコン化)
|
|
169
|
+
send: "M2.01 21 23 12 2.01 3 2 10l15 2-15 2z",
|
|
170
|
+
// 削除ボタン(ゴミ箱。スタンプ一覧からの削除等。#416フォローアップ)
|
|
171
|
+
delete: "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z",
|
|
172
|
+
// My Playlist(#452)への追加ボタン。塗り星(追加済み)/枠線星(未追加)。
|
|
173
|
+
star: "M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z",
|
|
174
|
+
star_outline: "M22 9.24l-7.19-.62L12 2 9.19 8.62 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z",
|
|
175
|
+
// 人物+追加。フォローボタン(未フォロー状態)用。(#397)
|
|
176
|
+
person_add: "M15 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm-9-2V7H4v3H1v2h3v3h2v-3h3v-2H6zm9 4c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z",
|
|
177
|
+
// 通知ベル(ヘッダーのin-appお知らせ通知アイコン。#390)
|
|
178
|
+
notifications: "M12 22c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2zm6-6v-5c0-3.07-1.63-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.64 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z",
|
|
179
|
+
// CDプレーヤービュー切替(#421)。円盤+小さなスピンドル穴(レコードの album より穴を小さくして
|
|
180
|
+
// 実物のCDに近い比率にする)。非零巻き数ルールで外側円(時計回り)と内側円(反時計回り)を
|
|
181
|
+
// 重ねて穴を開ける(album アイコンと同じ手法)。
|
|
182
|
+
cd: "M2,12A10,10 0 1,1 22,12A10,10 0 1,1 2,12Z M10.4,12A1.6,1.6 0 1,0 13.6,12A1.6,1.6 0 1,0 10.4,12Z",
|
|
183
|
+
// カセットプレーヤービュー切替(#421)。外枠(フレーム状に穴抜き)+2つのリール窓(各々小さな
|
|
184
|
+
// スピンドル穴つき)+中央のテープ帯。cd と同じ非零巻き数の穴あけ手法を入れ子で使う。
|
|
185
|
+
cassette: "M3,5H21V19H3Z M5,7V17H19V7Z M6.3,12A2.2,2.2 0 1,1 10.7,12A2.2,2.2 0 1,1 6.3,12Z M7.6,12A0.9,0.9 0 1,0 9.4,12A0.9,0.9 0 1,0 7.6,12Z M13.3,12A2.2,2.2 0 1,1 17.7,12A2.2,2.2 0 1,1 13.3,12Z M14.6,12A0.9,0.9 0 1,0 16.4,12A0.9,0.9 0 1,0 14.6,12Z M10.5,11.4H13.5V12.6H10.5Z",
|
|
186
|
+
// コミュニティ機能(#579)で使う追加アイコン。標準 Material Icons(0 0 24 24)。
|
|
187
|
+
search: "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z",
|
|
188
|
+
more_horiz: "M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z",
|
|
189
|
+
info: "M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z",
|
|
190
|
+
music_note: "M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z",
|
|
191
|
+
schedule: "M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z",
|
|
192
|
+
chevron_right: "M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z",
|
|
193
|
+
tag: "M20 10V8h-4V4h-2v4h-4V4H8v4H4v2h4v4H4v2h4v4h2v-4h4v4h2v-4h4v-2h-4v-4h4zm-6 4h-4v-4h4v4z",
|
|
194
|
+
play_circle: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z",
|
|
195
|
+
login: "M11 7 9.6 8.4l2.6 2.6H2v2h10.2l-2.6 2.6L11 17l5-5-5-5zm9 12h-8v2h8c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-8v2h8v14z",
|
|
196
|
+
add_photo_alternate: "M18 20H4V6h9V4H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-9h-2v9zm-7.79-3.17-1.96-2.36L5.5 18h11l-3.54-4.71zM20 4V1h-2v3h-3c.01.01 0 2 0 2h3v2.99c.01.01 2 0 2 0V6h3V4h-3z",
|
|
197
|
+
mood: "M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z",
|
|
198
|
+
diversity_3: "M12 2C10.34 2 9 3.34 9 5s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3zm-7 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3zm14 0c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3zM12 13c-2.67 0-4 1.34-4 3v2h8v-2c0-1.66-1.33-3-4-3z",
|
|
199
|
+
waving_hand: "M2.24 11.19 1 12.43l6.36 6.37a5.997 5.997 0 0 0 8.49 0l4.24-4.25c.78-.78.78-2.05 0-2.83a2.01 2.01 0 0 0-1.68-.57 2 2 0 0 0-1.9-2.35c-.24 0-.47.05-.68.13a2 2 0 0 0-2.83-1.11l-1.42-1.42a2.007 2.007 0 0 0-2.83 0l-.71.71 4.6 4.6-.71.71-6.36-6.37-1.24 1.24 1.42 1.42-2.29 2.66z",
|
|
200
|
+
// 運営管理画面(Operator Console。#625)のアイコンレール/各画面で使う Material Icons(0 0 24 24)。
|
|
201
|
+
dashboard: "M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z",
|
|
202
|
+
forum: "M15 4v7H5.17L4 12.17V4h11m1-2H3c-.55 0-1 .45-1 1v14l4-4h10c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm5 4h-2v9H6v2c0 .55.45 1 1 1h11l4 4V7c0-.55-.45-1-1-1z",
|
|
203
|
+
table_view: "M10 10.02h5V21h-5zM17 21h3c1.1 0 2-.9 2-2v-9h-5v11zm3-18H5c-1.1 0-2 .9-2 2v3h19V5c0-1.1-.9-2-2-2zM3 19c0 1.1.9 2 2 2h3V10H3v9z",
|
|
204
|
+
campaign: "M18 11v2h4v-2h-4zm-2 6.61c.96.71 2.21 1.65 3.2 2.39.4-.53.8-1.07 1.2-1.6-.99-.74-2.24-1.68-3.2-2.4-.4.54-.8 1.08-1.2 1.61zM20.4 5.6c-.4-.53-.8-1.07-1.2-1.6-.99.74-2.24 1.68-3.2 2.4.4.53.8 1.07 1.2 1.6.96-.72 2.21-1.65 3.2-2.4zM4 9c-1.1 0-2 .9-2 2v2c0 1.1.9 2 2 2h1v4h2v-4h1l5 3V6L8 9H4zm11.5 3c0-1.33-.58-2.53-1.5-3.35v6.69c.92-.81 1.5-2.01 1.5-3.34z",
|
|
205
|
+
inbox: "M19 3H4.99c-1.11 0-1.98.9-1.98 2L3 19c0 1.1.88 2 1.99 2H19c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 12h-4c0 1.66-1.35 3-3 3s-3-1.34-3-3H4.99V5H19v10z",
|
|
206
|
+
arrow_forward: "M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z",
|
|
207
|
+
arrow_downward: "M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z",
|
|
208
|
+
filter_list: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z",
|
|
209
|
+
swap_vert: "M16 17.01V10h-2v7.01h-3L15 21l4-3.99h-3zM9 3L5 6.99h3V14h2V6.99h3L9 3z",
|
|
210
|
+
view_column: "M14.67 6v12H9.33V6h5.34zm1 12H21V6h-5.33v12zm-7.34 0V6H3v12h5.33z",
|
|
211
|
+
download: "M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z",
|
|
212
|
+
upload: "M9 16h6v-6h4l-7-7-7 7h4v6zm-4 2h14v2H5v-2z",
|
|
213
|
+
drag_indicator: "M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z",
|
|
214
|
+
chevron_left: "M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z",
|
|
215
|
+
flag: "M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z",
|
|
216
|
+
// UGCモデレーション(#1056): チャットメニューの「このユーザーをブロック」用アイコン。
|
|
217
|
+
block: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z",
|
|
218
|
+
meeting_room: "M14 6v15H3v-2h2V3h9v1h5v15h2v2h-4V6h-3zm-4 5v2h2v-2h-2z",
|
|
219
|
+
pending: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-5 11c-.83 0-1.5-.67-1.5-1.5S6.17 10 7 10s1.5.67 1.5 1.5S7.83 13 7 13zm5 0c-.83 0-1.5-.67-1.5-1.5S11.17 10 12 10s1.5.67 1.5 1.5S12.83 13 12 13zm5 0c-.83 0-1.5-.67-1.5-1.5S16.17 10 17 10s1.5.67 1.5 1.5S17.83 13 17 13z",
|
|
220
|
+
// 自動 Picture-in-Picture(#909)のトップバー開閉ボタン用。Material Icons picture_in_picture_alt 由来。
|
|
221
|
+
picture_in_picture: "M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14z",
|
|
222
|
+
// レスポンシブ拡張PiP(#926)の「ルームに戻る」ボタン用。Material Icons open_in_full 由来。
|
|
223
|
+
open_in_full: "M3 3h7v2H5v5H3V3zm18 0v7h-2V5h-5V3h7zM3 21v-7h2v5h5v2H3zm18 0h-7v-2h5v-5h2v7z",
|
|
224
|
+
// ホワイトボード「ギャラリーへ保存」ボタン用(#962)。フロッピーディスク(保存の定番アイコン)。
|
|
225
|
+
// Material Icons save 由来。
|
|
226
|
+
save: "M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z",
|
|
227
|
+
// チャットメッセージのピン留め(#1052)。Material Icons push_pin 由来。
|
|
228
|
+
push_pin: "M16 12V4h1V2H7v2h1v8l-2 2v2h5.2v6h1.6v-6H18v-2l-2-2z"
|
|
229
|
+
};
|
|
230
|
+
var CUSTOM_VIEWBOX = {
|
|
231
|
+
sticker: "0 -960 960 960"
|
|
232
|
+
};
|
|
233
|
+
var EXTRA_PATHS = {
|
|
234
|
+
sticker: "M460-360q69 0 120-45t60-113l-320 90q26 32 62 50t78 18ZM294-510l106-30q4-28-14-49t-46-21q-25 0-42.5 17.5T280-550q0 11 4 21t10 19Zm240-70 106-30q5-28-13.5-49T580-680q-25 0-42.5 17.5T520-620q0 11 4 21t10 19Zm106 460H200q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v440L640-120Zm-40-80v-80q0-33 23.5-56.5T680-360h80v-400H200v560h400Zm0 0Zm-400 0v-560 560Z"
|
|
235
|
+
};
|
|
236
|
+
var ALL_PATHS = { ...PATHS, ...EXTRA_PATHS };
|
|
237
|
+
function Icon({ name, size = 20, className }) {
|
|
238
|
+
return /* @__PURE__ */ jsx2(
|
|
239
|
+
"svg",
|
|
240
|
+
{
|
|
241
|
+
viewBox: CUSTOM_VIEWBOX[name] ?? "0 0 24 24",
|
|
242
|
+
width: size,
|
|
243
|
+
height: size,
|
|
244
|
+
fill: "currentColor",
|
|
245
|
+
"aria-hidden": "true",
|
|
246
|
+
className,
|
|
247
|
+
children: /* @__PURE__ */ jsx2("path", { d: ALL_PATHS[name] })
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// badge.tsx
|
|
253
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
254
|
+
function CountChip({ children, animated = false, className = "" }) {
|
|
255
|
+
return /* @__PURE__ */ jsx3(
|
|
256
|
+
"span",
|
|
257
|
+
{
|
|
258
|
+
className: `inline-flex items-center justify-center min-w-[20px] h-[20px] px-1.5 rounded-pill bg-success-surface-strong text-success text-xs font-extrabold tracking-normal${animated ? " animate-[pop-in_0.3s_var(--ease-spring)]" : ""} ${className}`.trim(),
|
|
259
|
+
children
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
var TONE = {
|
|
264
|
+
live: "text-success bg-success-surface",
|
|
265
|
+
warn: "text-warning bg-warning-surface",
|
|
266
|
+
danger: "text-accent bg-tint-12",
|
|
267
|
+
info: "text-info bg-info-surface",
|
|
268
|
+
neutral: "text-text-dim bg-surface-3",
|
|
269
|
+
pro: "text-on-fill bg-fill"
|
|
270
|
+
};
|
|
271
|
+
var DOT = {
|
|
272
|
+
live: "bg-success",
|
|
273
|
+
warn: "bg-warning",
|
|
274
|
+
danger: "bg-accent",
|
|
275
|
+
info: "bg-info",
|
|
276
|
+
neutral: "bg-text-faint",
|
|
277
|
+
pro: "bg-on-fill"
|
|
278
|
+
};
|
|
279
|
+
var PILL_TONES = ["live", "warn", "danger", "info"];
|
|
280
|
+
function Badge({
|
|
281
|
+
children,
|
|
282
|
+
tone,
|
|
283
|
+
dot = false,
|
|
284
|
+
icon,
|
|
285
|
+
shape,
|
|
286
|
+
className = "",
|
|
287
|
+
variant
|
|
288
|
+
}) {
|
|
289
|
+
const resolvedTone = tone ?? "neutral";
|
|
290
|
+
const legacyTone = variant ? "live" : resolvedTone;
|
|
291
|
+
const showDot = dot || variant === "live";
|
|
292
|
+
const legacyNew = variant === "new";
|
|
293
|
+
const isPill = shape ? shape === "pill" : PILL_TONES.includes(legacyTone);
|
|
294
|
+
const shapeClass = isPill ? "rounded-pill" : "rounded-chip";
|
|
295
|
+
return /* @__PURE__ */ jsxs2(
|
|
296
|
+
"span",
|
|
297
|
+
{
|
|
298
|
+
className: `inline-flex shrink-0 items-center gap-1.5 px-2.5 py-1 font-mono text-xs font-semibold ${TONE[legacyTone]} ${shapeClass}${legacyNew ? " uppercase tracking-tag" : ""} ${className}`.trim(),
|
|
299
|
+
children: [
|
|
300
|
+
showDot && /* @__PURE__ */ jsx3("span", { className: `h-1.5 w-1.5 rounded-pill ${DOT[legacyTone]}`, "aria-hidden": "true" }),
|
|
301
|
+
icon != null && (typeof icon === "string" ? /* @__PURE__ */ jsx3(Icon, { name: icon, size: 13 }) : icon),
|
|
302
|
+
children
|
|
303
|
+
]
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// bottom-sheet.tsx
|
|
309
|
+
import { useEffect, useRef, useState } from "react";
|
|
310
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
311
|
+
var MID_RATIO = 0.68;
|
|
312
|
+
var FULL_RATIO = 0.94;
|
|
313
|
+
var CLOSE_RATIO = 0.32;
|
|
314
|
+
function BottomSheet({
|
|
315
|
+
open,
|
|
316
|
+
onClose,
|
|
317
|
+
children,
|
|
318
|
+
ariaLabel,
|
|
319
|
+
closeLabel,
|
|
320
|
+
closeOnEsc = true
|
|
321
|
+
}) {
|
|
322
|
+
const [mode, setMode] = useState("mid");
|
|
323
|
+
const sheetRef = useRef(null);
|
|
324
|
+
useEffect(() => {
|
|
325
|
+
if (open) setMode("mid");
|
|
326
|
+
}, [open]);
|
|
327
|
+
useEffect(() => {
|
|
328
|
+
if (!open || !closeOnEsc) return void 0;
|
|
329
|
+
const onKey = (e) => {
|
|
330
|
+
if (e.key === "Escape") onClose();
|
|
331
|
+
};
|
|
332
|
+
window.addEventListener("keydown", onKey);
|
|
333
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
334
|
+
}, [open, onClose, closeOnEsc]);
|
|
335
|
+
function onHandlePointerDown(e) {
|
|
336
|
+
const sheet = sheetRef.current;
|
|
337
|
+
if (!sheet) return;
|
|
338
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
339
|
+
const handle = e.currentTarget;
|
|
340
|
+
handle.setPointerCapture(e.pointerId);
|
|
341
|
+
const startHeight = sheet.getBoundingClientRect().height;
|
|
342
|
+
const vh = window.innerHeight;
|
|
343
|
+
const drag = { pointerId: e.pointerId, startY: e.clientY, startHeight, vh };
|
|
344
|
+
sheet.style.transition = "none";
|
|
345
|
+
const onMove = (ev) => {
|
|
346
|
+
if (ev.pointerId !== drag.pointerId) return;
|
|
347
|
+
const delta = drag.startY - ev.clientY;
|
|
348
|
+
const next = Math.min(
|
|
349
|
+
drag.vh * FULL_RATIO,
|
|
350
|
+
Math.max(drag.vh * 0.18, drag.startHeight + delta)
|
|
351
|
+
);
|
|
352
|
+
sheet.style.height = `${next}px`;
|
|
353
|
+
};
|
|
354
|
+
const onUp = (ev) => {
|
|
355
|
+
if (ev.pointerId !== drag.pointerId) return;
|
|
356
|
+
handle.removeEventListener("pointermove", onMove);
|
|
357
|
+
handle.removeEventListener("pointerup", onUp);
|
|
358
|
+
handle.removeEventListener("pointercancel", onUp);
|
|
359
|
+
sheet.style.transition = "";
|
|
360
|
+
const finalHeight = sheet.getBoundingClientRect().height;
|
|
361
|
+
sheet.style.height = "";
|
|
362
|
+
if (finalHeight < drag.vh * CLOSE_RATIO) {
|
|
363
|
+
onClose();
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const midPx = drag.vh * MID_RATIO;
|
|
367
|
+
const fullPx = drag.vh * FULL_RATIO;
|
|
368
|
+
setMode(Math.abs(finalHeight - fullPx) < Math.abs(finalHeight - midPx) ? "full" : "mid");
|
|
369
|
+
};
|
|
370
|
+
handle.addEventListener("pointermove", onMove);
|
|
371
|
+
handle.addEventListener("pointerup", onUp);
|
|
372
|
+
handle.addEventListener("pointercancel", onUp);
|
|
373
|
+
}
|
|
374
|
+
if (!open) return null;
|
|
375
|
+
return /* @__PURE__ */ jsx4("div", { className: "bottom-sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs3(
|
|
376
|
+
"div",
|
|
377
|
+
{
|
|
378
|
+
ref: sheetRef,
|
|
379
|
+
className: `bottom-sheet bottom-sheet--${mode}`,
|
|
380
|
+
role: "dialog",
|
|
381
|
+
"aria-modal": "true",
|
|
382
|
+
"aria-label": ariaLabel,
|
|
383
|
+
onClick: (e) => e.stopPropagation(),
|
|
384
|
+
children: [
|
|
385
|
+
/* @__PURE__ */ jsx4(
|
|
386
|
+
"div",
|
|
387
|
+
{
|
|
388
|
+
className: "bottom-sheet-handle-area",
|
|
389
|
+
onPointerDown: onHandlePointerDown,
|
|
390
|
+
"aria-hidden": "true",
|
|
391
|
+
children: /* @__PURE__ */ jsx4("span", { className: "bottom-sheet-handle" })
|
|
392
|
+
}
|
|
393
|
+
),
|
|
394
|
+
closeLabel && /* @__PURE__ */ jsx4(
|
|
395
|
+
"button",
|
|
396
|
+
{
|
|
397
|
+
type: "button",
|
|
398
|
+
className: "bottom-sheet-close",
|
|
399
|
+
"aria-label": closeLabel,
|
|
400
|
+
title: closeLabel,
|
|
401
|
+
onClick: onClose,
|
|
402
|
+
children: "\xD7"
|
|
403
|
+
}
|
|
404
|
+
),
|
|
405
|
+
/* @__PURE__ */ jsx4("div", { className: "bottom-sheet-body", children })
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
) });
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// breakpoints.ts
|
|
412
|
+
var MOBILE_LAYOUT_MQ = "(hover: none), (pointer: coarse), (max-width: 560px)";
|
|
413
|
+
|
|
414
|
+
// spinner.tsx
|
|
415
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
416
|
+
function Spinner({ size = 16, thickness, label, className = "" }) {
|
|
417
|
+
const border = thickness ?? Math.max(2, Math.round(size / 8));
|
|
418
|
+
return /* @__PURE__ */ jsx5(
|
|
419
|
+
"span",
|
|
420
|
+
{
|
|
421
|
+
role: label ? "status" : void 0,
|
|
422
|
+
"aria-label": label,
|
|
423
|
+
"aria-hidden": label ? void 0 : true,
|
|
424
|
+
className: `inline-block shrink-0 rounded-pill border-solid border-border-strong animate-spin ${className}`.trim(),
|
|
425
|
+
style: {
|
|
426
|
+
width: size,
|
|
427
|
+
height: size,
|
|
428
|
+
borderWidth: border,
|
|
429
|
+
borderTopColor: "var(--color-mint)"
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// button.tsx
|
|
436
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
437
|
+
var BASE = "inline-flex items-center justify-center gap-2 border-2 border-solid border-transparent box-border font-display cursor-pointer select-none transition-[transform,filter,background,color,box-shadow] duration-(--dur-fast) ease-spring enabled:active:scale-[0.97] disabled:bg-surface-3 disabled:text-text-dim disabled:border-transparent disabled:cursor-not-allowed disabled:shadow-none focus-visible:shadow-focus focus-visible:outline-none";
|
|
438
|
+
var VARIANT = {
|
|
439
|
+
primary: "bg-fill text-on-fill font-bold enabled:hover:brightness-[.93]",
|
|
440
|
+
accent: "bg-accent text-on-accent font-bold enabled:hover:brightness-[.93]",
|
|
441
|
+
secondary: "bg-transparent border-text text-text font-bold enabled:hover:bg-surface-hover",
|
|
442
|
+
ghost: "bg-transparent text-info font-semibold enabled:hover:bg-surface-hover",
|
|
443
|
+
danger: "bg-danger-surface border-danger-border text-danger font-bold enabled:hover:brightness-[.93]",
|
|
444
|
+
live: "bg-success text-white font-bold enabled:hover:brightness-[.93]",
|
|
445
|
+
// 後方互換: join は live と同一。
|
|
446
|
+
join: "bg-success text-white font-bold enabled:hover:brightness-[.93]"
|
|
447
|
+
};
|
|
448
|
+
var SIZE = {
|
|
449
|
+
xs: "text-xs px-3 py-1.5",
|
|
450
|
+
sm: "text-sm px-4 py-2",
|
|
451
|
+
md: "text-md px-[22px] py-3",
|
|
452
|
+
lg: "text-md px-7 py-3.5"
|
|
453
|
+
};
|
|
454
|
+
var GHOST_PAD = "px-3.5";
|
|
455
|
+
var SPINNER_SIZE = { xs: 12, sm: 13, md: 15, lg: 16 };
|
|
456
|
+
var ICON_SIZE = { xs: 13, sm: 14, md: 17, lg: 18 };
|
|
457
|
+
function renderIcon(icon, px) {
|
|
458
|
+
if (icon == null) return null;
|
|
459
|
+
if (typeof icon === "string") return /* @__PURE__ */ jsx6(Icon, { name: icon, size: px });
|
|
460
|
+
return icon;
|
|
461
|
+
}
|
|
462
|
+
function Button({
|
|
463
|
+
variant = "primary",
|
|
464
|
+
size = "md",
|
|
465
|
+
loading = false,
|
|
466
|
+
disabled = false,
|
|
467
|
+
pill = false,
|
|
468
|
+
dot = false,
|
|
469
|
+
icon,
|
|
470
|
+
iconRight,
|
|
471
|
+
type = "button",
|
|
472
|
+
children,
|
|
473
|
+
className = "",
|
|
474
|
+
...rest
|
|
475
|
+
}) {
|
|
476
|
+
const pad = variant === "ghost" ? `${SIZE[size]} ${GHOST_PAD}` : SIZE[size];
|
|
477
|
+
const isLive = variant === "live" || variant === "join";
|
|
478
|
+
const radius = pill || isLive ? "rounded-pill" : "rounded-md";
|
|
479
|
+
const showDot = (dot || isLive) && !loading;
|
|
480
|
+
const iconPx = ICON_SIZE[size];
|
|
481
|
+
return /* @__PURE__ */ jsxs4(
|
|
482
|
+
"button",
|
|
483
|
+
{
|
|
484
|
+
type,
|
|
485
|
+
disabled: disabled || loading,
|
|
486
|
+
"aria-busy": loading || void 0,
|
|
487
|
+
className: `${BASE} ${radius} ${VARIANT[variant]} ${pad} ${className}`.trim(),
|
|
488
|
+
...rest,
|
|
489
|
+
children: [
|
|
490
|
+
showDot && /* @__PURE__ */ jsx6("span", { className: "h-2 w-2 rounded-pill bg-white", "aria-hidden": "true" }),
|
|
491
|
+
loading && /* @__PURE__ */ jsx6(Spinner, { size: SPINNER_SIZE[size] }),
|
|
492
|
+
!loading && renderIcon(icon, iconPx),
|
|
493
|
+
children,
|
|
494
|
+
!loading && renderIcon(iconRight, iconPx)
|
|
495
|
+
]
|
|
496
|
+
}
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// checkbox.tsx
|
|
501
|
+
import { useId } from "react";
|
|
502
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
503
|
+
function Checkbox({ checked, label, id, className = "", ...rest }) {
|
|
504
|
+
const autoId = useId();
|
|
505
|
+
const inputId = id ?? autoId;
|
|
506
|
+
return /* @__PURE__ */ jsxs5(
|
|
507
|
+
"label",
|
|
508
|
+
{
|
|
509
|
+
htmlFor: inputId,
|
|
510
|
+
className: `inline-flex cursor-pointer select-none items-center gap-3 ${className}`.trim(),
|
|
511
|
+
children: [
|
|
512
|
+
/* @__PURE__ */ jsx7("input", { id: inputId, type: "checkbox", checked, className: "peer sr-only", ...rest }),
|
|
513
|
+
/* @__PURE__ */ jsx7(
|
|
514
|
+
"span",
|
|
515
|
+
{
|
|
516
|
+
className: `grid h-[22px] w-[22px] place-items-center rounded-chip border-2 border-solid transition-colors peer-focus-visible:shadow-focus ${checked ? "border-fill bg-fill text-on-fill" : "border-border-strong bg-transparent text-transparent"}`,
|
|
517
|
+
children: /* @__PURE__ */ jsx7(Icon, { name: "check", size: 15 })
|
|
518
|
+
}
|
|
519
|
+
),
|
|
520
|
+
label != null && /* @__PURE__ */ jsx7("span", { className: "text-md text-text", children: label })
|
|
521
|
+
]
|
|
522
|
+
}
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// chip.tsx
|
|
527
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
528
|
+
var BASE2 = "inline-flex items-center gap-1.5 rounded-pill border border-solid text-[12.5px] cursor-pointer select-none transition-colors duration-(--dur-fast)";
|
|
529
|
+
var PAD_DEFAULT = "px-3.5 py-[7px]";
|
|
530
|
+
var PAD_REMOVABLE = "pl-[14px] pr-2.5 py-1.5";
|
|
531
|
+
var PAD_AVATAR = "pl-[5px] pr-[13px] py-[5px]";
|
|
532
|
+
var DEFAULT = "bg-surface-2 border-border-strong text-text font-semibold enabled:hover:bg-surface-hover";
|
|
533
|
+
var SELECTED = "bg-tint-22 border-[color-mix(in_srgb,var(--color-accent)_55%,transparent)] text-accent font-bold";
|
|
534
|
+
function Chip({
|
|
535
|
+
selected = false,
|
|
536
|
+
icon,
|
|
537
|
+
avatar,
|
|
538
|
+
removable = false,
|
|
539
|
+
onRemove,
|
|
540
|
+
children,
|
|
541
|
+
type = "button",
|
|
542
|
+
className = "",
|
|
543
|
+
...rest
|
|
544
|
+
}) {
|
|
545
|
+
const pad = removable ? PAD_REMOVABLE : avatar ? PAD_AVATAR : PAD_DEFAULT;
|
|
546
|
+
return /* @__PURE__ */ jsxs6(
|
|
547
|
+
"button",
|
|
548
|
+
{
|
|
549
|
+
type,
|
|
550
|
+
"aria-pressed": selected,
|
|
551
|
+
className: `${BASE2} ${pad} ${selected ? SELECTED : DEFAULT} ${className}`.trim(),
|
|
552
|
+
...rest,
|
|
553
|
+
children: [
|
|
554
|
+
avatar && /* @__PURE__ */ jsx8(
|
|
555
|
+
"span",
|
|
556
|
+
{
|
|
557
|
+
className: "inline-flex h-[22px] w-[22px] items-center justify-center rounded-pill bg-success text-xs font-bold text-white",
|
|
558
|
+
style: avatar.color ? { background: avatar.color } : void 0,
|
|
559
|
+
"aria-hidden": "true",
|
|
560
|
+
children: avatar.label
|
|
561
|
+
}
|
|
562
|
+
),
|
|
563
|
+
selected ? /* @__PURE__ */ jsx8(Icon, { name: "check", size: 16 }) : icon,
|
|
564
|
+
children,
|
|
565
|
+
removable && /* @__PURE__ */ jsx8(
|
|
566
|
+
"span",
|
|
567
|
+
{
|
|
568
|
+
role: "button",
|
|
569
|
+
tabIndex: -1,
|
|
570
|
+
"aria-label": "remove",
|
|
571
|
+
className: "inline-flex text-text-dim",
|
|
572
|
+
onClick: (e) => {
|
|
573
|
+
e.stopPropagation();
|
|
574
|
+
onRemove?.();
|
|
575
|
+
},
|
|
576
|
+
children: /* @__PURE__ */ jsx8(Icon, { name: "close", size: 15 })
|
|
577
|
+
}
|
|
578
|
+
)
|
|
579
|
+
]
|
|
580
|
+
}
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// composer.tsx
|
|
585
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
586
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
587
|
+
var AUTO_GROW_RETRY_MS = 200;
|
|
588
|
+
var AUTO_GROW_RETRY_LIMIT = 25;
|
|
589
|
+
function Composer({
|
|
590
|
+
value,
|
|
591
|
+
onChange,
|
|
592
|
+
onSubmit,
|
|
593
|
+
placeholder,
|
|
594
|
+
maxLength,
|
|
595
|
+
disabled = false,
|
|
596
|
+
sendLabel,
|
|
597
|
+
actions,
|
|
598
|
+
flash = false,
|
|
599
|
+
textareaRef,
|
|
600
|
+
size = "default",
|
|
601
|
+
className = ""
|
|
602
|
+
}) {
|
|
603
|
+
const ownRef = useRef2(null);
|
|
604
|
+
const ref = textareaRef ?? ownRef;
|
|
605
|
+
const autoGrowRetryTimerRef = useRef2(null);
|
|
606
|
+
const autoGrowRetryCountRef = useRef2(0);
|
|
607
|
+
function clearAutoGrowRetry() {
|
|
608
|
+
if (autoGrowRetryTimerRef.current !== null) {
|
|
609
|
+
clearTimeout(autoGrowRetryTimerRef.current);
|
|
610
|
+
autoGrowRetryTimerRef.current = null;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
function autoGrow() {
|
|
614
|
+
clearAutoGrowRetry();
|
|
615
|
+
const el = ref.current;
|
|
616
|
+
if (!el) return;
|
|
617
|
+
el.style.height = "auto";
|
|
618
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
619
|
+
const maxHeight = Number.parseFloat(getComputedStyle(el).maxHeight);
|
|
620
|
+
if (!Number.isFinite(maxHeight) || maxHeight <= 0) {
|
|
621
|
+
el.style.overflowY = "hidden";
|
|
622
|
+
if (autoGrowRetryCountRef.current < AUTO_GROW_RETRY_LIMIT) {
|
|
623
|
+
autoGrowRetryCountRef.current += 1;
|
|
624
|
+
autoGrowRetryTimerRef.current = setTimeout(autoGrow, AUTO_GROW_RETRY_MS);
|
|
625
|
+
}
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
autoGrowRetryCountRef.current = 0;
|
|
629
|
+
el.style.overflowY = el.scrollHeight > maxHeight ? "auto" : "hidden";
|
|
630
|
+
}
|
|
631
|
+
useEffect2(() => {
|
|
632
|
+
autoGrow();
|
|
633
|
+
return () => clearAutoGrowRetry();
|
|
634
|
+
}, [value]);
|
|
635
|
+
function trySubmit() {
|
|
636
|
+
const text = value.trim();
|
|
637
|
+
if (!text) return;
|
|
638
|
+
onSubmit(text);
|
|
639
|
+
}
|
|
640
|
+
function handleFormSubmit(e) {
|
|
641
|
+
e.preventDefault();
|
|
642
|
+
trySubmit();
|
|
643
|
+
}
|
|
644
|
+
function handleKeyDown(e) {
|
|
645
|
+
if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing) {
|
|
646
|
+
e.preventDefault();
|
|
647
|
+
trySubmit();
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
const canSubmit = !disabled && value.trim().length > 0;
|
|
651
|
+
const textareaPad = size === "compact" ? "px-3.5 pt-2 pb-0.5" : "px-4.5 pt-2.5 pb-1";
|
|
652
|
+
const actionsPad = size === "compact" ? "px-2 py-1.5" : "px-2 py-2.5";
|
|
653
|
+
const iconSize = size === "compact" ? 14 : 16;
|
|
654
|
+
const btnSize = size === "compact" ? "h-6.5 w-6.5" : "h-7.5 w-7.5";
|
|
655
|
+
return /* @__PURE__ */ jsxs7(
|
|
656
|
+
"form",
|
|
657
|
+
{
|
|
658
|
+
onSubmit: handleFormSubmit,
|
|
659
|
+
className: `flex flex-col rounded-card border-[1.5px] border-solid bg-surface transition-[border-color,box-shadow] duration-(--dur-fast) ${flash ? "border-mint shadow-focus" : "border-border"} ${className}`.trim(),
|
|
660
|
+
children: [
|
|
661
|
+
/* @__PURE__ */ jsx9(
|
|
662
|
+
"textarea",
|
|
663
|
+
{
|
|
664
|
+
ref,
|
|
665
|
+
value,
|
|
666
|
+
onChange: (e) => onChange(e.target.value),
|
|
667
|
+
onKeyDown: handleKeyDown,
|
|
668
|
+
placeholder,
|
|
669
|
+
maxLength,
|
|
670
|
+
disabled,
|
|
671
|
+
rows: 1,
|
|
672
|
+
autoComplete: "off",
|
|
673
|
+
className: `max-h-[120px] resize-none border-none bg-transparent font-body text-md leading-snug text-text outline-none placeholder:text-text-faint ${textareaPad}`
|
|
674
|
+
}
|
|
675
|
+
),
|
|
676
|
+
/* @__PURE__ */ jsxs7("div", { className: `flex items-center justify-between gap-2 ${actionsPad}`, children: [
|
|
677
|
+
/* @__PURE__ */ jsx9("div", { className: "flex items-center gap-0.5", children: actions }),
|
|
678
|
+
/* @__PURE__ */ jsx9(
|
|
679
|
+
"button",
|
|
680
|
+
{
|
|
681
|
+
type: "submit",
|
|
682
|
+
"aria-label": sendLabel,
|
|
683
|
+
title: sendLabel,
|
|
684
|
+
disabled: !canSubmit,
|
|
685
|
+
className: `inline-flex shrink-0 cursor-pointer items-center justify-center rounded-pill border-none bg-transparent p-0 transition-colors duration-(--dur-fast) ${btnSize} ${canSubmit ? "text-mint-soft" : "text-text-dim"} enabled:hover:bg-tint-5 enabled:hover:text-mint-soft disabled:cursor-not-allowed disabled:opacity-35`,
|
|
686
|
+
children: /* @__PURE__ */ jsx9(Icon, { name: "send", size: iconSize })
|
|
687
|
+
}
|
|
688
|
+
)
|
|
689
|
+
] })
|
|
690
|
+
]
|
|
691
|
+
}
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// modal.tsx
|
|
696
|
+
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
697
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
698
|
+
function Modal({
|
|
699
|
+
onClose,
|
|
700
|
+
children,
|
|
701
|
+
width,
|
|
702
|
+
className = "",
|
|
703
|
+
ariaLabel,
|
|
704
|
+
closeLabel,
|
|
705
|
+
as = "div",
|
|
706
|
+
onSubmit,
|
|
707
|
+
closeOnEsc = true,
|
|
708
|
+
title,
|
|
709
|
+
footer
|
|
710
|
+
}) {
|
|
711
|
+
const backdropRef = useRef3(null);
|
|
712
|
+
useEffect3(() => {
|
|
713
|
+
if (!closeOnEsc) return void 0;
|
|
714
|
+
const win = backdropRef.current?.ownerDocument?.defaultView ?? window;
|
|
715
|
+
const onKey = (e) => {
|
|
716
|
+
if (e.key === "Escape") onClose();
|
|
717
|
+
};
|
|
718
|
+
win.addEventListener("keydown", onKey);
|
|
719
|
+
return () => win.removeEventListener("keydown", onKey);
|
|
720
|
+
}, [onClose, closeOnEsc]);
|
|
721
|
+
const Box = as;
|
|
722
|
+
const ds = title != null || footer != null;
|
|
723
|
+
return /* @__PURE__ */ jsx10("div", { className: "modal-backdrop", ref: backdropRef, onClick: onClose, children: ds ? (
|
|
724
|
+
// DS 構造(トークンのユーティリティ)。
|
|
725
|
+
/* @__PURE__ */ jsxs8(
|
|
726
|
+
Box,
|
|
727
|
+
{
|
|
728
|
+
className: `relative flex w-full flex-col overflow-hidden rounded-card border border-solid border-border bg-surface shadow-overlay animate-[card-in_0.4s_var(--ease-spring)_both] ${className}`.trim(),
|
|
729
|
+
style: width ? { width } : { width: "min(420px, 92vw)" },
|
|
730
|
+
role: "dialog",
|
|
731
|
+
"aria-modal": "true",
|
|
732
|
+
"aria-label": ariaLabel,
|
|
733
|
+
onClick: (e) => e.stopPropagation(),
|
|
734
|
+
onSubmit,
|
|
735
|
+
children: [
|
|
736
|
+
title != null && /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between gap-3 border-b border-solid border-border px-[18px] py-4", children: [
|
|
737
|
+
/* @__PURE__ */ jsx10("span", { className: "text-lg font-extrabold text-text", children: title }),
|
|
738
|
+
closeLabel && /* @__PURE__ */ jsx10(
|
|
739
|
+
"button",
|
|
740
|
+
{
|
|
741
|
+
type: "button",
|
|
742
|
+
"aria-label": closeLabel,
|
|
743
|
+
title: closeLabel,
|
|
744
|
+
onClick: onClose,
|
|
745
|
+
className: "inline-flex h-[30px] w-[30px] items-center justify-center rounded-chip border-none bg-transparent text-text-dim cursor-pointer enabled:hover:bg-surface-hover enabled:hover:text-text",
|
|
746
|
+
children: /* @__PURE__ */ jsx10(Icon, { name: "close", size: 19 })
|
|
747
|
+
}
|
|
748
|
+
)
|
|
749
|
+
] }),
|
|
750
|
+
/* @__PURE__ */ jsx10("div", { className: "p-[18px]", children }),
|
|
751
|
+
footer != null && /* @__PURE__ */ jsx10("div", { className: "flex justify-end gap-2.5 border-t border-solid border-border bg-surface-2 px-[18px] py-3.5", children: footer })
|
|
752
|
+
]
|
|
753
|
+
}
|
|
754
|
+
)
|
|
755
|
+
) : (
|
|
756
|
+
// 既定(legacy 共有プリミティブ)。従来経路と完全同一。
|
|
757
|
+
/* @__PURE__ */ jsxs8(
|
|
758
|
+
Box,
|
|
759
|
+
{
|
|
760
|
+
className: `modal ${className}`.trim(),
|
|
761
|
+
style: width ? { width } : void 0,
|
|
762
|
+
role: "dialog",
|
|
763
|
+
"aria-modal": "true",
|
|
764
|
+
"aria-label": ariaLabel,
|
|
765
|
+
onClick: (e) => e.stopPropagation(),
|
|
766
|
+
onSubmit,
|
|
767
|
+
children: [
|
|
768
|
+
closeLabel && /* @__PURE__ */ jsx10(
|
|
769
|
+
"button",
|
|
770
|
+
{
|
|
771
|
+
type: "button",
|
|
772
|
+
className: "modal-close",
|
|
773
|
+
"aria-label": closeLabel,
|
|
774
|
+
title: closeLabel,
|
|
775
|
+
onClick: onClose,
|
|
776
|
+
children: "\xD7"
|
|
777
|
+
}
|
|
778
|
+
),
|
|
779
|
+
children
|
|
780
|
+
]
|
|
781
|
+
}
|
|
782
|
+
)
|
|
783
|
+
) });
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// confirm-modal.tsx
|
|
787
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
788
|
+
var TONE_CIRCLE = {
|
|
789
|
+
danger: "text-danger bg-danger-surface",
|
|
790
|
+
warn: "text-warning bg-warning-surface",
|
|
791
|
+
info: "text-info bg-info-surface"
|
|
792
|
+
};
|
|
793
|
+
function ConfirmModal({
|
|
794
|
+
onClose,
|
|
795
|
+
onConfirm,
|
|
796
|
+
title,
|
|
797
|
+
children,
|
|
798
|
+
confirmLabel,
|
|
799
|
+
cancelLabel,
|
|
800
|
+
confirmVariant = "primary",
|
|
801
|
+
tone,
|
|
802
|
+
icon = "warning",
|
|
803
|
+
loading = false,
|
|
804
|
+
ariaLabel,
|
|
805
|
+
className = ""
|
|
806
|
+
}) {
|
|
807
|
+
const resolvedTone = tone ?? (confirmVariant === "danger" ? "danger" : "info");
|
|
808
|
+
return /* @__PURE__ */ jsxs9(Modal, { onClose, ariaLabel: ariaLabel ?? title, className, children: [
|
|
809
|
+
/* @__PURE__ */ jsx11(
|
|
810
|
+
"span",
|
|
811
|
+
{
|
|
812
|
+
className: `mx-auto inline-flex h-[46px] w-[46px] items-center justify-center rounded-pill ${TONE_CIRCLE[resolvedTone]}`,
|
|
813
|
+
"aria-hidden": "true",
|
|
814
|
+
children: /* @__PURE__ */ jsx11(Icon, { name: icon, size: 24 })
|
|
815
|
+
}
|
|
816
|
+
),
|
|
817
|
+
/* @__PURE__ */ jsx11("h2", { children: title }),
|
|
818
|
+
/* @__PURE__ */ jsx11("p", { className: "break-words text-center text-base leading-[1.55] text-text-dim", children }),
|
|
819
|
+
/* @__PURE__ */ jsxs9("div", { className: "mt-2 flex gap-2.5", children: [
|
|
820
|
+
/* @__PURE__ */ jsx11(Button, { variant: "ghost", className: "flex-1", onClick: onClose, children: cancelLabel }),
|
|
821
|
+
/* @__PURE__ */ jsx11(Button, { variant: confirmVariant, className: "flex-1", loading, onClick: onConfirm, children: confirmLabel })
|
|
822
|
+
] })
|
|
823
|
+
] });
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// empty-note.tsx
|
|
827
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
828
|
+
var VARIANT2 = {
|
|
829
|
+
default: "px-4 py-5 text-center",
|
|
830
|
+
compact: "flex min-h-32 items-center justify-center px-1 py-3.5 text-center",
|
|
831
|
+
dropdown: "flex min-h-28 items-center justify-center px-4 py-[18px] text-center"
|
|
832
|
+
};
|
|
833
|
+
function EmptyNote({ children, variant = "default" }) {
|
|
834
|
+
return /* @__PURE__ */ jsx12("p", { className: `${VARIANT2[variant]} text-base leading-[1.7] text-text-faint`, children });
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// icon-button.tsx
|
|
838
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
839
|
+
var VARIANT3 = {
|
|
840
|
+
surface: "bg-surface-2 border border-solid border-border text-text-dim enabled:hover:bg-surface-hover enabled:hover:text-text",
|
|
841
|
+
accent: "bg-accent border border-solid border-transparent text-on-accent enabled:hover:brightness-[.93]",
|
|
842
|
+
ghost: "bg-transparent border border-solid border-transparent text-text-dim enabled:hover:bg-surface-hover"
|
|
843
|
+
};
|
|
844
|
+
function IconButton({
|
|
845
|
+
label,
|
|
846
|
+
icon,
|
|
847
|
+
variant = "surface",
|
|
848
|
+
size = 36,
|
|
849
|
+
type = "button",
|
|
850
|
+
className = "",
|
|
851
|
+
disabled,
|
|
852
|
+
...rest
|
|
853
|
+
}) {
|
|
854
|
+
return /* @__PURE__ */ jsx13(
|
|
855
|
+
"button",
|
|
856
|
+
{
|
|
857
|
+
type,
|
|
858
|
+
"aria-label": label,
|
|
859
|
+
disabled,
|
|
860
|
+
style: { width: size, height: size },
|
|
861
|
+
className: `inline-flex shrink-0 items-center justify-center rounded-md cursor-pointer transition-colors duration-(--dur-fast) disabled:cursor-not-allowed disabled:opacity-(--disabled-opacity) focus-visible:shadow-focus focus-visible:outline-none ${VARIANT3[variant]} ${className}`.trim(),
|
|
862
|
+
...rest,
|
|
863
|
+
children: icon
|
|
864
|
+
}
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// icons/google-icon.tsx
|
|
869
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
870
|
+
function GoogleIcon() {
|
|
871
|
+
return /* @__PURE__ */ jsxs10("svg", { className: "google-icon", viewBox: "0 0 18 18", width: "18", height: "18", "aria-hidden": "true", children: [
|
|
872
|
+
/* @__PURE__ */ jsx14(
|
|
873
|
+
"path",
|
|
874
|
+
{
|
|
875
|
+
fill: "#4285F4",
|
|
876
|
+
d: "M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62Z"
|
|
877
|
+
}
|
|
878
|
+
),
|
|
879
|
+
/* @__PURE__ */ jsx14(
|
|
880
|
+
"path",
|
|
881
|
+
{
|
|
882
|
+
fill: "#34A853",
|
|
883
|
+
d: "M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18Z"
|
|
884
|
+
}
|
|
885
|
+
),
|
|
886
|
+
/* @__PURE__ */ jsx14(
|
|
887
|
+
"path",
|
|
888
|
+
{
|
|
889
|
+
fill: "#FBBC05",
|
|
890
|
+
d: "M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33Z"
|
|
891
|
+
}
|
|
892
|
+
),
|
|
893
|
+
/* @__PURE__ */ jsx14(
|
|
894
|
+
"path",
|
|
895
|
+
{
|
|
896
|
+
fill: "#EA4335",
|
|
897
|
+
d: "M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58C13.46.89 11.42 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58Z"
|
|
898
|
+
}
|
|
899
|
+
)
|
|
900
|
+
] });
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
// icons/person-icon.tsx
|
|
904
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
905
|
+
function PersonIcon() {
|
|
906
|
+
return /* @__PURE__ */ jsxs11("svg", { viewBox: "0 0 24 24", width: "18", height: "18", "aria-hidden": "true", fill: "none", children: [
|
|
907
|
+
/* @__PURE__ */ jsx15("circle", { cx: "12", cy: "8", r: "4", stroke: "currentColor", strokeWidth: "1.8" }),
|
|
908
|
+
/* @__PURE__ */ jsx15(
|
|
909
|
+
"path",
|
|
910
|
+
{
|
|
911
|
+
d: "M4 20c0-3.3 3.6-6 8-6s8 2.7 8 6",
|
|
912
|
+
stroke: "currentColor",
|
|
913
|
+
strokeWidth: "1.8",
|
|
914
|
+
strokeLinecap: "round"
|
|
915
|
+
}
|
|
916
|
+
)
|
|
917
|
+
] });
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// input.tsx
|
|
921
|
+
import { useId as useId2, useState as useState2 } from "react";
|
|
922
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
923
|
+
var LABEL = "font-mono text-xs font-semibold tracking-widest uppercase transition-colors";
|
|
924
|
+
var FIELD = "flex items-center w-full bg-surface-2 border-[1.5px] border-solid rounded-md px-3.5 py-3 transition-[border-color,box-shadow] duration-(--dur-fast)";
|
|
925
|
+
var CONTROL = "flex-1 min-w-0 border-none outline-none bg-transparent text-md text-text placeholder:text-text-faint";
|
|
926
|
+
function Input({
|
|
927
|
+
label,
|
|
928
|
+
error,
|
|
929
|
+
prefix,
|
|
930
|
+
id,
|
|
931
|
+
onFocus,
|
|
932
|
+
onBlur,
|
|
933
|
+
className = "",
|
|
934
|
+
...rest
|
|
935
|
+
}) {
|
|
936
|
+
const autoId = useId2();
|
|
937
|
+
const inputId = id ?? autoId;
|
|
938
|
+
const invalid = error != null && error !== false;
|
|
939
|
+
const [focused, setFocused] = useState2(false);
|
|
940
|
+
const labelColor = invalid ? "text-accent" : focused ? "text-info" : "text-text-dim";
|
|
941
|
+
const fieldState = invalid ? "border-accent" : focused ? "border-info shadow-focus" : "border-border";
|
|
942
|
+
return /* @__PURE__ */ jsxs12("div", { className: `flex flex-col gap-[7px] ${className}`.trim(), children: [
|
|
943
|
+
label != null && /* @__PURE__ */ jsx16("label", { htmlFor: inputId, className: `${LABEL} ${labelColor}`, children: label }),
|
|
944
|
+
/* @__PURE__ */ jsxs12("div", { className: `${FIELD} ${fieldState}`, children: [
|
|
945
|
+
prefix != null && /* @__PURE__ */ jsx16("span", { className: "mr-0.5 shrink-0 font-mono text-md text-text-dim", children: prefix }),
|
|
946
|
+
/* @__PURE__ */ jsx16(
|
|
947
|
+
"input",
|
|
948
|
+
{
|
|
949
|
+
id: inputId,
|
|
950
|
+
"aria-invalid": invalid || void 0,
|
|
951
|
+
className: CONTROL,
|
|
952
|
+
onFocus: (e) => {
|
|
953
|
+
setFocused(true);
|
|
954
|
+
onFocus?.(e);
|
|
955
|
+
},
|
|
956
|
+
onBlur: (e) => {
|
|
957
|
+
setFocused(false);
|
|
958
|
+
onBlur?.(e);
|
|
959
|
+
},
|
|
960
|
+
...rest
|
|
961
|
+
}
|
|
962
|
+
)
|
|
963
|
+
] }),
|
|
964
|
+
invalid && /* @__PURE__ */ jsx16("span", { className: "text-xs text-accent", children: error })
|
|
965
|
+
] });
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// link.tsx
|
|
969
|
+
import {
|
|
970
|
+
cloneElement,
|
|
971
|
+
isValidElement
|
|
972
|
+
} from "react";
|
|
973
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
974
|
+
var VARIANT4 = {
|
|
975
|
+
inline: "text-link font-semibold no-underline cursor-pointer transition-colors duration-(--dur-fast) hover:text-link-hover",
|
|
976
|
+
subtle: "text-link text-sm font-semibold no-underline cursor-pointer transition-colors duration-(--dur-fast) hover:text-link-hover",
|
|
977
|
+
pill: "inline-flex items-center gap-1.5 self-start px-4 py-2.5 rounded-pill border border-solid border-border bg-surface text-text text-sm font-bold tracking-pill uppercase no-underline cursor-pointer transition-[background,color,transform] duration-(--dur-base) ease-spring hover:bg-surface-hover hover:text-accent hover:-translate-y-px",
|
|
978
|
+
wrapper: "text-inherit no-underline cursor-pointer"
|
|
979
|
+
};
|
|
980
|
+
function linkClass(variant = "inline", className = "") {
|
|
981
|
+
return `${VARIANT4[variant]} ${className}`.trim();
|
|
982
|
+
}
|
|
983
|
+
function Link({
|
|
984
|
+
variant = "inline",
|
|
985
|
+
asChild = false,
|
|
986
|
+
className = "",
|
|
987
|
+
children,
|
|
988
|
+
...rest
|
|
989
|
+
}) {
|
|
990
|
+
const cls = linkClass(variant, className);
|
|
991
|
+
if (asChild && isValidElement(children)) {
|
|
992
|
+
const child = children;
|
|
993
|
+
return cloneElement(child, {
|
|
994
|
+
...rest,
|
|
995
|
+
className: `${cls} ${child.props.className ?? ""}`.trim()
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
return /* @__PURE__ */ jsx17("a", { className: cls, ...rest, children });
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// logo-mark.tsx
|
|
1002
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1003
|
+
var DOT_CORAL = "#FF5A36";
|
|
1004
|
+
var DOT_AMBER = "#F5A524";
|
|
1005
|
+
var DOT_BLUE = "#3B6FE0";
|
|
1006
|
+
function Mark({ size }) {
|
|
1007
|
+
return /* @__PURE__ */ jsxs13(
|
|
1008
|
+
"svg",
|
|
1009
|
+
{
|
|
1010
|
+
"aria-hidden": "true",
|
|
1011
|
+
width: size,
|
|
1012
|
+
height: size,
|
|
1013
|
+
viewBox: "0 0 48 48",
|
|
1014
|
+
fill: "none",
|
|
1015
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1016
|
+
className: "text-text",
|
|
1017
|
+
children: [
|
|
1018
|
+
/* @__PURE__ */ jsx18("circle", { cx: "24", cy: "24", r: "13", stroke: "currentColor", strokeWidth: "4", fill: "none" }),
|
|
1019
|
+
/* @__PURE__ */ jsx18("circle", { cx: "24", cy: "11", r: "6.5", fill: DOT_CORAL }),
|
|
1020
|
+
/* @__PURE__ */ jsx18("circle", { cx: "35.3", cy: "30.5", r: "6.5", fill: DOT_AMBER }),
|
|
1021
|
+
/* @__PURE__ */ jsx18("circle", { cx: "12.7", cy: "30.5", r: "6.5", fill: DOT_BLUE })
|
|
1022
|
+
]
|
|
1023
|
+
}
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
function LogoMark({
|
|
1027
|
+
variant = "row",
|
|
1028
|
+
size = 20,
|
|
1029
|
+
showWordmark = false,
|
|
1030
|
+
wordmarkSize,
|
|
1031
|
+
className = ""
|
|
1032
|
+
}) {
|
|
1033
|
+
if (variant === "cluster") {
|
|
1034
|
+
return /* @__PURE__ */ jsx18("span", { className: `inline-flex ${className}`.trim(), children: /* @__PURE__ */ jsx18(Mark, { size }) });
|
|
1035
|
+
}
|
|
1036
|
+
const wordmarkPx = wordmarkSize ?? Math.round(size * 0.85);
|
|
1037
|
+
return /* @__PURE__ */ jsxs13("span", { className: `inline-flex items-center gap-2 ${className}`.trim(), children: [
|
|
1038
|
+
/* @__PURE__ */ jsx18(Mark, { size }),
|
|
1039
|
+
showWordmark && /* @__PURE__ */ jsx18(
|
|
1040
|
+
"span",
|
|
1041
|
+
{
|
|
1042
|
+
className: "font-display font-extrabold uppercase tracking-tight text-text",
|
|
1043
|
+
style: { fontSize: wordmarkPx },
|
|
1044
|
+
children: "LOOPHUB"
|
|
1045
|
+
}
|
|
1046
|
+
)
|
|
1047
|
+
] });
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
// lozenge.tsx
|
|
1051
|
+
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1052
|
+
var TONE2 = {
|
|
1053
|
+
success: "text-success bg-success-surface-strong",
|
|
1054
|
+
warning: "text-warning bg-warning-surface-strong",
|
|
1055
|
+
accent: "text-accent bg-tint-22",
|
|
1056
|
+
info: "text-info bg-info-surface-strong",
|
|
1057
|
+
// neutral は tint(accent 色相)ではなく中立の面を使う。tint を濃くすると accent tone と
|
|
1058
|
+
// 見分けが付かなくなるため、面は surface-3・文字は text-text で濃度を確保する(#765)。
|
|
1059
|
+
neutral: "text-text bg-surface-3"
|
|
1060
|
+
};
|
|
1061
|
+
var DOT2 = {
|
|
1062
|
+
success: "bg-success",
|
|
1063
|
+
warning: "bg-warning",
|
|
1064
|
+
accent: "bg-accent",
|
|
1065
|
+
info: "bg-info",
|
|
1066
|
+
neutral: "bg-text-faint"
|
|
1067
|
+
};
|
|
1068
|
+
function Lozenge({
|
|
1069
|
+
tone = "neutral",
|
|
1070
|
+
dot = false,
|
|
1071
|
+
children,
|
|
1072
|
+
className = ""
|
|
1073
|
+
}) {
|
|
1074
|
+
return /* @__PURE__ */ jsxs14(
|
|
1075
|
+
"span",
|
|
1076
|
+
{
|
|
1077
|
+
className: `inline-flex items-center gap-1.5 rounded-pill px-2.5 py-1 font-mono text-xs font-semibold uppercase tracking-pill ${TONE2[tone]} ${className}`.trim(),
|
|
1078
|
+
children: [
|
|
1079
|
+
dot && /* @__PURE__ */ jsx19("span", { className: `h-1.5 w-1.5 rounded-pill ${DOT2[tone]}`, "aria-hidden": "true" }),
|
|
1080
|
+
children
|
|
1081
|
+
]
|
|
1082
|
+
}
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
// menu.tsx
|
|
1087
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1088
|
+
function Menu({ children, ariaLabel, className = "" }) {
|
|
1089
|
+
return /* @__PURE__ */ jsx20(
|
|
1090
|
+
"ul",
|
|
1091
|
+
{
|
|
1092
|
+
role: "menu",
|
|
1093
|
+
"aria-label": ariaLabel,
|
|
1094
|
+
className: `m-0 flex list-none flex-col gap-0.5 p-0 ${className}`.trim(),
|
|
1095
|
+
children
|
|
1096
|
+
}
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1099
|
+
var ROW = "flex w-full items-center gap-[13px] rounded-md border-none bg-transparent px-[13px] py-[11px] text-left text-[15px] shadow-none transition-colors duration-(--dur-fast) cursor-pointer disabled:opacity-(--disabled-opacity) disabled:cursor-not-allowed";
|
|
1100
|
+
function MenuItem({
|
|
1101
|
+
onSelect,
|
|
1102
|
+
children,
|
|
1103
|
+
icon,
|
|
1104
|
+
trailing,
|
|
1105
|
+
active = false,
|
|
1106
|
+
danger = false,
|
|
1107
|
+
disabled = false,
|
|
1108
|
+
role = "menuitem"
|
|
1109
|
+
}) {
|
|
1110
|
+
const tone = danger ? "text-danger enabled:hover:bg-danger-surface" : active ? "text-success bg-[color-mix(in_srgb,var(--color-success)_10%,transparent)]" : "text-text enabled:hover:bg-surface-hover";
|
|
1111
|
+
return /* @__PURE__ */ jsx20("li", { children: /* @__PURE__ */ jsxs15(
|
|
1112
|
+
"button",
|
|
1113
|
+
{
|
|
1114
|
+
type: "button",
|
|
1115
|
+
role,
|
|
1116
|
+
"aria-checked": role === "menuitem" ? void 0 : active,
|
|
1117
|
+
disabled,
|
|
1118
|
+
className: `${ROW} ${tone}`,
|
|
1119
|
+
onClick: onSelect,
|
|
1120
|
+
children: [
|
|
1121
|
+
icon && /* @__PURE__ */ jsx20("span", { className: "shrink-0", "aria-hidden": "true", children: icon }),
|
|
1122
|
+
/* @__PURE__ */ jsx20("span", { className: "min-w-0 flex-1 truncate", children }),
|
|
1123
|
+
trailing && /* @__PURE__ */ jsx20("span", { className: "shrink-0", children: trailing })
|
|
1124
|
+
]
|
|
1125
|
+
}
|
|
1126
|
+
) });
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// popover.tsx
|
|
1130
|
+
import {
|
|
1131
|
+
useId as useId3,
|
|
1132
|
+
useLayoutEffect,
|
|
1133
|
+
useMemo,
|
|
1134
|
+
useRef as useRef4,
|
|
1135
|
+
useState as useState3
|
|
1136
|
+
} from "react";
|
|
1137
|
+
import { createPortal } from "react-dom";
|
|
1138
|
+
|
|
1139
|
+
// use-dismiss.ts
|
|
1140
|
+
import { useEffect as useEffect4 } from "react";
|
|
1141
|
+
function useDismiss(open, ref, onDismiss, options = {}) {
|
|
1142
|
+
const { closeOnEsc = true, closeOnOutside = true, ignore } = options;
|
|
1143
|
+
useEffect4(() => {
|
|
1144
|
+
if (!open) return void 0;
|
|
1145
|
+
const refs = Array.isArray(ref) ? ref : [ref];
|
|
1146
|
+
const win = refs.map((r) => r.current?.ownerDocument?.defaultView).find(Boolean) ?? window;
|
|
1147
|
+
const onDown = (e) => {
|
|
1148
|
+
if (!closeOnOutside) return;
|
|
1149
|
+
const target = e.target;
|
|
1150
|
+
if (ignore?.(target)) return;
|
|
1151
|
+
if (refs.some((r) => r.current?.contains(target))) return;
|
|
1152
|
+
onDismiss();
|
|
1153
|
+
};
|
|
1154
|
+
const onKey = (e) => {
|
|
1155
|
+
if (closeOnEsc && e.key === "Escape") onDismiss();
|
|
1156
|
+
};
|
|
1157
|
+
win.addEventListener("mousedown", onDown);
|
|
1158
|
+
win.addEventListener("keydown", onKey);
|
|
1159
|
+
return () => {
|
|
1160
|
+
win.removeEventListener("mousedown", onDown);
|
|
1161
|
+
win.removeEventListener("keydown", onKey);
|
|
1162
|
+
};
|
|
1163
|
+
}, [open, ref, onDismiss, closeOnEsc, closeOnOutside, ignore]);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
// popover.tsx
|
|
1167
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1168
|
+
var PLACEMENT = {
|
|
1169
|
+
"bottom-start": "top-[calc(100%+8px)] left-0",
|
|
1170
|
+
"bottom-end": "top-[calc(100%+8px)] right-0",
|
|
1171
|
+
"top-start": "bottom-[calc(100%+8px)] left-0",
|
|
1172
|
+
"top-end": "bottom-[calc(100%+8px)] right-0"
|
|
1173
|
+
};
|
|
1174
|
+
var PANEL_BASE = "min-w-[220px] max-w-[calc(100vw-24px)] bg-surface border border-solid border-border-strong rounded-card animate-[card-in_var(--dur-base)_var(--ease-spring)_both]";
|
|
1175
|
+
var PORTAL_OFFSET_PX = 8;
|
|
1176
|
+
var PORTAL_GUTTER_PX = 12;
|
|
1177
|
+
var FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])';
|
|
1178
|
+
function getScrollClipAncestor(el) {
|
|
1179
|
+
let node = el?.parentElement ?? null;
|
|
1180
|
+
while (node && node !== document.body && node !== document.documentElement) {
|
|
1181
|
+
const style = getComputedStyle(node);
|
|
1182
|
+
if (style.position === "fixed") return null;
|
|
1183
|
+
if (style.overflowY !== "visible" || style.overflowX !== "visible") return node;
|
|
1184
|
+
node = node.parentElement;
|
|
1185
|
+
}
|
|
1186
|
+
return null;
|
|
1187
|
+
}
|
|
1188
|
+
function Popover({
|
|
1189
|
+
open,
|
|
1190
|
+
onClose,
|
|
1191
|
+
trigger,
|
|
1192
|
+
children,
|
|
1193
|
+
placement = "bottom-start",
|
|
1194
|
+
ariaLabel,
|
|
1195
|
+
role = "menu",
|
|
1196
|
+
panelClassName = "",
|
|
1197
|
+
panelShadow = "shadow-popover",
|
|
1198
|
+
panelPadding = true,
|
|
1199
|
+
panelScroll = true,
|
|
1200
|
+
mobileSheet = false,
|
|
1201
|
+
portal = false,
|
|
1202
|
+
closeOnEsc = true,
|
|
1203
|
+
closeOnOutside = true
|
|
1204
|
+
}) {
|
|
1205
|
+
const ref = useRef4(null);
|
|
1206
|
+
const panelRef = useRef4(null);
|
|
1207
|
+
const panelId = useId3();
|
|
1208
|
+
const effectivePortal = portal && !mobileSheet;
|
|
1209
|
+
const dismissRefs = useMemo(() => effectivePortal ? [ref, panelRef] : ref, [effectivePortal]);
|
|
1210
|
+
useDismiss(open, dismissRefs, onClose, { closeOnEsc, closeOnOutside });
|
|
1211
|
+
const [sheetTop, setSheetTop] = useState3(0);
|
|
1212
|
+
useLayoutEffect(() => {
|
|
1213
|
+
if (!open || !mobileSheet) return void 0;
|
|
1214
|
+
const measure = () => {
|
|
1215
|
+
const el = ref.current;
|
|
1216
|
+
if (el) setSheetTop(el.getBoundingClientRect().bottom + 8);
|
|
1217
|
+
};
|
|
1218
|
+
measure();
|
|
1219
|
+
window.addEventListener("resize", measure);
|
|
1220
|
+
return () => window.removeEventListener("resize", measure);
|
|
1221
|
+
}, [open, mobileSheet]);
|
|
1222
|
+
const [portalPos, setPortalPos] = useState3(null);
|
|
1223
|
+
const [triggerClipped, setTriggerClipped] = useState3(false);
|
|
1224
|
+
useLayoutEffect(() => {
|
|
1225
|
+
if (!open || !effectivePortal) {
|
|
1226
|
+
setPortalPos(null);
|
|
1227
|
+
setTriggerClipped(false);
|
|
1228
|
+
return void 0;
|
|
1229
|
+
}
|
|
1230
|
+
const clipAncestor = getScrollClipAncestor(ref.current);
|
|
1231
|
+
const compute = () => {
|
|
1232
|
+
const triggerEl = ref.current;
|
|
1233
|
+
const panelEl2 = panelRef.current;
|
|
1234
|
+
if (!triggerEl || !panelEl2) return;
|
|
1235
|
+
const triggerRect = triggerEl.getBoundingClientRect();
|
|
1236
|
+
const panelWidth = panelEl2.offsetWidth;
|
|
1237
|
+
const panelHeight = panelEl2.offsetHeight;
|
|
1238
|
+
const vw = window.innerWidth;
|
|
1239
|
+
const vh = window.innerHeight;
|
|
1240
|
+
const clipRect = clipAncestor ? clipAncestor.getBoundingClientRect() : { top: 0, left: 0, right: vw, bottom: vh };
|
|
1241
|
+
const clipped = triggerRect.bottom <= clipRect.top || triggerRect.top >= clipRect.bottom || triggerRect.right <= clipRect.left || triggerRect.left >= clipRect.right;
|
|
1242
|
+
setTriggerClipped((prev) => prev === clipped ? prev : clipped);
|
|
1243
|
+
let top = placement.startsWith("bottom") ? triggerRect.bottom + PORTAL_OFFSET_PX : triggerRect.top - PORTAL_OFFSET_PX - panelHeight;
|
|
1244
|
+
let left = placement.endsWith("end") ? triggerRect.right - panelWidth : triggerRect.left;
|
|
1245
|
+
const maxLeft = Math.max(PORTAL_GUTTER_PX, vw - panelWidth - PORTAL_GUTTER_PX);
|
|
1246
|
+
const maxTop = Math.max(PORTAL_GUTTER_PX, vh - panelHeight - PORTAL_GUTTER_PX);
|
|
1247
|
+
left = Math.min(Math.max(left, PORTAL_GUTTER_PX), maxLeft);
|
|
1248
|
+
top = Math.min(Math.max(top, PORTAL_GUTTER_PX), maxTop);
|
|
1249
|
+
setPortalPos((p) => p && p.top === top && p.left === left ? p : { top, left });
|
|
1250
|
+
};
|
|
1251
|
+
compute();
|
|
1252
|
+
let raf = 0;
|
|
1253
|
+
const schedule = () => {
|
|
1254
|
+
if (raf) return;
|
|
1255
|
+
raf = requestAnimationFrame(() => {
|
|
1256
|
+
raf = 0;
|
|
1257
|
+
compute();
|
|
1258
|
+
});
|
|
1259
|
+
};
|
|
1260
|
+
window.addEventListener("resize", schedule);
|
|
1261
|
+
window.addEventListener("scroll", schedule, true);
|
|
1262
|
+
const panelEl = panelRef.current;
|
|
1263
|
+
let ro;
|
|
1264
|
+
if (panelEl) {
|
|
1265
|
+
ro = new ResizeObserver(compute);
|
|
1266
|
+
ro.observe(panelEl);
|
|
1267
|
+
}
|
|
1268
|
+
return () => {
|
|
1269
|
+
window.removeEventListener("resize", schedule);
|
|
1270
|
+
window.removeEventListener("scroll", schedule, true);
|
|
1271
|
+
ro?.disconnect();
|
|
1272
|
+
if (raf) cancelAnimationFrame(raf);
|
|
1273
|
+
};
|
|
1274
|
+
}, [open, effectivePortal, placement]);
|
|
1275
|
+
const previousFocusRef = useRef4(null);
|
|
1276
|
+
const focusMovedRef = useRef4(false);
|
|
1277
|
+
useLayoutEffect(() => {
|
|
1278
|
+
if (!open || !effectivePortal) return void 0;
|
|
1279
|
+
previousFocusRef.current = document.activeElement;
|
|
1280
|
+
focusMovedRef.current = false;
|
|
1281
|
+
return () => {
|
|
1282
|
+
const prev = previousFocusRef.current;
|
|
1283
|
+
if (focusMovedRef.current && document.activeElement === document.body && prev?.isConnected) {
|
|
1284
|
+
prev.focus({ preventScroll: true });
|
|
1285
|
+
}
|
|
1286
|
+
previousFocusRef.current = null;
|
|
1287
|
+
};
|
|
1288
|
+
}, [open, effectivePortal]);
|
|
1289
|
+
useLayoutEffect(() => {
|
|
1290
|
+
if (!open || !effectivePortal || !portalPos || triggerClipped || focusMovedRef.current)
|
|
1291
|
+
return void 0;
|
|
1292
|
+
const panelEl = panelRef.current;
|
|
1293
|
+
if (!panelEl) return void 0;
|
|
1294
|
+
const focusable = panelEl.querySelector(FOCUSABLE_SELECTOR);
|
|
1295
|
+
(focusable ?? panelEl).focus({ preventScroll: true });
|
|
1296
|
+
focusMovedRef.current = panelEl.contains(document.activeElement);
|
|
1297
|
+
return void 0;
|
|
1298
|
+
}, [open, effectivePortal, portalPos, triggerClipped]);
|
|
1299
|
+
const handlePanelKeyDown = (e) => {
|
|
1300
|
+
if (e.key !== "Tab") return;
|
|
1301
|
+
const panelEl = panelRef.current;
|
|
1302
|
+
if (!panelEl) return;
|
|
1303
|
+
const focusables = panelEl.querySelectorAll(FOCUSABLE_SELECTOR);
|
|
1304
|
+
if (focusables.length === 0) {
|
|
1305
|
+
e.preventDefault();
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
const first = focusables[0];
|
|
1309
|
+
const last = focusables[focusables.length - 1];
|
|
1310
|
+
const active = document.activeElement;
|
|
1311
|
+
if (e.shiftKey) {
|
|
1312
|
+
if (active === first || !panelEl.contains(active)) {
|
|
1313
|
+
e.preventDefault();
|
|
1314
|
+
last.focus({ preventScroll: true });
|
|
1315
|
+
}
|
|
1316
|
+
} else if (active === last || !panelEl.contains(active)) {
|
|
1317
|
+
e.preventDefault();
|
|
1318
|
+
first.focus({ preventScroll: true });
|
|
1319
|
+
}
|
|
1320
|
+
};
|
|
1321
|
+
const smAnchor = PLACEMENT[placement].split(" ").map((c) => `sm:${c}`).join(" ");
|
|
1322
|
+
const positioning = mobileSheet ? `fixed top-(--popover-sheet-top) left-3 right-3 w-auto sm:absolute sm:left-auto ${smAnchor}` : effectivePortal ? "fixed" : `absolute ${PLACEMENT[placement]}`;
|
|
1323
|
+
const zIndexClass = effectivePortal ? "z-[var(--z-popover-portal,35)]" : "z-(--z-dropdown)";
|
|
1324
|
+
const panelStyle = mobileSheet ? { "--popover-sheet-top": `${sheetTop}px` } : effectivePortal ? portalPos ? triggerClipped ? {
|
|
1325
|
+
top: portalPos.top,
|
|
1326
|
+
left: portalPos.left,
|
|
1327
|
+
visibility: "hidden",
|
|
1328
|
+
pointerEvents: "none"
|
|
1329
|
+
} : { top: portalPos.top, left: portalPos.left } : { top: -9999, left: -9999, visibility: "hidden", pointerEvents: "none" } : void 0;
|
|
1330
|
+
const panel = open && /* @__PURE__ */ jsx21(
|
|
1331
|
+
"div",
|
|
1332
|
+
{
|
|
1333
|
+
ref: panelRef,
|
|
1334
|
+
id: effectivePortal ? panelId : void 0,
|
|
1335
|
+
tabIndex: effectivePortal ? -1 : void 0,
|
|
1336
|
+
role,
|
|
1337
|
+
"aria-label": ariaLabel,
|
|
1338
|
+
onKeyDown: effectivePortal ? handlePanelKeyDown : void 0,
|
|
1339
|
+
className: `${PANEL_BASE} ${zIndexClass} ${panelScroll ? "max-h-80 overflow-y-auto" : ""} ${panelPadding ? "p-3" : ""} ${positioning} ${panelShadow} ${panelClassName}`.trim(),
|
|
1340
|
+
style: panelStyle,
|
|
1341
|
+
children
|
|
1342
|
+
}
|
|
1343
|
+
);
|
|
1344
|
+
return /* @__PURE__ */ jsxs16(
|
|
1345
|
+
"div",
|
|
1346
|
+
{
|
|
1347
|
+
className: "relative inline-flex",
|
|
1348
|
+
ref,
|
|
1349
|
+
"aria-owns": effectivePortal && open ? panelId : void 0,
|
|
1350
|
+
children: [
|
|
1351
|
+
trigger,
|
|
1352
|
+
effectivePortal ? panel ? createPortal(panel, document.body) : null : panel
|
|
1353
|
+
]
|
|
1354
|
+
}
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
// profile-modal.tsx
|
|
1359
|
+
import { createContext, useContext } from "react";
|
|
1360
|
+
var noopOpenProfile = () => {
|
|
1361
|
+
};
|
|
1362
|
+
var ProfileModalContext = createContext(noopOpenProfile);
|
|
1363
|
+
function useOpenProfile() {
|
|
1364
|
+
return useContext(ProfileModalContext);
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
// radio.tsx
|
|
1368
|
+
import { useId as useId4 } from "react";
|
|
1369
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1370
|
+
function Radio({ checked, label, id, className = "", ...rest }) {
|
|
1371
|
+
const autoId = useId4();
|
|
1372
|
+
const inputId = id ?? autoId;
|
|
1373
|
+
return /* @__PURE__ */ jsxs17(
|
|
1374
|
+
"label",
|
|
1375
|
+
{
|
|
1376
|
+
htmlFor: inputId,
|
|
1377
|
+
className: `inline-flex cursor-pointer select-none items-center gap-3 ${className}`.trim(),
|
|
1378
|
+
children: [
|
|
1379
|
+
/* @__PURE__ */ jsx22("input", { id: inputId, type: "radio", checked, className: "peer sr-only", ...rest }),
|
|
1380
|
+
/* @__PURE__ */ jsx22(
|
|
1381
|
+
"span",
|
|
1382
|
+
{
|
|
1383
|
+
className: `grid h-[22px] w-[22px] place-items-center rounded-pill border-2 border-solid transition-colors peer-focus-visible:shadow-focus ${checked ? "border-text" : "border-border-strong"}`,
|
|
1384
|
+
children: /* @__PURE__ */ jsx22(
|
|
1385
|
+
"span",
|
|
1386
|
+
{
|
|
1387
|
+
className: `h-2.5 w-2.5 rounded-pill bg-accent transition-transform duration-(--dur-fast) ${checked ? "scale-100" : "scale-0"}`
|
|
1388
|
+
}
|
|
1389
|
+
)
|
|
1390
|
+
}
|
|
1391
|
+
),
|
|
1392
|
+
label != null && /* @__PURE__ */ jsx22("span", { className: "text-md text-text", children: label })
|
|
1393
|
+
]
|
|
1394
|
+
}
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
// ring-timer.tsx
|
|
1399
|
+
import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1400
|
+
function RingTimer({
|
|
1401
|
+
secondsLeft,
|
|
1402
|
+
totalSeconds,
|
|
1403
|
+
size = 118,
|
|
1404
|
+
urgentThreshold = 10,
|
|
1405
|
+
caption,
|
|
1406
|
+
className = ""
|
|
1407
|
+
}) {
|
|
1408
|
+
const urgent = secondsLeft <= urgentThreshold;
|
|
1409
|
+
const pct = totalSeconds > 0 ? Math.min(100, Math.max(0, secondsLeft / totalSeconds * 100)) : 0;
|
|
1410
|
+
const ringColor = urgent ? "var(--color-accent)" : "var(--color-mint)";
|
|
1411
|
+
const maskStyle = {
|
|
1412
|
+
background: `conic-gradient(${ringColor} ${pct}%, var(--color-border) 0)`,
|
|
1413
|
+
WebkitMask: "radial-gradient(closest-side, transparent 72%, #000 73%)",
|
|
1414
|
+
mask: "radial-gradient(closest-side, transparent 72%, #000 73%)"
|
|
1415
|
+
};
|
|
1416
|
+
const wrapperClass = [
|
|
1417
|
+
"relative inline-flex shrink-0 items-center justify-center rounded-pill",
|
|
1418
|
+
urgent ? "animate-[ring-timer-urgent-pulse_1s_ease-in-out_infinite]" : "",
|
|
1419
|
+
className
|
|
1420
|
+
].filter(Boolean).join(" ");
|
|
1421
|
+
return /* @__PURE__ */ jsxs18("div", { className: wrapperClass, style: { width: size, height: size }, children: [
|
|
1422
|
+
/* @__PURE__ */ jsx23("div", { className: "absolute inset-0 rounded-pill", style: maskStyle, "aria-hidden": "true" }),
|
|
1423
|
+
/* @__PURE__ */ jsxs18("div", { className: "relative flex flex-col items-center justify-center", children: [
|
|
1424
|
+
/* @__PURE__ */ jsx23(
|
|
1425
|
+
"span",
|
|
1426
|
+
{
|
|
1427
|
+
className: `font-bold leading-none tabular-nums ${urgent ? "text-accent" : "text-text"}`,
|
|
1428
|
+
style: { fontSize: Math.round(size * 0.28) },
|
|
1429
|
+
children: Math.max(0, Math.round(secondsLeft))
|
|
1430
|
+
}
|
|
1431
|
+
),
|
|
1432
|
+
caption && /* @__PURE__ */ jsx23("span", { className: "mt-1 text-2xs text-text-dim", children: caption })
|
|
1433
|
+
] })
|
|
1434
|
+
] });
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
// search-field.tsx
|
|
1438
|
+
import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1439
|
+
var FIELD2 = "flex items-center gap-2 bg-surface-2 border-[1.5px] border-solid border-border rounded-md px-3.5 py-2.5 transition-[border-color,box-shadow] duration-(--dur-fast) focus-within:border-info focus-within:shadow-focus";
|
|
1440
|
+
var CONTROL2 = "flex-1 min-w-0 border-none outline-none bg-transparent text-md text-text placeholder:text-text-faint";
|
|
1441
|
+
function SearchField({ className = "", ...rest }) {
|
|
1442
|
+
return /* @__PURE__ */ jsxs19("div", { className: `${FIELD2} ${className}`.trim(), children: [
|
|
1443
|
+
/* @__PURE__ */ jsx24(Icon, { name: "search", size: 16, className: "shrink-0 text-text-faint" }),
|
|
1444
|
+
/* @__PURE__ */ jsx24("input", { className: CONTROL2, ...rest })
|
|
1445
|
+
] });
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
// split-modal.tsx
|
|
1449
|
+
import { useEffect as useEffect5, useState as useState4 } from "react";
|
|
1450
|
+
import { Fragment, jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1451
|
+
var NARROW_MAX_WIDTH = 768;
|
|
1452
|
+
function useNarrowViewport(maxWidth) {
|
|
1453
|
+
const [narrow, setNarrow] = useState4(false);
|
|
1454
|
+
useEffect5(() => {
|
|
1455
|
+
if (typeof window === "undefined") return void 0;
|
|
1456
|
+
const sync = () => setNarrow(window.innerWidth <= maxWidth);
|
|
1457
|
+
sync();
|
|
1458
|
+
const mq = window.matchMedia?.(`(max-width: ${maxWidth}px)`);
|
|
1459
|
+
mq?.addEventListener("change", sync);
|
|
1460
|
+
window.addEventListener("resize", sync);
|
|
1461
|
+
const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(sync) : null;
|
|
1462
|
+
ro?.observe(document.documentElement);
|
|
1463
|
+
return () => {
|
|
1464
|
+
mq?.removeEventListener("change", sync);
|
|
1465
|
+
window.removeEventListener("resize", sync);
|
|
1466
|
+
ro?.disconnect();
|
|
1467
|
+
};
|
|
1468
|
+
}, [maxWidth]);
|
|
1469
|
+
return narrow;
|
|
1470
|
+
}
|
|
1471
|
+
function SplitModal({
|
|
1472
|
+
items,
|
|
1473
|
+
value,
|
|
1474
|
+
onSelect,
|
|
1475
|
+
children,
|
|
1476
|
+
onClose,
|
|
1477
|
+
navLabel,
|
|
1478
|
+
navTitle,
|
|
1479
|
+
navFooter,
|
|
1480
|
+
title,
|
|
1481
|
+
description,
|
|
1482
|
+
footer,
|
|
1483
|
+
ariaLabel,
|
|
1484
|
+
closeLabel,
|
|
1485
|
+
backLabel,
|
|
1486
|
+
asSheet = false,
|
|
1487
|
+
width = "min(760px, 94vw)",
|
|
1488
|
+
navWidth = 214,
|
|
1489
|
+
className = "",
|
|
1490
|
+
narrow
|
|
1491
|
+
}) {
|
|
1492
|
+
const autoNarrow = useNarrowViewport(NARROW_MAX_WIDTH);
|
|
1493
|
+
const isNarrow = narrow ?? autoNarrow;
|
|
1494
|
+
const [drilled, setDrilled] = useState4(false);
|
|
1495
|
+
useEffect5(() => {
|
|
1496
|
+
if (!isNarrow) setDrilled(false);
|
|
1497
|
+
}, [isNarrow]);
|
|
1498
|
+
const current = items.find((it) => it.id === value);
|
|
1499
|
+
const closeButton = closeLabel ? /* @__PURE__ */ jsx25(
|
|
1500
|
+
"button",
|
|
1501
|
+
{
|
|
1502
|
+
type: "button",
|
|
1503
|
+
"aria-label": closeLabel,
|
|
1504
|
+
title: closeLabel,
|
|
1505
|
+
onClick: onClose,
|
|
1506
|
+
className: "inline-flex h-[30px] w-[30px] shrink-0 items-center justify-center rounded-chip border-none bg-transparent p-0 text-text-dim cursor-pointer [&>svg]:shrink-0 enabled:hover:bg-surface-hover enabled:hover:text-text",
|
|
1507
|
+
children: /* @__PURE__ */ jsx25(Icon, { name: "close", size: 19 })
|
|
1508
|
+
}
|
|
1509
|
+
) : null;
|
|
1510
|
+
const paneHead = title || closeButton ? /* @__PURE__ */ jsxs20("div", { className: "flex shrink-0 items-start justify-between gap-3", children: [
|
|
1511
|
+
title ? /* @__PURE__ */ jsxs20("div", { className: "min-w-0", children: [
|
|
1512
|
+
/* @__PURE__ */ jsx25("h4", { className: "m-0 text-lg font-extrabold text-text", children: title }),
|
|
1513
|
+
description && // max-w-[52ch] は意図的な据え置き(#950)。可読な行長(1行あたり文字数)を確保する
|
|
1514
|
+
// ための「文字数」基準の制約で、px/rem のスケールトークンに載せる性質の値ではない
|
|
1515
|
+
// (52ch は一般的な可読上限の目安。テキストコンテンツ量に応じた相対値なので
|
|
1516
|
+
// トークン化しても再利用の意味が薄い)。
|
|
1517
|
+
/* @__PURE__ */ jsx25("p", { className: "mt-1.5 mb-0 max-w-[52ch] text-[13px] leading-relaxed text-text-dim", children: description })
|
|
1518
|
+
] }) : /* @__PURE__ */ jsx25("span", {}),
|
|
1519
|
+
closeButton
|
|
1520
|
+
] }) : null;
|
|
1521
|
+
const list = /* @__PURE__ */ jsxs20("div", { className: "flex flex-1 min-h-0 flex-col", children: [
|
|
1522
|
+
(navTitle || closeButton) && /* @__PURE__ */ jsxs20("div", { className: "flex shrink-0 items-center gap-2.5 border-b border-solid border-border bg-bg-elevated px-3.5 py-3", children: [
|
|
1523
|
+
/* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1 text-sm font-extrabold text-text", children: navTitle }),
|
|
1524
|
+
closeButton
|
|
1525
|
+
] }),
|
|
1526
|
+
/* @__PURE__ */ jsx25("nav", { className: "flex flex-1 min-h-0 flex-col overflow-y-auto", "aria-label": navLabel, children: items.map((it) => /* @__PURE__ */ jsxs20(
|
|
1527
|
+
"button",
|
|
1528
|
+
{
|
|
1529
|
+
type: "button",
|
|
1530
|
+
className: "flex w-full cursor-pointer items-center gap-3 border-none border-b border-solid border-border bg-transparent px-4 py-3.5 text-left text-base font-semibold text-text",
|
|
1531
|
+
onClick: () => {
|
|
1532
|
+
onSelect(it.id);
|
|
1533
|
+
setDrilled(true);
|
|
1534
|
+
},
|
|
1535
|
+
children: [
|
|
1536
|
+
it.icon && /* @__PURE__ */ jsx25("span", { className: "shrink-0 text-accent", "aria-hidden": "true", children: /* @__PURE__ */ jsx25(Icon, { name: it.icon, size: 20 }) }),
|
|
1537
|
+
/* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1", children: it.label }),
|
|
1538
|
+
/* @__PURE__ */ jsx25("span", { className: "shrink-0 text-lg text-text-faint", "aria-hidden": "true", children: "\u203A" })
|
|
1539
|
+
]
|
|
1540
|
+
},
|
|
1541
|
+
it.id
|
|
1542
|
+
)) })
|
|
1543
|
+
] });
|
|
1544
|
+
const detail = /* @__PURE__ */ jsxs20("div", { className: "flex flex-1 min-h-0 flex-col", children: [
|
|
1545
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex shrink-0 items-center gap-2 border-b border-solid border-border bg-bg-elevated px-3.5 py-3", children: [
|
|
1546
|
+
/* @__PURE__ */ jsx25(
|
|
1547
|
+
"button",
|
|
1548
|
+
{
|
|
1549
|
+
type: "button",
|
|
1550
|
+
"aria-label": backLabel,
|
|
1551
|
+
title: backLabel,
|
|
1552
|
+
onClick: () => setDrilled(false),
|
|
1553
|
+
className: "-ml-1.5 inline-flex h-8 w-8 shrink-0 cursor-pointer items-center justify-center rounded-chip border-none bg-transparent p-0 text-text-dim [&>svg]:shrink-0 enabled:hover:bg-surface-hover enabled:hover:text-text",
|
|
1554
|
+
children: /* @__PURE__ */ jsx25(Icon, { name: "chevron_left", size: 20 })
|
|
1555
|
+
}
|
|
1556
|
+
),
|
|
1557
|
+
/* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1 text-sm font-extrabold text-text", children: current?.label }),
|
|
1558
|
+
closeButton
|
|
1559
|
+
] }),
|
|
1560
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex flex-1 min-w-0 min-h-0 flex-col gap-[18px] overflow-y-auto px-4 pt-4 pb-1", children: [
|
|
1561
|
+
description && /* @__PURE__ */ jsx25("p", { className: "m-0 text-[13px] leading-relaxed text-text-dim", children: description }),
|
|
1562
|
+
children
|
|
1563
|
+
] }),
|
|
1564
|
+
footer && /* @__PURE__ */ jsx25("div", { className: "flex shrink-0 justify-end gap-2.5 border-t border-solid border-border bg-bg-elevated px-4 py-3", children: footer })
|
|
1565
|
+
] });
|
|
1566
|
+
const wide = /* @__PURE__ */ jsxs20(Fragment, { children: [
|
|
1567
|
+
/* @__PURE__ */ jsxs20(
|
|
1568
|
+
"aside",
|
|
1569
|
+
{
|
|
1570
|
+
className: "flex shrink-0 flex-col gap-5 self-stretch border-r border-solid border-border bg-bg-elevated px-4 py-[22px]",
|
|
1571
|
+
style: { width: navWidth },
|
|
1572
|
+
children: [
|
|
1573
|
+
navTitle && /* @__PURE__ */ jsx25("h3", { className: "m-0 px-1 text-[15px] font-extrabold text-text", children: navTitle }),
|
|
1574
|
+
/* @__PURE__ */ jsx25("nav", { className: "flex flex-col gap-1", "aria-label": navLabel, children: items.map((it) => {
|
|
1575
|
+
const active = it.id === value;
|
|
1576
|
+
return /* @__PURE__ */ jsxs20(
|
|
1577
|
+
"button",
|
|
1578
|
+
{
|
|
1579
|
+
type: "button",
|
|
1580
|
+
"aria-selected": active,
|
|
1581
|
+
className: `flex w-full cursor-pointer items-center gap-2.5 rounded-md border border-solid px-3 py-2.5 text-left text-[13.5px] transition-colors ${active ? "border-border bg-surface-3 font-bold text-text" : "border-transparent bg-transparent font-semibold text-text-dim hover:bg-surface-hover hover:text-text"}`,
|
|
1582
|
+
onClick: () => onSelect(it.id),
|
|
1583
|
+
children: [
|
|
1584
|
+
it.icon && /* @__PURE__ */ jsx25(
|
|
1585
|
+
"span",
|
|
1586
|
+
{
|
|
1587
|
+
className: `shrink-0 ${active ? "text-accent" : "text-text-faint"}`,
|
|
1588
|
+
"aria-hidden": "true",
|
|
1589
|
+
children: /* @__PURE__ */ jsx25(Icon, { name: it.icon, size: 17 })
|
|
1590
|
+
}
|
|
1591
|
+
),
|
|
1592
|
+
/* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1", children: it.label })
|
|
1593
|
+
]
|
|
1594
|
+
},
|
|
1595
|
+
it.id
|
|
1596
|
+
);
|
|
1597
|
+
}) }),
|
|
1598
|
+
navFooter && /* @__PURE__ */ jsx25("div", { className: "mt-auto px-1 text-xs leading-relaxed text-text-faint", children: navFooter })
|
|
1599
|
+
]
|
|
1600
|
+
}
|
|
1601
|
+
),
|
|
1602
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
1603
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex flex-1 min-w-0 min-h-0 flex-col gap-[18px] overflow-y-auto px-[26px] py-6", children: [
|
|
1604
|
+
paneHead,
|
|
1605
|
+
children
|
|
1606
|
+
] }),
|
|
1607
|
+
footer && /* @__PURE__ */ jsx25("div", { className: "flex shrink-0 justify-end gap-2.5 border-t border-solid border-border bg-bg-elevated px-[26px] py-3.5", children: footer })
|
|
1608
|
+
] })
|
|
1609
|
+
] });
|
|
1610
|
+
const innerClass = isNarrow ? "flex flex-col flex-1 min-h-0" : asSheet ? "flex flex-1 min-h-0" : "flex flex-[1_1_auto] min-h-0 max-h-[min(520px,72dvh)] h-[min(520px,72dvh)]";
|
|
1611
|
+
const inner = /* @__PURE__ */ jsx25("div", { className: innerClass, children: isNarrow ? drilled ? detail : list : wide });
|
|
1612
|
+
if (asSheet) {
|
|
1613
|
+
return /* @__PURE__ */ jsx25(BottomSheet, { open: true, onClose, ariaLabel, closeLabel, children: /* @__PURE__ */ jsx25("div", { className: "flex flex-1 min-h-0 flex-col", children: inner }) });
|
|
1614
|
+
}
|
|
1615
|
+
return /* @__PURE__ */ jsx25(
|
|
1616
|
+
Modal,
|
|
1617
|
+
{
|
|
1618
|
+
onClose,
|
|
1619
|
+
width,
|
|
1620
|
+
className: `gap-0 overflow-hidden p-0 text-left max-h-[calc(100dvh-40px)] ${className}`.trim(),
|
|
1621
|
+
ariaLabel,
|
|
1622
|
+
children: inner
|
|
1623
|
+
}
|
|
1624
|
+
);
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
// status.tsx
|
|
1628
|
+
import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1629
|
+
var DOT_TONE = {
|
|
1630
|
+
success: "bg-success",
|
|
1631
|
+
warning: "bg-warning",
|
|
1632
|
+
danger: "bg-danger",
|
|
1633
|
+
info: "bg-info",
|
|
1634
|
+
neutral: "bg-text-faint"
|
|
1635
|
+
};
|
|
1636
|
+
function StatusDot({
|
|
1637
|
+
tone = "neutral",
|
|
1638
|
+
size = 8,
|
|
1639
|
+
pulse = false,
|
|
1640
|
+
label,
|
|
1641
|
+
className = ""
|
|
1642
|
+
}) {
|
|
1643
|
+
return /* @__PURE__ */ jsx26(
|
|
1644
|
+
"span",
|
|
1645
|
+
{
|
|
1646
|
+
role: label ? "status" : void 0,
|
|
1647
|
+
"aria-label": label,
|
|
1648
|
+
"aria-hidden": label ? void 0 : true,
|
|
1649
|
+
style: { width: size, height: size },
|
|
1650
|
+
className: `inline-block shrink-0 rounded-pill ${DOT_TONE[tone]}${pulse ? " animate-pulse" : ""} ${className}`.trim()
|
|
1651
|
+
}
|
|
1652
|
+
);
|
|
1653
|
+
}
|
|
1654
|
+
var BADGE_TONE = {
|
|
1655
|
+
success: "bg-success-surface text-success border-success-border",
|
|
1656
|
+
warning: "bg-warning-surface text-warning border-warning-border",
|
|
1657
|
+
danger: "bg-danger-surface text-danger border-danger-border",
|
|
1658
|
+
info: "bg-info-surface text-info border-info-border",
|
|
1659
|
+
neutral: "bg-tint-8 text-text-dim border-border"
|
|
1660
|
+
};
|
|
1661
|
+
function StatusBadge({
|
|
1662
|
+
tone = "neutral",
|
|
1663
|
+
children,
|
|
1664
|
+
dot = false,
|
|
1665
|
+
pulse = false,
|
|
1666
|
+
className = ""
|
|
1667
|
+
}) {
|
|
1668
|
+
return /* @__PURE__ */ jsxs21(
|
|
1669
|
+
"span",
|
|
1670
|
+
{
|
|
1671
|
+
className: `inline-flex shrink-0 items-center gap-1.5 rounded-pill border border-solid px-2 py-0.5 text-2xs font-extrabold uppercase tracking-tag ${BADGE_TONE[tone]} ${className}`.trim(),
|
|
1672
|
+
children: [
|
|
1673
|
+
dot && /* @__PURE__ */ jsx26(StatusDot, { tone, size: 6, pulse }),
|
|
1674
|
+
children
|
|
1675
|
+
]
|
|
1676
|
+
}
|
|
1677
|
+
);
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
// step-flow.tsx
|
|
1681
|
+
import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1682
|
+
var PILL_TONE = {
|
|
1683
|
+
done: "bg-success-surface text-success border-success-border",
|
|
1684
|
+
current: "bg-accent text-on-accent border-transparent",
|
|
1685
|
+
todo: "bg-surface text-text-dim border-transparent"
|
|
1686
|
+
};
|
|
1687
|
+
function stepTone(index, currentIndex) {
|
|
1688
|
+
if (index < currentIndex) return "done";
|
|
1689
|
+
if (index === currentIndex) return "current";
|
|
1690
|
+
return "todo";
|
|
1691
|
+
}
|
|
1692
|
+
function StepFlow({
|
|
1693
|
+
steps,
|
|
1694
|
+
currentIndex,
|
|
1695
|
+
direction = "row",
|
|
1696
|
+
className = ""
|
|
1697
|
+
}) {
|
|
1698
|
+
const isRow = direction === "row";
|
|
1699
|
+
return /* @__PURE__ */ jsx27(
|
|
1700
|
+
"div",
|
|
1701
|
+
{
|
|
1702
|
+
className: `flex ${isRow ? "flex-row flex-wrap items-center gap-1.5" : "flex-col items-stretch gap-1.5"} ${className}`.trim(),
|
|
1703
|
+
children: steps.map((step, index) => {
|
|
1704
|
+
const tone = stepTone(index, currentIndex);
|
|
1705
|
+
const showSeparator = isRow && index < steps.length - 1;
|
|
1706
|
+
return /* @__PURE__ */ jsxs22("div", { className: isRow ? "inline-flex items-center gap-1.5" : "contents", children: [
|
|
1707
|
+
/* @__PURE__ */ jsx27(
|
|
1708
|
+
"span",
|
|
1709
|
+
{
|
|
1710
|
+
className: `inline-flex items-center justify-center border border-solid px-2.5 py-1 text-smd font-bold ${isRow ? "rounded-pill" : "rounded-md"} ${PILL_TONE[tone]}`,
|
|
1711
|
+
children: step.label
|
|
1712
|
+
}
|
|
1713
|
+
),
|
|
1714
|
+
showSeparator && /* @__PURE__ */ jsx27("span", { className: "text-xs text-text-dim", "aria-hidden": "true", children: "\u25B8" })
|
|
1715
|
+
] }, step.key);
|
|
1716
|
+
})
|
|
1717
|
+
}
|
|
1718
|
+
);
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
// stepper.tsx
|
|
1722
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1723
|
+
var BTN = "w-[30px] h-[30px] pointer-coarse:w-10 pointer-coarse:h-10 p-0 inline-flex items-center justify-center text-lg leading-none rounded-full bg-tint-7 border border-solid border-border text-text-dim transition-[background,box-shadow] enabled:hover:bg-tint-13 enabled:hover:shadow-glow disabled:opacity-(--disabled-opacity) disabled:cursor-not-allowed";
|
|
1724
|
+
function Stepper({
|
|
1725
|
+
value,
|
|
1726
|
+
min,
|
|
1727
|
+
max,
|
|
1728
|
+
step,
|
|
1729
|
+
onChange,
|
|
1730
|
+
disabled = false,
|
|
1731
|
+
decLabel = "-",
|
|
1732
|
+
incLabel = "+"
|
|
1733
|
+
}) {
|
|
1734
|
+
return /* @__PURE__ */ jsxs23("div", { className: "inline-flex items-center gap-1.5", children: [
|
|
1735
|
+
/* @__PURE__ */ jsx28(
|
|
1736
|
+
"button",
|
|
1737
|
+
{
|
|
1738
|
+
type: "button",
|
|
1739
|
+
className: BTN,
|
|
1740
|
+
"aria-label": decLabel,
|
|
1741
|
+
disabled: disabled || value <= min,
|
|
1742
|
+
onClick: () => onChange(Math.max(min, value - step)),
|
|
1743
|
+
children: "\u2212"
|
|
1744
|
+
}
|
|
1745
|
+
),
|
|
1746
|
+
/* @__PURE__ */ jsx28("span", { className: "min-w-[34px] text-center text-lg font-bold tabular-nums text-text", children: value }),
|
|
1747
|
+
/* @__PURE__ */ jsx28(
|
|
1748
|
+
"button",
|
|
1749
|
+
{
|
|
1750
|
+
type: "button",
|
|
1751
|
+
className: BTN,
|
|
1752
|
+
"aria-label": incLabel,
|
|
1753
|
+
disabled: disabled || value >= max,
|
|
1754
|
+
onClick: () => onChange(Math.min(max, value + step)),
|
|
1755
|
+
children: "\uFF0B"
|
|
1756
|
+
}
|
|
1757
|
+
)
|
|
1758
|
+
] });
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
// tabs.tsx
|
|
1762
|
+
import { jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1763
|
+
var TAB_BASE = "relative inline-flex items-center justify-center gap-1.5 border-none bg-transparent py-3 font-display text-smd font-bold tracking-widest text-text-faint shadow-none transition-colors duration-(--dur-base) cursor-pointer hover:text-text-dim hover:bg-transparent hover:shadow-none active:scale-100 active:bg-transparent after:absolute after:inset-x-[12%] after:-bottom-px after:h-0.5 after:origin-center after:scale-x-0 after:rounded-xs after:bg-accent after:transition-transform after:duration-(--dur-base) after:ease-spring after:content-['']";
|
|
1764
|
+
var TAB_WIDTH = {
|
|
1765
|
+
default: "flex-none px-3.5",
|
|
1766
|
+
fill: "flex-1 px-1.5"
|
|
1767
|
+
};
|
|
1768
|
+
var TAB_ACTIVE = "text-text after:scale-x-100";
|
|
1769
|
+
function Tabs({
|
|
1770
|
+
tabs,
|
|
1771
|
+
value,
|
|
1772
|
+
onChange,
|
|
1773
|
+
ariaLabel,
|
|
1774
|
+
trailing,
|
|
1775
|
+
className = "",
|
|
1776
|
+
variant = "default"
|
|
1777
|
+
}) {
|
|
1778
|
+
const tabClass = `${TAB_BASE} ${TAB_WIDTH[variant]}`;
|
|
1779
|
+
return /* @__PURE__ */ jsxs24(
|
|
1780
|
+
"div",
|
|
1781
|
+
{
|
|
1782
|
+
role: "tablist",
|
|
1783
|
+
"aria-label": ariaLabel,
|
|
1784
|
+
className: `flex border-t-0 border-x-0 border-b border-solid border-border ${className}`.trim(),
|
|
1785
|
+
children: [
|
|
1786
|
+
tabs.map((tab) => {
|
|
1787
|
+
const active = tab.key === value;
|
|
1788
|
+
return /* @__PURE__ */ jsxs24(
|
|
1789
|
+
"button",
|
|
1790
|
+
{
|
|
1791
|
+
type: "button",
|
|
1792
|
+
role: "tab",
|
|
1793
|
+
"aria-selected": active,
|
|
1794
|
+
className: `${tabClass}${active ? ` ${TAB_ACTIVE}` : ""}`,
|
|
1795
|
+
onClick: () => onChange(tab.key),
|
|
1796
|
+
children: [
|
|
1797
|
+
tab.label,
|
|
1798
|
+
tab.badge
|
|
1799
|
+
]
|
|
1800
|
+
},
|
|
1801
|
+
tab.key
|
|
1802
|
+
);
|
|
1803
|
+
}),
|
|
1804
|
+
trailing
|
|
1805
|
+
]
|
|
1806
|
+
}
|
|
1807
|
+
);
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
// toast.tsx
|
|
1811
|
+
import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1812
|
+
var SNACKBAR_TONE = {
|
|
1813
|
+
success: { border: "border-border-strong", icon: "text-success" },
|
|
1814
|
+
error: { border: "border-snackbar-danger-border", icon: "text-snackbar-danger" },
|
|
1815
|
+
info: { border: "border-border-strong", icon: "text-success" },
|
|
1816
|
+
warn: { border: "border-border-strong", icon: "text-warning" },
|
|
1817
|
+
danger: { border: "border-snackbar-danger-border", icon: "text-snackbar-danger" }
|
|
1818
|
+
};
|
|
1819
|
+
var DS_TONE = {
|
|
1820
|
+
info: { border: "border-l-info", text: "text-info" },
|
|
1821
|
+
success: { border: "border-l-success", text: "text-success" },
|
|
1822
|
+
warn: { border: "border-l-warning", text: "text-warning" },
|
|
1823
|
+
danger: { border: "border-l-danger", text: "text-danger" },
|
|
1824
|
+
error: { border: "border-l-danger", text: "text-danger" }
|
|
1825
|
+
};
|
|
1826
|
+
var FIXED = "fixed bottom-[26px] left-1/2 z-(--z-snackbar) pointer-events-none animate-[snackbar-in_var(--dur-slow)_var(--ease-spring)_both]";
|
|
1827
|
+
function Toast({
|
|
1828
|
+
children,
|
|
1829
|
+
tone = "success",
|
|
1830
|
+
variant = "default",
|
|
1831
|
+
icon,
|
|
1832
|
+
title,
|
|
1833
|
+
message,
|
|
1834
|
+
action,
|
|
1835
|
+
onAction,
|
|
1836
|
+
onClose,
|
|
1837
|
+
fixed = true,
|
|
1838
|
+
role = "status",
|
|
1839
|
+
className = ""
|
|
1840
|
+
}) {
|
|
1841
|
+
if (variant === "snackbar") {
|
|
1842
|
+
const t2 = SNACKBAR_TONE[tone];
|
|
1843
|
+
return /* @__PURE__ */ jsxs25(
|
|
1844
|
+
"div",
|
|
1845
|
+
{
|
|
1846
|
+
role,
|
|
1847
|
+
className: `inline-flex items-center gap-[9px] rounded-pill border border-solid bg-snackbar-surface px-5 py-[11px] text-[14px] text-text shadow-overlay ${t2.border}${fixed ? ` ${FIXED}` : ""} ${className}`.trim(),
|
|
1848
|
+
children: [
|
|
1849
|
+
icon && /* @__PURE__ */ jsx29("span", { className: `${t2.icon} text-[13px] font-extrabold`, "aria-hidden": "true", children: icon }),
|
|
1850
|
+
children
|
|
1851
|
+
]
|
|
1852
|
+
}
|
|
1853
|
+
);
|
|
1854
|
+
}
|
|
1855
|
+
const t = DS_TONE[tone];
|
|
1856
|
+
return /* @__PURE__ */ jsxs25(
|
|
1857
|
+
"div",
|
|
1858
|
+
{
|
|
1859
|
+
role,
|
|
1860
|
+
className: `inline-flex min-w-[280px] max-w-[420px] items-start gap-3 rounded-md border border-solid border-border border-l-[3px] bg-surface px-[15px] py-[13px] text-text shadow-popover ${t.border}${fixed ? ` ${FIXED}` : ""} ${className}`.trim(),
|
|
1861
|
+
children: [
|
|
1862
|
+
icon && /* @__PURE__ */ jsx29("span", { className: `mt-px shrink-0 ${t.text}`, "aria-hidden": "true", children: icon }),
|
|
1863
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex min-w-0 flex-1 flex-col gap-[3px]", children: [
|
|
1864
|
+
title != null && /* @__PURE__ */ jsx29("span", { className: "text-[13.5px] font-bold text-text", children: title }),
|
|
1865
|
+
message != null && /* @__PURE__ */ jsx29("span", { className: "text-[12.5px] leading-[1.5] text-text-dim", children: message }),
|
|
1866
|
+
children
|
|
1867
|
+
] }),
|
|
1868
|
+
action != null && /* @__PURE__ */ jsx29(
|
|
1869
|
+
"button",
|
|
1870
|
+
{
|
|
1871
|
+
type: "button",
|
|
1872
|
+
onClick: onAction,
|
|
1873
|
+
className: `shrink-0 whitespace-nowrap border-none bg-transparent text-[12.5px] font-bold ${t.text} cursor-pointer`,
|
|
1874
|
+
children: action
|
|
1875
|
+
}
|
|
1876
|
+
),
|
|
1877
|
+
onClose && /* @__PURE__ */ jsx29(
|
|
1878
|
+
"button",
|
|
1879
|
+
{
|
|
1880
|
+
type: "button",
|
|
1881
|
+
onClick: onClose,
|
|
1882
|
+
"aria-label": "close",
|
|
1883
|
+
className: "shrink-0 inline-flex border-none bg-transparent p-0 text-text-dim cursor-pointer",
|
|
1884
|
+
children: /* @__PURE__ */ jsx29(Icon, { name: "close", size: 17 })
|
|
1885
|
+
}
|
|
1886
|
+
)
|
|
1887
|
+
]
|
|
1888
|
+
}
|
|
1889
|
+
);
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
// toggle.tsx
|
|
1893
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
1894
|
+
function Toggle({
|
|
1895
|
+
checked = false,
|
|
1896
|
+
onChange,
|
|
1897
|
+
label,
|
|
1898
|
+
disabled = false
|
|
1899
|
+
}) {
|
|
1900
|
+
return /* @__PURE__ */ jsx30(
|
|
1901
|
+
"button",
|
|
1902
|
+
{
|
|
1903
|
+
type: "button",
|
|
1904
|
+
role: "switch",
|
|
1905
|
+
"aria-checked": checked,
|
|
1906
|
+
"aria-label": label,
|
|
1907
|
+
disabled,
|
|
1908
|
+
onClick: onChange,
|
|
1909
|
+
className: `relative inline-flex h-[26px] w-[46px] shrink-0 items-center rounded-pill border border-solid border-transparent p-0 transition-colors duration-(--dur-fast) cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed focus-visible:shadow-focus focus-visible:outline-none ${checked ? "bg-success" : "bg-border-strong"}`,
|
|
1910
|
+
children: /* @__PURE__ */ jsx30(
|
|
1911
|
+
"span",
|
|
1912
|
+
{
|
|
1913
|
+
"aria-hidden": "true",
|
|
1914
|
+
className: `absolute top-[3px] h-5 w-5 rounded-pill bg-white shadow-[0_1px_2px_rgba(0,0,0,0.25)] transition-[left] duration-(--dur-fast) ${checked ? "left-[23px]" : "left-[3px]"}`
|
|
1915
|
+
}
|
|
1916
|
+
)
|
|
1917
|
+
}
|
|
1918
|
+
);
|
|
1919
|
+
}
|
|
1920
|
+
export {
|
|
1921
|
+
Avatar,
|
|
1922
|
+
AvatarStack,
|
|
1923
|
+
Badge,
|
|
1924
|
+
BottomSheet,
|
|
1925
|
+
Button,
|
|
1926
|
+
Checkbox,
|
|
1927
|
+
Chip,
|
|
1928
|
+
Composer,
|
|
1929
|
+
ConfirmModal,
|
|
1930
|
+
CountChip,
|
|
1931
|
+
EmptyNote,
|
|
1932
|
+
GoogleIcon,
|
|
1933
|
+
Icon,
|
|
1934
|
+
IconButton,
|
|
1935
|
+
Input,
|
|
1936
|
+
Link,
|
|
1937
|
+
LogoMark,
|
|
1938
|
+
Lozenge,
|
|
1939
|
+
MOBILE_LAYOUT_MQ,
|
|
1940
|
+
Menu,
|
|
1941
|
+
MenuItem,
|
|
1942
|
+
Modal,
|
|
1943
|
+
PersonIcon,
|
|
1944
|
+
Popover,
|
|
1945
|
+
ProfileModalContext,
|
|
1946
|
+
Radio,
|
|
1947
|
+
RingTimer,
|
|
1948
|
+
SearchField,
|
|
1949
|
+
Spinner,
|
|
1950
|
+
SplitModal,
|
|
1951
|
+
StatusBadge,
|
|
1952
|
+
StatusDot,
|
|
1953
|
+
StepFlow,
|
|
1954
|
+
Stepper,
|
|
1955
|
+
Tabs,
|
|
1956
|
+
Toast,
|
|
1957
|
+
Toggle,
|
|
1958
|
+
linkClass,
|
|
1959
|
+
useDismiss,
|
|
1960
|
+
useOpenProfile
|
|
1961
|
+
};
|
|
1962
|
+
//# sourceMappingURL=index.js.map
|