@astralui/core 0.1.10 → 0.1.12
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/dist/index.cjs +130 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +130 -24
- package/dist/index.js.map +1 -1
- package/dist/styles.css +5 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -167,48 +167,139 @@ function AstralThemeProvider({ colors, children }) {
|
|
|
167
167
|
children
|
|
168
168
|
] });
|
|
169
169
|
}
|
|
170
|
-
|
|
170
|
+
var dialogSeq = 0;
|
|
171
|
+
var dialogStack = [];
|
|
172
|
+
var FOCUSABLE = [
|
|
173
|
+
"a[href]",
|
|
174
|
+
"area[href]",
|
|
175
|
+
"button:not([disabled])",
|
|
176
|
+
'input:not([disabled]):not([type="hidden"])',
|
|
177
|
+
"select:not([disabled])",
|
|
178
|
+
"textarea:not([disabled])",
|
|
179
|
+
"iframe",
|
|
180
|
+
"object",
|
|
181
|
+
"embed",
|
|
182
|
+
"[contenteditable]",
|
|
183
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
184
|
+
].join(",");
|
|
185
|
+
function useDialog(opened, onClose) {
|
|
186
|
+
const panelRef = useRef(null);
|
|
187
|
+
const idRef = useRef("");
|
|
188
|
+
if (!idRef.current) idRef.current = "au-dialog-title-" + String(++dialogSeq);
|
|
189
|
+
const onCloseRef = useRef(onClose);
|
|
190
|
+
onCloseRef.current = onClose;
|
|
171
191
|
useEffect(() => {
|
|
172
192
|
if (!opened) return;
|
|
193
|
+
const panel = panelRef.current;
|
|
194
|
+
if (!panel) return;
|
|
195
|
+
const restoreTo = document.activeElement;
|
|
196
|
+
dialogStack.push(panel);
|
|
197
|
+
const isTop = () => dialogStack[dialogStack.length - 1] === panel;
|
|
198
|
+
const focusables = () => Array.from(panel.querySelectorAll(FOCUSABLE)).filter(
|
|
199
|
+
(el) => el.offsetWidth > 0 || el.offsetHeight > 0 || el === document.activeElement
|
|
200
|
+
);
|
|
201
|
+
const raf = requestAnimationFrame(() => {
|
|
202
|
+
if (panel.contains(document.activeElement)) return;
|
|
203
|
+
const list = focusables();
|
|
204
|
+
const target = list.find((el) => !el.classList.contains("au-modal-x")) ?? list[0] ?? panel;
|
|
205
|
+
target.focus();
|
|
206
|
+
});
|
|
173
207
|
const onKey = (e) => {
|
|
174
|
-
if (
|
|
208
|
+
if (!isTop()) return;
|
|
209
|
+
if (e.key === "Escape") {
|
|
210
|
+
onCloseRef.current();
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (e.key !== "Tab") return;
|
|
214
|
+
const list = focusables();
|
|
215
|
+
if (!list.length) {
|
|
216
|
+
e.preventDefault();
|
|
217
|
+
panel.focus();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const first = list[0];
|
|
221
|
+
const last = list[list.length - 1];
|
|
222
|
+
const active = document.activeElement;
|
|
223
|
+
if (!panel.contains(active)) {
|
|
224
|
+
e.preventDefault();
|
|
225
|
+
(e.shiftKey ? last : first).focus();
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (e.shiftKey && active === first) {
|
|
229
|
+
e.preventDefault();
|
|
230
|
+
last.focus();
|
|
231
|
+
} else if (!e.shiftKey && active === last) {
|
|
232
|
+
e.preventDefault();
|
|
233
|
+
first.focus();
|
|
234
|
+
}
|
|
175
235
|
};
|
|
176
|
-
document.addEventListener("keydown", onKey);
|
|
177
|
-
const
|
|
236
|
+
document.addEventListener("keydown", onKey, true);
|
|
237
|
+
const prevOverflow = document.body.style.overflow;
|
|
178
238
|
document.body.style.overflow = "hidden";
|
|
179
239
|
return () => {
|
|
180
|
-
|
|
181
|
-
document.
|
|
240
|
+
cancelAnimationFrame(raf);
|
|
241
|
+
document.removeEventListener("keydown", onKey, true);
|
|
242
|
+
const at = dialogStack.indexOf(panel);
|
|
243
|
+
if (at !== -1) dialogStack.splice(at, 1);
|
|
244
|
+
document.body.style.overflow = prevOverflow;
|
|
245
|
+
if (restoreTo && document.contains(restoreTo)) restoreTo.focus();
|
|
182
246
|
};
|
|
183
|
-
}, [opened
|
|
247
|
+
}, [opened]);
|
|
248
|
+
return { panelRef, titleId: idRef.current };
|
|
184
249
|
}
|
|
185
250
|
function AstralModal({ opened, onClose, title, brand, width = 460, zIndex, children }) {
|
|
186
|
-
|
|
251
|
+
const { panelRef, titleId } = useDialog(opened, onClose);
|
|
187
252
|
if (!opened) return null;
|
|
188
253
|
const style = { maxWidth: width, ...brand ? { "--au-ic": brand } : {} };
|
|
189
254
|
return createPortal(
|
|
190
|
-
/* @__PURE__ */ jsx("div", { className: "au-modal-overlay", onMouseDown: onClose, style: zIndex != null ? { zIndex } : void 0, children: /* @__PURE__ */ jsxs(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
255
|
+
/* @__PURE__ */ jsx("div", { className: "au-modal-overlay", onMouseDown: onClose, style: zIndex != null ? { zIndex } : void 0, children: /* @__PURE__ */ jsxs(
|
|
256
|
+
"div",
|
|
257
|
+
{
|
|
258
|
+
ref: panelRef,
|
|
259
|
+
className: "au-modal-panel",
|
|
260
|
+
style,
|
|
261
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
262
|
+
role: "dialog",
|
|
263
|
+
"aria-modal": "true",
|
|
264
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
265
|
+
tabIndex: -1,
|
|
266
|
+
children: [
|
|
267
|
+
/* @__PURE__ */ jsxs("div", { className: "au-modal-head", children: [
|
|
268
|
+
/* @__PURE__ */ jsx("span", { className: "au-modal-title", id: titleId, children: title }),
|
|
269
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "au-modal-x", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx(IconX, {}) })
|
|
270
|
+
] }),
|
|
271
|
+
/* @__PURE__ */ jsx("div", { className: "au-modal-body", children })
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
) }),
|
|
197
275
|
document.body
|
|
198
276
|
);
|
|
199
277
|
}
|
|
200
278
|
function AstralDrawer({ opened, onClose, title, brand, width = 440, zIndex, children }) {
|
|
201
|
-
|
|
279
|
+
const { panelRef, titleId } = useDialog(opened, onClose);
|
|
202
280
|
if (!opened) return null;
|
|
203
281
|
const style = { width, ...brand ? { "--au-ic": brand } : {} };
|
|
204
282
|
return createPortal(
|
|
205
|
-
/* @__PURE__ */ jsx("div", { className: "au-drawer-overlay", onMouseDown: onClose, style: zIndex != null ? { zIndex } : void 0, children: /* @__PURE__ */ jsxs(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
283
|
+
/* @__PURE__ */ jsx("div", { className: "au-drawer-overlay", onMouseDown: onClose, style: zIndex != null ? { zIndex } : void 0, children: /* @__PURE__ */ jsxs(
|
|
284
|
+
"div",
|
|
285
|
+
{
|
|
286
|
+
ref: panelRef,
|
|
287
|
+
className: "au-drawer-panel",
|
|
288
|
+
style,
|
|
289
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
290
|
+
role: "dialog",
|
|
291
|
+
"aria-modal": "true",
|
|
292
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
293
|
+
tabIndex: -1,
|
|
294
|
+
children: [
|
|
295
|
+
/* @__PURE__ */ jsxs("div", { className: "au-drawer-head", children: [
|
|
296
|
+
/* @__PURE__ */ jsx("span", { className: "au-drawer-title", id: titleId, children: title }),
|
|
297
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "au-modal-x", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx(IconX, {}) })
|
|
298
|
+
] }),
|
|
299
|
+
/* @__PURE__ */ jsx("div", { className: "au-drawer-body", children })
|
|
300
|
+
]
|
|
301
|
+
}
|
|
302
|
+
) }),
|
|
212
303
|
document.body
|
|
213
304
|
);
|
|
214
305
|
}
|
|
@@ -912,6 +1003,17 @@ var COLOR_MAP = {
|
|
|
912
1003
|
replied: "#8b5cf6",
|
|
913
1004
|
success: "#16a34a"
|
|
914
1005
|
};
|
|
1006
|
+
var FG = {
|
|
1007
|
+
"#eab308": ["#854d0e", "#fde047"],
|
|
1008
|
+
"#06b6d4": ["#155e75", "#67e8f9"],
|
|
1009
|
+
"#EF8E2E": ["#9a4a06", "#fdba74"],
|
|
1010
|
+
"#9ca3af": ["#4b5563", "#d1d5db"],
|
|
1011
|
+
"#16a34a": ["#14532d", "#4ade80"],
|
|
1012
|
+
"#3b82f6": ["#1e40af", "#93c5fd"],
|
|
1013
|
+
"#ef4444": ["#991b1b", "#fca5a5"],
|
|
1014
|
+
"#8b5cf6": ["#5b21b6", "#c4b5fd"]
|
|
1015
|
+
};
|
|
1016
|
+
var SOLID = { "#16a34a": "#166534" };
|
|
915
1017
|
var FILLED = /* @__PURE__ */ new Set(["running", "active", "online"]);
|
|
916
1018
|
function StatusBadge({ status, label, color, filled }) {
|
|
917
1019
|
const c = color ?? COLOR_MAP[status] ?? "#9ca3af";
|
|
@@ -921,7 +1023,11 @@ function StatusBadge({ status, label, color, filled }) {
|
|
|
921
1023
|
"span",
|
|
922
1024
|
{
|
|
923
1025
|
className: `au-sbadge${isFilled ? " filled" : ""}`,
|
|
924
|
-
style: {
|
|
1026
|
+
style: {
|
|
1027
|
+
"--au-sb": c,
|
|
1028
|
+
...FG[c] ? { "--au-sb-fg": `light-dark(${FG[c][0]}, ${FG[c][1]})` } : {},
|
|
1029
|
+
...SOLID[c] ? { "--au-sb-solid": SOLID[c] } : {}
|
|
1030
|
+
},
|
|
925
1031
|
title: typeof text === "string" ? text : void 0,
|
|
926
1032
|
children: [
|
|
927
1033
|
/* @__PURE__ */ jsx("span", { className: "au-sbadge-dot" }),
|