@enderfall/ui 0.2.0 → 0.2.4
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/components/Dropdown.d.ts.map +1 -1
- package/dist/components/Dropdown.js +3 -1
- package/dist/components/MainHeader.d.ts +2 -2
- package/dist/components/MainHeader.d.ts.map +1 -1
- package/dist/components/MainHeader.js +25 -2
- package/dist/components/Tabs.js +1 -1
- package/package.json +1 -1
- package/src/components/Dropdown.tsx +1 -1
- package/src/components/HeaderMenu.css +37 -2
- package/src/components/MainHeader.tsx +74 -24
- package/src/components/Toggle.css +3 -0
- package/src/variables.css +36 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.d.ts","sourceRoot":"","sources":["../../src/components/Dropdown.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Dropdown.d.ts","sourceRoot":"","sources":["../../src/components/Dropdown.tsx"],"names":[],"mappings":"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"}
|
|
@@ -31,7 +31,9 @@ export const Dropdown = (props) => {
|
|
|
31
31
|
return (_jsx("div", { className: "ef-menu-bar", children: props.menus.map((menu) => (_jsxs("div", { className: "ef-menu-group", "data-open": props.menuOpen === menu.id ? "true" : "false", onMouseEnter: () => {
|
|
32
32
|
cancelScheduledClose();
|
|
33
33
|
props.onOpenMenu(menu.id);
|
|
34
|
-
}, onMouseLeave: scheduleClose, children: [_jsx(
|
|
34
|
+
}, onMouseLeave: scheduleClose, children: [_jsx(Button, { className: ["ef-menu-button", "ef-tab", props.menuOpen === menu.id ? "is-active" : ""]
|
|
35
|
+
.filter(Boolean)
|
|
36
|
+
.join(" "), type: "button", variant: "tab", subvariant: "default", "data-open": props.menuOpen === menu.id ? "true" : "false", children: menu.label }), props.menuOpen === menu.id ? (_jsx("div", { className: "ef-menu-popover", "data-open": "true", onMouseEnter: () => {
|
|
35
37
|
cancelScheduledClose();
|
|
36
38
|
props.onOpenMenu(menu.id);
|
|
37
39
|
}, onMouseLeave: scheduleClose, children: menu.content })) : null] }, menu.id))) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MainHeader.d.ts","sourceRoot":"","sources":["../../src/components/MainHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"MainHeader.d.ts","sourceRoot":"","sources":["../../src/components/MainHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,KAAK,eAAe,GAAG;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,kFASxB,eAAe,4CA2EjB,CAAC"}
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import { Button } from "./Button";
|
|
3
4
|
import { Panel } from "./Panel";
|
|
4
5
|
export const MainHeader = ({ title = "Enderfall", subtitle = "Galaxy tools for creators", logoSrc, menus, menuOpen, onOpenMenu, onCloseMenu, actions, }) => {
|
|
5
|
-
|
|
6
|
+
const closeTimerRef = useRef(null);
|
|
7
|
+
const closeDelayMs = 160;
|
|
8
|
+
const cancelScheduledClose = () => {
|
|
9
|
+
if (closeTimerRef.current !== null) {
|
|
10
|
+
window.clearTimeout(closeTimerRef.current);
|
|
11
|
+
closeTimerRef.current = null;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const scheduleClose = () => {
|
|
15
|
+
cancelScheduledClose();
|
|
16
|
+
closeTimerRef.current = window.setTimeout(() => {
|
|
17
|
+
onCloseMenu();
|
|
18
|
+
}, closeDelayMs);
|
|
19
|
+
};
|
|
20
|
+
return (_jsxs(Panel, { variant: "header", borderWidth: 2, className: "ef-main-header", children: [_jsxs("div", { className: "ef-header-left", children: [_jsxs("div", { className: "ef-brand", children: [logoSrc ? (_jsx("img", { src: logoSrc, alt: title, className: "ef-logo" })) : (_jsx("div", { className: "ef-logo-fallback", children: "E" })), _jsxs("div", { children: [_jsx("div", { className: "ef-brand-name", children: title }), subtitle ? _jsx("div", { className: "ef-tagline", children: subtitle }) : null] })] }), _jsx("div", { className: "ef-menu-bar", children: menus.map((menu) => (_jsxs("div", { className: "ef-menu-group", "data-open": menuOpen === menu.id ? "true" : "false", onMouseEnter: () => {
|
|
21
|
+
cancelScheduledClose();
|
|
22
|
+
onOpenMenu(menu.id);
|
|
23
|
+
}, onMouseLeave: scheduleClose, children: [_jsx(Button, { className: ["ef-menu-button", "ef-tab", menuOpen === menu.id ? "is-active" : ""]
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.join(" "), type: "button", variant: "tab", subvariant: "default", "data-open": menuOpen === menu.id ? "true" : "false", children: menu.label }), menuOpen === menu.id ? (_jsx("div", { className: "ef-menu-popover", "data-open": "true", onMouseEnter: () => {
|
|
26
|
+
cancelScheduledClose();
|
|
27
|
+
onOpenMenu(menu.id);
|
|
28
|
+
}, onMouseLeave: scheduleClose, children: menu.content })) : null] }, menu.id))) })] }), _jsx("div", { className: "ef-header-actions", children: actions })] }));
|
|
6
29
|
};
|
package/dist/components/Tabs.js
CHANGED
|
@@ -5,7 +5,7 @@ export const Tabs = ({ tabs, activeTab, onChange, orientation = "horizontal", sh
|
|
|
5
5
|
const active = tabs.find((tab) => tab.id === activeTab);
|
|
6
6
|
return (_jsxs("div", { className: ["ef-tabs", isVertical ? "ef-tabs--vertical" : "", className].filter(Boolean).join(" "), children: [_jsx("div", { className: ["ef-tabs-list", isVertical ? "ef-tabs-list--vertical" : ""].filter(Boolean).join(" "), children: tabs.map((tab) => {
|
|
7
7
|
const isActive = tab.id === activeTab;
|
|
8
|
-
return (_jsxs(Button, { variant:
|
|
8
|
+
return (_jsxs(Button, { variant: "tab", subvariant: "default", className: ["ef-tab", isVertical ? "ef-tab--vertical" : "", isActive ? "is-active" : ""]
|
|
9
9
|
.filter(Boolean)
|
|
10
10
|
.join(" "), onClick: () => onChange(tab.id), children: [tab.icon ? _jsx("span", { className: "ef-tab-icon", children: tab.icon }) : null, _jsx("span", { className: "ef-tab-text", children: tab.label }), isVertical && isActive ? _jsx("span", { className: "ef-tab-active-indicator" }) : null] }, tab.id));
|
|
11
11
|
}) }), (active?.content || renderTabContent) && (_jsx("div", { className: [
|
package/package.json
CHANGED
|
@@ -218,7 +218,7 @@ export const Dropdown = (props: DropdownProps) => {
|
|
|
218
218
|
onMouseLeave={scheduleClose}
|
|
219
219
|
>
|
|
220
220
|
<Button
|
|
221
|
-
className={["ef-menu-button", props.menuOpen === menu.id ? "is-active" : ""]
|
|
221
|
+
className={["ef-menu-button", "ef-tab", props.menuOpen === menu.id ? "is-active" : ""]
|
|
222
222
|
.filter(Boolean)
|
|
223
223
|
.join(" ")}
|
|
224
224
|
type="button"
|
|
@@ -14,10 +14,45 @@
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
.ef-menu-button {
|
|
17
|
+
color: var(--ef-nav-text);
|
|
18
|
+
text-decoration: none;
|
|
17
19
|
font-size: 1rem;
|
|
20
|
+
font-weight: 600;
|
|
21
|
+
transition: color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
|
|
18
22
|
text-transform: uppercase;
|
|
19
|
-
letter-spacing: 0.08em;
|
|
20
|
-
padding: 8px 18px;
|
|
23
|
+
letter-spacing: var(--ef-nav-letter-spacing, 0.08em);
|
|
24
|
+
padding: var(--ef-nav-padding-y, 8px) var(--ef-nav-padding-x, 18px);
|
|
25
|
+
border-radius: var(--ef-nav-radius, 8px);
|
|
26
|
+
border: 2px solid transparent;
|
|
27
|
+
background: var(--ef-nav-surface);
|
|
28
|
+
box-shadow: var(--ef-nav-shadow);
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
font-family: inherit;
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
gap: 8px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.ef-menu-button:hover {
|
|
38
|
+
color: var(--ef-nav-text-hover);
|
|
39
|
+
box-shadow: var(--ef-nav-shadow-hover);
|
|
40
|
+
transform: var(--ef-nav-transform-hover, translateY(-1px));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.ef-menu-button:focus-visible {
|
|
44
|
+
color: var(--ef-nav-text-hover);
|
|
45
|
+
box-shadow: var(--ef-nav-shadow-focus);
|
|
46
|
+
transform: var(--ef-nav-transform-hover, translateY(-1px));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ef-menu-button.is-active,
|
|
50
|
+
.ef-menu-button[data-open="true"] {
|
|
51
|
+
background:
|
|
52
|
+
linear-gradient(var(--ef-button-surface), var(--ef-button-surface)) padding-box,
|
|
53
|
+
var(--ef-nav-border) border-box;
|
|
54
|
+
color: var(--ef-nav-text-active);
|
|
55
|
+
box-shadow: var(--ef-nav-shadow-active);
|
|
21
56
|
}
|
|
22
57
|
|
|
23
58
|
.ef-menu-popover {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useRef, type ReactNode } from "react";
|
|
2
|
+
import type { HeaderMenuItem } from "./Dropdown";
|
|
3
|
+
import { Button } from "./Button";
|
|
4
|
+
import { Panel } from "./Panel";
|
|
4
5
|
|
|
5
6
|
type MainHeaderProps = {
|
|
6
7
|
title?: string;
|
|
@@ -13,19 +14,36 @@ type MainHeaderProps = {
|
|
|
13
14
|
actions?: ReactNode;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
|
-
export const MainHeader = ({
|
|
17
|
+
export const MainHeader = ({
|
|
17
18
|
title = "Enderfall",
|
|
18
19
|
subtitle = "Galaxy tools for creators",
|
|
19
20
|
logoSrc,
|
|
20
21
|
menus,
|
|
21
22
|
menuOpen,
|
|
22
23
|
onOpenMenu,
|
|
23
|
-
onCloseMenu,
|
|
24
|
-
actions,
|
|
25
|
-
}: MainHeaderProps) => {
|
|
26
|
-
|
|
24
|
+
onCloseMenu,
|
|
25
|
+
actions,
|
|
26
|
+
}: MainHeaderProps) => {
|
|
27
|
+
const closeTimerRef = useRef<number | null>(null);
|
|
28
|
+
const closeDelayMs = 160;
|
|
29
|
+
|
|
30
|
+
const cancelScheduledClose = () => {
|
|
31
|
+
if (closeTimerRef.current !== null) {
|
|
32
|
+
window.clearTimeout(closeTimerRef.current);
|
|
33
|
+
closeTimerRef.current = null;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const scheduleClose = () => {
|
|
38
|
+
cancelScheduledClose();
|
|
39
|
+
closeTimerRef.current = window.setTimeout(() => {
|
|
40
|
+
onCloseMenu();
|
|
41
|
+
}, closeDelayMs);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return (
|
|
27
45
|
<Panel variant="header" borderWidth={2} className="ef-main-header">
|
|
28
|
-
<div className="ef-header-left">
|
|
46
|
+
<div className="ef-header-left">
|
|
29
47
|
<div className="ef-brand">
|
|
30
48
|
{logoSrc ? (
|
|
31
49
|
<img src={logoSrc} alt={title} className="ef-logo" />
|
|
@@ -34,18 +52,50 @@ export const MainHeader = ({
|
|
|
34
52
|
)}
|
|
35
53
|
<div>
|
|
36
54
|
<div className="ef-brand-name">{title}</div>
|
|
37
|
-
{subtitle ? <div className="ef-tagline">{subtitle}</div> : null}
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
{subtitle ? <div className="ef-tagline">{subtitle}</div> : null}
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
<div className="ef-menu-bar">
|
|
59
|
+
{menus.map((menu) => (
|
|
60
|
+
<div
|
|
61
|
+
key={menu.id}
|
|
62
|
+
className="ef-menu-group"
|
|
63
|
+
data-open={menuOpen === menu.id ? "true" : "false"}
|
|
64
|
+
onMouseEnter={() => {
|
|
65
|
+
cancelScheduledClose();
|
|
66
|
+
onOpenMenu(menu.id);
|
|
67
|
+
}}
|
|
68
|
+
onMouseLeave={scheduleClose}
|
|
69
|
+
>
|
|
70
|
+
<Button
|
|
71
|
+
className={["ef-menu-button", "ef-tab", menuOpen === menu.id ? "is-active" : ""]
|
|
72
|
+
.filter(Boolean)
|
|
73
|
+
.join(" ")}
|
|
74
|
+
type="button"
|
|
75
|
+
variant="tab"
|
|
76
|
+
subvariant="default"
|
|
77
|
+
data-open={menuOpen === menu.id ? "true" : "false"}
|
|
78
|
+
>
|
|
79
|
+
{menu.label}
|
|
80
|
+
</Button>
|
|
81
|
+
{menuOpen === menu.id ? (
|
|
82
|
+
<div
|
|
83
|
+
className="ef-menu-popover"
|
|
84
|
+
data-open="true"
|
|
85
|
+
onMouseEnter={() => {
|
|
86
|
+
cancelScheduledClose();
|
|
87
|
+
onOpenMenu(menu.id);
|
|
88
|
+
}}
|
|
89
|
+
onMouseLeave={scheduleClose}
|
|
90
|
+
>
|
|
91
|
+
{menu.content}
|
|
92
|
+
</div>
|
|
93
|
+
) : null}
|
|
94
|
+
</div>
|
|
95
|
+
))}
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
<div className="ef-header-actions">{actions}</div>
|
|
99
|
+
</Panel>
|
|
100
|
+
);
|
|
101
|
+
};
|
package/src/variables.css
CHANGED
|
@@ -272,6 +272,11 @@
|
|
|
272
272
|
--ef-nav-shadow-active: 0 0 0 1px rgba(24, 32, 40, 0.3);
|
|
273
273
|
--ef-menu-item-shadow: none;
|
|
274
274
|
--ef-menu-item-shadow-hover: 0 0 0 1px rgba(24, 32, 40, 0.2);
|
|
275
|
+
--ef-tabs-surface: #ffffff;
|
|
276
|
+
--ef-tabs-border: linear-gradient(135deg, rgba(24, 32, 40, 0.18), rgba(24, 32, 40, 0.18));
|
|
277
|
+
--ef-tabs-content-surface: #ffffff;
|
|
278
|
+
--ef-tabs-content-border: linear-gradient(135deg, rgba(24, 32, 40, 0.14), rgba(24, 32, 40, 0.14));
|
|
279
|
+
--ef-tabs-indicator: linear-gradient(180deg, rgba(24, 32, 40, 0.82), rgba(24, 32, 40, 0.82));
|
|
275
280
|
}
|
|
276
281
|
|
|
277
282
|
:root[data-theme="plain-dark"] {
|
|
@@ -302,6 +307,11 @@
|
|
|
302
307
|
--ef-nav-shadow-active: 0 0 0 1px rgba(255, 255, 255, 0.3);
|
|
303
308
|
--ef-menu-item-shadow: none;
|
|
304
309
|
--ef-menu-item-shadow-hover: 0 0 0 1px rgba(255, 255, 255, 0.2);
|
|
310
|
+
--ef-tabs-surface: #0b0c1a;
|
|
311
|
+
--ef-tabs-border: linear-gradient(135deg, rgba(255, 255, 255, 0.24), rgba(255, 255, 255, 0.24));
|
|
312
|
+
--ef-tabs-content-surface: #0b0c1a;
|
|
313
|
+
--ef-tabs-content-border: linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2));
|
|
314
|
+
--ef-tabs-indicator: linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0.92));
|
|
305
315
|
}
|
|
306
316
|
|
|
307
317
|
|
|
@@ -420,6 +430,29 @@
|
|
|
420
430
|
--ef-toggle-check-radius: 2px;
|
|
421
431
|
}
|
|
422
432
|
|
|
433
|
+
/*
|
|
434
|
+
Optional "galaxy-light" surface mode (when host app toggles body class).
|
|
435
|
+
Keeps light readability while preserving galaxy accent treatment for nav/tabs.
|
|
436
|
+
*/
|
|
437
|
+
body.ef-galaxy-light {
|
|
438
|
+
--ef-nav-text: rgba(29, 35, 42, 0.82);
|
|
439
|
+
--ef-nav-text-hover: #1d232a;
|
|
440
|
+
--ef-nav-text-active: #1d232a;
|
|
441
|
+
--ef-nav-surface: rgba(255, 255, 255, 0.86);
|
|
442
|
+
--ef-nav-border: linear-gradient(135deg, rgba(0, 229, 255, 0.72), rgba(124, 77, 255, 0.72), rgba(255, 77, 210, 0.72), rgba(255, 183, 77, 0.72));
|
|
443
|
+
--ef-nav-shadow: none;
|
|
444
|
+
--ef-nav-shadow-hover: 0 0 16px rgba(124, 77, 255, 0.24);
|
|
445
|
+
--ef-nav-shadow-focus: 0 0 20px rgba(124, 77, 255, 0.28);
|
|
446
|
+
--ef-nav-shadow-active: 0 0 20px rgba(124, 77, 255, 0.3);
|
|
447
|
+
--ef-menu-item-shadow: 0 0 10px rgba(124, 77, 255, 0.15);
|
|
448
|
+
--ef-menu-item-shadow-hover: 0 0 14px rgba(124, 77, 255, 0.2);
|
|
449
|
+
--ef-tabs-surface: rgba(255, 255, 255, 0.92);
|
|
450
|
+
--ef-tabs-border: linear-gradient(135deg, rgba(0, 229, 255, 0.52), rgba(124, 77, 255, 0.52), rgba(255, 77, 210, 0.52));
|
|
451
|
+
--ef-tabs-content-surface: rgba(255, 255, 255, 0.94);
|
|
452
|
+
--ef-tabs-content-border: linear-gradient(135deg, rgba(0, 229, 255, 0.36), rgba(124, 77, 255, 0.36), rgba(255, 77, 210, 0.36));
|
|
453
|
+
--ef-tabs-indicator: linear-gradient(180deg, #00a0bc, #7c4dff, #c24aa2);
|
|
454
|
+
}
|
|
455
|
+
|
|
423
456
|
:root[data-theme="system"] {
|
|
424
457
|
color-scheme: light dark;
|
|
425
458
|
}
|
|
@@ -437,7 +470,10 @@
|
|
|
437
470
|
--ef-menu-item-shadow: 0 0 10px rgba(31, 122, 140, 0.12);
|
|
438
471
|
--ef-menu-item-shadow-hover: 0 0 14px rgba(31, 122, 140, 0.18);
|
|
439
472
|
--ef-tabs-surface: #ffffff;
|
|
473
|
+
--ef-tabs-border: linear-gradient(135deg, rgba(0, 229, 255, 0.35), rgba(124, 77, 255, 0.35), rgba(255, 77, 210, 0.35));
|
|
440
474
|
--ef-tabs-content-surface: #ffffff;
|
|
475
|
+
--ef-tabs-content-border: linear-gradient(135deg, rgba(0, 229, 255, 0.2), rgba(124, 77, 255, 0.2), rgba(255, 77, 210, 0.2));
|
|
476
|
+
--ef-tabs-indicator: linear-gradient(180deg, #1f7a8c, #7c4dff, #f29f45);
|
|
441
477
|
}
|
|
442
478
|
}
|
|
443
479
|
|