@xaui/hybrid 0.0.8 → 0.0.9
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/index.d.ts +2 -0
- package/dist/alert/index.js +6 -0
- package/dist/chunk-7HVBAJHB.js +326 -0
- package/dist/chunk-YJF3QRMW.js +177 -0
- package/dist/core/index.d.ts +3 -20
- package/dist/core/index.js +10 -79
- package/dist/index-5BCfEjU-.d.ts +63 -0
- package/dist/index-CMptPfU-.d.ts +51 -0
- package/dist/index.css +305 -0
- package/dist/index.d.ts +12 -1
- package/dist/index.js +28 -0
- package/package.json +7 -22
- package/dist/core/index.cjs +0 -125
- package/dist/core/index.d.cts +0 -20
- package/dist/index.cjs +0 -18
- package/dist/index.d.cts +0 -2
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// src/components/alert/alert.style.ts
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
var alertStyles = tv({
|
|
4
|
+
slots: {
|
|
5
|
+
container: "xui-alert flex flex-row items-center w-full gap-3 bg-[var(--xui-alert-bg)] [border-width:var(--xui-alert-border-width)] [border-color:var(--xui-alert-border-color)] px-[var(--xui-spacing-md)] py-[var(--xui-spacing-sm)]",
|
|
6
|
+
mainWrapper: "flex-1 flex-col justify-center gap-0.5",
|
|
7
|
+
iconWrapper: "size-7 rounded-full flex items-center justify-center shrink-0 text-[var(--xui-alert-text)] bg-[var(--xui-alert-icon-bg)] [border-width:var(--xui-alert-icon-border-width)] [border-color:var(--xui-alert-icon-border-color)]",
|
|
8
|
+
title: "m-0 leading-tight text-[var(--xui-alert-text)] text-[length:var(--xui-text-sm)] font-[var(--xui-font-semibold)]",
|
|
9
|
+
description: "m-0 mt-1 leading-none text-[var(--xui-alert-description)] text-[length:var(--xui-text-xs)] font-[var(--xui-font-normal)]",
|
|
10
|
+
iconText: "font-[var(--xui-font-semibold)]",
|
|
11
|
+
closeButton: "self-start p-1 cursor-pointer bg-transparent border-0 rounded flex text-[var(--xui-alert-text)]",
|
|
12
|
+
extraContent: "mt-1"
|
|
13
|
+
},
|
|
14
|
+
variants: {
|
|
15
|
+
themeColor: {
|
|
16
|
+
default: {
|
|
17
|
+
container: "[--xui-alert-main:var(--xui-default)] [--xui-alert-fg:var(--xui-default-fg)] [--xui-alert-bg-base:var(--xui-default-bg)] [--xui-alert-text-base:var(--xui-foreground)] [--xui-alert-accent:var(--xui-foreground)]"
|
|
18
|
+
},
|
|
19
|
+
primary: {
|
|
20
|
+
container: "[--xui-alert-main:var(--xui-primary)] [--xui-alert-fg:var(--xui-primary-fg)] [--xui-alert-bg-base:var(--xui-primary-bg)] [--xui-alert-text-base:var(--xui-primary)] [--xui-alert-accent:var(--xui-primary)]"
|
|
21
|
+
},
|
|
22
|
+
secondary: {
|
|
23
|
+
container: "[--xui-alert-main:var(--xui-secondary)] [--xui-alert-fg:var(--xui-secondary-fg)] [--xui-alert-bg-base:var(--xui-secondary-bg)] [--xui-alert-text-base:var(--xui-secondary)] [--xui-alert-accent:var(--xui-secondary)]"
|
|
24
|
+
},
|
|
25
|
+
tertiary: {
|
|
26
|
+
container: "[--xui-alert-main:var(--xui-tertiary)] [--xui-alert-fg:var(--xui-tertiary-fg)] [--xui-alert-bg-base:var(--xui-tertiary-bg)] [--xui-alert-text-base:var(--xui-tertiary)] [--xui-alert-accent:var(--xui-tertiary)]"
|
|
27
|
+
},
|
|
28
|
+
success: {
|
|
29
|
+
container: "[--xui-alert-main:var(--xui-success)] [--xui-alert-fg:var(--xui-success-fg)] [--xui-alert-bg-base:var(--xui-success-bg)] [--xui-alert-text-base:var(--xui-success)] [--xui-alert-accent:var(--xui-success)]"
|
|
30
|
+
},
|
|
31
|
+
warning: {
|
|
32
|
+
container: "[--xui-alert-main:var(--xui-warning)] [--xui-alert-fg:var(--xui-warning-fg)] [--xui-alert-bg-base:var(--xui-warning-bg)] [--xui-alert-text-base:var(--xui-warning)] [--xui-alert-accent:var(--xui-warning)]"
|
|
33
|
+
},
|
|
34
|
+
danger: {
|
|
35
|
+
container: "[--xui-alert-main:var(--xui-danger)] [--xui-alert-fg:var(--xui-danger-fg)] [--xui-alert-bg-base:var(--xui-danger-bg)] [--xui-alert-text-base:var(--xui-danger)] [--xui-alert-accent:var(--xui-danger)]"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
variant: {
|
|
39
|
+
solid: {
|
|
40
|
+
container: "[--xui-alert-bg:var(--xui-alert-solid-bg)] [--xui-alert-text:var(--xui-alert-solid-text)] [--xui-alert-description:color-mix(in_srgb,var(--xui-alert-solid-text)_75%,transparent)] [--xui-alert-border-width:0px] [--xui-alert-border-color:transparent]",
|
|
41
|
+
iconWrapper: "[--xui-alert-icon-bg:var(--xui-alert-solid-icon-bg)] [--xui-alert-icon-border-width:0px] [--xui-alert-icon-border-color:transparent]"
|
|
42
|
+
},
|
|
43
|
+
flat: {
|
|
44
|
+
container: "[--xui-alert-bg:var(--xui-alert-flat-bg)] [--xui-alert-text:var(--xui-alert-text-base)] [--xui-alert-description:color-mix(in_srgb,var(--xui-alert-text-base)_75%,transparent)] [--xui-alert-border-width:0px] [--xui-alert-border-color:transparent]",
|
|
45
|
+
iconWrapper: "[--xui-alert-icon-bg:color-mix(in_srgb,var(--xui-alert-accent)_12%,transparent)] [--xui-alert-icon-border-width:0px] [--xui-alert-icon-border-color:transparent]"
|
|
46
|
+
},
|
|
47
|
+
bordered: {
|
|
48
|
+
container: "border-solid [--xui-alert-bg:transparent] [--xui-alert-text:var(--xui-alert-text-base)] [--xui-alert-description:color-mix(in_srgb,var(--xui-alert-text-base)_75%,transparent)] [--xui-alert-border-width:var(--xui-border-md)] [--xui-alert-border-color:color-mix(in_srgb,var(--xui-alert-main)_75%,transparent)]",
|
|
49
|
+
iconWrapper: "border-solid [--xui-alert-icon-bg:color-mix(in_srgb,var(--xui-alert-accent)_12%,transparent)] [--xui-alert-icon-border-width:var(--xui-border-xs)] [--xui-alert-icon-border-color:color-mix(in_srgb,var(--xui-alert-accent)_20%,transparent)]"
|
|
50
|
+
},
|
|
51
|
+
faded: {
|
|
52
|
+
container: "border-solid [--xui-alert-bg:color-mix(in_srgb,var(--xui-alert-bg-base)_75%,transparent)] [--xui-alert-text:var(--xui-alert-text-base)] [--xui-alert-description:color-mix(in_srgb,var(--xui-alert-text-base)_75%,transparent)] [--xui-alert-border-width:var(--xui-border-md)] [--xui-alert-border-color:color-mix(in_srgb,var(--xui-alert-accent)_25%,transparent)]",
|
|
53
|
+
iconWrapper: "border-solid [--xui-alert-icon-bg:color-mix(in_srgb,var(--xui-alert-accent)_12%,transparent)] [--xui-alert-icon-border-width:var(--xui-border-xs)] [--xui-alert-icon-border-color:color-mix(in_srgb,var(--xui-alert-accent)_20%,transparent)]"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
radius: {
|
|
57
|
+
none: { container: "rounded-[var(--xui-radius-none)]" },
|
|
58
|
+
sm: { container: "rounded-[var(--xui-radius-sm)]" },
|
|
59
|
+
md: { container: "rounded-[var(--xui-radius-md)]" },
|
|
60
|
+
lg: { container: "rounded-[var(--xui-radius-lg)]" },
|
|
61
|
+
full: { container: "rounded-[var(--xui-radius-full)]" }
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
defaultVariants: {
|
|
65
|
+
themeColor: "default",
|
|
66
|
+
variant: "flat",
|
|
67
|
+
radius: "md"
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// src/components/alert/alert.hook.tsx
|
|
72
|
+
import {
|
|
73
|
+
cloneElement,
|
|
74
|
+
isValidElement,
|
|
75
|
+
useCallback,
|
|
76
|
+
useEffect,
|
|
77
|
+
useMemo,
|
|
78
|
+
useRef,
|
|
79
|
+
useState
|
|
80
|
+
} from "react";
|
|
81
|
+
|
|
82
|
+
// src/components/alert/alert-icons.tsx
|
|
83
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
84
|
+
function InfoIcon({ color, size }) {
|
|
85
|
+
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", overflow: "hidden", children: [
|
|
86
|
+
/* @__PURE__ */ jsx("circle", { cx: 12, cy: 12, r: 10, stroke: color, strokeWidth: 2 }),
|
|
87
|
+
/* @__PURE__ */ jsx("line", { x1: 12, y1: 10, x2: 12, y2: 16, stroke: color, strokeWidth: 2, strokeLinecap: "round" }),
|
|
88
|
+
/* @__PURE__ */ jsx("circle", { cx: 12, cy: 7, r: 1, fill: color })
|
|
89
|
+
] });
|
|
90
|
+
}
|
|
91
|
+
function SuccessIcon({ color, size }) {
|
|
92
|
+
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", overflow: "hidden", children: [
|
|
93
|
+
/* @__PURE__ */ jsx("circle", { cx: 12, cy: 12, r: 10, stroke: color, strokeWidth: 2 }),
|
|
94
|
+
/* @__PURE__ */ jsx(
|
|
95
|
+
"path",
|
|
96
|
+
{
|
|
97
|
+
d: "M7 12.5L10.2 15.5L17 9",
|
|
98
|
+
stroke: color,
|
|
99
|
+
strokeWidth: 2,
|
|
100
|
+
strokeLinecap: "round",
|
|
101
|
+
strokeLinejoin: "round"
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
106
|
+
function WarningIcon({ color, size }) {
|
|
107
|
+
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 26 26", fill: "none", overflow: "hidden", children: [
|
|
108
|
+
/* @__PURE__ */ jsx(
|
|
109
|
+
"path",
|
|
110
|
+
{
|
|
111
|
+
d: "M13 3.5L22.5 21H3.5L13 3.5Z",
|
|
112
|
+
stroke: color,
|
|
113
|
+
strokeWidth: 2,
|
|
114
|
+
strokeLinejoin: "round"
|
|
115
|
+
}
|
|
116
|
+
),
|
|
117
|
+
/* @__PURE__ */ jsx("line", { x1: 13, y1: 10, x2: 13, y2: 15, stroke: color, strokeWidth: 2, strokeLinecap: "round" }),
|
|
118
|
+
/* @__PURE__ */ jsx("circle", { cx: 13, cy: 18, r: 1, fill: color })
|
|
119
|
+
] });
|
|
120
|
+
}
|
|
121
|
+
function DangerIcon({ color, size }) {
|
|
122
|
+
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", overflow: "hidden", children: [
|
|
123
|
+
/* @__PURE__ */ jsx("circle", { cx: 12, cy: 12, r: 10, stroke: color, strokeWidth: 2 }),
|
|
124
|
+
/* @__PURE__ */ jsx("line", { x1: 9, y1: 9, x2: 15, y2: 15, stroke: color, strokeWidth: 2, strokeLinecap: "round" }),
|
|
125
|
+
/* @__PURE__ */ jsx("line", { x1: 15, y1: 9, x2: 9, y2: 15, stroke: color, strokeWidth: 2, strokeLinecap: "round" })
|
|
126
|
+
] });
|
|
127
|
+
}
|
|
128
|
+
function CloseIcon({ color, size }) {
|
|
129
|
+
return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", overflow: "hidden", children: [
|
|
130
|
+
/* @__PURE__ */ jsx("line", { x1: 18, y1: 6, x2: 6, y2: 18, stroke: color, strokeWidth: 2, strokeLinecap: "round" }),
|
|
131
|
+
/* @__PURE__ */ jsx("line", { x1: 6, y1: 6, x2: 18, y2: 18, stroke: color, strokeWidth: 2, strokeLinecap: "round" })
|
|
132
|
+
] });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// src/components/alert/alert.hook.tsx
|
|
136
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
137
|
+
var iconMap = {
|
|
138
|
+
default: InfoIcon,
|
|
139
|
+
primary: InfoIcon,
|
|
140
|
+
secondary: InfoIcon,
|
|
141
|
+
tertiary: InfoIcon,
|
|
142
|
+
success: SuccessIcon,
|
|
143
|
+
warning: WarningIcon,
|
|
144
|
+
danger: DangerIcon
|
|
145
|
+
};
|
|
146
|
+
var useAlertVisibility = ({
|
|
147
|
+
isVisible,
|
|
148
|
+
onClose,
|
|
149
|
+
onVisibleChange
|
|
150
|
+
}) => {
|
|
151
|
+
const [internalVisible, setInternalVisible] = useState(isVisible ?? true);
|
|
152
|
+
const [shouldRender, setShouldRender] = useState(isVisible ?? true);
|
|
153
|
+
const [animState, setAnimState] = useState("open");
|
|
154
|
+
const isInitialMount = useRef(true);
|
|
155
|
+
const isControlled = typeof isVisible === "boolean";
|
|
156
|
+
const visible = isControlled ? isVisible : internalVisible;
|
|
157
|
+
const finishClosing = useCallback(() => {
|
|
158
|
+
setShouldRender(false);
|
|
159
|
+
if (!isControlled) {
|
|
160
|
+
setInternalVisible(false);
|
|
161
|
+
}
|
|
162
|
+
onVisibleChange?.(false);
|
|
163
|
+
onClose?.();
|
|
164
|
+
}, [isControlled, onClose, onVisibleChange]);
|
|
165
|
+
const handleClose = useCallback(() => {
|
|
166
|
+
if (!visible) return;
|
|
167
|
+
setAnimState("closed");
|
|
168
|
+
}, [visible]);
|
|
169
|
+
const handleAnimationEnd = useCallback(() => {
|
|
170
|
+
if (animState === "closed") {
|
|
171
|
+
finishClosing();
|
|
172
|
+
}
|
|
173
|
+
}, [animState, finishClosing]);
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
if (isInitialMount.current) {
|
|
176
|
+
isInitialMount.current = false;
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (visible && !shouldRender) {
|
|
180
|
+
setShouldRender(true);
|
|
181
|
+
setAnimState("open");
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (!visible && shouldRender) {
|
|
185
|
+
handleClose();
|
|
186
|
+
}
|
|
187
|
+
}, [visible, shouldRender, handleClose]);
|
|
188
|
+
return {
|
|
189
|
+
shouldRender,
|
|
190
|
+
animState,
|
|
191
|
+
handleClose,
|
|
192
|
+
handleAnimationEnd
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
var useAlertIconNode = ({
|
|
196
|
+
hideIcon,
|
|
197
|
+
icon,
|
|
198
|
+
themeColor,
|
|
199
|
+
slots
|
|
200
|
+
}) => {
|
|
201
|
+
return useMemo(() => {
|
|
202
|
+
if (hideIcon) return null;
|
|
203
|
+
if (icon && isValidElement(icon)) {
|
|
204
|
+
return cloneElement(icon, { color: "currentColor", size: 18 });
|
|
205
|
+
}
|
|
206
|
+
if (icon) {
|
|
207
|
+
return /* @__PURE__ */ jsx2("span", { className: slots.iconText(), children: icon });
|
|
208
|
+
}
|
|
209
|
+
const IconComponent = iconMap[themeColor ?? "default"] ?? InfoIcon;
|
|
210
|
+
return /* @__PURE__ */ jsx2(IconComponent, { color: "currentColor", size: 18 });
|
|
211
|
+
}, [hideIcon, icon, slots, themeColor]);
|
|
212
|
+
};
|
|
213
|
+
var useAlertContentNodes = ({
|
|
214
|
+
title,
|
|
215
|
+
description,
|
|
216
|
+
children,
|
|
217
|
+
customAppearance,
|
|
218
|
+
slots
|
|
219
|
+
}) => {
|
|
220
|
+
const renderContentText = useCallback(
|
|
221
|
+
(content) => {
|
|
222
|
+
if (content === null || content === void 0) return null;
|
|
223
|
+
if (typeof content === "string" || typeof content === "number") {
|
|
224
|
+
return /* @__PURE__ */ jsx2("p", { className: slots.description(), style: customAppearance?.description, children: content });
|
|
225
|
+
}
|
|
226
|
+
return content;
|
|
227
|
+
},
|
|
228
|
+
[customAppearance?.description, slots]
|
|
229
|
+
);
|
|
230
|
+
const titleNode = useMemo(() => {
|
|
231
|
+
if (title === null || title === void 0) return null;
|
|
232
|
+
if (typeof title === "string" || typeof title === "number") {
|
|
233
|
+
return /* @__PURE__ */ jsx2("p", { className: slots.title(), style: customAppearance?.title, children: title });
|
|
234
|
+
}
|
|
235
|
+
return title;
|
|
236
|
+
}, [title, customAppearance?.title, slots]);
|
|
237
|
+
const descriptionNode = renderContentText(description);
|
|
238
|
+
const childrenNode = renderContentText(children);
|
|
239
|
+
return { titleNode, descriptionNode, childrenNode };
|
|
240
|
+
};
|
|
241
|
+
var useAlertCloseButtonNode = ({
|
|
242
|
+
closeButton,
|
|
243
|
+
handleClose
|
|
244
|
+
}) => {
|
|
245
|
+
return useMemo(() => {
|
|
246
|
+
if (!closeButton) return null;
|
|
247
|
+
if (!isValidElement(closeButton)) return closeButton;
|
|
248
|
+
const existingOnClick = closeButton.props.onClick;
|
|
249
|
+
return cloneElement(closeButton, {
|
|
250
|
+
onClick: (e) => {
|
|
251
|
+
existingOnClick?.(e);
|
|
252
|
+
handleClose();
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}, [closeButton, handleClose]);
|
|
256
|
+
};
|
|
257
|
+
var DefaultAlertCloseButton = ({
|
|
258
|
+
onClick,
|
|
259
|
+
className
|
|
260
|
+
}) => /* @__PURE__ */ jsx2("button", { type: "button", "aria-label": "Close", onClick, className, children: /* @__PURE__ */ jsx2(CloseIcon, { size: 20, color: "currentColor" }) });
|
|
261
|
+
|
|
262
|
+
// src/components/alert/alert.tsx
|
|
263
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
264
|
+
var Alert = ({
|
|
265
|
+
title,
|
|
266
|
+
description,
|
|
267
|
+
icon,
|
|
268
|
+
themeColor = "default",
|
|
269
|
+
variant = "flat",
|
|
270
|
+
radius = "md",
|
|
271
|
+
isClosable = false,
|
|
272
|
+
hideIcon = false,
|
|
273
|
+
closeButton,
|
|
274
|
+
isVisible,
|
|
275
|
+
customAppearance,
|
|
276
|
+
children,
|
|
277
|
+
onClose,
|
|
278
|
+
onVisibleChange
|
|
279
|
+
}) => {
|
|
280
|
+
const slots = alertStyles({ variant, themeColor, radius });
|
|
281
|
+
const { shouldRender, animState, handleClose, handleAnimationEnd } = useAlertVisibility({
|
|
282
|
+
isVisible,
|
|
283
|
+
onClose,
|
|
284
|
+
onVisibleChange
|
|
285
|
+
});
|
|
286
|
+
const shouldShowClose = Boolean(closeButton || isClosable || onClose);
|
|
287
|
+
const iconNode = useAlertIconNode({ hideIcon, icon, themeColor, slots });
|
|
288
|
+
const { titleNode, descriptionNode, childrenNode } = useAlertContentNodes({
|
|
289
|
+
title,
|
|
290
|
+
description,
|
|
291
|
+
children,
|
|
292
|
+
customAppearance,
|
|
293
|
+
slots
|
|
294
|
+
});
|
|
295
|
+
const closeButtonNode = useAlertCloseButtonNode({ closeButton, handleClose });
|
|
296
|
+
if (!shouldRender) return null;
|
|
297
|
+
return /* @__PURE__ */ jsxs2(
|
|
298
|
+
"div",
|
|
299
|
+
{
|
|
300
|
+
role: "alert",
|
|
301
|
+
"data-xui-state": animState,
|
|
302
|
+
className: slots.container(),
|
|
303
|
+
style: customAppearance?.container,
|
|
304
|
+
onAnimationEnd: handleAnimationEnd,
|
|
305
|
+
children: [
|
|
306
|
+
!hideIcon && /* @__PURE__ */ jsx3("div", { className: slots.iconWrapper(), children: iconNode }),
|
|
307
|
+
/* @__PURE__ */ jsxs2("div", { className: slots.mainWrapper(), children: [
|
|
308
|
+
titleNode,
|
|
309
|
+
descriptionNode,
|
|
310
|
+
childrenNode && /* @__PURE__ */ jsx3("div", { className: slots.extraContent(), children: childrenNode })
|
|
311
|
+
] }),
|
|
312
|
+
shouldShowClose && /* @__PURE__ */ jsx3("div", { children: closeButtonNode ?? /* @__PURE__ */ jsx3(
|
|
313
|
+
DefaultAlertCloseButton,
|
|
314
|
+
{
|
|
315
|
+
onClick: handleClose,
|
|
316
|
+
className: slots.closeButton()
|
|
317
|
+
}
|
|
318
|
+
) })
|
|
319
|
+
]
|
|
320
|
+
}
|
|
321
|
+
);
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
export {
|
|
325
|
+
Alert
|
|
326
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// src/core/theme-provider.tsx
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
4
|
+
var getSystemColorMode = () => {
|
|
5
|
+
if (typeof globalThis === "undefined" || !globalThis.matchMedia) return "light";
|
|
6
|
+
return globalThis.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
7
|
+
};
|
|
8
|
+
function XUIProvider({
|
|
9
|
+
children,
|
|
10
|
+
colorScheme,
|
|
11
|
+
target = "html",
|
|
12
|
+
variables,
|
|
13
|
+
darkVariables
|
|
14
|
+
}) {
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (typeof document === "undefined") return;
|
|
17
|
+
const root = document.documentElement;
|
|
18
|
+
const styleTarget = target === "body" ? document.body : root;
|
|
19
|
+
if (!styleTarget) return;
|
|
20
|
+
const resolvedMode = colorScheme ?? getSystemColorMode();
|
|
21
|
+
root.dataset.colorScheme = resolvedMode;
|
|
22
|
+
const activeVars = resolvedMode === "dark" ? { ...variables, ...darkVariables } : variables;
|
|
23
|
+
if (!activeVars) return;
|
|
24
|
+
const appliedKeys = [];
|
|
25
|
+
for (const [key, value] of Object.entries(activeVars)) {
|
|
26
|
+
if (value === void 0 || value === null) continue;
|
|
27
|
+
styleTarget.style.setProperty(key, String(value));
|
|
28
|
+
appliedKeys.push(key);
|
|
29
|
+
}
|
|
30
|
+
return () => {
|
|
31
|
+
for (const key of appliedKeys) {
|
|
32
|
+
styleTarget.style.removeProperty(key);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}, [colorScheme, darkVariables, target, variables]);
|
|
36
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/core/theme-hooks.ts
|
|
40
|
+
import { useEffect as useEffect2, useMemo, useState } from "react";
|
|
41
|
+
var getDocumentColorMode = () => {
|
|
42
|
+
if (typeof document === "undefined") return null;
|
|
43
|
+
const scheme = document.documentElement.dataset.colorScheme;
|
|
44
|
+
return scheme === "dark" || scheme === "light" ? scheme : null;
|
|
45
|
+
};
|
|
46
|
+
var getWebColorMode = () => {
|
|
47
|
+
if (typeof globalThis === "undefined") return "light";
|
|
48
|
+
const globalScope = globalThis;
|
|
49
|
+
if (!globalScope.matchMedia) return "light";
|
|
50
|
+
return globalScope.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
51
|
+
};
|
|
52
|
+
function useColorMode() {
|
|
53
|
+
const [webScheme, setWebScheme] = useState(() => getWebColorMode());
|
|
54
|
+
useEffect2(() => {
|
|
55
|
+
if (typeof globalThis === "undefined") return;
|
|
56
|
+
const globalScope = globalThis;
|
|
57
|
+
if (!globalScope.matchMedia) return;
|
|
58
|
+
const media = globalScope.matchMedia("(prefers-color-scheme: dark)");
|
|
59
|
+
const handleChange = () => {
|
|
60
|
+
setWebScheme(media.matches ? "dark" : "light");
|
|
61
|
+
};
|
|
62
|
+
handleChange();
|
|
63
|
+
if (typeof media.addEventListener === "function") {
|
|
64
|
+
media.addEventListener("change", handleChange);
|
|
65
|
+
return () => media.removeEventListener?.("change", handleChange);
|
|
66
|
+
}
|
|
67
|
+
const legacyMedia = media;
|
|
68
|
+
legacyMedia.addListener?.(handleChange);
|
|
69
|
+
return () => legacyMedia.removeListener?.(handleChange);
|
|
70
|
+
}, []);
|
|
71
|
+
return webScheme;
|
|
72
|
+
}
|
|
73
|
+
function useXUITheme() {
|
|
74
|
+
const systemScheme = useColorMode();
|
|
75
|
+
const [documentScheme, setDocumentScheme] = useState(
|
|
76
|
+
() => getDocumentColorMode()
|
|
77
|
+
);
|
|
78
|
+
useEffect2(() => {
|
|
79
|
+
if (typeof document === "undefined") return;
|
|
80
|
+
const node = document.documentElement;
|
|
81
|
+
const update = () => setDocumentScheme(getDocumentColorMode());
|
|
82
|
+
update();
|
|
83
|
+
const observer = new MutationObserver(update);
|
|
84
|
+
observer.observe(node, {
|
|
85
|
+
attributes: true,
|
|
86
|
+
attributeFilter: ["data-color-scheme"]
|
|
87
|
+
});
|
|
88
|
+
return () => observer.disconnect();
|
|
89
|
+
}, []);
|
|
90
|
+
const resolvedScheme = documentScheme ?? systemScheme;
|
|
91
|
+
return useMemo(
|
|
92
|
+
() => ({
|
|
93
|
+
mode: resolvedScheme,
|
|
94
|
+
palette: {
|
|
95
|
+
primary: "var(--xui-primary)",
|
|
96
|
+
secondary: "var(--xui-secondary)",
|
|
97
|
+
tertiary: "var(--xui-tertiary)",
|
|
98
|
+
danger: "var(--xui-danger)",
|
|
99
|
+
warning: "var(--xui-warning)",
|
|
100
|
+
success: "var(--xui-success)",
|
|
101
|
+
default: "var(--xui-default)"
|
|
102
|
+
},
|
|
103
|
+
colors: {
|
|
104
|
+
primary: {
|
|
105
|
+
main: "var(--xui-primary)",
|
|
106
|
+
foreground: "var(--xui-primary-fg)",
|
|
107
|
+
background: "var(--xui-primary-bg)"
|
|
108
|
+
},
|
|
109
|
+
secondary: {
|
|
110
|
+
main: "var(--xui-secondary)",
|
|
111
|
+
foreground: "var(--xui-secondary-fg)",
|
|
112
|
+
background: "var(--xui-secondary-bg)"
|
|
113
|
+
},
|
|
114
|
+
tertiary: {
|
|
115
|
+
main: "var(--xui-tertiary)",
|
|
116
|
+
foreground: "var(--xui-tertiary-fg)",
|
|
117
|
+
background: "var(--xui-tertiary-bg)"
|
|
118
|
+
},
|
|
119
|
+
danger: {
|
|
120
|
+
main: "var(--xui-danger)",
|
|
121
|
+
foreground: "var(--xui-danger-fg)",
|
|
122
|
+
background: "var(--xui-danger-bg)"
|
|
123
|
+
},
|
|
124
|
+
warning: {
|
|
125
|
+
main: "var(--xui-warning)",
|
|
126
|
+
foreground: "var(--xui-warning-fg)",
|
|
127
|
+
background: "var(--xui-warning-bg)"
|
|
128
|
+
},
|
|
129
|
+
success: {
|
|
130
|
+
main: "var(--xui-success)",
|
|
131
|
+
foreground: "var(--xui-success-fg)",
|
|
132
|
+
background: "var(--xui-success-bg)"
|
|
133
|
+
},
|
|
134
|
+
default: {
|
|
135
|
+
main: "var(--xui-default)",
|
|
136
|
+
foreground: "var(--xui-default-fg)",
|
|
137
|
+
background: "var(--xui-default-bg)"
|
|
138
|
+
},
|
|
139
|
+
background: "var(--xui-background)",
|
|
140
|
+
foreground: "var(--xui-foreground)"
|
|
141
|
+
},
|
|
142
|
+
borderRadius: {
|
|
143
|
+
none: "var(--xui-radius-none)",
|
|
144
|
+
sm: "var(--xui-radius-sm)",
|
|
145
|
+
md: "var(--xui-radius-md)",
|
|
146
|
+
lg: "var(--xui-radius-lg)",
|
|
147
|
+
full: "var(--xui-radius-full)"
|
|
148
|
+
}
|
|
149
|
+
}),
|
|
150
|
+
[resolvedScheme]
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
function useXUIColors() {
|
|
154
|
+
const theme = useXUITheme();
|
|
155
|
+
return theme.colors;
|
|
156
|
+
}
|
|
157
|
+
function useXUIPalette() {
|
|
158
|
+
const theme = useXUITheme();
|
|
159
|
+
return useMemo(() => theme.palette, [theme]);
|
|
160
|
+
}
|
|
161
|
+
function useBorderRadiusStyles(radius) {
|
|
162
|
+
return useMemo(
|
|
163
|
+
() => ({
|
|
164
|
+
borderRadius: `var(--xui-radius-${radius})`
|
|
165
|
+
}),
|
|
166
|
+
[radius]
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export {
|
|
171
|
+
XUIProvider,
|
|
172
|
+
useColorMode,
|
|
173
|
+
useXUITheme,
|
|
174
|
+
useXUIColors,
|
|
175
|
+
useXUIPalette,
|
|
176
|
+
useBorderRadiusStyles
|
|
177
|
+
};
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
type DeepPartial<T> = {
|
|
6
|
-
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
7
|
-
};
|
|
8
|
-
interface XUIProviderProps {
|
|
9
|
-
children: ReactNode;
|
|
10
|
-
theme?: DeepPartial<XUITheme>;
|
|
11
|
-
darkTheme?: DeepPartial<XUITheme>;
|
|
12
|
-
}
|
|
13
|
-
declare function XUIProvider({ children, theme: lightTheme, darkTheme, }: XUIProviderProps): react_jsx_runtime.JSX.Element;
|
|
14
|
-
|
|
15
|
-
type ColorMode = 'light' | 'dark';
|
|
16
|
-
declare function useColorMode(): ColorMode;
|
|
17
|
-
declare function useXUITheme(): XUITheme;
|
|
18
|
-
declare function useXUIColors(): XUITheme['colors'];
|
|
19
|
-
|
|
20
|
-
export { XUIProvider, useColorMode, useXUIColors, useXUITheme };
|
|
1
|
+
export { X as XUIProvider, a as XUIProviderProps, b as XUIVariables, f as useBorderRadiusStyles, u as useColorMode, d as useXUIColors, e as useXUIPalette, c as useXUITheme } from '../index-5BCfEjU-.js';
|
|
2
|
+
import 'react/jsx-runtime';
|
|
3
|
+
import 'react';
|
package/dist/core/index.js
CHANGED
|
@@ -1,85 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (!globalScope.matchMedia) {
|
|
10
|
-
return "light";
|
|
11
|
-
}
|
|
12
|
-
return globalScope.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
13
|
-
};
|
|
14
|
-
function useColorMode() {
|
|
15
|
-
const [webScheme, setWebScheme] = useState(() => getWebColorMode());
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
if (typeof globalThis === "undefined") return;
|
|
18
|
-
const globalScope = globalThis;
|
|
19
|
-
if (!globalScope.matchMedia) return;
|
|
20
|
-
const media = globalScope.matchMedia("(prefers-color-scheme: dark)");
|
|
21
|
-
const handleChange = () => {
|
|
22
|
-
setWebScheme(media.matches ? "dark" : "light");
|
|
23
|
-
};
|
|
24
|
-
handleChange();
|
|
25
|
-
if (typeof media.addEventListener === "function") {
|
|
26
|
-
media.addEventListener("change", handleChange);
|
|
27
|
-
return () => media.removeEventListener?.("change", handleChange);
|
|
28
|
-
}
|
|
29
|
-
const legacyMedia = media;
|
|
30
|
-
legacyMedia.addListener?.(handleChange);
|
|
31
|
-
return () => legacyMedia.removeListener?.(handleChange);
|
|
32
|
-
}, []);
|
|
33
|
-
return webScheme;
|
|
34
|
-
}
|
|
35
|
-
function useXUITheme() {
|
|
36
|
-
const theme = useContext(XUIThemeContext);
|
|
37
|
-
if (!theme) {
|
|
38
|
-
throw new Error("useXUITheme must be used within XUIProvider");
|
|
39
|
-
}
|
|
40
|
-
return theme;
|
|
41
|
-
}
|
|
42
|
-
function useXUIColors() {
|
|
43
|
-
const theme = useXUITheme();
|
|
44
|
-
return theme.colors;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// src/core/theme-context.tsx
|
|
48
|
-
import { defaultTheme } from "@xaui/core/theme";
|
|
49
|
-
import { jsx } from "react/jsx-runtime";
|
|
50
|
-
var XUIThemeContext = createContext(null);
|
|
51
|
-
function XUIProvider({
|
|
52
|
-
children,
|
|
53
|
-
theme: lightTheme,
|
|
54
|
-
darkTheme
|
|
55
|
-
}) {
|
|
56
|
-
const colorScheme = useColorMode();
|
|
57
|
-
const theme = React.useMemo(() => {
|
|
58
|
-
if (!darkTheme && !lightTheme) return defaultTheme;
|
|
59
|
-
const activeTheme = colorScheme === "dark" && darkTheme ? darkTheme : lightTheme;
|
|
60
|
-
if (!activeTheme) return defaultTheme;
|
|
61
|
-
return {
|
|
62
|
-
...defaultTheme,
|
|
63
|
-
...activeTheme,
|
|
64
|
-
colors: {
|
|
65
|
-
...defaultTheme.colors,
|
|
66
|
-
...activeTheme.colors
|
|
67
|
-
},
|
|
68
|
-
fontFamilies: {
|
|
69
|
-
...defaultTheme.fontFamilies,
|
|
70
|
-
...activeTheme.fontFamilies
|
|
71
|
-
},
|
|
72
|
-
fontSizes: {
|
|
73
|
-
...defaultTheme.fontSizes,
|
|
74
|
-
...activeTheme.fontSizes
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
}, [lightTheme, darkTheme, colorScheme]);
|
|
78
|
-
return /* @__PURE__ */ jsx(XUIThemeContext.Provider, { value: theme, children });
|
|
79
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
XUIProvider,
|
|
3
|
+
useBorderRadiusStyles,
|
|
4
|
+
useColorMode,
|
|
5
|
+
useXUIColors,
|
|
6
|
+
useXUIPalette,
|
|
7
|
+
useXUITheme
|
|
8
|
+
} from "../chunk-YJF3QRMW.js";
|
|
80
9
|
export {
|
|
81
10
|
XUIProvider,
|
|
11
|
+
useBorderRadiusStyles,
|
|
82
12
|
useColorMode,
|
|
83
13
|
useXUIColors,
|
|
14
|
+
useXUIPalette,
|
|
84
15
|
useXUITheme
|
|
85
16
|
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type ColorMode$1 = 'light' | 'dark';
|
|
5
|
+
type CSSVarValue = string | number;
|
|
6
|
+
type XUIVariables = Record<`--xui-${string}`, CSSVarValue>;
|
|
7
|
+
interface XUIProviderProps {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
colorScheme?: ColorMode$1;
|
|
10
|
+
target?: 'html' | 'body';
|
|
11
|
+
variables?: Partial<XUIVariables>;
|
|
12
|
+
darkVariables?: Partial<XUIVariables>;
|
|
13
|
+
}
|
|
14
|
+
declare function XUIProvider({ children, colorScheme, target, variables, darkVariables, }: XUIProviderProps): react_jsx_runtime.JSX.Element;
|
|
15
|
+
|
|
16
|
+
type Size = 'xs' | 'sm' | 'md' | 'lg';
|
|
17
|
+
type Radius = 'none' | 'sm' | 'md' | 'lg' | 'full';
|
|
18
|
+
type SizeValues = {
|
|
19
|
+
xs: number;
|
|
20
|
+
sm: number;
|
|
21
|
+
md: number;
|
|
22
|
+
lg: number;
|
|
23
|
+
};
|
|
24
|
+
type RadiusValues = {
|
|
25
|
+
none: number;
|
|
26
|
+
sm: number;
|
|
27
|
+
md: number;
|
|
28
|
+
lg: number;
|
|
29
|
+
full: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type ColorMode = 'light' | 'dark';
|
|
33
|
+
type CSSVarString = `var(--${string})`;
|
|
34
|
+
type CSSColorScheme = {
|
|
35
|
+
main: CSSVarString;
|
|
36
|
+
foreground: CSSVarString;
|
|
37
|
+
background: CSSVarString;
|
|
38
|
+
};
|
|
39
|
+
type HybridXUITheme = {
|
|
40
|
+
mode: ColorMode;
|
|
41
|
+
palette: Record<string, CSSVarString>;
|
|
42
|
+
colors: {
|
|
43
|
+
primary: CSSColorScheme;
|
|
44
|
+
secondary: CSSColorScheme;
|
|
45
|
+
tertiary: CSSColorScheme;
|
|
46
|
+
danger: CSSColorScheme;
|
|
47
|
+
warning: CSSColorScheme;
|
|
48
|
+
success: CSSColorScheme;
|
|
49
|
+
default: CSSColorScheme;
|
|
50
|
+
background: CSSVarString;
|
|
51
|
+
foreground: CSSVarString;
|
|
52
|
+
};
|
|
53
|
+
borderRadius: Record<Radius, CSSVarString>;
|
|
54
|
+
};
|
|
55
|
+
declare function useColorMode(): ColorMode;
|
|
56
|
+
declare function useXUITheme(): HybridXUITheme;
|
|
57
|
+
declare function useXUIColors(): HybridXUITheme['colors'];
|
|
58
|
+
declare function useXUIPalette(): HybridXUITheme['palette'];
|
|
59
|
+
declare function useBorderRadiusStyles(radius: Radius): {
|
|
60
|
+
borderRadius: string;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export { type Radius as R, type Size as S, XUIProvider as X, type XUIProviderProps as a, type XUIVariables as b, useXUITheme as c, useXUIColors as d, useXUIPalette as e, useBorderRadiusStyles as f, type SizeValues as g, type RadiusValues as h, useColorMode as u };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { ReactNode, CSSProperties } from 'react';
|
|
2
|
+
|
|
3
|
+
type ThemeColor = 'primary' | 'secondary' | 'tertiary' | 'danger' | 'warning' | 'success' | 'default';
|
|
4
|
+
|
|
5
|
+
type AlertVariant = 'solid' | 'bordered' | 'flat' | 'faded';
|
|
6
|
+
type AlertRadius = 'none' | 'sm' | 'md' | 'lg' | 'full';
|
|
7
|
+
type AlertEvents = {
|
|
8
|
+
onClose?: () => void;
|
|
9
|
+
onVisibleChange?: (isVisible: boolean) => void;
|
|
10
|
+
};
|
|
11
|
+
type AlertCustomAppearance = {
|
|
12
|
+
container?: CSSProperties;
|
|
13
|
+
title?: CSSProperties;
|
|
14
|
+
description?: CSSProperties;
|
|
15
|
+
};
|
|
16
|
+
type AlertProps = {
|
|
17
|
+
title?: ReactNode;
|
|
18
|
+
description?: ReactNode;
|
|
19
|
+
icon?: ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* @default 'default'
|
|
22
|
+
*/
|
|
23
|
+
themeColor?: ThemeColor;
|
|
24
|
+
/**
|
|
25
|
+
* @default 'flat'
|
|
26
|
+
*/
|
|
27
|
+
variant?: AlertVariant;
|
|
28
|
+
/**
|
|
29
|
+
* @default 'md'
|
|
30
|
+
*/
|
|
31
|
+
radius?: AlertRadius;
|
|
32
|
+
/**
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
isClosable?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
hideIcon?: boolean;
|
|
40
|
+
closeButton?: ReactNode;
|
|
41
|
+
/**
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
isVisible?: boolean;
|
|
45
|
+
customAppearance?: AlertCustomAppearance;
|
|
46
|
+
children?: ReactNode;
|
|
47
|
+
} & AlertEvents;
|
|
48
|
+
|
|
49
|
+
declare const Alert: React.FC<AlertProps>;
|
|
50
|
+
|
|
51
|
+
export { Alert as A, type ThemeColor as T, type AlertProps as a, type AlertVariant as b, type AlertRadius as c };
|
package/dist/index.css
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/* XUI Design System
|
|
2
|
+
* Import this file once in your app's root CSS:
|
|
3
|
+
* @import "@xaui/hybrid/dist/index.css";
|
|
4
|
+
*
|
|
5
|
+
* All --xui-* variables can be overridden to customize the theme.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
:root {
|
|
9
|
+
/* Primary */
|
|
10
|
+
--xui-primary: #6b21a8;
|
|
11
|
+
--xui-primary-fg: #ffffff;
|
|
12
|
+
--xui-primary-bg: #e9d5ff;
|
|
13
|
+
|
|
14
|
+
/* Secondary */
|
|
15
|
+
--xui-secondary: #71717a;
|
|
16
|
+
--xui-secondary-fg: #ffffff;
|
|
17
|
+
--xui-secondary-bg: #e4e4e7;
|
|
18
|
+
|
|
19
|
+
/* Tertiary */
|
|
20
|
+
--xui-tertiary: #78716c;
|
|
21
|
+
--xui-tertiary-fg: #ffffff;
|
|
22
|
+
--xui-tertiary-bg: #f5f5f4;
|
|
23
|
+
|
|
24
|
+
/* Danger */
|
|
25
|
+
--xui-danger: #b91c1c;
|
|
26
|
+
--xui-danger-fg: #ffffff;
|
|
27
|
+
--xui-danger-bg: #fecdd3;
|
|
28
|
+
|
|
29
|
+
/* Warning */
|
|
30
|
+
--xui-warning: #d97706;
|
|
31
|
+
--xui-warning-fg: #111827;
|
|
32
|
+
--xui-warning-bg: #fef3c7;
|
|
33
|
+
|
|
34
|
+
/* Success */
|
|
35
|
+
--xui-success: #16a34a;
|
|
36
|
+
--xui-success-fg: #ffffff;
|
|
37
|
+
--xui-success-bg: #dcfce7;
|
|
38
|
+
|
|
39
|
+
/* Default */
|
|
40
|
+
--xui-default: #18181b;
|
|
41
|
+
--xui-default-fg: #ffffff;
|
|
42
|
+
--xui-default-bg: #e4e4e7;
|
|
43
|
+
|
|
44
|
+
/* Global */
|
|
45
|
+
--xui-background: #ffffff;
|
|
46
|
+
--xui-foreground: #18181b;
|
|
47
|
+
|
|
48
|
+
/* Spacing */
|
|
49
|
+
--xui-spacing-xs: 4px;
|
|
50
|
+
--xui-spacing-sm: 8px;
|
|
51
|
+
--xui-spacing-md: 16px;
|
|
52
|
+
--xui-spacing-lg: 24px;
|
|
53
|
+
--xui-spacing-xl: 32px;
|
|
54
|
+
--xui-spacing-2xl: 48px;
|
|
55
|
+
--xui-spacing-3xl: 64px;
|
|
56
|
+
|
|
57
|
+
/* Border radius */
|
|
58
|
+
--xui-radius-none: 0px;
|
|
59
|
+
--xui-radius-sm: 4px;
|
|
60
|
+
--xui-radius-md: 8px;
|
|
61
|
+
--xui-radius-lg: 12px;
|
|
62
|
+
--xui-radius-xl: 16px;
|
|
63
|
+
--xui-radius-2xl: 24px;
|
|
64
|
+
--xui-radius-3xl: 32px;
|
|
65
|
+
--xui-radius-full: 9999px;
|
|
66
|
+
|
|
67
|
+
/* Border width */
|
|
68
|
+
--xui-border-none: 0px;
|
|
69
|
+
--xui-border-xs: 0.5px;
|
|
70
|
+
--xui-border-sm: 1px;
|
|
71
|
+
--xui-border-md: 1.75px;
|
|
72
|
+
--xui-border-lg: 2.5px;
|
|
73
|
+
--xui-border-xl: 3px;
|
|
74
|
+
|
|
75
|
+
/* Font sizes */
|
|
76
|
+
--xui-text-xs: 12px;
|
|
77
|
+
--xui-text-sm: 14px;
|
|
78
|
+
--xui-text-md: 16px;
|
|
79
|
+
--xui-text-lg: 18px;
|
|
80
|
+
--xui-text-xl: 20px;
|
|
81
|
+
--xui-text-2xl: 24px;
|
|
82
|
+
--xui-text-3xl: 30px;
|
|
83
|
+
--xui-text-4xl: 36px;
|
|
84
|
+
|
|
85
|
+
/* Font weights */
|
|
86
|
+
--xui-font-light: 300;
|
|
87
|
+
--xui-font-normal: 400;
|
|
88
|
+
--xui-font-medium: 500;
|
|
89
|
+
--xui-font-semibold: 600;
|
|
90
|
+
--xui-font-bold: 700;
|
|
91
|
+
--xui-font-extrabold: 800;
|
|
92
|
+
|
|
93
|
+
/* Component sizes */
|
|
94
|
+
--xui-size-xs: 38px;
|
|
95
|
+
--xui-size-sm: 42px;
|
|
96
|
+
--xui-size-md: 46px;
|
|
97
|
+
--xui-size-lg: 50px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Dark mode — toggled by setting data-color-scheme on <html> */
|
|
101
|
+
[data-color-scheme='dark'] {
|
|
102
|
+
--xui-primary: #d8b4fe;
|
|
103
|
+
--xui-primary-fg: #3b0764;
|
|
104
|
+
--xui-primary-bg: #4c1d95;
|
|
105
|
+
|
|
106
|
+
--xui-secondary: #d4d4d8;
|
|
107
|
+
--xui-secondary-fg: #3f3f46;
|
|
108
|
+
--xui-secondary-bg: #52525b;
|
|
109
|
+
|
|
110
|
+
--xui-tertiary: #fecaca;
|
|
111
|
+
--xui-tertiary-fg: #500724;
|
|
112
|
+
--xui-tertiary-bg: #57534e;
|
|
113
|
+
|
|
114
|
+
--xui-danger: #fca5a5;
|
|
115
|
+
--xui-danger-fg: #4c0519;
|
|
116
|
+
--xui-danger-bg: #991b1b;
|
|
117
|
+
|
|
118
|
+
--xui-warning: #fbbf24;
|
|
119
|
+
--xui-warning-fg: #f9fafb;
|
|
120
|
+
--xui-warning-bg: #78350f;
|
|
121
|
+
|
|
122
|
+
--xui-success: #4ade80;
|
|
123
|
+
--xui-success-fg: #f9fafb;
|
|
124
|
+
--xui-success-bg: #14532d;
|
|
125
|
+
|
|
126
|
+
--xui-default: #e7e5e4;
|
|
127
|
+
--xui-default-fg: #18181b;
|
|
128
|
+
--xui-default-bg: #3f3f46;
|
|
129
|
+
|
|
130
|
+
--xui-background: #18181b;
|
|
131
|
+
--xui-foreground: #e7e5e4;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* SSR/no-JS fallback: honor OS dark mode until data-color-scheme is set */
|
|
135
|
+
@media (prefers-color-scheme: dark) {
|
|
136
|
+
:root:not([data-color-scheme]) {
|
|
137
|
+
--xui-primary: #d8b4fe;
|
|
138
|
+
--xui-primary-fg: #3b0764;
|
|
139
|
+
--xui-primary-bg: #4c1d95;
|
|
140
|
+
|
|
141
|
+
--xui-secondary: #d4d4d8;
|
|
142
|
+
--xui-secondary-fg: #3f3f46;
|
|
143
|
+
--xui-secondary-bg: #52525b;
|
|
144
|
+
|
|
145
|
+
--xui-tertiary: #fecaca;
|
|
146
|
+
--xui-tertiary-fg: #500724;
|
|
147
|
+
--xui-tertiary-bg: #57534e;
|
|
148
|
+
|
|
149
|
+
--xui-danger: #fca5a5;
|
|
150
|
+
--xui-danger-fg: #4c0519;
|
|
151
|
+
--xui-danger-bg: #991b1b;
|
|
152
|
+
|
|
153
|
+
--xui-warning: #fbbf24;
|
|
154
|
+
--xui-warning-fg: #f9fafb;
|
|
155
|
+
--xui-warning-bg: #78350f;
|
|
156
|
+
|
|
157
|
+
--xui-success: #4ade80;
|
|
158
|
+
--xui-success-fg: #f9fafb;
|
|
159
|
+
--xui-success-bg: #14532d;
|
|
160
|
+
|
|
161
|
+
--xui-default: #e7e5e4;
|
|
162
|
+
--xui-default-fg: #18181b;
|
|
163
|
+
--xui-default-bg: #3f3f46;
|
|
164
|
+
|
|
165
|
+
--xui-background: #18181b;
|
|
166
|
+
--xui-foreground: #e7e5e4;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Animations CSS — used via data-xui-state attribute */
|
|
171
|
+
@keyframes xui-fade-in {
|
|
172
|
+
from {
|
|
173
|
+
opacity: 0;
|
|
174
|
+
transform: scale(0.95);
|
|
175
|
+
}
|
|
176
|
+
to {
|
|
177
|
+
opacity: 1;
|
|
178
|
+
transform: scale(1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@keyframes xui-fade-out {
|
|
183
|
+
from {
|
|
184
|
+
opacity: 1;
|
|
185
|
+
transform: scale(1);
|
|
186
|
+
}
|
|
187
|
+
to {
|
|
188
|
+
opacity: 0;
|
|
189
|
+
transform: scale(0.95);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
[data-xui-state='open'] {
|
|
194
|
+
animation: xui-fade-in 250ms ease forwards;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
[data-xui-state='closed'] {
|
|
198
|
+
animation: xui-fade-out 250ms ease forwards;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Alert mode tokens derived from selected --xui-alert-* role vars */
|
|
202
|
+
.xui-alert {
|
|
203
|
+
--xui-alert-solid-bg: var(--xui-alert-main);
|
|
204
|
+
--xui-alert-solid-text: #ffffff;
|
|
205
|
+
--xui-alert-solid-icon-bg: color-mix(in srgb, #ffffff 16%, transparent);
|
|
206
|
+
--xui-alert-flat-bg: var(--xui-alert-bg-base);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
[data-color-scheme='dark'] .xui-alert {
|
|
210
|
+
--xui-alert-solid-bg: var(--xui-alert-bg-base);
|
|
211
|
+
--xui-alert-solid-text: var(--xui-alert-main);
|
|
212
|
+
--xui-alert-solid-icon-bg: color-mix(in srgb, var(--xui-alert-main) 16%, transparent);
|
|
213
|
+
--xui-alert-flat-bg: color-mix(in srgb, var(--xui-alert-bg-base) 50%, transparent);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
@media (prefers-color-scheme: dark) {
|
|
217
|
+
:root:not([data-color-scheme]) .xui-alert {
|
|
218
|
+
--xui-alert-solid-bg: var(--xui-alert-bg-base);
|
|
219
|
+
--xui-alert-solid-text: var(--xui-alert-main);
|
|
220
|
+
--xui-alert-solid-icon-bg: color-mix(in srgb, var(--xui-alert-main) 16%, transparent);
|
|
221
|
+
--xui-alert-flat-bg: color-mix(in srgb, var(--xui-alert-bg-base) 50%, transparent);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Tailwind v4 — register XUI tokens as utilities via @theme inline.
|
|
226
|
+
* Colors become: bg-primary, text-primary-fg, border-danger, etc.
|
|
227
|
+
* Spacing becomes: p-xui-md, m-xui-lg, gap-xui-sm, etc.
|
|
228
|
+
* Radius becomes: rounded-xui-md, rounded-xui-full, etc.
|
|
229
|
+
*/
|
|
230
|
+
@theme inline {
|
|
231
|
+
/* Colors */
|
|
232
|
+
--color-primary: var(--xui-primary);
|
|
233
|
+
--color-primary-fg: var(--xui-primary-fg);
|
|
234
|
+
--color-primary-bg: var(--xui-primary-bg);
|
|
235
|
+
|
|
236
|
+
--color-secondary: var(--xui-secondary);
|
|
237
|
+
--color-secondary-fg: var(--xui-secondary-fg);
|
|
238
|
+
--color-secondary-bg: var(--xui-secondary-bg);
|
|
239
|
+
|
|
240
|
+
--color-tertiary: var(--xui-tertiary);
|
|
241
|
+
--color-tertiary-fg: var(--xui-tertiary-fg);
|
|
242
|
+
--color-tertiary-bg: var(--xui-tertiary-bg);
|
|
243
|
+
|
|
244
|
+
--color-danger: var(--xui-danger);
|
|
245
|
+
--color-danger-fg: var(--xui-danger-fg);
|
|
246
|
+
--color-danger-bg: var(--xui-danger-bg);
|
|
247
|
+
|
|
248
|
+
--color-warning: var(--xui-warning);
|
|
249
|
+
--color-warning-fg: var(--xui-warning-fg);
|
|
250
|
+
--color-warning-bg: var(--xui-warning-bg);
|
|
251
|
+
|
|
252
|
+
--color-success: var(--xui-success);
|
|
253
|
+
--color-success-fg: var(--xui-success-fg);
|
|
254
|
+
--color-success-bg: var(--xui-success-bg);
|
|
255
|
+
|
|
256
|
+
--color-default: var(--xui-default);
|
|
257
|
+
--color-default-fg: var(--xui-default-fg);
|
|
258
|
+
--color-default-bg: var(--xui-default-bg);
|
|
259
|
+
|
|
260
|
+
--color-xui-background: var(--xui-background);
|
|
261
|
+
--color-xui-foreground: var(--xui-foreground);
|
|
262
|
+
|
|
263
|
+
/* Spacing */
|
|
264
|
+
--spacing-xui-xs: var(--xui-spacing-xs);
|
|
265
|
+
--spacing-xui-sm: var(--xui-spacing-sm);
|
|
266
|
+
--spacing-xui-md: var(--xui-spacing-md);
|
|
267
|
+
--spacing-xui-lg: var(--xui-spacing-lg);
|
|
268
|
+
--spacing-xui-xl: var(--xui-spacing-xl);
|
|
269
|
+
--spacing-xui-2xl: var(--xui-spacing-2xl);
|
|
270
|
+
--spacing-xui-3xl: var(--xui-spacing-3xl);
|
|
271
|
+
|
|
272
|
+
/* Border radius */
|
|
273
|
+
--radius-xui-none: var(--xui-radius-none);
|
|
274
|
+
--radius-xui-sm: var(--xui-radius-sm);
|
|
275
|
+
--radius-xui-md: var(--xui-radius-md);
|
|
276
|
+
--radius-xui-lg: var(--xui-radius-lg);
|
|
277
|
+
--radius-xui-xl: var(--xui-radius-xl);
|
|
278
|
+
--radius-xui-2xl: var(--xui-radius-2xl);
|
|
279
|
+
--radius-xui-3xl: var(--xui-radius-3xl);
|
|
280
|
+
--radius-xui-full: var(--xui-radius-full);
|
|
281
|
+
|
|
282
|
+
/* Font sizes */
|
|
283
|
+
--text-xui-xs: var(--xui-text-xs);
|
|
284
|
+
--text-xui-sm: var(--xui-text-sm);
|
|
285
|
+
--text-xui-md: var(--xui-text-md);
|
|
286
|
+
--text-xui-lg: var(--xui-text-lg);
|
|
287
|
+
--text-xui-xl: var(--xui-text-xl);
|
|
288
|
+
--text-xui-2xl: var(--xui-text-2xl);
|
|
289
|
+
--text-xui-3xl: var(--xui-text-3xl);
|
|
290
|
+
--text-xui-4xl: var(--xui-text-4xl);
|
|
291
|
+
|
|
292
|
+
/* Font weights */
|
|
293
|
+
--font-weight-xui-light: var(--xui-font-light);
|
|
294
|
+
--font-weight-xui-normal: var(--xui-font-normal);
|
|
295
|
+
--font-weight-xui-medium: var(--xui-font-medium);
|
|
296
|
+
--font-weight-xui-semibold: var(--xui-font-semibold);
|
|
297
|
+
--font-weight-xui-bold: var(--xui-font-bold);
|
|
298
|
+
--font-weight-xui-extrabold: var(--xui-font-extrabold);
|
|
299
|
+
|
|
300
|
+
/* Component sizes (as spacing — usable as w-xui-size-md, h-xui-size-lg, etc.) */
|
|
301
|
+
--spacing-xui-size-xs: var(--xui-size-xs);
|
|
302
|
+
--spacing-xui-size-sm: var(--xui-size-sm);
|
|
303
|
+
--spacing-xui-size-md: var(--xui-size-md);
|
|
304
|
+
--spacing-xui-size-lg: var(--xui-size-lg);
|
|
305
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
|
+
export { R as Radius, h as RadiusValues, S as Size, g as SizeValues, X as XUIProvider, a as XUIProviderProps, b as XUIVariables, f as useBorderRadiusStyles, u as useColorMode, d as useXUIColors, e as useXUIPalette, c as useXUITheme } from './index-5BCfEjU-.js';
|
|
2
|
+
import { ClassValue } from 'clsx';
|
|
3
|
+
export { A as Alert, a as AlertProps, c as AlertRadius, b as AlertVariant, T as ThemeColor } from './index-CMptPfU-.js';
|
|
4
|
+
import 'react/jsx-runtime';
|
|
5
|
+
import 'react';
|
|
1
6
|
|
|
2
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Merges class names using clsx and tailwind-merge.
|
|
9
|
+
* Useful for handling conditional classes and resolving Tailwind conflicts.
|
|
10
|
+
*/
|
|
11
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
12
|
+
|
|
13
|
+
export { cn };
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
XUIProvider,
|
|
3
|
+
useBorderRadiusStyles,
|
|
4
|
+
useColorMode,
|
|
5
|
+
useXUIColors,
|
|
6
|
+
useXUIPalette,
|
|
7
|
+
useXUITheme
|
|
8
|
+
} from "./chunk-YJF3QRMW.js";
|
|
9
|
+
import {
|
|
10
|
+
Alert
|
|
11
|
+
} from "./chunk-7HVBAJHB.js";
|
|
12
|
+
|
|
13
|
+
// src/utils/cn.ts
|
|
14
|
+
import { clsx } from "clsx";
|
|
15
|
+
import { twMerge } from "tailwind-merge";
|
|
16
|
+
function cn(...inputs) {
|
|
17
|
+
return twMerge(clsx(inputs));
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
Alert,
|
|
21
|
+
XUIProvider,
|
|
22
|
+
cn,
|
|
23
|
+
useBorderRadiusStyles,
|
|
24
|
+
useColorMode,
|
|
25
|
+
useXUIColors,
|
|
26
|
+
useXUIPalette,
|
|
27
|
+
useXUITheme
|
|
28
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xaui/hybrid",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Flutter-inspired React UI components for web and mobile webview
|
|
3
|
+
"version": "0.0.9",
|
|
4
|
+
"description": "Flutter-inspired React UI components for web and mobile webview with Tailwind CSS styling and CSS animations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
7
7
|
"web",
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
"ui",
|
|
11
11
|
"components",
|
|
12
12
|
"flutter",
|
|
13
|
-
"framer-motion",
|
|
14
13
|
"tailwindcss",
|
|
15
14
|
"xaui"
|
|
16
15
|
],
|
|
@@ -20,28 +19,15 @@
|
|
|
20
19
|
"exports": {
|
|
21
20
|
".": {
|
|
22
21
|
"types": "./dist/index.d.ts",
|
|
23
|
-
"import": "./dist/index.js"
|
|
24
|
-
"require": "./dist/index.js"
|
|
22
|
+
"import": "./dist/index.js"
|
|
25
23
|
},
|
|
26
24
|
"./core": {
|
|
27
25
|
"types": "./dist/core/index.d.ts",
|
|
28
|
-
"import": "./dist/core/index.js"
|
|
29
|
-
"require": "./dist/core/index.js"
|
|
26
|
+
"import": "./dist/core/index.js"
|
|
30
27
|
},
|
|
31
|
-
"./
|
|
32
|
-
"types": "./dist/
|
|
33
|
-
"import": "./dist/
|
|
34
|
-
"require": "./dist/button/index.js"
|
|
35
|
-
},
|
|
36
|
-
"./progress": {
|
|
37
|
-
"types": "./dist/progress/index.d.ts",
|
|
38
|
-
"import": "./dist/progress/index.js",
|
|
39
|
-
"require": "./dist/progress/index.js"
|
|
40
|
-
},
|
|
41
|
-
"./indicator": {
|
|
42
|
-
"types": "./dist/indicator/index.d.ts",
|
|
43
|
-
"import": "./dist/indicator/index.js",
|
|
44
|
-
"require": "./dist/indicator/index.js"
|
|
28
|
+
"./alert": {
|
|
29
|
+
"types": "./dist/alert/index.d.ts",
|
|
30
|
+
"import": "./dist/alert/index.js"
|
|
45
31
|
},
|
|
46
32
|
"./dist/index.css": "./dist/index.css"
|
|
47
33
|
},
|
|
@@ -68,7 +54,6 @@
|
|
|
68
54
|
"devDependencies": {
|
|
69
55
|
"@types/react": "^19.1.0",
|
|
70
56
|
"@types/react-dom": "^19.1.0",
|
|
71
|
-
"esbuild-sass-plugin": "^3.6.0",
|
|
72
57
|
"react": "19.1.0",
|
|
73
58
|
"react-dom": "19.1.0",
|
|
74
59
|
"tsup": "^8.5.1",
|
package/dist/core/index.cjs
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/core/index.ts
|
|
31
|
-
var core_exports = {};
|
|
32
|
-
__export(core_exports, {
|
|
33
|
-
XUIProvider: () => XUIProvider,
|
|
34
|
-
useColorMode: () => useColorMode,
|
|
35
|
-
useXUIColors: () => useXUIColors,
|
|
36
|
-
useXUITheme: () => useXUITheme
|
|
37
|
-
});
|
|
38
|
-
module.exports = __toCommonJS(core_exports);
|
|
39
|
-
|
|
40
|
-
// src/core/theme-context.tsx
|
|
41
|
-
var import_react2 = __toESM(require("react"), 1);
|
|
42
|
-
|
|
43
|
-
// src/core/theme-hooks.ts
|
|
44
|
-
var import_react = require("react");
|
|
45
|
-
var getWebColorMode = () => {
|
|
46
|
-
if (typeof globalThis === "undefined") return "light";
|
|
47
|
-
const globalScope = globalThis;
|
|
48
|
-
if (!globalScope.matchMedia) {
|
|
49
|
-
return "light";
|
|
50
|
-
}
|
|
51
|
-
return globalScope.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
52
|
-
};
|
|
53
|
-
function useColorMode() {
|
|
54
|
-
const [webScheme, setWebScheme] = (0, import_react.useState)(() => getWebColorMode());
|
|
55
|
-
(0, import_react.useEffect)(() => {
|
|
56
|
-
if (typeof globalThis === "undefined") return;
|
|
57
|
-
const globalScope = globalThis;
|
|
58
|
-
if (!globalScope.matchMedia) return;
|
|
59
|
-
const media = globalScope.matchMedia("(prefers-color-scheme: dark)");
|
|
60
|
-
const handleChange = () => {
|
|
61
|
-
setWebScheme(media.matches ? "dark" : "light");
|
|
62
|
-
};
|
|
63
|
-
handleChange();
|
|
64
|
-
if (typeof media.addEventListener === "function") {
|
|
65
|
-
media.addEventListener("change", handleChange);
|
|
66
|
-
return () => media.removeEventListener?.("change", handleChange);
|
|
67
|
-
}
|
|
68
|
-
const legacyMedia = media;
|
|
69
|
-
legacyMedia.addListener?.(handleChange);
|
|
70
|
-
return () => legacyMedia.removeListener?.(handleChange);
|
|
71
|
-
}, []);
|
|
72
|
-
return webScheme;
|
|
73
|
-
}
|
|
74
|
-
function useXUITheme() {
|
|
75
|
-
const theme = (0, import_react.useContext)(XUIThemeContext);
|
|
76
|
-
if (!theme) {
|
|
77
|
-
throw new Error("useXUITheme must be used within XUIProvider");
|
|
78
|
-
}
|
|
79
|
-
return theme;
|
|
80
|
-
}
|
|
81
|
-
function useXUIColors() {
|
|
82
|
-
const theme = useXUITheme();
|
|
83
|
-
return theme.colors;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// src/core/theme-context.tsx
|
|
87
|
-
var import_theme = require("@xaui/core/theme");
|
|
88
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
89
|
-
var XUIThemeContext = (0, import_react2.createContext)(null);
|
|
90
|
-
function XUIProvider({
|
|
91
|
-
children,
|
|
92
|
-
theme: lightTheme,
|
|
93
|
-
darkTheme
|
|
94
|
-
}) {
|
|
95
|
-
const colorScheme = useColorMode();
|
|
96
|
-
const theme = import_react2.default.useMemo(() => {
|
|
97
|
-
if (!darkTheme && !lightTheme) return import_theme.defaultTheme;
|
|
98
|
-
const activeTheme = colorScheme === "dark" && darkTheme ? darkTheme : lightTheme;
|
|
99
|
-
if (!activeTheme) return import_theme.defaultTheme;
|
|
100
|
-
return {
|
|
101
|
-
...import_theme.defaultTheme,
|
|
102
|
-
...activeTheme,
|
|
103
|
-
colors: {
|
|
104
|
-
...import_theme.defaultTheme.colors,
|
|
105
|
-
...activeTheme.colors
|
|
106
|
-
},
|
|
107
|
-
fontFamilies: {
|
|
108
|
-
...import_theme.defaultTheme.fontFamilies,
|
|
109
|
-
...activeTheme.fontFamilies
|
|
110
|
-
},
|
|
111
|
-
fontSizes: {
|
|
112
|
-
...import_theme.defaultTheme.fontSizes,
|
|
113
|
-
...activeTheme.fontSizes
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
}, [lightTheme, darkTheme, colorScheme]);
|
|
117
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(XUIThemeContext.Provider, { value: theme, children });
|
|
118
|
-
}
|
|
119
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
120
|
-
0 && (module.exports = {
|
|
121
|
-
XUIProvider,
|
|
122
|
-
useColorMode,
|
|
123
|
-
useXUIColors,
|
|
124
|
-
useXUITheme
|
|
125
|
-
});
|
package/dist/core/index.d.cts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
3
|
-
import { XUITheme } from '@xaui/core/theme';
|
|
4
|
-
|
|
5
|
-
type DeepPartial<T> = {
|
|
6
|
-
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
7
|
-
};
|
|
8
|
-
interface XUIProviderProps {
|
|
9
|
-
children: ReactNode;
|
|
10
|
-
theme?: DeepPartial<XUITheme>;
|
|
11
|
-
darkTheme?: DeepPartial<XUITheme>;
|
|
12
|
-
}
|
|
13
|
-
declare function XUIProvider({ children, theme: lightTheme, darkTheme, }: XUIProviderProps): react_jsx_runtime.JSX.Element;
|
|
14
|
-
|
|
15
|
-
type ColorMode = 'light' | 'dark';
|
|
16
|
-
declare function useColorMode(): ColorMode;
|
|
17
|
-
declare function useXUITheme(): XUITheme;
|
|
18
|
-
declare function useXUIColors(): XUITheme['colors'];
|
|
19
|
-
|
|
20
|
-
export { XUIProvider, useColorMode, useXUIColors, useXUITheme };
|
package/dist/index.cjs
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __copyProps = (to, from, except, desc) => {
|
|
7
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
-
for (let key of __getOwnPropNames(from))
|
|
9
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
-
}
|
|
12
|
-
return to;
|
|
13
|
-
};
|
|
14
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
-
|
|
16
|
-
// src/index.ts
|
|
17
|
-
var src_exports = {};
|
|
18
|
-
module.exports = __toCommonJS(src_exports);
|
package/dist/index.d.cts
DELETED