@coko/client
Version:
Client side common code for coko apps
88 lines (86 loc) • 3.36 kB
JavaScript
import { grid as e } from "../../toolkit/themeHelper.js";
import "../../toolkit/index.js";
import t from "../../theme/index.js";
import { uuid as n } from "../../index.js";
import { cloneElement as r, useEffect as i, useRef as a, useState as o } from "react";
import s from "styled-components";
import { jsx as c, jsxs as l } from "react/jsx-runtime";
//#region src/ui/common/Popup.tsx
var u = s.div`
background: ${t.colorBackground};
border: 1px solid ${t.colorBorder};
border-radius: 10px;
display: ${({ $visible: e }) => e ? "block" : "none"};
${(e) => {
let { $position: t, $alignment: n } = e;
switch (`${t}/${n}`) {
case "block-start/start": return `inset-block-end: 100%; inset-inline-start: 0; margin-block-end: ${e.theme.gridUnit};`;
case "block-start/end": return `inset-block-end: 100%; inset-inline-end: 0; margin-block-end: ${e.theme.gridUnit};`;
case "block-end/start": return `inset-block-start: 100%; inset-inline-start: 0; margin-block-start: ${e.theme.gridUnit};`;
case "block-end/end": return `inset-block-start: 100%; inset-inline-end: 0; margin-block-start: ${e.theme.gridUnit};`;
case "inline-start/start": return `inset-inline-end: 100%; inset-block-start: 0; margin-inline-end: ${e.theme.gridUnit};`;
case "inline-start/end": return `inset-inline-end: 100%; inset-block-end: 0; margin-inline-end: ${e.theme.gridUnit};`;
case "inline-end/start": return `inset-inline-start: 100%; inset-block-start: 0; margin-inline-start: ${e.theme.gridUnit};`;
case "inline-end/end": return `inset-inline-start: 100%; inset-block-end: 0; margin-inline-start: ${e.theme.gridUnit};`;
default: return `inset-block-end: 100%; inset-inline-start: 0; margin-block-end: ${e.theme.gridUnit};`;
}
}}
padding: ${e(5)};
position: absolute;
z-index: 1000;
`, d = s.div`
display: inline-block;
position: relative;
`, f = [
"a[href]",
"area[href]",
"input:not([disabled]):not([type=hidden])",
"select:not([disabled])",
"textarea:not([disabled])",
"button:not([disabled])",
"object",
"embed",
"[tabindex]:not([tabindex=\"-1\"])",
"audio[controls]",
"video[controls]",
"[contenteditable]:not([contenteditable=\"false\"])"
], p = ({ alignment: e = "start", children: t, focusableContent: s = f, id: p = n(), toggle: m, position: h = "block-start" }) => {
let g = a(null), _ = a(null), [v, y] = o([]), [b, x] = o(!1);
return i(() => {
b && v && v.length > 0 && v[0].focus();
}, [b, v]), i(() => {
if (_.current) {
let e = s.join(", ");
y(Array.from(_.current.querySelectorAll(e)));
}
}, [t, s]), /* @__PURE__ */ l(d, {
ref: g,
children: [r(m, {
onClick: () => {
x(!b);
},
"aria-controls": p,
"aria-expanded": b,
"aria-haspopup": "dialog"
}), /* @__PURE__ */ c(u, {
$alignment: e,
$position: h,
$visible: b,
id: p,
onBlur: (e) => {
g.current?.contains(e.relatedTarget) || x(!1);
},
onKeyDown: (e) => {
let t = e.key === "Escape";
if (e.key !== "Tab" && !t || (t && ((_.current?.previousElementSibling)?.focus(), x(!1)), !v || v.length === 0)) return;
let n = v[0], r = v[v.length - 1];
e.shiftKey ? document.activeElement === n && (r.focus(), e.preventDefault()) : document.activeElement === r && (n.focus(), e.preventDefault());
},
ref: _,
tabIndex: 0,
children: t
})]
});
};
//#endregion
export { p as default };