@epoch32/visage 0.0.0-stage → 0.0.0
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/LICENSE +373 -0
- package/README.md +110 -2
- package/dist/bundle.dev.js +4875 -0
- package/dist/index.js +9633 -0
- package/dist/src/api/index.js +4002 -0
- package/dist/src/charts/index.js +2717 -0
- package/dist/src/devtools/index.js +4677 -0
- package/dist/src/dom/index.js +1550 -0
- package/dist/src/form/index.js +1415 -0
- package/dist/src/index.js +11826 -0
- package/dist/src/jsx-runtime/index.js +1630 -0
- package/dist/src/query/index.js +2422 -0
- package/dist/src/router/index.js +1856 -0
- package/dist/src/rpc/index.js +3484 -0
- package/dist/src/server/index.js +1173 -0
- package/dist/src/signals/index.js +1077 -0
- package/dist/src/style/index.js +2340 -0
- package/dist/src/template/index.js +1149 -0
- package/dist/src/ui/index.js +4155 -0
- package/dist/src/virtual/index.js +1955 -0
- package/dist/src/vite/index.js +984 -0
- package/dist/vite/index.js +707 -0
- package/package.json +140 -4
- package/src/api/client.ts +371 -0
- package/src/api/file-router.ts +183 -0
- package/src/api/handler.ts +326 -0
- package/src/api/index.ts +71 -0
- package/src/api/middleware.ts +54 -0
- package/src/api/pragma.ts +155 -0
- package/src/api/procedure.ts +172 -0
- package/src/api/types.ts +249 -0
- package/src/charts/Area.tsx +111 -0
- package/src/charts/Axis.tsx +126 -0
- package/src/charts/Bar.tsx +86 -0
- package/src/charts/CartesianGrid.tsx +72 -0
- package/src/charts/Chart.tsx +269 -0
- package/src/charts/Cursor.tsx +42 -0
- package/src/charts/Legend.tsx +56 -0
- package/src/charts/Line.tsx +106 -0
- package/src/charts/Pie.tsx +88 -0
- package/src/charts/Tooltip.tsx +127 -0
- package/src/charts/context.ts +30 -0
- package/src/charts/index.ts +14 -0
- package/src/charts/path.ts +155 -0
- package/src/charts/scale.ts +133 -0
- package/src/charts/types.ts +50 -0
- package/src/devtools/DomTab.tsx +134 -0
- package/src/devtools/GraphInspector.tsx +196 -0
- package/src/devtools/GraphTab.tsx +315 -0
- package/src/devtools/QueryTab.tsx +200 -0
- package/src/devtools/RpcTab.tsx +190 -0
- package/src/devtools/SignalsTab.tsx +129 -0
- package/src/devtools/component.tsx +243 -0
- package/src/devtools/highlighter.ts +134 -0
- package/src/devtools/hub.ts +175 -0
- package/src/devtools/index.ts +20 -0
- package/src/devtools/styles.ts +313 -0
- package/src/devtools/types.ts +45 -0
- package/src/dom/async.ts +232 -0
- package/src/dom/control-flow.ts +353 -0
- package/src/dom/index.ts +32 -0
- package/src/dom/lazy.ts +82 -0
- package/src/dom/render.ts +286 -0
- package/src/dom/resource.ts +120 -0
- package/src/form/form.ts +218 -0
- package/src/form/index.ts +17 -0
- package/src/form/schema.ts +299 -0
- package/src/index.ts +413 -0
- package/src/jsx-dev-runtime/index.ts +1 -0
- package/src/jsx-runtime/index.ts +112 -0
- package/src/jsx-runtime/jsx.d.ts +278 -0
- package/src/query/create-mutation.ts +64 -0
- package/src/query/create-query.ts +426 -0
- package/src/query/focus-manager.ts +68 -0
- package/src/query/index.ts +63 -0
- package/src/query/mutation-cache.ts +138 -0
- package/src/query/online-manager.ts +67 -0
- package/src/query/query-cache.ts +369 -0
- package/src/query/query-client.ts +248 -0
- package/src/query/types.ts +221 -0
- package/src/query/utils.ts +132 -0
- package/src/router/index.ts +19 -0
- package/src/router/router.tsx +352 -0
- package/src/rpc/client.ts +317 -0
- package/src/rpc/error.ts +70 -0
- package/src/rpc/index.ts +52 -0
- package/src/rpc/procedure.ts +88 -0
- package/src/rpc/router.ts +105 -0
- package/src/rpc/server.ts +511 -0
- package/src/rpc/types.ts +328 -0
- package/src/server/hydrate.ts +21 -0
- package/src/server/index.ts +10 -0
- package/src/server/render-to-stream.ts +31 -0
- package/src/server/render-to-string.ts +125 -0
- package/src/signals/computed.ts +217 -0
- package/src/signals/context.ts +89 -0
- package/src/signals/effect.ts +161 -0
- package/src/signals/index.ts +57 -0
- package/src/signals/scope.ts +132 -0
- package/src/signals/signal.ts +203 -0
- package/src/signals/store.ts +163 -0
- package/src/signals/system.ts +124 -0
- package/src/signals/types.ts +64 -0
- package/src/style/component.tsx +122 -0
- package/src/style/create-style.ts +229 -0
- package/src/style/cx.ts +75 -0
- package/src/style/hash.ts +19 -0
- package/src/style/index.ts +8 -0
- package/src/style/layout.tsx +406 -0
- package/src/style/manager.ts +87 -0
- package/src/style/parser.ts +257 -0
- package/src/style/scale.ts +237 -0
- package/src/template/index.ts +4 -0
- package/src/template/template.ts +126 -0
- package/src/ui/accordion.tsx +286 -0
- package/src/ui/command-dialog.tsx +49 -0
- package/src/ui/command.tsx +400 -0
- package/src/ui/data-table.tsx +322 -0
- package/src/ui/dialog.tsx +362 -0
- package/src/ui/dropdown-menu.tsx +381 -0
- package/src/ui/icon.tsx +69 -0
- package/src/ui/index.ts +138 -0
- package/src/ui/layout.tsx +13 -0
- package/src/ui/popover.tsx +249 -0
- package/src/ui/switch.tsx +114 -0
- package/src/ui/tabs.tsx +297 -0
- package/src/ui/toast.tsx +280 -0
- package/src/ui/tooltip.tsx +262 -0
- package/src/ui/utils.ts +110 -0
- package/src/virtual/index.ts +12 -0
- package/src/virtual/virtual-list.tsx +185 -0
- package/src/virtual/virtualizer.ts +274 -0
- package/src/vite/hmr.ts +38 -0
- package/src/vite/index.ts +3 -0
- package/src/vite/lucide.ts +124 -0
- package/src/vite/plugin.ts +102 -0
- package/src/vite/rpc-middleware.ts +82 -0
- package/src/vite/types.ts +65 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { Portal } from "../dom/control-flow";
|
|
2
|
+
import type { Child } from "../dom/render";
|
|
3
|
+
import { onCleanup, type ReadonlySignal } from "../signals";
|
|
4
|
+
import { createContext, useContext } from "../signals/context";
|
|
5
|
+
import { createControllableSignal, createId, onClickOutside } from "./utils";
|
|
6
|
+
|
|
7
|
+
export interface DropdownMenuContextValue {
|
|
8
|
+
open: ReadonlySignal<boolean>;
|
|
9
|
+
setOpen: (open: boolean) => void;
|
|
10
|
+
triggerRef: { current: HTMLElement | null };
|
|
11
|
+
contentRef: { current: HTMLElement | null };
|
|
12
|
+
menuId: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const DropdownMenuContext = createContext<DropdownMenuContextValue | null>(null);
|
|
16
|
+
|
|
17
|
+
export function useDropdownMenuContext(): DropdownMenuContextValue | null {
|
|
18
|
+
return useContext(DropdownMenuContext);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface DropdownMenuItemData {
|
|
22
|
+
label?: Child | (() => Child);
|
|
23
|
+
icon?: Child | (() => Child);
|
|
24
|
+
disabled?: boolean | (() => boolean);
|
|
25
|
+
danger?: boolean;
|
|
26
|
+
separator?: boolean;
|
|
27
|
+
onSelect?: (e: Event) => void;
|
|
28
|
+
class?: any;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface DropdownMenuProps {
|
|
32
|
+
open?: () => boolean | undefined;
|
|
33
|
+
defaultOpen?: boolean;
|
|
34
|
+
onOpenChange?: (open: boolean) => void;
|
|
35
|
+
trigger?: Child | (() => Child);
|
|
36
|
+
items?: DropdownMenuItemData[];
|
|
37
|
+
triggerClass?: any;
|
|
38
|
+
contentClass?: any;
|
|
39
|
+
itemClass?: any;
|
|
40
|
+
separatorClass?: any;
|
|
41
|
+
portalled?: boolean;
|
|
42
|
+
children?: Child | (() => Child);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function DropdownMenuRoot(props: DropdownMenuProps): Child {
|
|
46
|
+
const [open, setOpen] = createControllableSignal<boolean>({
|
|
47
|
+
value: props.open,
|
|
48
|
+
defaultValue: props.defaultOpen ?? false,
|
|
49
|
+
onChange: props.onOpenChange
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const triggerRef: { current: HTMLElement | null } = { current: null };
|
|
53
|
+
const contentRef: { current: HTMLElement | null } = { current: null };
|
|
54
|
+
const menuId = createId("dropdown-menu");
|
|
55
|
+
|
|
56
|
+
const ctx: DropdownMenuContextValue = {
|
|
57
|
+
open,
|
|
58
|
+
setOpen,
|
|
59
|
+
triggerRef,
|
|
60
|
+
contentRef,
|
|
61
|
+
menuId
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
if (props.trigger !== undefined || props.items !== undefined) {
|
|
65
|
+
return DropdownMenuContext.Provider({
|
|
66
|
+
value: ctx,
|
|
67
|
+
children: () => (
|
|
68
|
+
<div class="visage-dropdown-root" style={{ position: "relative", display: "inline-block" }}>
|
|
69
|
+
{props.trigger ? (
|
|
70
|
+
<DropdownMenuTrigger as="span" class={props.triggerClass}>
|
|
71
|
+
{typeof props.trigger === "function" ? props.trigger() : props.trigger}
|
|
72
|
+
</DropdownMenuTrigger>
|
|
73
|
+
) : null}
|
|
74
|
+
<DropdownMenuContent portalled={props.portalled ?? false} class={props.contentClass}>
|
|
75
|
+
{props.items
|
|
76
|
+
? props.items.map((item) => {
|
|
77
|
+
if (item.separator) {
|
|
78
|
+
return <DropdownMenuSeparator class={item.class ?? props.separatorClass} />;
|
|
79
|
+
}
|
|
80
|
+
return (
|
|
81
|
+
<DropdownMenuItem
|
|
82
|
+
disabled={item.disabled}
|
|
83
|
+
onSelect={item.onSelect}
|
|
84
|
+
class={[props.itemClass, item.class, item.danger ? "danger" : ""]
|
|
85
|
+
.filter(Boolean)
|
|
86
|
+
.join(" ")}
|
|
87
|
+
>
|
|
88
|
+
{item.icon ? (
|
|
89
|
+
<span
|
|
90
|
+
class="dropdown-item-icon"
|
|
91
|
+
style={{
|
|
92
|
+
display: "inline-flex",
|
|
93
|
+
alignItems: "center",
|
|
94
|
+
marginRight: "8px"
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
97
|
+
{typeof item.icon === "function" ? item.icon() : item.icon}
|
|
98
|
+
</span>
|
|
99
|
+
) : null}
|
|
100
|
+
{typeof item.label === "function" ? item.label() : item.label}
|
|
101
|
+
</DropdownMenuItem>
|
|
102
|
+
);
|
|
103
|
+
})
|
|
104
|
+
: null}
|
|
105
|
+
{typeof props.children === "function" ? props.children() : props.children}
|
|
106
|
+
</DropdownMenuContent>
|
|
107
|
+
</div>
|
|
108
|
+
)
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return DropdownMenuContext.Provider({
|
|
113
|
+
value: ctx,
|
|
114
|
+
children: props.children
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface DropdownMenuTriggerProps {
|
|
119
|
+
as?: string;
|
|
120
|
+
class?: any;
|
|
121
|
+
style?: any;
|
|
122
|
+
onClick?: (e: MouseEvent) => void;
|
|
123
|
+
onKeyDown?: (e: KeyboardEvent) => void;
|
|
124
|
+
children: Child | (() => Child);
|
|
125
|
+
[key: string]: any;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function DropdownMenuTrigger(props: DropdownMenuTriggerProps): Child {
|
|
129
|
+
const ctx = useContext(DropdownMenuContext);
|
|
130
|
+
|
|
131
|
+
const handleClick = (e: MouseEvent) => {
|
|
132
|
+
if (props.onClick) props.onClick(e);
|
|
133
|
+
if (!e.defaultPrevented && ctx) {
|
|
134
|
+
ctx.setOpen(!ctx.open());
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const handleKeyDown = (e: KeyboardEvent) => {
|
|
139
|
+
if (props.onKeyDown) props.onKeyDown(e);
|
|
140
|
+
if (e.defaultPrevented) return;
|
|
141
|
+
|
|
142
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
143
|
+
if (ctx) {
|
|
144
|
+
ctx.setOpen(true);
|
|
145
|
+
e.preventDefault();
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
const firstItem = ctx.contentRef.current?.querySelector<HTMLElement>(
|
|
148
|
+
'[role="menuitem"]:not([disabled])'
|
|
149
|
+
);
|
|
150
|
+
firstItem?.focus();
|
|
151
|
+
}, 0);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const {
|
|
157
|
+
as: Tag = "button",
|
|
158
|
+
children,
|
|
159
|
+
onClick,
|
|
160
|
+
onKeyDown,
|
|
161
|
+
class: className,
|
|
162
|
+
style,
|
|
163
|
+
...rest
|
|
164
|
+
} = props;
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<Tag
|
|
168
|
+
ref={(el: HTMLElement | null) => {
|
|
169
|
+
if (ctx) ctx.triggerRef.current = el;
|
|
170
|
+
}}
|
|
171
|
+
type={Tag === "button" ? "button" : undefined}
|
|
172
|
+
aria-haspopup="menu"
|
|
173
|
+
aria-expanded={() => ctx?.open() ?? false}
|
|
174
|
+
aria-controls={ctx?.menuId}
|
|
175
|
+
data-state={() => (ctx?.open() ? "open" : "closed")}
|
|
176
|
+
class={className}
|
|
177
|
+
style={style}
|
|
178
|
+
onClick={handleClick}
|
|
179
|
+
onKeyDown={handleKeyDown}
|
|
180
|
+
{...rest}
|
|
181
|
+
>
|
|
182
|
+
{children}
|
|
183
|
+
</Tag>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export interface DropdownMenuPortalProps {
|
|
188
|
+
mount?: HTMLElement | null;
|
|
189
|
+
children: Child | (() => Child);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export function DropdownMenuPortal(props: DropdownMenuPortalProps): Child {
|
|
193
|
+
return <Portal mount={props.mount}>{props.children}</Portal>;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface DropdownMenuContentProps {
|
|
197
|
+
as?: string;
|
|
198
|
+
portalled?: boolean;
|
|
199
|
+
mount?: HTMLElement | null;
|
|
200
|
+
class?: any;
|
|
201
|
+
style?: any;
|
|
202
|
+
onKeyDown?: (e: KeyboardEvent) => void;
|
|
203
|
+
children: Child | (() => Child);
|
|
204
|
+
[key: string]: any;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function DropdownMenuContent(props: DropdownMenuContentProps): Child {
|
|
208
|
+
const ctx = useContext(DropdownMenuContext);
|
|
209
|
+
|
|
210
|
+
const handleKeyDown = (e: KeyboardEvent) => {
|
|
211
|
+
if (props.onKeyDown) props.onKeyDown(e);
|
|
212
|
+
if (e.defaultPrevented) return;
|
|
213
|
+
|
|
214
|
+
const el = ctx?.contentRef.current;
|
|
215
|
+
if (!el) return;
|
|
216
|
+
|
|
217
|
+
const items = Array.from(el.querySelectorAll<HTMLElement>('[role="menuitem"]:not([disabled])'));
|
|
218
|
+
const active = document.activeElement as HTMLElement | null;
|
|
219
|
+
const index = active ? items.indexOf(active) : -1;
|
|
220
|
+
|
|
221
|
+
if (e.key === "ArrowDown") {
|
|
222
|
+
const nextIndex = index === items.length - 1 || index === -1 ? 0 : index + 1;
|
|
223
|
+
items[nextIndex]?.focus();
|
|
224
|
+
e.preventDefault();
|
|
225
|
+
} else if (e.key === "ArrowUp") {
|
|
226
|
+
const nextIndex = index <= 0 ? items.length - 1 : index - 1;
|
|
227
|
+
items[nextIndex]?.focus();
|
|
228
|
+
e.preventDefault();
|
|
229
|
+
} else if (e.key === "Home") {
|
|
230
|
+
items[0]?.focus();
|
|
231
|
+
e.preventDefault();
|
|
232
|
+
} else if (e.key === "End") {
|
|
233
|
+
items[items.length - 1]?.focus();
|
|
234
|
+
e.preventDefault();
|
|
235
|
+
} else if (e.key === "Escape") {
|
|
236
|
+
if (ctx) {
|
|
237
|
+
ctx.setOpen(false);
|
|
238
|
+
ctx.triggerRef.current?.focus();
|
|
239
|
+
}
|
|
240
|
+
e.preventDefault();
|
|
241
|
+
} else if (e.key === "Tab") {
|
|
242
|
+
if (ctx) ctx.setOpen(false);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const {
|
|
247
|
+
as: Tag = "div",
|
|
248
|
+
children,
|
|
249
|
+
onKeyDown,
|
|
250
|
+
class: className,
|
|
251
|
+
style,
|
|
252
|
+
portalled = true,
|
|
253
|
+
mount,
|
|
254
|
+
...rest
|
|
255
|
+
} = props;
|
|
256
|
+
|
|
257
|
+
const content = (
|
|
258
|
+
<Tag
|
|
259
|
+
ref={(el: HTMLElement | null) => {
|
|
260
|
+
if (ctx) {
|
|
261
|
+
ctx.contentRef.current = el;
|
|
262
|
+
if (el) {
|
|
263
|
+
const cleanup = onClickOutside([ctx.triggerRef.current, el], () => {
|
|
264
|
+
if (ctx.open()) {
|
|
265
|
+
ctx.setOpen(false);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
onCleanup(cleanup);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}}
|
|
272
|
+
id={ctx?.menuId}
|
|
273
|
+
role="menu"
|
|
274
|
+
aria-orientation="vertical"
|
|
275
|
+
data-state={() => (ctx?.open() ? "open" : "closed")}
|
|
276
|
+
class={className}
|
|
277
|
+
style={() => ({
|
|
278
|
+
display: ctx?.open() ? undefined : "none",
|
|
279
|
+
...style
|
|
280
|
+
})}
|
|
281
|
+
onKeyDown={handleKeyDown}
|
|
282
|
+
tabIndex={-1}
|
|
283
|
+
{...rest}
|
|
284
|
+
>
|
|
285
|
+
{children}
|
|
286
|
+
</Tag>
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
return portalled ? <Portal mount={mount}>{content}</Portal> : content;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export interface DropdownMenuItemProps {
|
|
293
|
+
disabled?: boolean | (() => boolean);
|
|
294
|
+
closeOnSelect?: boolean;
|
|
295
|
+
as?: string;
|
|
296
|
+
class?: any;
|
|
297
|
+
style?: any;
|
|
298
|
+
onSelect?: (e: Event) => void;
|
|
299
|
+
onClick?: (e: MouseEvent) => void;
|
|
300
|
+
onKeyDown?: (e: KeyboardEvent) => void;
|
|
301
|
+
children: Child | (() => Child);
|
|
302
|
+
[key: string]: any;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export function DropdownMenuItem(props: DropdownMenuItemProps): Child {
|
|
306
|
+
const ctx = useContext(DropdownMenuContext);
|
|
307
|
+
const closeOnSelect = props.closeOnSelect ?? true;
|
|
308
|
+
|
|
309
|
+
const handleSelect = (e: Event) => {
|
|
310
|
+
if (props.disabled) return;
|
|
311
|
+
if (props.onSelect) props.onSelect(e);
|
|
312
|
+
if (!e.defaultPrevented && closeOnSelect && ctx) {
|
|
313
|
+
ctx.setOpen(false);
|
|
314
|
+
ctx.triggerRef.current?.focus();
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const handleClick = (e: MouseEvent) => {
|
|
319
|
+
if (props.onClick) props.onClick(e);
|
|
320
|
+
handleSelect(e);
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const handleKeyDown = (e: KeyboardEvent) => {
|
|
324
|
+
if (props.onKeyDown) props.onKeyDown(e);
|
|
325
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
326
|
+
e.preventDefault();
|
|
327
|
+
handleSelect(e);
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const {
|
|
332
|
+
disabled,
|
|
333
|
+
closeOnSelect: _cos,
|
|
334
|
+
as: Tag = "div",
|
|
335
|
+
children,
|
|
336
|
+
onClick,
|
|
337
|
+
onKeyDown,
|
|
338
|
+
onSelect: _os,
|
|
339
|
+
class: className,
|
|
340
|
+
style,
|
|
341
|
+
...rest
|
|
342
|
+
} = props;
|
|
343
|
+
|
|
344
|
+
return (
|
|
345
|
+
<Tag
|
|
346
|
+
role="menuitem"
|
|
347
|
+
tabIndex={-1}
|
|
348
|
+
aria-disabled={disabled}
|
|
349
|
+
class={className}
|
|
350
|
+
style={style}
|
|
351
|
+
onClick={handleClick}
|
|
352
|
+
onKeyDown={handleKeyDown}
|
|
353
|
+
{...rest}
|
|
354
|
+
>
|
|
355
|
+
{children}
|
|
356
|
+
</Tag>
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export interface DropdownMenuSeparatorProps {
|
|
361
|
+
as?: string;
|
|
362
|
+
class?: any;
|
|
363
|
+
style?: any;
|
|
364
|
+
[key: string]: any;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export function DropdownMenuSeparator(props: DropdownMenuSeparatorProps): Child {
|
|
368
|
+
const { as: Tag = "div", class: className, style, ...rest } = props;
|
|
369
|
+
return (
|
|
370
|
+
<Tag role="separator" aria-orientation="horizontal" class={className} style={style} {...rest} />
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export const DropdownMenu = Object.assign(DropdownMenuRoot, {
|
|
375
|
+
Root: DropdownMenuRoot,
|
|
376
|
+
Trigger: DropdownMenuTrigger,
|
|
377
|
+
Portal: DropdownMenuPortal,
|
|
378
|
+
Content: DropdownMenuContent,
|
|
379
|
+
Item: DropdownMenuItem,
|
|
380
|
+
Separator: DropdownMenuSeparator
|
|
381
|
+
});
|
package/src/ui/icon.tsx
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Child } from "../dom/render";
|
|
2
|
+
|
|
3
|
+
export type IconNode = [string, Record<string, any>][];
|
|
4
|
+
|
|
5
|
+
export interface IconProps {
|
|
6
|
+
size?: number | string | (() => number | string);
|
|
7
|
+
color?: string | (() => string);
|
|
8
|
+
strokeWidth?: number | string | (() => number | string);
|
|
9
|
+
class?: any;
|
|
10
|
+
style?: any;
|
|
11
|
+
children?: Child | (() => Child);
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a native Visage SVG component from a Lucide / SVG icon node definition
|
|
17
|
+
*/
|
|
18
|
+
export function createIcon(name: string, iconNode: IconNode) {
|
|
19
|
+
const IconComponent = function Icon(props: IconProps = {}): Child {
|
|
20
|
+
const size = () =>
|
|
21
|
+
typeof props.size === "function" ? (props.size as () => any)() : (props.size ?? 24);
|
|
22
|
+
const color = () =>
|
|
23
|
+
typeof props.color === "function"
|
|
24
|
+
? (props.color as () => any)()
|
|
25
|
+
: (props.color ?? "currentColor");
|
|
26
|
+
const strokeWidth = () =>
|
|
27
|
+
typeof props.strokeWidth === "function"
|
|
28
|
+
? (props.strokeWidth as () => any)()
|
|
29
|
+
: (props.strokeWidth ?? 2);
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
size: _s,
|
|
33
|
+
color: _c,
|
|
34
|
+
strokeWidth: _sw,
|
|
35
|
+
class: className,
|
|
36
|
+
style,
|
|
37
|
+
children,
|
|
38
|
+
...rest
|
|
39
|
+
} = props;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<svg
|
|
43
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
44
|
+
width={size}
|
|
45
|
+
height={size}
|
|
46
|
+
viewBox="0 0 24 24"
|
|
47
|
+
fill="none"
|
|
48
|
+
stroke={color}
|
|
49
|
+
stroke-width={strokeWidth}
|
|
50
|
+
stroke-linecap="round"
|
|
51
|
+
stroke-linejoin="round"
|
|
52
|
+
class={className}
|
|
53
|
+
style={style}
|
|
54
|
+
role="img"
|
|
55
|
+
aria-label={props["aria-label"] ?? name}
|
|
56
|
+
{...rest}
|
|
57
|
+
>
|
|
58
|
+
<title>{props.title ?? name}</title>
|
|
59
|
+
{iconNode.map(([Tag, attrs]) => (
|
|
60
|
+
<Tag {...attrs} />
|
|
61
|
+
))}
|
|
62
|
+
{typeof children === "function" ? (children as () => Child)() : children}
|
|
63
|
+
</svg>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
IconComponent.displayName = name;
|
|
68
|
+
return IconComponent;
|
|
69
|
+
}
|
package/src/ui/index.ts
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Accordion,
|
|
3
|
+
AccordionContent,
|
|
4
|
+
AccordionItem,
|
|
5
|
+
type AccordionItemProps,
|
|
6
|
+
type AccordionMultipleProps,
|
|
7
|
+
type AccordionProps,
|
|
8
|
+
type AccordionSingleProps,
|
|
9
|
+
AccordionTrigger,
|
|
10
|
+
useAccordionContext,
|
|
11
|
+
useAccordionItemContext
|
|
12
|
+
} from "./accordion";
|
|
13
|
+
export {
|
|
14
|
+
Command,
|
|
15
|
+
CommandDialog,
|
|
16
|
+
type CommandDialogProps,
|
|
17
|
+
CommandEmpty,
|
|
18
|
+
CommandGroup,
|
|
19
|
+
type CommandGroupData,
|
|
20
|
+
CommandInput,
|
|
21
|
+
type CommandInputProps,
|
|
22
|
+
CommandItem,
|
|
23
|
+
type CommandItemData,
|
|
24
|
+
type CommandItemProps,
|
|
25
|
+
CommandList,
|
|
26
|
+
type CommandProps,
|
|
27
|
+
useCommandContext
|
|
28
|
+
} from "./command";
|
|
29
|
+
export {
|
|
30
|
+
type ColumnDef,
|
|
31
|
+
DataTable,
|
|
32
|
+
type DataTableProps,
|
|
33
|
+
type SortDirection,
|
|
34
|
+
type SortState
|
|
35
|
+
} from "./data-table";
|
|
36
|
+
export {
|
|
37
|
+
Dialog,
|
|
38
|
+
DialogClose,
|
|
39
|
+
DialogContent,
|
|
40
|
+
type DialogContentProps,
|
|
41
|
+
DialogDescription,
|
|
42
|
+
DialogOverlay,
|
|
43
|
+
DialogPortal,
|
|
44
|
+
type DialogProps,
|
|
45
|
+
DialogTitle,
|
|
46
|
+
DialogTrigger,
|
|
47
|
+
useDialogContext
|
|
48
|
+
} from "./dialog";
|
|
49
|
+
export {
|
|
50
|
+
DropdownMenu,
|
|
51
|
+
DropdownMenuContent,
|
|
52
|
+
DropdownMenuItem,
|
|
53
|
+
type DropdownMenuItemProps,
|
|
54
|
+
DropdownMenuPortal,
|
|
55
|
+
type DropdownMenuProps,
|
|
56
|
+
DropdownMenuSeparator,
|
|
57
|
+
DropdownMenuTrigger,
|
|
58
|
+
useDropdownMenuContext
|
|
59
|
+
} from "./dropdown-menu";
|
|
60
|
+
export {
|
|
61
|
+
createIcon,
|
|
62
|
+
type IconNode,
|
|
63
|
+
type IconProps
|
|
64
|
+
} from "./icon";
|
|
65
|
+
export {
|
|
66
|
+
type BaseLayoutProps,
|
|
67
|
+
Center,
|
|
68
|
+
type CenterProps,
|
|
69
|
+
Grid,
|
|
70
|
+
type GridProps,
|
|
71
|
+
Row,
|
|
72
|
+
type RowProps,
|
|
73
|
+
Spacer,
|
|
74
|
+
type SpacerProps,
|
|
75
|
+
Stack,
|
|
76
|
+
type StackProps
|
|
77
|
+
} from "./layout";
|
|
78
|
+
export {
|
|
79
|
+
Popover,
|
|
80
|
+
PopoverClose,
|
|
81
|
+
PopoverContent,
|
|
82
|
+
type PopoverContentProps,
|
|
83
|
+
PopoverPortal,
|
|
84
|
+
type PopoverProps,
|
|
85
|
+
PopoverTrigger,
|
|
86
|
+
usePopoverContext
|
|
87
|
+
} from "./popover";
|
|
88
|
+
export {
|
|
89
|
+
Switch,
|
|
90
|
+
type SwitchProps,
|
|
91
|
+
SwitchThumb,
|
|
92
|
+
type SwitchThumbProps
|
|
93
|
+
} from "./switch";
|
|
94
|
+
export {
|
|
95
|
+
Tabs,
|
|
96
|
+
TabsContent,
|
|
97
|
+
type TabsContentProps,
|
|
98
|
+
TabsList,
|
|
99
|
+
type TabsProps,
|
|
100
|
+
TabsTrigger,
|
|
101
|
+
useTabsContext
|
|
102
|
+
} from "./tabs";
|
|
103
|
+
export type {
|
|
104
|
+
ToastData,
|
|
105
|
+
ToastManager,
|
|
106
|
+
ToastOptions,
|
|
107
|
+
ToastProps,
|
|
108
|
+
ToastVariant
|
|
109
|
+
} from "./toast";
|
|
110
|
+
export {
|
|
111
|
+
createToastManager,
|
|
112
|
+
defaultToastManager,
|
|
113
|
+
Toast,
|
|
114
|
+
ToastClose,
|
|
115
|
+
ToastDescription,
|
|
116
|
+
ToastProvider,
|
|
117
|
+
type ToastProviderProps,
|
|
118
|
+
ToastTitle,
|
|
119
|
+
ToastViewport,
|
|
120
|
+
type ToastViewportProps,
|
|
121
|
+
toast,
|
|
122
|
+
useToast
|
|
123
|
+
} from "./toast";
|
|
124
|
+
export {
|
|
125
|
+
Tooltip,
|
|
126
|
+
TooltipContent,
|
|
127
|
+
type TooltipContentProps,
|
|
128
|
+
TooltipPortal,
|
|
129
|
+
type TooltipProps,
|
|
130
|
+
TooltipTrigger,
|
|
131
|
+
useTooltipContext
|
|
132
|
+
} from "./tooltip";
|
|
133
|
+
export {
|
|
134
|
+
createControllableSignal,
|
|
135
|
+
createId,
|
|
136
|
+
onClickOutside,
|
|
137
|
+
trapFocus
|
|
138
|
+
} from "./utils";
|