@rimelight/ui 0.0.44 → 0.0.46
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/icons--RzV1RTU.d.mts +72 -0
- package/dist/icons.d.mts +2 -0
- package/dist/icons.mjs +32 -0
- package/dist/icons.raw-CjAuL2Sc.mjs +67 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.mjs +26 -0
- package/dist/preset.d.mts +2 -0
- package/dist/preset.mjs +215 -0
- package/dist/resolver.d.mts +6 -0
- package/dist/resolver.mjs +116 -0
- package/dist/shortcuts.d.mts +29 -0
- package/dist/shortcuts.mjs +119 -0
- package/dist/stores.d.mts +9 -0
- package/dist/stores.mjs +19 -0
- package/dist/types-DqAgCNcm.d.mts +86 -0
- package/dist/types.d.mts +2 -0
- package/dist/types.mjs +1 -0
- package/package.json +36 -7
- package/src/components/button/RLSButton.tsx +1 -1
- package/src/components/dashboard-sidebar/RLADashboardSidebar.astro +53 -24
- package/src/components/dashboard-sidebar/dashboard-sidebar.theme.ts +5 -5
- package/src/components/icon/RLSIcon.tsx +1 -1
- package/src/components/modal/RLAModal.astro +8 -5
- package/src/components/modal/RLSModal.tsx +17 -12
- package/src/components/modal/modal.theme.ts +5 -4
- package/src/index.ts +13 -3
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
//#region src/icons.raw.d.ts
|
|
2
|
+
declare const svg: (inner: string) => string;
|
|
3
|
+
declare const ICONS: {
|
|
4
|
+
readonly alertTriangle: `<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4M12 17h.01"/>`;
|
|
5
|
+
readonly alignLeft: `<line x1="21" x2="3" y1="6" y2="6"/><line x1="15" x2="3" y1="12" y2="12"/><line x1="17" x2="3" y1="18" y2="18"/>`;
|
|
6
|
+
readonly arrowLeft: `<path d="M19 12H5M12 19l-7-7 7-7"/>`;
|
|
7
|
+
readonly arrowRight: `<path d="M5 12h14M12 5l7 7-7 7"/>`;
|
|
8
|
+
readonly bell: `<path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9M10.3 21a1.94 1.94 0 0 0 3.4 0"/>`;
|
|
9
|
+
readonly check: `<path d="M20 6 9 17l-5-5"/>`;
|
|
10
|
+
readonly chevronDown: `<path d="m6 9 6 6 6-6"/>`;
|
|
11
|
+
readonly chevronLeft: `<path d="m15 18-6-6 6-6"/>`;
|
|
12
|
+
readonly chevronRight: `<path d="m9 18 6-6-6-6"/>`;
|
|
13
|
+
readonly chevronsUpDown: `<path d="m7 15 5 5 5-5M7 9l5-5 5 5"/>`;
|
|
14
|
+
readonly circleCheck: `<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>`;
|
|
15
|
+
readonly circleX: `<circle cx="12" cy="12" r="10"/><path d="m15 9-6 6M9 9l6 6"/>`;
|
|
16
|
+
readonly close: `<path d="M18 6 6 18M6 6l12 12"/>`;
|
|
17
|
+
readonly copy: `<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>`;
|
|
18
|
+
readonly download: `<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/>`;
|
|
19
|
+
readonly externalLink: `<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14 21 3"/>`;
|
|
20
|
+
readonly fileQuestion: `<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4M9.1 11.8a3 3 0 0 1 5.8 1c0 .9-.6 1.4-1.1 1.8-.4.3-.8.7-.8 1.4M12 19h.01"/>`;
|
|
21
|
+
readonly gripHorizontal: `<circle cx="12" cy="9" r="1"/><circle cx="19" cy="9" r="1"/><circle cx="5" cy="9" r="1"/><circle cx="12" cy="15" r="1"/><circle cx="19" cy="15" r="1"/><circle cx="5" cy="15" r="1"/>`;
|
|
22
|
+
readonly gripVertical: `<circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/>`;
|
|
23
|
+
readonly hardDrive: `<rect width="20" height="8" x="2" y="14" rx="2"/><path d="M6 18h.01M10 18h.01M2 14L5 3h14l3 11"/>`;
|
|
24
|
+
readonly image: `<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>`;
|
|
25
|
+
readonly imageUpscale: `<path d="M16 3H3v13h13V3z"/><path d="M21 21v-4a2 2 0 0 0-2-2h-3M21 11V9M21 5a2 2 0 0 0-2-2h-1"/>`;
|
|
26
|
+
readonly info: `<circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/>`;
|
|
27
|
+
readonly layers: `<path d="m12 3-10 5L12 13l10-5-10-5Z"/><path d="M2 17l10 5 10-5M2 12l10 5 10-5"/>`;
|
|
28
|
+
readonly list: `<line x1="8" x2="21" y1="6" y2="6"/><line x1="8" x2="21" y1="12" y2="12"/><line x1="8" x2="21" y1="18" y2="18"/><line x1="3" x2="3.01" y1="6" y2="6"/><line x1="3" x2="3.01" y1="12" y2="12"/><line x1="3" x2="3.01" y1="18" y2="18"/>`;
|
|
29
|
+
readonly loaderCircle: `<path d="M21 12a9 9 0 1 1-6.219-8.56"/>`;
|
|
30
|
+
readonly moon: `<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>`;
|
|
31
|
+
readonly panelLeft: `<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><path d="M9 3v18"/>`;
|
|
32
|
+
readonly play: `<polygon points="6 3 20 12 6 21 6 3"/>`;
|
|
33
|
+
readonly quote: `<path d="M3 21c3 0 7-1 7-8V5c0-1.25-.75-2-2-2H4c-1.25 0-2 .75-2 2v6c0 1.25.75 2 2 2h3c0 4-3 6-3 6Zm11 0c3 0 7-1 7-8V5c0-1.25-.75-2-2-2h-4c-1.25 0-2 .75-2 2v6c0 1.25.75 2 2 2h3c0 4-3 6-3 6Z"/>`;
|
|
34
|
+
readonly search: `<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>`;
|
|
35
|
+
readonly share: `<circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="m8.59 13.51 6.83 3.98M15.41 6.51l-6.82 3.98"/>`;
|
|
36
|
+
readonly sun: `<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/>`;
|
|
37
|
+
readonly uploadCloud: `<path d="M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242M12 12v9M9 15l3-3 3 3"/>`;
|
|
38
|
+
readonly user: `<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>`;
|
|
39
|
+
readonly star: `<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>`;
|
|
40
|
+
readonly lock: `<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>`;
|
|
41
|
+
readonly eye: `<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0z"/><circle cx="12" cy="12" r="3"/>`;
|
|
42
|
+
readonly eyeOff: `<path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"/><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"/><path d="M17.479 17.499A10.75 10.75 0 0 1 2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.225-4.22"/><line x1="2" x2="22" y1="2" y2="22"/>`;
|
|
43
|
+
readonly arrowUp: `<path d="M12 19V5M5 12l7-7 7 7"/>`;
|
|
44
|
+
readonly arrowDown: `<path d="M12 5v14M19 12l-7 7-7-7"/>`;
|
|
45
|
+
readonly edit: `<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>`;
|
|
46
|
+
readonly link: `<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>`;
|
|
47
|
+
readonly plus: `<path d="M5 12h14M12 5v14"/>`;
|
|
48
|
+
readonly trash: `<path d="M3 6h18M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6M10 11v6M14 11v6"/><path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/>`;
|
|
49
|
+
readonly fileText: `<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8M16 13H8M16 17H8"/>`;
|
|
50
|
+
readonly settings: `<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>`;
|
|
51
|
+
readonly type: `<polyline points="4 7 4 4 20 4 20 7"/><line x1="9" x2="15" y1="20" y2="20"/><line x1="12" x2="12" y1="4" y2="20"/>`;
|
|
52
|
+
readonly code: `<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>`;
|
|
53
|
+
readonly film: `<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M7 3v18M17 3v18M3 7h4M17 7h4M3 12h18M3 17h4M17 17h4"/>`;
|
|
54
|
+
readonly messageSquare: `<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>`;
|
|
55
|
+
readonly bookOpen: `<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>`;
|
|
56
|
+
readonly panelRight: `<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><path d="M15 3v18"/>`;
|
|
57
|
+
readonly pin: `<path d="M12 17v5"/><path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"/>`;
|
|
58
|
+
readonly ellipsisVertical: `<circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/>`;
|
|
59
|
+
readonly arrowUpFromLine: `<path d="m18 9-6-6-6 6"/><path d="M12 3v14"/><path d="M5 21h14"/>`;
|
|
60
|
+
readonly arrowDownToLine: `<path d="M12 17V3"/><path d="m6 11 6 6 6-6"/><path d="M5 21h14"/>`;
|
|
61
|
+
};
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/icons.d.ts
|
|
64
|
+
declare const getSvgIcon: (k: string) => string;
|
|
65
|
+
declare const DEFAULT_ICONS: Record<keyof typeof ICONS, string>;
|
|
66
|
+
type RimelightIcons = Partial<Record<keyof typeof ICONS | (string & {}), string>>;
|
|
67
|
+
declare const resolveIcon: (name?: string, custom?: string) => {
|
|
68
|
+
isClass: boolean;
|
|
69
|
+
content: string;
|
|
70
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
export { ICONS as a, resolveIcon as i, RimelightIcons as n, svg as o, getSvgIcon as r, DEFAULT_ICONS as t };
|
package/dist/icons.d.mts
ADDED
package/dist/icons.mjs
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { n as getIconSvg, r as svg, t as ICONS } from "./icons.raw-CjAuL2Sc.mjs";
|
|
2
|
+
import uiConfig from "virtual:rimelight/ui";
|
|
3
|
+
//#region src/icons.ts
|
|
4
|
+
const getSvgIcon = (k) => getIconSvg(k) ?? "";
|
|
5
|
+
const DEFAULT_ICONS = Object.fromEntries(Object.keys(ICONS).map((k) => [k, getSvgIcon(k)]));
|
|
6
|
+
const EMPTY_ICON = {
|
|
7
|
+
isClass: false,
|
|
8
|
+
content: ""
|
|
9
|
+
};
|
|
10
|
+
const cache = /* @__PURE__ */ new Map();
|
|
11
|
+
const resolveIcon = (name = "", custom) => {
|
|
12
|
+
if (!name) return EMPTY_ICON;
|
|
13
|
+
const raw = custom || uiConfig?.icons?.[name] || name;
|
|
14
|
+
let res = cache.get(raw);
|
|
15
|
+
if (!res) {
|
|
16
|
+
const content = getIconSvg(raw);
|
|
17
|
+
res = content !== void 0 ? {
|
|
18
|
+
isClass: false,
|
|
19
|
+
content
|
|
20
|
+
} : raw.startsWith("i-") || raw.includes(":") ? {
|
|
21
|
+
isClass: true,
|
|
22
|
+
content: raw
|
|
23
|
+
} : {
|
|
24
|
+
isClass: false,
|
|
25
|
+
content: raw.startsWith("<svg") ? raw : raw.startsWith("<") ? svg(raw) : ""
|
|
26
|
+
};
|
|
27
|
+
cache.set(raw, res);
|
|
28
|
+
}
|
|
29
|
+
return res;
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { DEFAULT_ICONS, ICONS, getSvgIcon, resolveIcon, svg };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
//#region src/icons.raw.ts
|
|
2
|
+
const svg = (inner) => `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" width="100%" height="100%">${inner}</svg>`;
|
|
3
|
+
const getIconSvg = (name) => {
|
|
4
|
+
if (!Object.prototype.hasOwnProperty.call(ICONS, name)) return void 0;
|
|
5
|
+
return svg(ICONS[name]);
|
|
6
|
+
};
|
|
7
|
+
const ICONS = {
|
|
8
|
+
alertTriangle: `<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4M12 17h.01"/>`,
|
|
9
|
+
alignLeft: `<line x1="21" x2="3" y1="6" y2="6"/><line x1="15" x2="3" y1="12" y2="12"/><line x1="17" x2="3" y1="18" y2="18"/>`,
|
|
10
|
+
arrowLeft: `<path d="M19 12H5M12 19l-7-7 7-7"/>`,
|
|
11
|
+
arrowRight: `<path d="M5 12h14M12 5l7 7-7 7"/>`,
|
|
12
|
+
bell: `<path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9M10.3 21a1.94 1.94 0 0 0 3.4 0"/>`,
|
|
13
|
+
check: `<path d="M20 6 9 17l-5-5"/>`,
|
|
14
|
+
chevronDown: `<path d="m6 9 6 6 6-6"/>`,
|
|
15
|
+
chevronLeft: `<path d="m15 18-6-6 6-6"/>`,
|
|
16
|
+
chevronRight: `<path d="m9 18 6-6-6-6"/>`,
|
|
17
|
+
chevronsUpDown: `<path d="m7 15 5 5 5-5M7 9l5-5 5 5"/>`,
|
|
18
|
+
circleCheck: `<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>`,
|
|
19
|
+
circleX: `<circle cx="12" cy="12" r="10"/><path d="m15 9-6 6M9 9l6 6"/>`,
|
|
20
|
+
close: `<path d="M18 6 6 18M6 6l12 12"/>`,
|
|
21
|
+
copy: `<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>`,
|
|
22
|
+
download: `<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/>`,
|
|
23
|
+
externalLink: `<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14 21 3"/>`,
|
|
24
|
+
fileQuestion: `<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4M9.1 11.8a3 3 0 0 1 5.8 1c0 .9-.6 1.4-1.1 1.8-.4.3-.8.7-.8 1.4M12 19h.01"/>`,
|
|
25
|
+
gripHorizontal: `<circle cx="12" cy="9" r="1"/><circle cx="19" cy="9" r="1"/><circle cx="5" cy="9" r="1"/><circle cx="12" cy="15" r="1"/><circle cx="19" cy="15" r="1"/><circle cx="5" cy="15" r="1"/>`,
|
|
26
|
+
gripVertical: `<circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/>`,
|
|
27
|
+
hardDrive: `<rect width="20" height="8" x="2" y="14" rx="2"/><path d="M6 18h.01M10 18h.01M2 14L5 3h14l3 11"/>`,
|
|
28
|
+
image: `<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>`,
|
|
29
|
+
imageUpscale: `<path d="M16 3H3v13h13V3z"/><path d="M21 21v-4a2 2 0 0 0-2-2h-3M21 11V9M21 5a2 2 0 0 0-2-2h-1"/>`,
|
|
30
|
+
info: `<circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/>`,
|
|
31
|
+
layers: `<path d="m12 3-10 5L12 13l10-5-10-5Z"/><path d="M2 17l10 5 10-5M2 12l10 5 10-5"/>`,
|
|
32
|
+
list: `<line x1="8" x2="21" y1="6" y2="6"/><line x1="8" x2="21" y1="12" y2="12"/><line x1="8" x2="21" y1="18" y2="18"/><line x1="3" x2="3.01" y1="6" y2="6"/><line x1="3" x2="3.01" y1="12" y2="12"/><line x1="3" x2="3.01" y1="18" y2="18"/>`,
|
|
33
|
+
loaderCircle: `<path d="M21 12a9 9 0 1 1-6.219-8.56"/>`,
|
|
34
|
+
moon: `<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>`,
|
|
35
|
+
panelLeft: `<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><path d="M9 3v18"/>`,
|
|
36
|
+
play: `<polygon points="6 3 20 12 6 21 6 3"/>`,
|
|
37
|
+
quote: `<path d="M3 21c3 0 7-1 7-8V5c0-1.25-.75-2-2-2H4c-1.25 0-2 .75-2 2v6c0 1.25.75 2 2 2h3c0 4-3 6-3 6Zm11 0c3 0 7-1 7-8V5c0-1.25-.75-2-2-2h-4c-1.25 0-2 .75-2 2v6c0 1.25.75 2 2 2h3c0 4-3 6-3 6Z"/>`,
|
|
38
|
+
search: `<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>`,
|
|
39
|
+
share: `<circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="m8.59 13.51 6.83 3.98M15.41 6.51l-6.82 3.98"/>`,
|
|
40
|
+
sun: `<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/>`,
|
|
41
|
+
uploadCloud: `<path d="M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242M12 12v9M9 15l3-3 3 3"/>`,
|
|
42
|
+
user: `<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>`,
|
|
43
|
+
star: `<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>`,
|
|
44
|
+
lock: `<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>`,
|
|
45
|
+
eye: `<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0z"/><circle cx="12" cy="12" r="3"/>`,
|
|
46
|
+
eyeOff: `<path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"/><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"/><path d="M17.479 17.499A10.75 10.75 0 0 1 2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.225-4.22"/><line x1="2" x2="22" y1="2" y2="22"/>`,
|
|
47
|
+
arrowUp: `<path d="M12 19V5M5 12l7-7 7 7"/>`,
|
|
48
|
+
arrowDown: `<path d="M12 5v14M19 12l-7 7-7-7"/>`,
|
|
49
|
+
edit: `<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>`,
|
|
50
|
+
link: `<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>`,
|
|
51
|
+
plus: `<path d="M5 12h14M12 5v14"/>`,
|
|
52
|
+
trash: `<path d="M3 6h18M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6M10 11v6M14 11v6"/><path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/>`,
|
|
53
|
+
fileText: `<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8M16 13H8M16 17H8"/>`,
|
|
54
|
+
settings: `<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>`,
|
|
55
|
+
type: `<polyline points="4 7 4 4 20 4 20 7"/><line x1="9" x2="15" y1="20" y2="20"/><line x1="12" x2="12" y1="4" y2="20"/>`,
|
|
56
|
+
code: `<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>`,
|
|
57
|
+
film: `<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M7 3v18M17 3v18M3 7h4M17 7h4M3 12h18M3 17h4M17 17h4"/>`,
|
|
58
|
+
messageSquare: `<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>`,
|
|
59
|
+
bookOpen: `<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>`,
|
|
60
|
+
panelRight: `<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><path d="M15 3v18"/>`,
|
|
61
|
+
pin: `<path d="M12 17v5"/><path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"/>`,
|
|
62
|
+
ellipsisVertical: `<circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/>`,
|
|
63
|
+
arrowUpFromLine: `<path d="m18 9-6-6-6 6"/><path d="M12 3v14"/><path d="M5 21h14"/>`,
|
|
64
|
+
arrowDownToLine: `<path d="M12 17V3"/><path d="m6 11 6 6 6-6"/><path d="M5 21h14"/>`
|
|
65
|
+
};
|
|
66
|
+
//#endregion
|
|
67
|
+
export { getIconSvg as n, svg as r, ICONS as t };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { c as UIConfig } from "./types-DqAgCNcm.mjs";
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
interface RimelightUIPlugin {
|
|
4
|
+
name: string;
|
|
5
|
+
enforce?: "pre" | "post";
|
|
6
|
+
resolveId?: (id: string) => string | null | undefined;
|
|
7
|
+
load?: (id: string) => string | null | undefined;
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
}
|
|
10
|
+
type RimelightUIPlugins = (RimelightUIPlugin | RimelightUIPlugin[])[];
|
|
11
|
+
declare const ui: ({ unocss, ...cfg }?: UIConfig) => RimelightUIPlugins;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { RimelightUIPlugin, RimelightUIPlugins, ui };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import rimelightUiPreset from "./preset.mjs";
|
|
2
|
+
import UnoCSS from "@unocss/vite";
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
const ID = "virtual:rimelight/ui";
|
|
5
|
+
const ui = ({ unocss = {}, ...cfg } = {}) => [...UnoCSS({
|
|
6
|
+
...unocss,
|
|
7
|
+
presets: [rimelightUiPreset(cfg), ...unocss.presets || []],
|
|
8
|
+
content: {
|
|
9
|
+
...unocss.content,
|
|
10
|
+
pipeline: unocss.content?.pipeline !== false && {
|
|
11
|
+
...unocss.content?.pipeline,
|
|
12
|
+
include: [
|
|
13
|
+
/\.(vue|svelte|[jt]sx?|mdx?|astro|html)($|\?)/,
|
|
14
|
+
/[\\/](@rimelight\/(ui|cms)|packages\/(ui|cms))[\\/]/,
|
|
15
|
+
...[unocss.content?.pipeline?.include].flat().filter((v) => Boolean(v))
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}), {
|
|
20
|
+
name: "rimelight/ui",
|
|
21
|
+
enforce: "pre",
|
|
22
|
+
resolveId: (id) => id === ID ? `\0${ID}` : null,
|
|
23
|
+
load: (id) => id === `\0${ID}` ? `import "virtual:uno.css";\nexport default ${JSON.stringify(cfg)};` : null
|
|
24
|
+
}];
|
|
25
|
+
//#endregion
|
|
26
|
+
export { ui };
|
package/dist/preset.mjs
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { n as getIconSvg } from "./icons.raw-CjAuL2Sc.mjs";
|
|
2
|
+
import { presetIcons, presetTypography, presetWind4 } from "unocss";
|
|
3
|
+
//#region src/preset.ts
|
|
4
|
+
const PALETTES = {
|
|
5
|
+
neutral: [0, 0],
|
|
6
|
+
primary: [.21, 260],
|
|
7
|
+
secondary: [.18, 70],
|
|
8
|
+
info: [.24, 260],
|
|
9
|
+
success: [.2, 150],
|
|
10
|
+
warning: [.17, 86],
|
|
11
|
+
error: [.24, 25],
|
|
12
|
+
commentary: [.29, 322],
|
|
13
|
+
ideation: [.28, 293],
|
|
14
|
+
source: [.13, 215]
|
|
15
|
+
};
|
|
16
|
+
const SHADE_ENTRIES = Object.entries({
|
|
17
|
+
"50": [
|
|
18
|
+
.985,
|
|
19
|
+
.1,
|
|
20
|
+
.145,
|
|
21
|
+
.2
|
|
22
|
+
],
|
|
23
|
+
"100": [
|
|
24
|
+
.965,
|
|
25
|
+
.25,
|
|
26
|
+
.2,
|
|
27
|
+
.35
|
|
28
|
+
],
|
|
29
|
+
"200": [
|
|
30
|
+
.925,
|
|
31
|
+
.45,
|
|
32
|
+
.28,
|
|
33
|
+
.55
|
|
34
|
+
],
|
|
35
|
+
"300": [
|
|
36
|
+
.85,
|
|
37
|
+
.7,
|
|
38
|
+
.35,
|
|
39
|
+
.75
|
|
40
|
+
],
|
|
41
|
+
"400": [
|
|
42
|
+
.72,
|
|
43
|
+
.9,
|
|
44
|
+
.44,
|
|
45
|
+
.9
|
|
46
|
+
],
|
|
47
|
+
"500": [
|
|
48
|
+
.55,
|
|
49
|
+
1,
|
|
50
|
+
.53,
|
|
51
|
+
1
|
|
52
|
+
],
|
|
53
|
+
"600": [
|
|
54
|
+
.44,
|
|
55
|
+
.9,
|
|
56
|
+
.61,
|
|
57
|
+
.85
|
|
58
|
+
],
|
|
59
|
+
"700": [
|
|
60
|
+
.35,
|
|
61
|
+
.75,
|
|
62
|
+
.69,
|
|
63
|
+
.7
|
|
64
|
+
],
|
|
65
|
+
"800": [
|
|
66
|
+
.27,
|
|
67
|
+
.6,
|
|
68
|
+
.77,
|
|
69
|
+
.55
|
|
70
|
+
],
|
|
71
|
+
"900": [
|
|
72
|
+
.2,
|
|
73
|
+
.45,
|
|
74
|
+
.86,
|
|
75
|
+
.4
|
|
76
|
+
],
|
|
77
|
+
"950": [
|
|
78
|
+
.145,
|
|
79
|
+
.3,
|
|
80
|
+
.93,
|
|
81
|
+
.25
|
|
82
|
+
]
|
|
83
|
+
});
|
|
84
|
+
const INTENTS = {
|
|
85
|
+
default: {
|
|
86
|
+
text: "700",
|
|
87
|
+
bg: "50",
|
|
88
|
+
border: "200",
|
|
89
|
+
ring: "300"
|
|
90
|
+
},
|
|
91
|
+
muted: {
|
|
92
|
+
text: "600",
|
|
93
|
+
bg: "100",
|
|
94
|
+
border: "200",
|
|
95
|
+
ring: "300"
|
|
96
|
+
},
|
|
97
|
+
elevated: {
|
|
98
|
+
text: "800",
|
|
99
|
+
bg: "100",
|
|
100
|
+
border: "200",
|
|
101
|
+
ring: "400"
|
|
102
|
+
},
|
|
103
|
+
accented: {
|
|
104
|
+
text: "900",
|
|
105
|
+
bg: "200",
|
|
106
|
+
border: "300",
|
|
107
|
+
ring: "500"
|
|
108
|
+
},
|
|
109
|
+
dimmed: {
|
|
110
|
+
text: "500",
|
|
111
|
+
bg: "50",
|
|
112
|
+
border: "300",
|
|
113
|
+
ring: "400"
|
|
114
|
+
},
|
|
115
|
+
toned: {
|
|
116
|
+
text: "800",
|
|
117
|
+
bg: "700",
|
|
118
|
+
border: "600",
|
|
119
|
+
ring: "900"
|
|
120
|
+
},
|
|
121
|
+
highlighted: {
|
|
122
|
+
text: "950",
|
|
123
|
+
bg: "200",
|
|
124
|
+
border: "800",
|
|
125
|
+
ring: "950"
|
|
126
|
+
},
|
|
127
|
+
inverted: {
|
|
128
|
+
text: "50",
|
|
129
|
+
bg: "950",
|
|
130
|
+
border: "800",
|
|
131
|
+
ring: "700"
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const createThemeShades = (name) => ({
|
|
135
|
+
DEFAULT: `var(--rl-${name}-500)`,
|
|
136
|
+
...Object.fromEntries(SHADE_ENTRIES.map(([s]) => [s, `var(--rl-${name}-${s})`]))
|
|
137
|
+
});
|
|
138
|
+
const createOklchShadeGetter = ([c, h]) => {
|
|
139
|
+
const oklch = (l, factor) => `oklch(${l} ${(factor * c).toFixed(3)} ${h})`;
|
|
140
|
+
return (_, [l1, c1, l2, c2]) => [oklch(l1, c1), oklch(l2, c2)];
|
|
141
|
+
};
|
|
142
|
+
const createCustomShadeGetter = (val) => {
|
|
143
|
+
const isSplit = "light" in val || "dark" in val;
|
|
144
|
+
const light = (isSplit ? val.light : val) ?? {};
|
|
145
|
+
const dark = (isSplit ? val.dark : light) ?? light;
|
|
146
|
+
const fallback = light["500"] ?? Object.values(light)[0] ?? "oklch(0.55 0.15 0)";
|
|
147
|
+
return (s) => [light[s] ?? fallback, dark[s] ?? fallback];
|
|
148
|
+
};
|
|
149
|
+
function resolveTokens(custom = {}) {
|
|
150
|
+
const themeColors = {};
|
|
151
|
+
const tokenVarLines = [];
|
|
152
|
+
for (const [name, val] of Object.entries({
|
|
153
|
+
...PALETTES,
|
|
154
|
+
...custom
|
|
155
|
+
})) {
|
|
156
|
+
themeColors[name] = createThemeShades(name);
|
|
157
|
+
const getShade = Array.isArray(val) ? createOklchShadeGetter(val) : createCustomShadeGetter(val);
|
|
158
|
+
for (const [s, coords] of SHADE_ENTRIES) {
|
|
159
|
+
const [light, dark] = getShade(s, coords);
|
|
160
|
+
tokenVarLines.push(`--rl-${name}-${s}: light-dark(${light}, ${dark});`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
themeColors,
|
|
165
|
+
tokenVarLines
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function rimelightUiPreset({ colors, icons, presets = {} } = {}) {
|
|
169
|
+
const { themeColors, tokenVarLines } = resolveTokens(colors);
|
|
170
|
+
return {
|
|
171
|
+
name: "rimelight-ui",
|
|
172
|
+
outputToCssLayers: true,
|
|
173
|
+
safelist: [...Object.keys(themeColors).map((c) => `rl-color-${c}`), ...Object.values(icons ?? {}).filter((v) => typeof v === "string" && v.startsWith("i-"))],
|
|
174
|
+
presets: [
|
|
175
|
+
presets.wind !== false && presetWind4(),
|
|
176
|
+
presets.typography !== false && presetTypography(),
|
|
177
|
+
presets.icons !== false && presetIcons({ collections: { rl: getIconSvg } }),
|
|
178
|
+
{
|
|
179
|
+
name: "rimelight-theme",
|
|
180
|
+
theme: {
|
|
181
|
+
spacing: { md: "1rem" },
|
|
182
|
+
colors: themeColors
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
].filter(Boolean),
|
|
186
|
+
shortcuts: [[/^(text|bg|ring|border)-([a-z]+)(?:\/(\d+))?$/, ([, p, n, o]) => {
|
|
187
|
+
const s = INTENTS[n]?.[p];
|
|
188
|
+
if (!s) return;
|
|
189
|
+
const base = `${p}-neutral-${s}${o ? `/${o}` : ""}`;
|
|
190
|
+
return p === "bg" && n === "inverted" ? `${base} text-neutral-50` : base;
|
|
191
|
+
}]],
|
|
192
|
+
rules: [[/^rl-color-([\w-]+)$/, ([, c]) => {
|
|
193
|
+
const v500 = `var(--rl-${c}-500)`;
|
|
194
|
+
const v600 = `var(--rl-${c}-600)`;
|
|
195
|
+
return {
|
|
196
|
+
"--rl-bg": v500,
|
|
197
|
+
"--rl-ring": v500,
|
|
198
|
+
"--rl-border": v500,
|
|
199
|
+
"--rl-bg-hover": v600,
|
|
200
|
+
"--rl-text": v600
|
|
201
|
+
};
|
|
202
|
+
}]],
|
|
203
|
+
preflights: [{ getCSS: () => `:root {
|
|
204
|
+
color-scheme: light dark;
|
|
205
|
+
--rl-header-height: 4rem;
|
|
206
|
+
--rl-container: 90rem;
|
|
207
|
+
${tokenVarLines.join("\n ")}
|
|
208
|
+
}
|
|
209
|
+
[data-theme="dark"] { color-scheme: dark; }
|
|
210
|
+
[data-theme="light"] { color-scheme: light; }
|
|
211
|
+
body { background-color: var(--rl-neutral-50); color: var(--rl-neutral-950); }` }]
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
//#endregion
|
|
215
|
+
export { PALETTES, rimelightUiPreset as default };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { n as ClassValue, s as ThemeConfig } from "./types-DqAgCNcm.mjs";
|
|
2
|
+
//#region src/resolver.d.ts
|
|
3
|
+
declare function cx(...args: ClassValue[]): string;
|
|
4
|
+
declare function defineTheme<const S extends string>(name: string, themeConfig: ThemeConfig<S>): (props?: any) => Record<S, string>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { cx, defineTheme };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import uiConfig from "virtual:rimelight/ui";
|
|
2
|
+
//#region src/resolver.ts
|
|
3
|
+
function cx(...args) {
|
|
4
|
+
let str = "";
|
|
5
|
+
for (let i = 0; i < args.length; i++) {
|
|
6
|
+
const val = args[i];
|
|
7
|
+
if (!val) continue;
|
|
8
|
+
if (typeof val === "string" || typeof val === "number") str += (str ? " " : "") + val;
|
|
9
|
+
else if (Array.isArray(val)) {
|
|
10
|
+
if (val.length) {
|
|
11
|
+
const inner = cx(...val);
|
|
12
|
+
if (inner) str += (str ? " " : "") + inner;
|
|
13
|
+
}
|
|
14
|
+
} else if (typeof val === "object") {
|
|
15
|
+
for (const k in val) if (val[k]) str += (str ? " " : "") + k;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return str;
|
|
19
|
+
}
|
|
20
|
+
function defineTheme(name, themeConfig) {
|
|
21
|
+
const custom = uiConfig?.components?.themes?.[name];
|
|
22
|
+
const slots = custom?.slots ?? themeConfig.slots ?? ["root"];
|
|
23
|
+
const rootSlot = slots.includes("root") ? "root" : slots[0] || "root";
|
|
24
|
+
if (uiConfig?.unstyled) return (props = {}) => {
|
|
25
|
+
const res = {};
|
|
26
|
+
const hasClass = props.class || props.className;
|
|
27
|
+
for (let i = 0; i < slots.length; i++) {
|
|
28
|
+
const slot = slots[i];
|
|
29
|
+
const base = slot === rootSlot && hasClass ? cx(props.class, props.className) : "";
|
|
30
|
+
const fn = props.ui?.[slot];
|
|
31
|
+
res[slot] = typeof fn === "function" ? fn(base) : cx(base, fn);
|
|
32
|
+
}
|
|
33
|
+
return res;
|
|
34
|
+
};
|
|
35
|
+
const autoColor = (custom?.variants ?? themeConfig.variants)?.color === "auto";
|
|
36
|
+
const defaultVariants = {
|
|
37
|
+
...themeConfig.defaultVariants,
|
|
38
|
+
...custom?.defaultVariants
|
|
39
|
+
};
|
|
40
|
+
const compiledCV = [...themeConfig.compoundVariants ?? [], ...custom?.compoundVariants ?? []].map((cv) => {
|
|
41
|
+
const { classNames, class: cls, ...rest } = cv;
|
|
42
|
+
const matchers = [];
|
|
43
|
+
for (const k in rest) matchers.push({
|
|
44
|
+
key: k,
|
|
45
|
+
exp: rest[k]
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
matchers,
|
|
49
|
+
cls: classNames || cls
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
const baseMap = {};
|
|
53
|
+
for (let i = 0; i < slots.length; i++) {
|
|
54
|
+
const s = slots[i];
|
|
55
|
+
baseMap[s] = cx(themeConfig.base?.[s], custom?.base?.[s]);
|
|
56
|
+
}
|
|
57
|
+
const variants = { ...themeConfig.variants };
|
|
58
|
+
if (custom?.variants) for (const k in custom.variants) variants[k] = {
|
|
59
|
+
...variants[k],
|
|
60
|
+
...custom.variants[k]
|
|
61
|
+
};
|
|
62
|
+
const variantKeys = Object.keys(variants).filter((k) => !(k === "color" && autoColor));
|
|
63
|
+
return (props = {}) => {
|
|
64
|
+
const res = {};
|
|
65
|
+
for (let i = 0; i < slots.length; i++) res[slots[i]] = baseMap[slots[i]] || "";
|
|
66
|
+
const values = {
|
|
67
|
+
...defaultVariants,
|
|
68
|
+
...props
|
|
69
|
+
};
|
|
70
|
+
const color = autoColor ? props.color ?? defaultVariants.color : void 0;
|
|
71
|
+
for (let k = 0; k < variantKeys.length; k++) {
|
|
72
|
+
const key = variantKeys[k];
|
|
73
|
+
const selected = values[key];
|
|
74
|
+
if (selected != null && variants[key]?.[selected]) {
|
|
75
|
+
const layer = variants[key][selected];
|
|
76
|
+
for (let i = 0; i < slots.length; i++) {
|
|
77
|
+
const s = slots[i];
|
|
78
|
+
const l = layer[s];
|
|
79
|
+
if (l) res[s] = res[s] ? `${res[s]} ${cx(l)}` : cx(l);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (compiledCV.length) for (let c = 0; c < compiledCV.length; c++) {
|
|
84
|
+
const { matchers, cls } = compiledCV[c];
|
|
85
|
+
if (!cls) continue;
|
|
86
|
+
let match = true;
|
|
87
|
+
for (let m = 0; m < matchers.length; m++) {
|
|
88
|
+
const { key, exp } = matchers[m];
|
|
89
|
+
const actual = values[key];
|
|
90
|
+
if (Array.isArray(exp) ? !exp.includes(actual) : actual !== exp) {
|
|
91
|
+
match = false;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (match) for (let i = 0; i < slots.length; i++) {
|
|
96
|
+
const s = slots[i];
|
|
97
|
+
const l = cls[s];
|
|
98
|
+
if (l) res[s] = res[s] ? `${res[s]} ${cx(l)}` : cx(l);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (let i = 0; i < slots.length; i++) {
|
|
102
|
+
const slot = slots[i];
|
|
103
|
+
let slotClass = res[slot];
|
|
104
|
+
if (slot === rootSlot) {
|
|
105
|
+
if (color) slotClass = slotClass ? `${slotClass} rl-color-${color}` : `rl-color-${color}`;
|
|
106
|
+
const extra = cx(props.class, props.className);
|
|
107
|
+
if (extra) slotClass = slotClass ? `${slotClass} ${extra}` : extra;
|
|
108
|
+
}
|
|
109
|
+
const override = props.ui?.[slot];
|
|
110
|
+
res[slot] = typeof override === "function" ? override(slotClass) : cx(slotClass, override);
|
|
111
|
+
}
|
|
112
|
+
return res;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { cx, defineTheme };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Atom } from "./stores.mjs";
|
|
2
|
+
//#region src/shortcuts.d.ts
|
|
3
|
+
type Handler = (e: KeyboardEvent) => void;
|
|
4
|
+
interface ShortcutConfig {
|
|
5
|
+
handler: Handler;
|
|
6
|
+
usingInput?: boolean | string | undefined;
|
|
7
|
+
label?: string | undefined;
|
|
8
|
+
description?: string | undefined;
|
|
9
|
+
category?: string | undefined;
|
|
10
|
+
order?: number | undefined;
|
|
11
|
+
}
|
|
12
|
+
type ShortcutsConfig = Record<string, ShortcutConfig | Handler | false | null | undefined>;
|
|
13
|
+
interface ShortcutsOptions {
|
|
14
|
+
chainDelay?: number | undefined;
|
|
15
|
+
}
|
|
16
|
+
interface RegisteredShortcut {
|
|
17
|
+
id: string;
|
|
18
|
+
keys: string[];
|
|
19
|
+
label?: string | undefined;
|
|
20
|
+
description?: string | undefined;
|
|
21
|
+
category?: string | undefined;
|
|
22
|
+
order?: number | undefined;
|
|
23
|
+
}
|
|
24
|
+
declare const normalizeModifier: (m: string) => string;
|
|
25
|
+
declare const formatShortcutKeys: (k: string) => string[];
|
|
26
|
+
declare const activeShortcutsStore: Atom<RegisteredShortcut[]>;
|
|
27
|
+
declare function defineShortcuts(config: ShortcutsConfig, options?: ShortcutsOptions): () => void;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { Handler, RegisteredShortcut, ShortcutConfig, ShortcutsConfig, ShortcutsOptions, activeShortcutsStore, defineShortcuts, formatShortcutKeys, normalizeModifier };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { atom } from "./stores.mjs";
|
|
2
|
+
//#region src/shortcuts.ts
|
|
3
|
+
const isMac = typeof navigator !== "undefined" && /Mac|iP/.test(navigator.userAgent);
|
|
4
|
+
const KEYS = {
|
|
5
|
+
ctrl: "Ctrl",
|
|
6
|
+
meta: isMac ? "⌘" : "Ctrl",
|
|
7
|
+
alt: isMac ? "⌥" : "Alt",
|
|
8
|
+
shift: isMac ? "⇧" : "Shift",
|
|
9
|
+
enter: "↵",
|
|
10
|
+
delete: "⌦",
|
|
11
|
+
backspace: "⌫",
|
|
12
|
+
escape: "Esc",
|
|
13
|
+
tab: "⇥",
|
|
14
|
+
space: "Space",
|
|
15
|
+
arrowup: "↑",
|
|
16
|
+
arrowdown: "↓",
|
|
17
|
+
arrowleft: "←",
|
|
18
|
+
arrowright: "→"
|
|
19
|
+
};
|
|
20
|
+
const MODS = {
|
|
21
|
+
cmd: "meta",
|
|
22
|
+
command: "meta",
|
|
23
|
+
control: "ctrl",
|
|
24
|
+
opt: "alt",
|
|
25
|
+
option: "alt"
|
|
26
|
+
};
|
|
27
|
+
const normalizeModifier = (m) => MODS[m.toLowerCase()] || m.toLowerCase();
|
|
28
|
+
const formatShortcutKeys = (k) => k.split(/[_-]/).map((p) => {
|
|
29
|
+
const norm = normalizeModifier(p);
|
|
30
|
+
return KEYS[norm] ?? (p ? p[0].toUpperCase() + p.slice(1) : "");
|
|
31
|
+
});
|
|
32
|
+
const activeShortcutsStore = atom([]);
|
|
33
|
+
const isUsingInput = (el) => {
|
|
34
|
+
const target = el?.shadowRoot?.activeElement || el;
|
|
35
|
+
return target && (/INPUT|TEXTAREA|SELECT/.test(target.tagName) || target.isContentEditable) ? target.getAttribute("name") || true : false;
|
|
36
|
+
};
|
|
37
|
+
const isEnabled = (s, input) => s.usingInput === true || (s.usingInput ? input === s.usingInput : !input);
|
|
38
|
+
const normalizeCombo = (combo) => {
|
|
39
|
+
const parts = combo.toLowerCase().split("_");
|
|
40
|
+
let meta = "";
|
|
41
|
+
let ctrl = "";
|
|
42
|
+
let alt = "";
|
|
43
|
+
let shift = "";
|
|
44
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
45
|
+
const m = MODS[parts[i]] || parts[i];
|
|
46
|
+
if (m === "meta") meta = "meta_";
|
|
47
|
+
else if (m === "ctrl") ctrl = "ctrl_";
|
|
48
|
+
else if (m === "alt") alt = "alt_";
|
|
49
|
+
else if (m === "shift") shift = "shift_";
|
|
50
|
+
}
|
|
51
|
+
return `${meta}${ctrl}${alt}${shift}${parts[parts.length - 1] || ""}`;
|
|
52
|
+
};
|
|
53
|
+
function defineShortcuts(config, options = {}) {
|
|
54
|
+
if (typeof window === "undefined") return () => {};
|
|
55
|
+
const map = /* @__PURE__ */ new Map();
|
|
56
|
+
const reg = [];
|
|
57
|
+
for (const [k, cfg] of Object.entries(config)) {
|
|
58
|
+
if (!cfg) continue;
|
|
59
|
+
const obj = typeof cfg === "object" ? cfg : null;
|
|
60
|
+
const handler = obj ? obj.handler : cfg;
|
|
61
|
+
if (typeof handler !== "function") continue;
|
|
62
|
+
const key = k.includes("-") && k !== "-" && !k.includes("_") ? k.toLowerCase() : normalizeCombo(k);
|
|
63
|
+
map.set(key, {
|
|
64
|
+
handler,
|
|
65
|
+
usingInput: obj?.usingInput
|
|
66
|
+
});
|
|
67
|
+
if (obj?.label || obj?.description) reg.push({
|
|
68
|
+
id: `${obj.category || "system"}-${k}`,
|
|
69
|
+
keys: formatShortcutKeys(k),
|
|
70
|
+
category: obj.category || "system",
|
|
71
|
+
label: obj.label,
|
|
72
|
+
description: obj.description,
|
|
73
|
+
order: obj.order
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const ids = new Set(reg.map((i) => i.id));
|
|
77
|
+
if (ids.size) activeShortcutsStore.set(activeShortcutsStore.get().filter((i) => !ids.has(i.id)).concat(reg));
|
|
78
|
+
const buffer = [];
|
|
79
|
+
let timer;
|
|
80
|
+
const onKeyDown = (e) => {
|
|
81
|
+
if (!e.key || e.isComposing) return;
|
|
82
|
+
const key = e.key === " " ? "space" : e.key.toLowerCase();
|
|
83
|
+
const codeKey = e.code ? e.code.replace(/^Key/, "").replace(/^Digit/, "").toLowerCase() : "";
|
|
84
|
+
const input = isUsingInput(typeof document !== "undefined" ? document.activeElement : null);
|
|
85
|
+
buffer.push(key);
|
|
86
|
+
if (buffer.length > 2) buffer.shift();
|
|
87
|
+
clearTimeout(timer);
|
|
88
|
+
if (buffer.length === 2) {
|
|
89
|
+
const chainedMatch = map.get(buffer.join("-"));
|
|
90
|
+
if (chainedMatch && isEnabled(chainedMatch, input)) {
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
chainedMatch.handler(e);
|
|
93
|
+
buffer.length = 0;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const keysToCheck = Array.from(new Set([key, codeKey].filter(Boolean)));
|
|
98
|
+
for (const k of keysToCheck) {
|
|
99
|
+
const sig = `${e.metaKey ? "meta_" : ""}${e.ctrlKey ? "ctrl_" : ""}${e.altKey ? "alt_" : ""}${e.shiftKey ? "shift_" : ""}${k}`;
|
|
100
|
+
const primarySig = !isMac && e.ctrlKey && !e.metaKey ? `meta_${e.altKey ? "alt_" : ""}${e.shiftKey ? "shift_" : ""}${k}` : sig;
|
|
101
|
+
const match = map.get(sig) || map.get(primarySig) || map.get(k);
|
|
102
|
+
if (match && isEnabled(match, input)) {
|
|
103
|
+
e.preventDefault();
|
|
104
|
+
match.handler(e);
|
|
105
|
+
buffer.length = 0;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
timer = setTimeout(() => void (buffer.length = 0), options.chainDelay ?? 800);
|
|
110
|
+
};
|
|
111
|
+
window.addEventListener("keydown", onKeyDown);
|
|
112
|
+
return () => {
|
|
113
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
114
|
+
clearTimeout(timer);
|
|
115
|
+
if (ids.size) activeShortcutsStore.set(activeShortcutsStore.get().filter((i) => !ids.has(i.id)));
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { activeShortcutsStore, defineShortcuts, formatShortcutKeys, normalizeModifier };
|
package/dist/stores.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/stores.ts
|
|
2
|
+
function atom(initial) {
|
|
3
|
+
let val = initial;
|
|
4
|
+
const subs = /* @__PURE__ */ new Set();
|
|
5
|
+
return {
|
|
6
|
+
get: () => val,
|
|
7
|
+
set: (next) => {
|
|
8
|
+
val = next;
|
|
9
|
+
subs.forEach((fn) => fn(val));
|
|
10
|
+
},
|
|
11
|
+
subscribe: (fn) => {
|
|
12
|
+
subs.add(fn);
|
|
13
|
+
fn(val);
|
|
14
|
+
return () => subs.delete(fn);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { atom };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { n as RimelightIcons } from "./icons--RzV1RTU.mjs";
|
|
2
|
+
import { Preset, UserConfig } from "unocss";
|
|
3
|
+
//#region src/preset.d.ts
|
|
4
|
+
declare const PALETTES: {
|
|
5
|
+
readonly neutral: readonly [0, 0];
|
|
6
|
+
readonly primary: readonly [0.21, 260];
|
|
7
|
+
readonly secondary: readonly [0.18, 70];
|
|
8
|
+
readonly info: readonly [0.24, 260];
|
|
9
|
+
readonly success: readonly [0.2, 150];
|
|
10
|
+
readonly warning: readonly [0.17, 86];
|
|
11
|
+
readonly error: readonly [0.24, 25];
|
|
12
|
+
readonly commentary: readonly [0.29, 322];
|
|
13
|
+
readonly ideation: readonly [0.28, 293];
|
|
14
|
+
readonly source: readonly [0.13, 215];
|
|
15
|
+
};
|
|
16
|
+
declare function rimelightUiPreset({ colors, icons, presets }?: UIConfig): Preset;
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/types.d.ts
|
|
19
|
+
type Theme = "light" | "dark";
|
|
20
|
+
type BuiltinThemeColor = keyof typeof PALETTES;
|
|
21
|
+
type ThemeColor = BuiltinThemeColor | (string & {});
|
|
22
|
+
type ClassValue = string | number | boolean | undefined | null | {
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
} | ClassValue[];
|
|
25
|
+
interface ThemeConfig<S extends string = string> {
|
|
26
|
+
slots?: readonly S[] | S[];
|
|
27
|
+
base?: Partial<Record<S, ClassValue>>;
|
|
28
|
+
variants?: Record<string, any>;
|
|
29
|
+
compoundVariants?: Array<Record<string, any> & {
|
|
30
|
+
classNames?: Partial<Record<S, ClassValue>>;
|
|
31
|
+
class?: Partial<Record<S, ClassValue>>;
|
|
32
|
+
}>;
|
|
33
|
+
defaultVariants?: Record<string, any>;
|
|
34
|
+
}
|
|
35
|
+
type ColorModeInput = [chroma: number, hue: number] | readonly [chroma: number, hue: number] | Record<string, string> | {
|
|
36
|
+
light?: Record<string, string>;
|
|
37
|
+
dark?: Record<string, string>;
|
|
38
|
+
};
|
|
39
|
+
interface PresetOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Custom colors.
|
|
42
|
+
*/
|
|
43
|
+
colors?: Record<string, ColorModeInput>;
|
|
44
|
+
/**
|
|
45
|
+
* Global icon overrides mapping icon names to class names (e.g. `i-lucide-x`) or raw SVG strings.
|
|
46
|
+
*/
|
|
47
|
+
icons?: RimelightIcons;
|
|
48
|
+
/**
|
|
49
|
+
* Configure which built-in UnoCSS presets are enabled/disabled.
|
|
50
|
+
*/
|
|
51
|
+
presets?: {
|
|
52
|
+
wind?: boolean;
|
|
53
|
+
typography?: boolean;
|
|
54
|
+
icons?: boolean;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
interface UIConfig extends PresetOptions {
|
|
58
|
+
/**
|
|
59
|
+
* Whether to strip default theme classes from all components.
|
|
60
|
+
*/
|
|
61
|
+
unstyled?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Configuration for keyboard shortcuts.
|
|
64
|
+
*/
|
|
65
|
+
shortcuts?: {
|
|
66
|
+
categories?: Record<string, {
|
|
67
|
+
label: string;
|
|
68
|
+
}>;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Configuration for the Logo component variants.
|
|
72
|
+
*/
|
|
73
|
+
logos?: Record<string, string | Record<string, string | undefined>>;
|
|
74
|
+
/**
|
|
75
|
+
* Global component configuration overrides.
|
|
76
|
+
*/
|
|
77
|
+
components?: {
|
|
78
|
+
themes?: Record<string, ThemeConfig<string>>;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Custom UnoCSS configuration overrides.
|
|
82
|
+
*/
|
|
83
|
+
unocss?: UserConfig;
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { Theme as a, UIConfig as c, PresetOptions as i, PALETTES as l, ClassValue as n, ThemeColor as o, ColorModeInput as r, ThemeConfig as s, BuiltinThemeColor as t, rimelightUiPreset as u };
|
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as Theme, c as UIConfig, i as PresetOptions, n as ClassValue, o as ThemeColor, r as ColorModeInput, s as ThemeConfig, t as BuiltinThemeColor } from "./types-DqAgCNcm.mjs";
|
|
2
|
+
export { BuiltinThemeColor, ClassValue, ColorModeInput, PresetOptions, Theme, ThemeColor, ThemeConfig, UIConfig };
|
package/dist/types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rimelight/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.46",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Rimelight Entertainment's UI Package",
|
|
6
6
|
"homepage": "https://rimelight.com/docs",
|
|
@@ -16,30 +16,58 @@
|
|
|
16
16
|
"url": "git+https://github.com/Rimelight-Entertainment/rimelight.git"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
|
+
"dist",
|
|
19
20
|
"src"
|
|
20
21
|
],
|
|
21
22
|
"type": "module",
|
|
22
23
|
"exports": {
|
|
23
|
-
".":
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.mts",
|
|
26
|
+
"import": "./dist/index.mjs"
|
|
27
|
+
},
|
|
28
|
+
"./preset": {
|
|
29
|
+
"types": "./dist/preset.d.mts",
|
|
30
|
+
"import": "./dist/preset.mjs"
|
|
31
|
+
},
|
|
32
|
+
"./resolver": {
|
|
33
|
+
"types": "./dist/resolver.d.mts",
|
|
34
|
+
"import": "./dist/resolver.mjs"
|
|
35
|
+
},
|
|
36
|
+
"./shortcuts": {
|
|
37
|
+
"types": "./dist/shortcuts.d.mts",
|
|
38
|
+
"import": "./dist/shortcuts.mjs"
|
|
39
|
+
},
|
|
40
|
+
"./stores": {
|
|
41
|
+
"types": "./dist/stores.d.mts",
|
|
42
|
+
"import": "./dist/stores.mjs"
|
|
43
|
+
},
|
|
44
|
+
"./types": {
|
|
45
|
+
"types": "./dist/types.d.mts",
|
|
46
|
+
"import": "./dist/types.mjs"
|
|
47
|
+
},
|
|
48
|
+
"./icons": {
|
|
49
|
+
"types": "./dist/icons.d.mts",
|
|
50
|
+
"import": "./dist/icons.mjs"
|
|
51
|
+
},
|
|
24
52
|
"./*": "./src/*"
|
|
25
53
|
},
|
|
26
54
|
"publishConfig": {
|
|
27
55
|
"access": "public"
|
|
28
56
|
},
|
|
29
57
|
"dependencies": {
|
|
30
|
-
"@unocss/vite": "66.
|
|
31
|
-
"unocss": "66.
|
|
58
|
+
"@unocss/vite": "66.10.0",
|
|
59
|
+
"unocss": "66.10.0"
|
|
32
60
|
},
|
|
33
61
|
"devDependencies": {
|
|
34
62
|
"@astrojs/check": "0.9.10",
|
|
35
63
|
"@astrojs/solid-js": "7.0.2",
|
|
36
64
|
"@astrojs/ts-plugin": "1.10.11",
|
|
37
65
|
"@astrojs/vue": "7.0.2",
|
|
38
|
-
"@rimelight/config": "0.0.
|
|
39
|
-
"astro": "7.
|
|
66
|
+
"@rimelight/config": "0.0.4",
|
|
67
|
+
"astro": "7.3.1",
|
|
40
68
|
"solid-js": "1.9.15",
|
|
41
69
|
"typescript": "6.0.3",
|
|
42
|
-
"vue": "3.5.
|
|
70
|
+
"vue": "3.5.42"
|
|
43
71
|
},
|
|
44
72
|
"peerDependencies": {
|
|
45
73
|
"@astrojs/solid-js": ">=7.0.1",
|
|
@@ -66,6 +94,7 @@
|
|
|
66
94
|
"node": ">=26.7.0"
|
|
67
95
|
},
|
|
68
96
|
"scripts": {
|
|
97
|
+
"build": "vp pack",
|
|
69
98
|
"astro": "astro",
|
|
70
99
|
"check": "vp check --fix && astro check"
|
|
71
100
|
}
|
|
@@ -75,7 +75,7 @@ const RLSButton: Component<RLSButtonProps> = (allProps) => {
|
|
|
75
75
|
justify: props.justify,
|
|
76
76
|
block: props.block,
|
|
77
77
|
square: props.square !== undefined ? props.square : !props.label && !props.children,
|
|
78
|
-
rounded: props.rounded,
|
|
78
|
+
rounded: props.rounded ?? false,
|
|
79
79
|
leading: isLeading(),
|
|
80
80
|
trailing: isTrailing(),
|
|
81
81
|
loading: props.loading,
|
|
@@ -15,9 +15,6 @@ const classes = dashboardSidebarTheme({
|
|
|
15
15
|
...Astro.props,
|
|
16
16
|
collapsed: collapsible && collapsed
|
|
17
17
|
});
|
|
18
|
-
|
|
19
|
-
const collapsedWidth = "4rem";
|
|
20
|
-
const defaultWidth = "16rem";
|
|
21
18
|
---
|
|
22
19
|
|
|
23
20
|
<div
|
|
@@ -26,11 +23,10 @@ const defaultWidth = "16rem";
|
|
|
26
23
|
data-collapsible={collapsible ? "true" : "false"}
|
|
27
24
|
data-collapsed={collapsible && collapsed ? "true" : "false"}
|
|
28
25
|
data-slot="root"
|
|
29
|
-
class={classes.root}
|
|
26
|
+
class:list={[classes.root, className]}
|
|
30
27
|
{...rest}
|
|
31
|
-
style={`width: ${collapsible && collapsed ? collapsedWidth : defaultWidth}; min-width: ${collapsible && collapsed ? collapsedWidth : defaultWidth}; flex-shrink: 0; --width: ${defaultWidth}; --collapsed-width: ${collapsedWidth}`}
|
|
32
28
|
>
|
|
33
|
-
<div data-slot="header" class={classes.header}
|
|
29
|
+
<div data-slot="header" class={classes.header}>
|
|
34
30
|
<slot name="header" />
|
|
35
31
|
</div>
|
|
36
32
|
|
|
@@ -48,15 +44,15 @@ const defaultWidth = "16rem";
|
|
|
48
44
|
<div
|
|
49
45
|
data-dashboard-sidebar-mobile
|
|
50
46
|
data-slot="content"
|
|
51
|
-
class={classes.content
|
|
47
|
+
class:list={[classes.content, "fixed inset-y-0 left-0 z-50 w-72 max-w-[85vw] bg-default shadow-2xl border-e border-default transform -translate-x-full transition-transform duration-300 flex flex-col h-full"]}
|
|
52
48
|
>
|
|
53
|
-
<div data-slot="header" class={classes.header
|
|
49
|
+
<div data-slot="header" class:list={[classes.header, "sm:px-6 shrink-0"]} data-menu>
|
|
54
50
|
<slot name="header" />
|
|
55
51
|
</div>
|
|
56
|
-
<div data-slot="body" class={classes.body
|
|
52
|
+
<div data-slot="body" class:list={[classes.body, "sm:px-6 overflow-y-auto flex-1"]} data-menu>
|
|
57
53
|
<slot />
|
|
58
54
|
</div>
|
|
59
|
-
<div data-slot="footer" class={classes.footer
|
|
55
|
+
<div data-slot="footer" class:list={[classes.footer, "sm:px-6 shrink-0"]} data-menu>
|
|
60
56
|
<slot name="footer" />
|
|
61
57
|
</div>
|
|
62
58
|
</div>
|
|
@@ -70,20 +66,34 @@ const defaultWidth = "16rem";
|
|
|
70
66
|
const mobilePanel = document.querySelector<HTMLElement>('[data-dashboard-sidebar-mobile]');
|
|
71
67
|
const overlay = document.querySelector<HTMLElement>('[data-dashboard-sidebar-overlay]');
|
|
72
68
|
|
|
73
|
-
const
|
|
69
|
+
const openMobile = () => {
|
|
70
|
+
if (!mobilePanel || !overlay) return;
|
|
71
|
+
mobilePanel.classList.remove('-translate-x-full');
|
|
72
|
+
mobilePanel.classList.add('translate-x-0');
|
|
73
|
+
overlay.classList.remove('hidden');
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const closeMobile = () => {
|
|
74
77
|
if (!mobilePanel || !overlay) return;
|
|
75
|
-
|
|
76
|
-
mobilePanel.classList.
|
|
77
|
-
overlay.classList.
|
|
78
|
+
mobilePanel.classList.add('-translate-x-full');
|
|
79
|
+
mobilePanel.classList.remove('translate-x-0');
|
|
80
|
+
overlay.classList.add('hidden');
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const toggleMobile = () => {
|
|
84
|
+
if (!mobilePanel) return;
|
|
85
|
+
if (mobilePanel.classList.contains('translate-x-0')) {
|
|
86
|
+
closeMobile();
|
|
87
|
+
} else {
|
|
88
|
+
openMobile();
|
|
89
|
+
}
|
|
78
90
|
};
|
|
79
91
|
|
|
80
92
|
const collapseSidebar = (val?: boolean) => {
|
|
81
93
|
if (!collapsible) return;
|
|
82
94
|
const isCollapsed = val !== undefined ? val : sidebar.dataset.collapsed !== 'true';
|
|
83
|
-
|
|
84
|
-
sidebar.
|
|
85
|
-
sidebar.style.minWidth = w;
|
|
86
|
-
sidebar.style.setProperty('--width', w);
|
|
95
|
+
sidebar.dataset.collapsed = isCollapsed ? 'true' : 'false';
|
|
96
|
+
sidebar.setAttribute('data-collapsed', isCollapsed ? 'true' : 'false');
|
|
87
97
|
|
|
88
98
|
document.querySelectorAll('[data-dashboard-toggle="collapse"]').forEach(btn => {
|
|
89
99
|
btn.querySelectorAll('[data-dashboard-collapse-icon]').forEach(el => {
|
|
@@ -92,16 +102,32 @@ const defaultWidth = "16rem";
|
|
|
92
102
|
});
|
|
93
103
|
};
|
|
94
104
|
|
|
95
|
-
|
|
105
|
+
const handleClick = (e: MouseEvent) => {
|
|
96
106
|
const target = e.target as Element | null;
|
|
97
|
-
|
|
107
|
+
if (!target) return;
|
|
108
|
+
|
|
109
|
+
// Toggle buttons (mobile drawer + collapse)
|
|
110
|
+
const toggle = target.closest<HTMLElement>('[data-dashboard-toggle]');
|
|
98
111
|
if (toggle) {
|
|
99
112
|
const side = toggle.dataset.dashboardToggle;
|
|
100
113
|
if (side === 'mobile') toggleMobile();
|
|
101
114
|
if (side === 'collapse') collapseSidebar();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Backdrop overlay click
|
|
119
|
+
if (target.closest('[data-dashboard-sidebar-overlay]')) {
|
|
120
|
+
closeMobile();
|
|
121
|
+
return;
|
|
102
122
|
}
|
|
103
123
|
|
|
104
|
-
|
|
124
|
+
// Close the mobile drawer when clicking a navigation link inside it
|
|
125
|
+
if (target.closest('[data-dashboard-sidebar-mobile] a')) {
|
|
126
|
+
closeMobile();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const navItem = target.closest<HTMLElement>('[data-dashboard-nav]');
|
|
105
131
|
if (navItem) {
|
|
106
132
|
const container = navItem.closest('[data-dashboard-nav-container]');
|
|
107
133
|
if (container) {
|
|
@@ -113,10 +139,13 @@ const defaultWidth = "16rem";
|
|
|
113
139
|
navItem.classList.add('bg-muted', 'text-highlighted');
|
|
114
140
|
}
|
|
115
141
|
}
|
|
116
|
-
}
|
|
142
|
+
};
|
|
117
143
|
|
|
118
|
-
|
|
144
|
+
const handleKey = (e: KeyboardEvent) => {
|
|
145
|
+
if (e.key === 'Escape') closeMobile();
|
|
146
|
+
};
|
|
119
147
|
|
|
120
|
-
(
|
|
148
|
+
document.addEventListener('click', handleClick);
|
|
149
|
+
document.addEventListener('keydown', handleKey);
|
|
121
150
|
})();
|
|
122
151
|
</script>
|
|
@@ -3,12 +3,12 @@ import { defineTheme } from "../../resolver"
|
|
|
3
3
|
export const dashboardSidebarTheme = defineTheme("dashboard-sidebar", {
|
|
4
4
|
slots: ["root", "header", "body", "footer", "toggle", "handle", "content", "overlay"],
|
|
5
5
|
base: {
|
|
6
|
-
root: "group relative flex flex-col h-full min-h-0 min-w-
|
|
6
|
+
root: "group relative hidden lg:flex flex-col h-full min-h-0 shrink-0 transition-[width] duration-300 w-64 min-w-64 max-w-64 data-[collapsed=true]:w-16 data-[collapsed=true]:min-w-16 data-[collapsed=true]:max-w-16 data-[collapsed=true]:overflow-hidden data-[collapsed=false]:w-64 data-[collapsed=false]:min-w-64 data-[collapsed=false]:max-w-64",
|
|
7
7
|
header:
|
|
8
|
-
"h-16 min-h-16 shrink-0 flex items-center gap-3 px-6 py-4 border-b border-default group-data-[collapsed=true]:justify-center group-data-[collapsed=true]:gap-0 group-data-[collapsed=true]:px-0",
|
|
9
|
-
body: "flex flex-col gap-1 flex-1 overflow-y-auto px-3 py-3",
|
|
8
|
+
"h-16 min-h-16 shrink-0 flex items-center gap-3 px-6 py-4 border-b border-default group-data-[collapsed=true]:justify-center group-data-[collapsed=true]:items-center group-data-[collapsed=true]:gap-0 group-data-[collapsed=true]:px-0",
|
|
9
|
+
body: "flex flex-col gap-1 flex-1 overflow-y-auto px-3 py-3 group-data-[collapsed=true]:items-center group-data-[collapsed=true]:px-0 group-data-[collapsed=true]:overflow-hidden",
|
|
10
10
|
footer:
|
|
11
|
-
"shrink-0 flex items-center gap-1.5 px-3 py-3 group-data-[collapsed=true]:
|
|
11
|
+
"shrink-0 flex items-center gap-1.5 px-3 py-3 border-t border-default/40 group-data-[collapsed=true]:justify-center group-data-[collapsed=true]:items-center group-data-[collapsed=true]:px-0",
|
|
12
12
|
toggle: "",
|
|
13
13
|
handle: "",
|
|
14
14
|
content: "lg:hidden",
|
|
@@ -32,7 +32,7 @@ export const dashboardSidebarTheme = defineTheme("dashboard-sidebar", {
|
|
|
32
32
|
},
|
|
33
33
|
collapsed: {
|
|
34
34
|
true: {
|
|
35
|
-
root: "w-16 w-
|
|
35
|
+
root: "w-16 min-w-16 max-w-16 overflow-hidden",
|
|
36
36
|
body: "overflow-hidden"
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -16,7 +16,7 @@ const RLSIcon: Component<IconProps> = (allProps) => {
|
|
|
16
16
|
return (
|
|
17
17
|
<span class={classes().root} data-slot="icon" aria-hidden="true" {...rest}>
|
|
18
18
|
{resolved().isClass ? (
|
|
19
|
-
<span class={`${resolved().content} size-full`} />
|
|
19
|
+
<span class={`${resolved().content} block size-full`} />
|
|
20
20
|
) : (
|
|
21
21
|
<span innerHTML={resolved().content} />
|
|
22
22
|
)}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { ModalProps } from "./modal"
|
|
3
3
|
import { modalTheme } from "./modal.theme"
|
|
4
|
-
import
|
|
4
|
+
import RLAButton from "../button/RLAButton.astro"
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
@@ -49,15 +49,18 @@ const modalId = `rla-modal-${Math.random().toString(36).substring(2, 9)}`
|
|
|
49
49
|
data-unmount-on-hide={unmountOnHide ? "true" : "false"}
|
|
50
50
|
{...rest}
|
|
51
51
|
>
|
|
52
|
-
<
|
|
52
|
+
<RLAButton
|
|
53
53
|
class={classes.closeButton}
|
|
54
54
|
data-slot="close-button"
|
|
55
55
|
type="button"
|
|
56
|
+
variant="ghost"
|
|
57
|
+
color="neutral"
|
|
58
|
+
size="sm"
|
|
59
|
+
square
|
|
60
|
+
leadingIcon="i-rl-close"
|
|
56
61
|
data-dialog-close={modalId}
|
|
57
62
|
aria-label="Close modal"
|
|
58
|
-
|
|
59
|
-
<RLAIcon name="i-rl-close" class="size-4" aria-hidden="true" />
|
|
60
|
-
</button>
|
|
63
|
+
/>
|
|
61
64
|
|
|
62
65
|
<div class={classes.header} data-slot="header">
|
|
63
66
|
{title && <h3 class={classes.title} data-slot="title">{title}</h3>}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "solid-js"
|
|
11
11
|
import type { ModalProps } from "./modal"
|
|
12
12
|
import { modalTheme } from "./modal.theme"
|
|
13
|
-
import
|
|
13
|
+
import RLSButton from "../button/RLSButton"
|
|
14
14
|
|
|
15
15
|
export interface RLSModalProps extends ModalProps {
|
|
16
16
|
onClose?: () => void
|
|
@@ -41,6 +41,7 @@ const RLSModal: Component<RLSModalProps> = (allProps) => {
|
|
|
41
41
|
|
|
42
42
|
const closeOnClickOutside = () => props.closeOnClickOutside !== false
|
|
43
43
|
const closeOnEscape = () => props.closeOnEscape !== false
|
|
44
|
+
const unmountOnHide = () => props.unmountOnHide !== false
|
|
44
45
|
|
|
45
46
|
const handleClose = () => {
|
|
46
47
|
props.onClose?.()
|
|
@@ -54,8 +55,8 @@ const RLSModal: Component<RLSModalProps> = (allProps) => {
|
|
|
54
55
|
e.preventDefault()
|
|
55
56
|
} else {
|
|
56
57
|
e.preventDefault()
|
|
57
|
-
handleClose()
|
|
58
58
|
}
|
|
59
|
+
handleClose()
|
|
59
60
|
}
|
|
60
61
|
const handleClick = (e: MouseEvent) => {
|
|
61
62
|
// Clicking the ::backdrop means e.target IS the dialog element
|
|
@@ -91,24 +92,28 @@ const RLSModal: Component<RLSModalProps> = (allProps) => {
|
|
|
91
92
|
})
|
|
92
93
|
|
|
93
94
|
return (
|
|
94
|
-
<Show when={props.open || !
|
|
95
|
+
<Show when={props.open || !unmountOnHide()}>
|
|
95
96
|
<dialog
|
|
96
97
|
ref={(el) => (dialogRef = el)}
|
|
97
|
-
class={`w-full rounded-xl border border-default bg-default p-6 shadow-xl outline-none flex flex-col max-h-[90vh] overflow-y-auto text-highlighted backdrop:bg-black/60 backdrop:backdrop-blur-sm ${
|
|
98
|
-
|
|
99
|
-
} ${props.class || ""}`}
|
|
98
|
+
class={`w-[calc(100%-1.5rem)] sm:w-full rounded-xl border border-default bg-default p-5 sm:p-6 shadow-xl outline-none flex flex-col max-h-[calc(100dvh-1.5rem)] sm:max-h-[90vh] overflow-y-auto text-highlighted backdrop:bg-black/60 backdrop:backdrop-blur-sm ${
|
|
99
|
+
props.open ? "" : "hidden"
|
|
100
|
+
} ${resolvedClasses().content || ""} ${props.class || ""}`}
|
|
101
|
+
data-state={props.open ? "open" : "closed"}
|
|
100
102
|
data-slot="content"
|
|
101
103
|
{...rest}
|
|
102
104
|
>
|
|
103
|
-
<
|
|
105
|
+
<RLSButton
|
|
104
106
|
type="button"
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
variant="ghost"
|
|
108
|
+
color="neutral"
|
|
109
|
+
size="sm"
|
|
110
|
+
square
|
|
111
|
+
leadingIcon="close"
|
|
107
112
|
aria-label="Close modal"
|
|
113
|
+
data-slot="close-button"
|
|
114
|
+
class="absolute right-4 top-4 text-muted hover:text-highlighted"
|
|
108
115
|
onClick={handleClose}
|
|
109
|
-
|
|
110
|
-
<RLSIcon name="close" size="sm" aria-hidden="true" />
|
|
111
|
-
</button>
|
|
116
|
+
/>
|
|
112
117
|
|
|
113
118
|
{props.title || props.description || props.titleSlot || props.descriptionSlot ? (
|
|
114
119
|
<div class={resolvedClasses().header || "mb-4"} data-slot="header">
|
|
@@ -17,8 +17,9 @@ export const modalTheme = defineTheme("modal", {
|
|
|
17
17
|
trigger: "",
|
|
18
18
|
backdrop: "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm transition-all duration-300",
|
|
19
19
|
content: [
|
|
20
|
-
"fixed left-1/2 top-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 rounded-xl border border-default",
|
|
21
|
-
"bg-default p-6 shadow-xl transition-all duration-300 outline-none",
|
|
20
|
+
"fixed left-1/2 top-1/2 z-50 w-[calc(100%-1.5rem)] sm:w-full max-w-lg -translate-x-1/2 -translate-y-1/2 rounded-xl border border-default",
|
|
21
|
+
"bg-default p-5 sm:p-6 shadow-xl transition-all duration-300 outline-none",
|
|
22
|
+
"max-h-[calc(100dvh-1.5rem)] sm:max-h-[90vh] overflow-y-auto",
|
|
22
23
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-1/2",
|
|
23
24
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-1/2"
|
|
24
25
|
],
|
|
@@ -27,8 +28,8 @@ export const modalTheme = defineTheme("modal", {
|
|
|
27
28
|
description: "text-sm text-muted leading-relaxed",
|
|
28
29
|
footer: "flex flex-col-reverse sm:flex-row sm:justify-end gap-2 mt-6",
|
|
29
30
|
closeButton: [
|
|
30
|
-
"absolute right-4 top-4
|
|
31
|
-
"focus:outline-none
|
|
31
|
+
"absolute right-4 top-4 opacity-70 transition-opacity hover:opacity-100",
|
|
32
|
+
"focus:outline-none"
|
|
32
33
|
]
|
|
33
34
|
},
|
|
34
35
|
variants: {
|
package/src/index.ts
CHANGED
|
@@ -4,8 +4,18 @@ import type { UIConfig } from "./types"
|
|
|
4
4
|
|
|
5
5
|
const ID = "virtual:rimelight/ui"
|
|
6
6
|
|
|
7
|
-
export
|
|
8
|
-
|
|
7
|
+
export interface RimelightUIPlugin {
|
|
8
|
+
name: string
|
|
9
|
+
enforce?: "pre" | "post"
|
|
10
|
+
resolveId?: (id: string) => string | null | undefined
|
|
11
|
+
load?: (id: string) => string | null | undefined
|
|
12
|
+
[key: string]: any
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type RimelightUIPlugins = (RimelightUIPlugin | RimelightUIPlugin[])[]
|
|
16
|
+
|
|
17
|
+
export const ui = ({ unocss = {}, ...cfg }: UIConfig = {}): RimelightUIPlugins => [
|
|
18
|
+
...(UnoCSS({
|
|
9
19
|
...unocss,
|
|
10
20
|
presets: [rimelightUiPreset(cfg), ...(unocss.presets || [])],
|
|
11
21
|
content: {
|
|
@@ -21,7 +31,7 @@ export const ui = ({ unocss = {}, ...cfg }: UIConfig = {}) => [
|
|
|
21
31
|
]
|
|
22
32
|
}
|
|
23
33
|
}
|
|
24
|
-
}),
|
|
34
|
+
}) as RimelightUIPlugin[]),
|
|
25
35
|
{
|
|
26
36
|
name: "rimelight/ui",
|
|
27
37
|
enforce: "pre",
|