@luxfi/ui 7.3.2 → 7.4.2
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/alert.cjs +2 -2
- package/dist/alert.js +1 -1
- package/dist/avatar.cjs +7 -6
- package/dist/avatar.js +7 -5
- package/dist/badge.cjs +36 -38
- package/dist/badge.js +31 -33
- package/dist/bank.cjs +13 -13
- package/dist/bank.d.cts +31 -24
- package/dist/bank.d.ts +31 -24
- package/dist/bank.js +1 -1
- package/dist/button.cjs +3 -3
- package/dist/button.js +1 -1
- package/dist/checkbox.cjs +4 -4
- package/dist/checkbox.d.cts +3 -2
- package/dist/checkbox.d.ts +3 -2
- package/dist/checkbox.js +5 -4
- package/dist/chrome.cjs +950 -0
- package/dist/chrome.d.cts +93 -0
- package/dist/chrome.d.ts +93 -0
- package/dist/chrome.js +921 -0
- package/dist/close-button.cjs +2 -2
- package/dist/close-button.js +1 -1
- package/dist/dialog.cjs +13 -14
- package/dist/dialog.d.cts +58 -5
- package/dist/dialog.d.ts +58 -5
- package/dist/dialog.js +1 -2
- package/dist/drawer.cjs +87 -21
- package/dist/drawer.js +85 -19
- package/dist/expiration-selector.cjs +3 -2
- package/dist/expiration-selector.js +3 -2
- package/dist/greeks-display.cjs +6 -6
- package/dist/greeks-display.js +6 -6
- package/dist/gui.cjs +13 -0
- package/dist/gui.d.cts +2 -0
- package/dist/gui.d.ts +2 -0
- package/dist/gui.js +2 -0
- package/dist/heading.cjs +4 -2
- package/dist/heading.js +4 -2
- package/dist/iam.cjs +206 -0
- package/dist/iam.d.cts +65 -0
- package/dist/iam.d.ts +65 -0
- package/dist/iam.js +201 -0
- package/dist/icon-button.cjs +2 -2
- package/dist/icon-button.js +1 -1
- package/dist/icons.cjs +13 -0
- package/dist/icons.d.cts +1 -0
- package/dist/icons.d.ts +1 -0
- package/dist/icons.js +2 -0
- package/dist/identity.cjs +420 -0
- package/dist/identity.d.cts +64 -0
- package/dist/identity.d.ts +64 -0
- package/dist/identity.js +398 -0
- package/dist/index.cjs +1699 -860
- package/dist/index.d.cts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +1618 -802
- package/dist/input.cjs +13 -3
- package/dist/input.d.cts +6 -0
- package/dist/input.d.ts +6 -0
- package/dist/input.js +13 -3
- package/dist/lux.config.cjs +77 -0
- package/dist/lux.config.d.cts +433 -0
- package/dist/lux.config.d.ts +433 -0
- package/dist/lux.config.js +69 -0
- package/dist/menu.cjs +4 -4
- package/dist/menu.js +4 -4
- package/dist/next.cjs +99 -0
- package/dist/next.d.cts +29 -0
- package/dist/next.d.ts +29 -0
- package/dist/next.js +96 -0
- package/dist/option-chain.cjs +1 -1
- package/dist/option-chain.js +1 -1
- package/dist/option-position.cjs +2 -1
- package/dist/option-position.js +2 -1
- package/dist/pnl-diagram.cjs +8 -6
- package/dist/pnl-diagram.js +8 -6
- package/dist/popover.cjs +8 -9
- package/dist/popover.js +1 -2
- package/dist/progress.cjs +7 -6
- package/dist/progress.js +7 -5
- package/dist/provider.cjs +199 -5
- package/dist/provider.d.cts +16 -3
- package/dist/provider.d.ts +16 -3
- package/dist/provider.js +195 -6
- package/dist/radio.cjs +9 -7
- package/dist/radio.js +10 -7
- package/dist/separator.cjs +3 -1
- package/dist/separator.js +3 -1
- package/dist/slider.cjs +28 -16
- package/dist/slider.js +28 -15
- package/dist/strategy-builder.cjs +2 -1
- package/dist/strategy-builder.js +2 -1
- package/dist/switch.cjs +11 -12
- package/dist/switch.js +12 -12
- package/dist/tag.cjs +38 -41
- package/dist/tag.js +31 -34
- package/dist/textarea.cjs +13 -3
- package/dist/textarea.d.cts +2 -0
- package/dist/textarea.d.ts +2 -0
- package/dist/textarea.js +13 -3
- package/dist/tooltip.cjs +31 -33
- package/dist/tooltip.js +25 -27
- package/dist/use-narrow.cjs +46 -0
- package/dist/use-narrow.d.cts +12 -0
- package/dist/use-narrow.d.ts +12 -0
- package/dist/use-narrow.js +20 -0
- package/dist/vite.cjs +40 -0
- package/dist/vite.d.cts +29 -0
- package/dist/vite.d.ts +29 -0
- package/dist/vite.js +38 -0
- package/dist/white-label.cjs +132 -0
- package/dist/white-label.d.cts +59 -0
- package/dist/white-label.d.ts +59 -0
- package/dist/white-label.js +124 -0
- package/package.json +95 -17
- package/src/avatar.tsx +22 -16
- package/src/bank.tsx +2 -2
- package/src/button.tsx +1 -1
- package/src/checkbox.tsx +15 -10
- package/src/chrome.tsx +459 -0
- package/src/close-button.tsx +1 -1
- package/src/dialog.tsx +1 -1
- package/src/drawer.tsx +83 -10
- package/src/expiration-selector.tsx +3 -2
- package/src/greeks-display.tsx +9 -6
- package/src/gui.ts +17 -0
- package/src/heading.tsx +12 -8
- package/src/iam.ts +170 -0
- package/src/icon-button.tsx +1 -1
- package/src/icons.ts +18 -0
- package/src/identity.tsx +318 -0
- package/src/index.ts +50 -1
- package/src/input.tsx +24 -4
- package/src/lux.config.ts +82 -0
- package/src/menu.tsx +4 -4
- package/src/next.ts +142 -0
- package/src/option-chain.tsx +1 -1
- package/src/option-position.tsx +2 -1
- package/src/pnl-diagram.tsx +11 -6
- package/src/popover.tsx +1 -1
- package/src/progress.tsx +15 -8
- package/src/provider.tsx +92 -12
- package/src/radio.tsx +15 -11
- package/src/separator.tsx +8 -3
- package/src/slider.tsx +35 -19
- package/src/strategy-builder.tsx +3 -2
- package/src/switch.tsx +17 -16
- package/src/textarea.tsx +18 -4
- package/src/tooltip.tsx +4 -23
- package/src/use-narrow.ts +40 -0
- package/src/vite.ts +78 -0
- package/src/white-label.ts +240 -0
- package/tokens.css +544 -319
- package/src/tokens.css +0 -438
package/dist/tooltip.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var gui = require('@hanzo/gui');
|
|
5
5
|
var usehooks = require('@uidotdev/usehooks');
|
|
6
|
-
var
|
|
6
|
+
var React2 = require('react');
|
|
7
7
|
var clsx = require('clsx');
|
|
8
8
|
var tailwindMerge = require('tailwind-merge');
|
|
9
9
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -26,32 +26,30 @@ function _interopNamespace(e) {
|
|
|
26
26
|
return Object.freeze(n);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
var
|
|
29
|
+
var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
|
|
30
30
|
|
|
31
31
|
// src/tooltip.tsx
|
|
32
|
+
var TOUCH_PX = 1024;
|
|
33
|
+
function useBelow(px) {
|
|
34
|
+
const [below, setBelow] = React2__namespace.useState(false);
|
|
35
|
+
React2__namespace.useEffect(() => {
|
|
36
|
+
const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
|
|
37
|
+
const apply = () => setBelow(mql.matches);
|
|
38
|
+
apply();
|
|
39
|
+
mql.addEventListener("change", apply);
|
|
40
|
+
return () => mql.removeEventListener("change", apply);
|
|
41
|
+
}, [px]);
|
|
42
|
+
return below;
|
|
43
|
+
}
|
|
44
|
+
var useIsTouch = () => useBelow(TOUCH_PX);
|
|
32
45
|
function cn(...inputs) {
|
|
33
46
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
34
47
|
}
|
|
35
|
-
var LG_BREAKPOINT = 1024;
|
|
36
|
-
function useIsMobile() {
|
|
37
|
-
const [isMobile, setIsMobile] = React__namespace.useState(() => {
|
|
38
|
-
if (typeof window === "undefined") return false;
|
|
39
|
-
return window.innerWidth < LG_BREAKPOINT;
|
|
40
|
-
});
|
|
41
|
-
React__namespace.useEffect(() => {
|
|
42
|
-
const mql = window.matchMedia(`(max-width: ${LG_BREAKPOINT - 1}px)`);
|
|
43
|
-
const handler = (e) => setIsMobile(e.matches);
|
|
44
|
-
setIsMobile(mql.matches);
|
|
45
|
-
mql.addEventListener("change", handler);
|
|
46
|
-
return () => mql.removeEventListener("change", handler);
|
|
47
|
-
}, []);
|
|
48
|
-
return isMobile;
|
|
49
|
-
}
|
|
50
48
|
function mapPlacement(p) {
|
|
51
49
|
if (!p) return void 0;
|
|
52
50
|
return p;
|
|
53
51
|
}
|
|
54
|
-
var Tooltip =
|
|
52
|
+
var Tooltip = React2__namespace.forwardRef(
|
|
55
53
|
function Tooltip2(props, ref) {
|
|
56
54
|
const {
|
|
57
55
|
showArrow: showArrowProp,
|
|
@@ -70,28 +68,28 @@ var Tooltip = React__namespace.forwardRef(
|
|
|
70
68
|
interactive,
|
|
71
69
|
positioning
|
|
72
70
|
} = props;
|
|
73
|
-
const [open, setOpen] =
|
|
74
|
-
const timeoutRef =
|
|
75
|
-
const isMobile =
|
|
76
|
-
const handleOpenChange =
|
|
71
|
+
const [open, setOpen] = React2__namespace.useState(defaultOpen);
|
|
72
|
+
const timeoutRef = React2__namespace.useRef(null);
|
|
73
|
+
const isMobile = useIsTouch();
|
|
74
|
+
const handleOpenChange = React2__namespace.useCallback((nextOpen) => {
|
|
77
75
|
setOpen(nextOpen);
|
|
78
76
|
onOpenChange?.({ open: nextOpen });
|
|
79
77
|
}, [onOpenChange]);
|
|
80
|
-
const handleOpenChangeManual =
|
|
78
|
+
const handleOpenChangeManual = React2__namespace.useCallback((nextOpen) => {
|
|
81
79
|
timeoutRef.current && window.clearTimeout(timeoutRef.current);
|
|
82
80
|
timeoutRef.current = window.setTimeout(() => {
|
|
83
81
|
setOpen(nextOpen);
|
|
84
82
|
onOpenChange?.({ open: nextOpen });
|
|
85
83
|
}, nextOpen ? openDelay : closeDelay);
|
|
86
84
|
}, [closeDelay, openDelay, onOpenChange]);
|
|
87
|
-
const handleClickAway =
|
|
85
|
+
const handleClickAway = React2__namespace.useCallback(() => {
|
|
88
86
|
handleOpenChangeManual(false);
|
|
89
87
|
}, [handleOpenChangeManual]);
|
|
90
88
|
const triggerRef = usehooks.useClickAway(handleClickAway);
|
|
91
|
-
const handleTriggerClick =
|
|
89
|
+
const handleTriggerClick = React2__namespace.useCallback(() => {
|
|
92
90
|
handleOpenChangeManual(!open);
|
|
93
91
|
}, [handleOpenChangeManual, open]);
|
|
94
|
-
const handleContentClick =
|
|
92
|
+
const handleContentClick = React2__namespace.useCallback((event) => {
|
|
95
93
|
event.stopPropagation();
|
|
96
94
|
if (interactive) {
|
|
97
95
|
const closestLink = event.target?.closest("a");
|
|
@@ -100,7 +98,7 @@ var Tooltip = React__namespace.forwardRef(
|
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
100
|
}, [interactive, handleOpenChangeManual]);
|
|
103
|
-
|
|
101
|
+
React2__namespace.useEffect(() => {
|
|
104
102
|
return () => {
|
|
105
103
|
if (timeoutRef.current) {
|
|
106
104
|
clearTimeout(timeoutRef.current);
|
|
@@ -113,8 +111,8 @@ var Tooltip = React__namespace.forwardRef(
|
|
|
113
111
|
const isPopover = variant === "popover";
|
|
114
112
|
const placement = mapPlacement(positioning?.placement) ?? "top";
|
|
115
113
|
const offset = positioning?.offset?.mainAxis ?? 4;
|
|
116
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
117
|
-
|
|
114
|
+
return /* @__PURE__ */ jsxRuntime.jsx(gui.TooltipGroup, { delay: openDelay, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
115
|
+
gui.Tooltip,
|
|
118
116
|
{
|
|
119
117
|
open,
|
|
120
118
|
onOpenChange: handleOpenChange,
|
|
@@ -124,7 +122,7 @@ var Tooltip = React__namespace.forwardRef(
|
|
|
124
122
|
unstyled: true,
|
|
125
123
|
children: [
|
|
126
124
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
127
|
-
|
|
125
|
+
gui.Tooltip.Trigger,
|
|
128
126
|
{
|
|
129
127
|
ref: open ? triggerRef : void 0,
|
|
130
128
|
asChild: true,
|
|
@@ -134,7 +132,7 @@ var Tooltip = React__namespace.forwardRef(
|
|
|
134
132
|
}
|
|
135
133
|
),
|
|
136
134
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
137
|
-
|
|
135
|
+
gui.Tooltip.Content,
|
|
138
136
|
{
|
|
139
137
|
ref,
|
|
140
138
|
unstyled: true,
|
|
@@ -151,7 +149,7 @@ var Tooltip = React__namespace.forwardRef(
|
|
|
151
149
|
...contentProps,
|
|
152
150
|
children: [
|
|
153
151
|
showArrow && /* @__PURE__ */ jsxRuntime.jsx(
|
|
154
|
-
|
|
152
|
+
gui.Tooltip.Arrow,
|
|
155
153
|
{
|
|
156
154
|
unstyled: true,
|
|
157
155
|
className: cn(
|
package/dist/tooltip.js
CHANGED
|
@@ -1,35 +1,33 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { TooltipGroup, Tooltip as Tooltip$1 } from '@
|
|
2
|
+
import { TooltipGroup, Tooltip as Tooltip$1 } from '@hanzo/gui';
|
|
3
3
|
import { useClickAway } from '@uidotdev/usehooks';
|
|
4
|
-
import * as
|
|
4
|
+
import * as React2 from 'react';
|
|
5
5
|
import { clsx } from 'clsx';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
8
|
|
|
9
9
|
// src/tooltip.tsx
|
|
10
|
+
var TOUCH_PX = 1024;
|
|
11
|
+
function useBelow(px) {
|
|
12
|
+
const [below, setBelow] = React2.useState(false);
|
|
13
|
+
React2.useEffect(() => {
|
|
14
|
+
const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
|
|
15
|
+
const apply = () => setBelow(mql.matches);
|
|
16
|
+
apply();
|
|
17
|
+
mql.addEventListener("change", apply);
|
|
18
|
+
return () => mql.removeEventListener("change", apply);
|
|
19
|
+
}, [px]);
|
|
20
|
+
return below;
|
|
21
|
+
}
|
|
22
|
+
var useIsTouch = () => useBelow(TOUCH_PX);
|
|
10
23
|
function cn(...inputs) {
|
|
11
24
|
return twMerge(clsx(inputs));
|
|
12
25
|
}
|
|
13
|
-
var LG_BREAKPOINT = 1024;
|
|
14
|
-
function useIsMobile() {
|
|
15
|
-
const [isMobile, setIsMobile] = React.useState(() => {
|
|
16
|
-
if (typeof window === "undefined") return false;
|
|
17
|
-
return window.innerWidth < LG_BREAKPOINT;
|
|
18
|
-
});
|
|
19
|
-
React.useEffect(() => {
|
|
20
|
-
const mql = window.matchMedia(`(max-width: ${LG_BREAKPOINT - 1}px)`);
|
|
21
|
-
const handler = (e) => setIsMobile(e.matches);
|
|
22
|
-
setIsMobile(mql.matches);
|
|
23
|
-
mql.addEventListener("change", handler);
|
|
24
|
-
return () => mql.removeEventListener("change", handler);
|
|
25
|
-
}, []);
|
|
26
|
-
return isMobile;
|
|
27
|
-
}
|
|
28
26
|
function mapPlacement(p) {
|
|
29
27
|
if (!p) return void 0;
|
|
30
28
|
return p;
|
|
31
29
|
}
|
|
32
|
-
var Tooltip =
|
|
30
|
+
var Tooltip = React2.forwardRef(
|
|
33
31
|
function Tooltip2(props, ref) {
|
|
34
32
|
const {
|
|
35
33
|
showArrow: showArrowProp,
|
|
@@ -48,28 +46,28 @@ var Tooltip = React.forwardRef(
|
|
|
48
46
|
interactive,
|
|
49
47
|
positioning
|
|
50
48
|
} = props;
|
|
51
|
-
const [open, setOpen] =
|
|
52
|
-
const timeoutRef =
|
|
53
|
-
const isMobile =
|
|
54
|
-
const handleOpenChange =
|
|
49
|
+
const [open, setOpen] = React2.useState(defaultOpen);
|
|
50
|
+
const timeoutRef = React2.useRef(null);
|
|
51
|
+
const isMobile = useIsTouch();
|
|
52
|
+
const handleOpenChange = React2.useCallback((nextOpen) => {
|
|
55
53
|
setOpen(nextOpen);
|
|
56
54
|
onOpenChange?.({ open: nextOpen });
|
|
57
55
|
}, [onOpenChange]);
|
|
58
|
-
const handleOpenChangeManual =
|
|
56
|
+
const handleOpenChangeManual = React2.useCallback((nextOpen) => {
|
|
59
57
|
timeoutRef.current && window.clearTimeout(timeoutRef.current);
|
|
60
58
|
timeoutRef.current = window.setTimeout(() => {
|
|
61
59
|
setOpen(nextOpen);
|
|
62
60
|
onOpenChange?.({ open: nextOpen });
|
|
63
61
|
}, nextOpen ? openDelay : closeDelay);
|
|
64
62
|
}, [closeDelay, openDelay, onOpenChange]);
|
|
65
|
-
const handleClickAway =
|
|
63
|
+
const handleClickAway = React2.useCallback(() => {
|
|
66
64
|
handleOpenChangeManual(false);
|
|
67
65
|
}, [handleOpenChangeManual]);
|
|
68
66
|
const triggerRef = useClickAway(handleClickAway);
|
|
69
|
-
const handleTriggerClick =
|
|
67
|
+
const handleTriggerClick = React2.useCallback(() => {
|
|
70
68
|
handleOpenChangeManual(!open);
|
|
71
69
|
}, [handleOpenChangeManual, open]);
|
|
72
|
-
const handleContentClick =
|
|
70
|
+
const handleContentClick = React2.useCallback((event) => {
|
|
73
71
|
event.stopPropagation();
|
|
74
72
|
if (interactive) {
|
|
75
73
|
const closestLink = event.target?.closest("a");
|
|
@@ -78,7 +76,7 @@ var Tooltip = React.forwardRef(
|
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
78
|
}, [interactive, handleOpenChangeManual]);
|
|
81
|
-
|
|
79
|
+
React2.useEffect(() => {
|
|
82
80
|
return () => {
|
|
83
81
|
if (timeoutRef.current) {
|
|
84
82
|
clearTimeout(timeoutRef.current);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var React = require('react');
|
|
5
|
+
|
|
6
|
+
function _interopNamespace(e) {
|
|
7
|
+
if (e && e.__esModule) return e;
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
25
|
+
|
|
26
|
+
var NARROW_PX = 640;
|
|
27
|
+
var TOUCH_PX = 1024;
|
|
28
|
+
function useBelow(px) {
|
|
29
|
+
const [below, setBelow] = React__namespace.useState(false);
|
|
30
|
+
React__namespace.useEffect(() => {
|
|
31
|
+
const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
|
|
32
|
+
const apply = () => setBelow(mql.matches);
|
|
33
|
+
apply();
|
|
34
|
+
mql.addEventListener("change", apply);
|
|
35
|
+
return () => mql.removeEventListener("change", apply);
|
|
36
|
+
}, [px]);
|
|
37
|
+
return below;
|
|
38
|
+
}
|
|
39
|
+
var useIsNarrow = () => useBelow(NARROW_PX);
|
|
40
|
+
var useIsTouch = () => useBelow(TOUCH_PX);
|
|
41
|
+
|
|
42
|
+
exports.NARROW_PX = NARROW_PX;
|
|
43
|
+
exports.TOUCH_PX = TOUCH_PX;
|
|
44
|
+
exports.useBelow = useBelow;
|
|
45
|
+
exports.useIsNarrow = useIsNarrow;
|
|
46
|
+
exports.useIsTouch = useIsTouch;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Below this the UI is a phone: menus become sheets, drawers drag. */
|
|
2
|
+
declare const NARROW_PX = 640;
|
|
3
|
+
/** Below this the pointer is a finger: hover-only affordances are suppressed. */
|
|
4
|
+
declare const TOUCH_PX = 1024;
|
|
5
|
+
/** True while the viewport is narrower than `px`. */
|
|
6
|
+
declare function useBelow(px: number): boolean;
|
|
7
|
+
/** Phone-sized: present menus as sheets. */
|
|
8
|
+
declare const useIsNarrow: () => boolean;
|
|
9
|
+
/** Touch-sized: no hover, so hover-only affordances must not be the only path. */
|
|
10
|
+
declare const useIsTouch: () => boolean;
|
|
11
|
+
|
|
12
|
+
export { NARROW_PX, TOUCH_PX, useBelow, useIsNarrow, useIsTouch };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Below this the UI is a phone: menus become sheets, drawers drag. */
|
|
2
|
+
declare const NARROW_PX = 640;
|
|
3
|
+
/** Below this the pointer is a finger: hover-only affordances are suppressed. */
|
|
4
|
+
declare const TOUCH_PX = 1024;
|
|
5
|
+
/** True while the viewport is narrower than `px`. */
|
|
6
|
+
declare function useBelow(px: number): boolean;
|
|
7
|
+
/** Phone-sized: present menus as sheets. */
|
|
8
|
+
declare const useIsNarrow: () => boolean;
|
|
9
|
+
/** Touch-sized: no hover, so hover-only affordances must not be the only path. */
|
|
10
|
+
declare const useIsTouch: () => boolean;
|
|
11
|
+
|
|
12
|
+
export { NARROW_PX, TOUCH_PX, useBelow, useIsNarrow, useIsTouch };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
var NARROW_PX = 640;
|
|
5
|
+
var TOUCH_PX = 1024;
|
|
6
|
+
function useBelow(px) {
|
|
7
|
+
const [below, setBelow] = React.useState(false);
|
|
8
|
+
React.useEffect(() => {
|
|
9
|
+
const mql = window.matchMedia(`(max-width: ${px - 1}px)`);
|
|
10
|
+
const apply = () => setBelow(mql.matches);
|
|
11
|
+
apply();
|
|
12
|
+
mql.addEventListener("change", apply);
|
|
13
|
+
return () => mql.removeEventListener("change", apply);
|
|
14
|
+
}, [px]);
|
|
15
|
+
return below;
|
|
16
|
+
}
|
|
17
|
+
var useIsNarrow = () => useBelow(NARROW_PX);
|
|
18
|
+
var useIsTouch = () => useBelow(TOUCH_PX);
|
|
19
|
+
|
|
20
|
+
export { NARROW_PX, TOUCH_PX, useBelow, useIsNarrow, useIsTouch };
|
package/dist/vite.cjs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/vite.ts
|
|
4
|
+
var DEDUPE = [
|
|
5
|
+
"react",
|
|
6
|
+
"react-dom",
|
|
7
|
+
"@tanstack/react-query",
|
|
8
|
+
"@hanzo/gui",
|
|
9
|
+
"@hanzogui/core",
|
|
10
|
+
"@hanzogui/web"
|
|
11
|
+
];
|
|
12
|
+
var INCLUDE = [
|
|
13
|
+
"react-native-web",
|
|
14
|
+
"@react-native/normalize-color",
|
|
15
|
+
"@hanzo/gui",
|
|
16
|
+
"@hanzogui/core",
|
|
17
|
+
"@luxfi/ui"
|
|
18
|
+
];
|
|
19
|
+
function luxUi(options = {}) {
|
|
20
|
+
return {
|
|
21
|
+
name: "@luxfi/ui",
|
|
22
|
+
config: () => ({
|
|
23
|
+
// The engine branches on these at module scope; without them it takes the
|
|
24
|
+
// native path in a browser bundle.
|
|
25
|
+
define: {
|
|
26
|
+
"process.env.EXPO_OS": JSON.stringify("web"),
|
|
27
|
+
"process.env.IS_WEB": JSON.stringify("true")
|
|
28
|
+
},
|
|
29
|
+
resolve: {
|
|
30
|
+
alias: { "react-native": "react-native-web" },
|
|
31
|
+
dedupe: [.../* @__PURE__ */ new Set([...DEDUPE, ...options.dedupe ?? []])]
|
|
32
|
+
},
|
|
33
|
+
optimizeDeps: {
|
|
34
|
+
include: [.../* @__PURE__ */ new Set([...INCLUDE, ...options.include ?? []])]
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
exports.luxUi = luxUi;
|
package/dist/vite.d.cts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
interface LuxUiViteOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Extra packages to keep to a single physical copy. React, the gui engine and
|
|
4
|
+
* TanStack Query are always deduped.
|
|
5
|
+
*/
|
|
6
|
+
readonly dedupe?: ReadonlyArray<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Extra packages to pre-bundle. The engine, react-native-web and the CJS-only
|
|
9
|
+
* colour helper are always included.
|
|
10
|
+
*/
|
|
11
|
+
readonly include?: ReadonlyArray<string>;
|
|
12
|
+
}
|
|
13
|
+
/** Minimal structural shape of a Vite plugin — avoids a hard `vite` type dep. */
|
|
14
|
+
interface LuxUiVitePlugin {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly config: () => {
|
|
17
|
+
define: Record<string, string>;
|
|
18
|
+
resolve: {
|
|
19
|
+
alias: Record<string, string>;
|
|
20
|
+
dedupe: Array<string>;
|
|
21
|
+
};
|
|
22
|
+
optimizeDeps: {
|
|
23
|
+
include: Array<string>;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
declare function luxUi(options?: LuxUiViteOptions): LuxUiVitePlugin;
|
|
28
|
+
|
|
29
|
+
export { type LuxUiViteOptions, luxUi };
|
package/dist/vite.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
interface LuxUiViteOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Extra packages to keep to a single physical copy. React, the gui engine and
|
|
4
|
+
* TanStack Query are always deduped.
|
|
5
|
+
*/
|
|
6
|
+
readonly dedupe?: ReadonlyArray<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Extra packages to pre-bundle. The engine, react-native-web and the CJS-only
|
|
9
|
+
* colour helper are always included.
|
|
10
|
+
*/
|
|
11
|
+
readonly include?: ReadonlyArray<string>;
|
|
12
|
+
}
|
|
13
|
+
/** Minimal structural shape of a Vite plugin — avoids a hard `vite` type dep. */
|
|
14
|
+
interface LuxUiVitePlugin {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly config: () => {
|
|
17
|
+
define: Record<string, string>;
|
|
18
|
+
resolve: {
|
|
19
|
+
alias: Record<string, string>;
|
|
20
|
+
dedupe: Array<string>;
|
|
21
|
+
};
|
|
22
|
+
optimizeDeps: {
|
|
23
|
+
include: Array<string>;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
declare function luxUi(options?: LuxUiViteOptions): LuxUiVitePlugin;
|
|
28
|
+
|
|
29
|
+
export { type LuxUiViteOptions, luxUi };
|
package/dist/vite.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/vite.ts
|
|
2
|
+
var DEDUPE = [
|
|
3
|
+
"react",
|
|
4
|
+
"react-dom",
|
|
5
|
+
"@tanstack/react-query",
|
|
6
|
+
"@hanzo/gui",
|
|
7
|
+
"@hanzogui/core",
|
|
8
|
+
"@hanzogui/web"
|
|
9
|
+
];
|
|
10
|
+
var INCLUDE = [
|
|
11
|
+
"react-native-web",
|
|
12
|
+
"@react-native/normalize-color",
|
|
13
|
+
"@hanzo/gui",
|
|
14
|
+
"@hanzogui/core",
|
|
15
|
+
"@luxfi/ui"
|
|
16
|
+
];
|
|
17
|
+
function luxUi(options = {}) {
|
|
18
|
+
return {
|
|
19
|
+
name: "@luxfi/ui",
|
|
20
|
+
config: () => ({
|
|
21
|
+
// The engine branches on these at module scope; without them it takes the
|
|
22
|
+
// native path in a browser bundle.
|
|
23
|
+
define: {
|
|
24
|
+
"process.env.EXPO_OS": JSON.stringify("web"),
|
|
25
|
+
"process.env.IS_WEB": JSON.stringify("true")
|
|
26
|
+
},
|
|
27
|
+
resolve: {
|
|
28
|
+
alias: { "react-native": "react-native-web" },
|
|
29
|
+
dedupe: [.../* @__PURE__ */ new Set([...DEDUPE, ...options.dedupe ?? []])]
|
|
30
|
+
},
|
|
31
|
+
optimizeDeps: {
|
|
32
|
+
include: [.../* @__PURE__ */ new Set([...INCLUDE, ...options.include ?? []])]
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { luxUi };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/white-label.ts
|
|
4
|
+
var LUX_BRAND = {
|
|
5
|
+
lux: "#7000FF",
|
|
6
|
+
zoo: "#6C5EFB",
|
|
7
|
+
hanzo: "#EA580C",
|
|
8
|
+
pars: "#1C3879",
|
|
9
|
+
// bootno.de is its own white label with its own IdP (id.bootno.de) — accent
|
|
10
|
+
// taken from the bootnode console's own brand default, not invented here.
|
|
11
|
+
bootnode: "#3B82F6"
|
|
12
|
+
};
|
|
13
|
+
var PARS_GOLD = "#C8A45C";
|
|
14
|
+
var ORGS = {
|
|
15
|
+
lux: {
|
|
16
|
+
org: "lux",
|
|
17
|
+
name: "Lux",
|
|
18
|
+
domain: "lux.network",
|
|
19
|
+
iamDomain: "lux.id",
|
|
20
|
+
accent: LUX_BRAND.lux,
|
|
21
|
+
accentForeground: "#FFFFFF"
|
|
22
|
+
},
|
|
23
|
+
zoo: {
|
|
24
|
+
org: "zoo",
|
|
25
|
+
name: "Zoo",
|
|
26
|
+
domain: "zoo.ngo",
|
|
27
|
+
// Zoo's IdP is `id.zoo.network`, not a `zoo.id` apex — the one row in this
|
|
28
|
+
// table where the issuer is not `<org>.id`, and the one every hand-rolled
|
|
29
|
+
// per-app branding map got wrong.
|
|
30
|
+
iamDomain: "id.zoo.network",
|
|
31
|
+
accent: LUX_BRAND.zoo,
|
|
32
|
+
accentForeground: "#FFFFFF"
|
|
33
|
+
},
|
|
34
|
+
bootnode: {
|
|
35
|
+
org: "bootnode",
|
|
36
|
+
name: "Bootnode",
|
|
37
|
+
domain: "bootno.de",
|
|
38
|
+
iamDomain: "id.bootno.de",
|
|
39
|
+
accent: LUX_BRAND.lux,
|
|
40
|
+
accentForeground: "#FFFFFF"
|
|
41
|
+
},
|
|
42
|
+
hanzo: {
|
|
43
|
+
org: "hanzo",
|
|
44
|
+
name: "Hanzo",
|
|
45
|
+
domain: "hanzo.ai",
|
|
46
|
+
iamDomain: "hanzo.id",
|
|
47
|
+
accent: LUX_BRAND.hanzo,
|
|
48
|
+
accentForeground: "#FFFFFF"
|
|
49
|
+
},
|
|
50
|
+
pars: {
|
|
51
|
+
org: "pars",
|
|
52
|
+
name: "Pars",
|
|
53
|
+
domain: "pars.id",
|
|
54
|
+
iamDomain: "pars.id",
|
|
55
|
+
accent: LUX_BRAND.pars,
|
|
56
|
+
accentForeground: PARS_GOLD
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var DOMAIN_ORG = [
|
|
60
|
+
["lux.network", "lux"],
|
|
61
|
+
["lux.cloud", "lux"],
|
|
62
|
+
["lux.id", "lux"],
|
|
63
|
+
["lux.finance", "lux"],
|
|
64
|
+
["zoo.ngo", "zoo"],
|
|
65
|
+
["zoo.network", "zoo"],
|
|
66
|
+
["zoo.cloud", "zoo"],
|
|
67
|
+
["zoo.id", "zoo"],
|
|
68
|
+
["hanzo.ai", "hanzo"],
|
|
69
|
+
["hanzo.cloud", "hanzo"],
|
|
70
|
+
["hanzo.id", "hanzo"],
|
|
71
|
+
["pars.id", "pars"],
|
|
72
|
+
["parsdao.org", "pars"],
|
|
73
|
+
["bootno.de", "bootnode", "platform"]
|
|
74
|
+
];
|
|
75
|
+
var DEFAULT_ORG = "lux";
|
|
76
|
+
function normalizeHost(host) {
|
|
77
|
+
const noPort = host.trim().toLowerCase().split(":")[0] ?? "";
|
|
78
|
+
return noPort.replace(/\.$/, "");
|
|
79
|
+
}
|
|
80
|
+
function isUnder(host, domain) {
|
|
81
|
+
return host === domain || host.endsWith(`.${domain}`);
|
|
82
|
+
}
|
|
83
|
+
function matchDomain(host) {
|
|
84
|
+
let best;
|
|
85
|
+
for (const entry of DOMAIN_ORG) {
|
|
86
|
+
if (isUnder(host, entry[0]) && (!best || entry[0].length > best[0].length)) {
|
|
87
|
+
best = entry;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return best;
|
|
91
|
+
}
|
|
92
|
+
function appSlug(host, domain, apexApp) {
|
|
93
|
+
const sub = host === domain ? "" : host.slice(0, -(domain.length + 1));
|
|
94
|
+
const leftmost = sub.split(".")[0] ?? "";
|
|
95
|
+
if (leftmost && leftmost !== "www") return leftmost;
|
|
96
|
+
if (apexApp) return apexApp;
|
|
97
|
+
const label = domain.split(".")[0] ?? "";
|
|
98
|
+
const tld = domain.split(".").slice(1).join(".");
|
|
99
|
+
return tld.split(".")[0] || label;
|
|
100
|
+
}
|
|
101
|
+
function isLocal(host) {
|
|
102
|
+
return host === "localhost" || host.endsWith(".localhost") || host === "127.0.0.1" || host === "0.0.0.0" || host === "[::1]" || host.endsWith(".local");
|
|
103
|
+
}
|
|
104
|
+
function resolveWhiteLabel(host) {
|
|
105
|
+
const h = normalizeHost(host ?? "");
|
|
106
|
+
const match = h ? matchDomain(h) : void 0;
|
|
107
|
+
const org = match ? match[1] : DEFAULT_ORG;
|
|
108
|
+
const identity = ORGS[org];
|
|
109
|
+
const app = match ? appSlug(h, match[0], match[2]) : h && isLocal(h) ? "local" : "app";
|
|
110
|
+
return {
|
|
111
|
+
...identity,
|
|
112
|
+
host: h,
|
|
113
|
+
app,
|
|
114
|
+
theme: `dark_${org}`,
|
|
115
|
+
issuer: `https://${identity.iamDomain}`,
|
|
116
|
+
clientId: `${org}-${app}`
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function currentHost() {
|
|
120
|
+
return typeof window === "undefined" ? "" : window.location.host;
|
|
121
|
+
}
|
|
122
|
+
function orgIdentity(org) {
|
|
123
|
+
return ORGS[org];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
exports.DEFAULT_ORG = DEFAULT_ORG;
|
|
127
|
+
exports.LUX_BRAND = LUX_BRAND;
|
|
128
|
+
exports.PARS_GOLD = PARS_GOLD;
|
|
129
|
+
exports.currentHost = currentHost;
|
|
130
|
+
exports.orgIdentity = orgIdentity;
|
|
131
|
+
exports.orgs = ORGS;
|
|
132
|
+
exports.resolveWhiteLabel = resolveWhiteLabel;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
declare const LUX_BRAND: {
|
|
2
|
+
readonly lux: "#7000FF";
|
|
3
|
+
readonly zoo: "#6C5EFB";
|
|
4
|
+
readonly hanzo: "#EA580C";
|
|
5
|
+
readonly pars: "#1C3879";
|
|
6
|
+
readonly bootnode: "#3B82F6";
|
|
7
|
+
};
|
|
8
|
+
declare const PARS_GOLD = "#C8A45C";
|
|
9
|
+
type LuxBrand = keyof typeof LUX_BRAND;
|
|
10
|
+
type Org = LuxBrand;
|
|
11
|
+
interface OrgIdentity {
|
|
12
|
+
/** Org id — also the gui child-theme suffix (`dark_lux`, `dark_zoo`, …). */
|
|
13
|
+
readonly org: Org;
|
|
14
|
+
/** Display name for chrome (header, title, sign-in copy). */
|
|
15
|
+
readonly name: string;
|
|
16
|
+
/** Canonical apex domain. */
|
|
17
|
+
readonly domain: string;
|
|
18
|
+
/** IAM/OIDC host. The issuer is `https://` + this. */
|
|
19
|
+
readonly iamDomain: string;
|
|
20
|
+
/** Brand accent hex — the same value the gui child-theme row is built from. */
|
|
21
|
+
readonly accent: string;
|
|
22
|
+
/** Foreground used on top of the accent. */
|
|
23
|
+
readonly accentForeground: string;
|
|
24
|
+
}
|
|
25
|
+
declare const ORGS: Readonly<Record<Org, OrgIdentity>>;
|
|
26
|
+
declare const DEFAULT_ORG: Org;
|
|
27
|
+
interface WhiteLabel extends OrgIdentity {
|
|
28
|
+
/** Hostname the identity was resolved from, port stripped, lowercased. */
|
|
29
|
+
readonly host: string;
|
|
30
|
+
/** App slug taken from the hostname — `mpc.lux.cloud` → `mpc`. */
|
|
31
|
+
readonly app: string;
|
|
32
|
+
/** gui child-theme row to hand GuiProvider — `dark_lux`, `dark_zoo`, … */
|
|
33
|
+
readonly theme: string;
|
|
34
|
+
/** OIDC issuer — `https://lux.id`. */
|
|
35
|
+
readonly issuer: string;
|
|
36
|
+
/** IAM client id, `<org>-<app>` per the fleet naming scheme — `lux-mpc`. */
|
|
37
|
+
readonly clientId: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the full white-label identity from a Host header value.
|
|
41
|
+
*
|
|
42
|
+
* Pure and total: an unknown or missing host falls back to the Lux row rather
|
|
43
|
+
* than throwing, so a preview URL or a health probe never blanks the UI.
|
|
44
|
+
*
|
|
45
|
+
* resolveWhiteLabel('mpc.lux.cloud') // org lux, clientId lux-mpc, issuer https://lux.id
|
|
46
|
+
* resolveWhiteLabel('zoo.network') // org zoo, clientId zoo-network, issuer https://zoo.id
|
|
47
|
+
* resolveWhiteLabel('id.pars.id') // org pars, clientId pars-id, issuer https://pars.id
|
|
48
|
+
*/
|
|
49
|
+
declare function resolveWhiteLabel(host?: string | null): WhiteLabel;
|
|
50
|
+
/**
|
|
51
|
+
* The current host in a browser, or '' during SSR / prerender.
|
|
52
|
+
* Server code must pass `req.headers.host` to resolveWhiteLabel explicitly —
|
|
53
|
+
* there is no ambient request here, and guessing would bake in a brand.
|
|
54
|
+
*/
|
|
55
|
+
declare function currentHost(): string;
|
|
56
|
+
/** Identity for the org id itself, for the rare surface that is not host-routed. */
|
|
57
|
+
declare function orgIdentity(org: Org): OrgIdentity;
|
|
58
|
+
|
|
59
|
+
export { DEFAULT_ORG, LUX_BRAND, type LuxBrand, type Org, type OrgIdentity, PARS_GOLD, type WhiteLabel, currentHost, orgIdentity, ORGS as orgs, resolveWhiteLabel };
|