@ui-sdk/react 0.0.0-stage → 0.1.0-beta.1
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 +202 -0
- package/README.md +10 -2
- package/dist/accordion.d.ts +331 -0
- package/dist/accordion.js +25 -0
- package/dist/agent.d.ts +2 -0
- package/dist/agent.js +8 -0
- package/dist/alert-dialog.d.ts +56 -0
- package/dist/alert-dialog.js +45 -0
- package/dist/async-options.d.ts +22 -0
- package/dist/async-options.js +56 -0
- package/dist/autocomplete.d.ts +102 -0
- package/dist/autocomplete.js +195 -0
- package/dist/avatar.d.ts +301 -0
- package/dist/avatar.js +17 -0
- package/dist/button.d.ts +21 -0
- package/dist/button.js +45 -0
- package/dist/calendar-context.d.ts +10 -0
- package/dist/calendar-context.js +9 -0
- package/dist/calendar.d.ts +80 -0
- package/dist/calendar.js +257 -0
- package/dist/carousel.d.ts +52 -0
- package/dist/carousel.js +151 -0
- package/dist/checkbox.d.ts +24 -0
- package/dist/checkbox.js +98 -0
- package/dist/children.d.ts +38 -0
- package/dist/children.js +63 -0
- package/dist/collapsible.d.ts +302 -0
- package/dist/collapsible.js +19 -0
- package/dist/color-picker.d.ts +72 -0
- package/dist/color-picker.js +133 -0
- package/dist/color.d.ts +2 -0
- package/dist/color.js +22 -0
- package/dist/combobox.d.ts +152 -0
- package/dist/combobox.js +338 -0
- package/dist/command.d.ts +88 -0
- package/dist/command.js +233 -0
- package/dist/controller-target.d.ts +3 -0
- package/dist/controller-target.js +59 -0
- package/dist/date-input.d.ts +19 -0
- package/dist/date-input.js +58 -0
- package/dist/date-picker.d.ts +47 -0
- package/dist/date-picker.js +310 -0
- package/dist/date.d.ts +2 -0
- package/dist/date.js +60 -0
- package/dist/dialog-parts.d.ts +23 -0
- package/dist/dialog-parts.js +142 -0
- package/dist/dialog.d.ts +57 -0
- package/dist/dialog.js +32 -0
- package/dist/drawer.d.ts +70 -0
- package/dist/drawer.js +158 -0
- package/dist/editor-context.d.ts +4 -0
- package/dist/editor-context.js +9 -0
- package/dist/field-context.d.ts +47 -0
- package/dist/field-context.js +87 -0
- package/dist/field.d.ts +49 -0
- package/dist/field.js +169 -0
- package/dist/file-input.d.ts +46 -0
- package/dist/file-input.js +170 -0
- package/dist/form-inputs.d.ts +5 -0
- package/dist/form-inputs.js +22 -0
- package/dist/gesture.d.ts +1 -0
- package/dist/gesture.js +16 -0
- package/dist/history.d.ts +2 -0
- package/dist/history.js +12 -0
- package/dist/hover-card.d.ts +33 -0
- package/dist/hover-card.js +84 -0
- package/dist/image-cropper.d.ts +333 -0
- package/dist/image-cropper.js +37 -0
- package/dist/image.d.ts +2 -0
- package/dist/image.js +6 -0
- package/dist/input.d.ts +22 -0
- package/dist/input.js +51 -0
- package/dist/label.d.ts +294 -0
- package/dist/label.js +9 -0
- package/dist/list-items.d.ts +15 -0
- package/dist/list-items.js +39 -0
- package/dist/list-text.d.ts +4 -0
- package/dist/list-text.js +15 -0
- package/dist/listbox.d.ts +56 -0
- package/dist/listbox.js +122 -0
- package/dist/menu.d.ts +116 -0
- package/dist/menu.js +426 -0
- package/dist/menubar-context.d.ts +4 -0
- package/dist/menubar-context.js +7 -0
- package/dist/menubar.d.ts +11 -0
- package/dist/menubar.js +32 -0
- package/dist/meter.d.ts +312 -0
- package/dist/meter.js +30 -0
- package/dist/navigation-menu.d.ts +61 -0
- package/dist/navigation-menu.js +169 -0
- package/dist/number-input.d.ts +44 -0
- package/dist/number-input.js +185 -0
- package/dist/number.d.ts +2 -0
- package/dist/number.js +40 -0
- package/dist/observe.d.ts +2 -0
- package/dist/observe.js +8 -0
- package/dist/otp-input.d.ts +29 -0
- package/dist/otp-input.js +94 -0
- package/dist/overlays.d.ts +26 -0
- package/dist/overlays.js +82 -0
- package/dist/pagination.d.ts +336 -0
- package/dist/pagination.js +71 -0
- package/dist/password-input.d.ts +23 -0
- package/dist/password-input.js +65 -0
- package/dist/popover.d.ts +54 -0
- package/dist/popover.js +151 -0
- package/dist/popup.d.ts +41 -0
- package/dist/popup.js +180 -0
- package/dist/preferences.d.ts +35 -0
- package/dist/preferences.js +93 -0
- package/dist/primitive.d.ts +2 -0
- package/dist/primitive.js +14 -0
- package/dist/progress.d.ts +312 -0
- package/dist/progress.js +30 -0
- package/dist/radio.d.ts +22 -0
- package/dist/radio.js +86 -0
- package/dist/rating.d.ts +20 -0
- package/dist/rating.js +94 -0
- package/dist/render-element.d.ts +35 -0
- package/dist/render-element.js +103 -0
- package/dist/resizable.d.ts +302 -0
- package/dist/resizable.js +23 -0
- package/dist/scroll-area.d.ts +324 -0
- package/dist/scroll-area.js +49 -0
- package/dist/segmented-control.d.ts +24 -0
- package/dist/segmented-control.js +78 -0
- package/dist/segmented-input.d.ts +15 -0
- package/dist/segmented-input.js +48 -0
- package/dist/select.d.ts +125 -0
- package/dist/select.js +330 -0
- package/dist/separator.d.ts +290 -0
- package/dist/separator.js +9 -0
- package/dist/shortcuts.d.ts +32 -0
- package/dist/shortcuts.js +61 -0
- package/dist/slider.d.ts +38 -0
- package/dist/slider.js +163 -0
- package/dist/switch.d.ts +15 -0
- package/dist/switch.js +39 -0
- package/dist/tabs.d.ts +331 -0
- package/dist/tabs.js +28 -0
- package/dist/text-control.d.ts +22 -0
- package/dist/text-control.js +24 -0
- package/dist/text-match.d.ts +2 -0
- package/dist/text-match.js +8 -0
- package/dist/textarea.d.ts +10 -0
- package/dist/textarea.js +48 -0
- package/dist/time-input.d.ts +19 -0
- package/dist/time-input.js +63 -0
- package/dist/timeline.d.ts +327 -0
- package/dist/timeline.js +31 -0
- package/dist/toast-parts.d.ts +63 -0
- package/dist/toast-parts.js +144 -0
- package/dist/toast.d.ts +2 -0
- package/dist/toast.js +22 -0
- package/dist/toggle.d.ts +23 -0
- package/dist/toggle.js +76 -0
- package/dist/token-input.d.ts +35 -0
- package/dist/token-input.js +100 -0
- package/dist/toolbar-context.d.ts +6 -0
- package/dist/toolbar-context.js +16 -0
- package/dist/toolbar.d.ts +38 -0
- package/dist/toolbar.js +63 -0
- package/dist/tooltip.d.ts +39 -0
- package/dist/tooltip.js +108 -0
- package/dist/tree.d.ts +51 -0
- package/dist/tree.js +150 -0
- package/dist/trigger-menu.d.ts +83 -0
- package/dist/trigger-menu.js +167 -0
- package/dist/use-primitive.d.ts +178 -0
- package/dist/use-primitive.js +674 -0
- package/dist/waterfall.d.ts +80 -0
- package/dist/waterfall.js +108 -0
- package/docs/README.md +89 -0
- package/docs/agents.md +1523 -0
- package/docs/components/accordion.md +1391 -0
- package/docs/components/alert-dialog.md +850 -0
- package/docs/components/autocomplete.md +1963 -0
- package/docs/components/avatar.md +252 -0
- package/docs/components/button.md +444 -0
- package/docs/components/calendar.md +1687 -0
- package/docs/components/carousel.md +1244 -0
- package/docs/components/checkbox.md +1069 -0
- package/docs/components/collapsible.md +567 -0
- package/docs/components/color-picker.md +736 -0
- package/docs/components/combobox.md +3647 -0
- package/docs/components/command.md +1573 -0
- package/docs/components/date-input.md +608 -0
- package/docs/components/date-picker.md +1266 -0
- package/docs/components/dialog.md +1469 -0
- package/docs/components/drawer.md +1197 -0
- package/docs/components/field.md +549 -0
- package/docs/components/file-input.md +609 -0
- package/docs/components/hover-card.md +514 -0
- package/docs/components/image-cropper.md +579 -0
- package/docs/components/input.md +301 -0
- package/docs/components/label.md +217 -0
- package/docs/components/listbox.md +1130 -0
- package/docs/components/menu.md +1286 -0
- package/docs/components/menubar.md +455 -0
- package/docs/components/meter.md +304 -0
- package/docs/components/navigation-menu.md +1581 -0
- package/docs/components/number-input.md +1086 -0
- package/docs/components/otp-input.md +565 -0
- package/docs/components/pagination.md +648 -0
- package/docs/components/password-input.md +737 -0
- package/docs/components/popover.md +1552 -0
- package/docs/components/preferences.md +220 -0
- package/docs/components/progress.md +443 -0
- package/docs/components/radio.md +846 -0
- package/docs/components/rating.md +458 -0
- package/docs/components/resizable.md +982 -0
- package/docs/components/scroll-area.md +980 -0
- package/docs/components/segmented-control.md +465 -0
- package/docs/components/select.md +2133 -0
- package/docs/components/separator.md +243 -0
- package/docs/components/slider.md +1169 -0
- package/docs/components/switch.md +613 -0
- package/docs/components/tabs.md +1014 -0
- package/docs/components/textarea.md +318 -0
- package/docs/components/time-input.md +231 -0
- package/docs/components/timeline.md +677 -0
- package/docs/components/toast.md +1395 -0
- package/docs/components/toggle.md +541 -0
- package/docs/components/token-input.md +1007 -0
- package/docs/components/toolbar.md +787 -0
- package/docs/components/tooltip.md +884 -0
- package/docs/components/tree.md +1346 -0
- package/docs/components/trigger-menu.md +1257 -0
- package/docs/components/waterfall.md +754 -0
- package/docs/controllers.md +89 -0
- package/docs/core.md +8027 -0
- package/docs/custom-parts.md +120 -0
- package/docs/first-component.md +83 -0
- package/docs/forms.md +148 -0
- package/docs/hooks/async-options.md +366 -0
- package/docs/hooks/shortcuts.md +221 -0
- package/docs/installation.md +45 -0
- package/docs/introduction.md +32 -0
- package/docs/lists-and-menus.md +170 -0
- package/docs/llms.txt +1844 -0
- package/docs/parts-and-composition.md +93 -0
- package/docs/popups.md +117 -0
- package/docs/rendering.md +121 -0
- package/docs/server-rendering.md +253 -0
- package/docs/state-and-events.md +105 -0
- package/docs/styling-and-animation.md +176 -0
- package/package.json +333 -3
|
@@ -0,0 +1,674 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
// src/use-primitive.tsx
|
|
3
|
+
import {
|
|
4
|
+
attrs,
|
|
5
|
+
commit,
|
|
6
|
+
directNames,
|
|
7
|
+
handlers as partHandlers,
|
|
8
|
+
keep,
|
|
9
|
+
partState,
|
|
10
|
+
present,
|
|
11
|
+
ref,
|
|
12
|
+
release,
|
|
13
|
+
renderVersion,
|
|
14
|
+
sameSlotState,
|
|
15
|
+
sameValue,
|
|
16
|
+
schemaOf,
|
|
17
|
+
selectedKeys,
|
|
18
|
+
subscribe,
|
|
19
|
+
takeOwnId,
|
|
20
|
+
unwatched,
|
|
21
|
+
yieldToAuthor
|
|
22
|
+
} from "@ui-sdk/core/renderer";
|
|
23
|
+
import * as React from "react";
|
|
24
|
+
import {
|
|
25
|
+
mergeProps,
|
|
26
|
+
mergeRefs,
|
|
27
|
+
renderElement
|
|
28
|
+
} from "./render-element.js";
|
|
29
|
+
import { jsx } from "react/jsx-runtime";
|
|
30
|
+
var camelCase = (names, prefix = "") => Object.fromEntries(
|
|
31
|
+
names.split(" ").map((name) => [name.toLowerCase(), prefix + name])
|
|
32
|
+
);
|
|
33
|
+
var propNames = {
|
|
34
|
+
class: "className",
|
|
35
|
+
for: "htmlFor",
|
|
36
|
+
checked: "defaultChecked",
|
|
37
|
+
.../* @__PURE__ */ camelCase(
|
|
38
|
+
"tabIndex readOnly inputMode enterKeyHint autoComplete autoCapitalize autoCorrect spellCheck contentEditable maxLength minLength"
|
|
39
|
+
)
|
|
40
|
+
};
|
|
41
|
+
var booleans = /* @__PURE__ */ new Set([
|
|
42
|
+
"hidden",
|
|
43
|
+
"disabled",
|
|
44
|
+
"readonly",
|
|
45
|
+
"required",
|
|
46
|
+
"inert",
|
|
47
|
+
"checked",
|
|
48
|
+
"multiple"
|
|
49
|
+
]);
|
|
50
|
+
var styles = /* @__PURE__ */ new Map();
|
|
51
|
+
function styleObject(css) {
|
|
52
|
+
let style = styles.get(css);
|
|
53
|
+
if (style) {
|
|
54
|
+
return style;
|
|
55
|
+
}
|
|
56
|
+
style = {};
|
|
57
|
+
for (const declaration of css.split(";")) {
|
|
58
|
+
const index = declaration.indexOf(":");
|
|
59
|
+
if (index === -1) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const name = declaration.slice(0, index).trim();
|
|
63
|
+
style[name.startsWith("--") ? name : name.replace(/-(\w)/g, (_, char) => char.toUpperCase())] = declaration.slice(index + 1).trim();
|
|
64
|
+
}
|
|
65
|
+
if (styles.size >= 500) {
|
|
66
|
+
styles.clear();
|
|
67
|
+
}
|
|
68
|
+
styles.set(css, style);
|
|
69
|
+
return style;
|
|
70
|
+
}
|
|
71
|
+
var eventProps = /* @__PURE__ */ Object.assign(
|
|
72
|
+
/* @__PURE__ */ camelCase(
|
|
73
|
+
"Click KeyDown KeyUp ContextMenu PointerDown MouseDown PointerUp PointerMove",
|
|
74
|
+
"on"
|
|
75
|
+
),
|
|
76
|
+
{
|
|
77
|
+
dblclick: "onDoubleClick",
|
|
78
|
+
focusin: "onFocus",
|
|
79
|
+
focusout: "onBlur",
|
|
80
|
+
input: "onChange",
|
|
81
|
+
submit: "onSubmit"
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
var host = {
|
|
85
|
+
by: "framework",
|
|
86
|
+
attaches: /* @__PURE__ */ Object.keys(eventProps)
|
|
87
|
+
};
|
|
88
|
+
function toReactProps(attrs2) {
|
|
89
|
+
const props = {};
|
|
90
|
+
for (const name in attrs2) {
|
|
91
|
+
const value = attrs2[name];
|
|
92
|
+
if (value === void 0) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
props[propNames[name] ?? name] = booleans.has(name) ? true : name === "style" ? styleObject(value) : value;
|
|
96
|
+
}
|
|
97
|
+
return props;
|
|
98
|
+
}
|
|
99
|
+
function usePrimitive(primitive, options) {
|
|
100
|
+
const id = `ui-sdk-${React.useId()}`;
|
|
101
|
+
const create = (from = {}) => unwatched(
|
|
102
|
+
() => primitive({
|
|
103
|
+
...options,
|
|
104
|
+
...from,
|
|
105
|
+
controller: void 0,
|
|
106
|
+
id
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
const [instance, setInstance] = React.useState(() => create());
|
|
110
|
+
React.useLayoutEffect(() => keep(instance), [instance]);
|
|
111
|
+
const next = { ...options, id };
|
|
112
|
+
const outers = outersOf(options);
|
|
113
|
+
const base = instance.get();
|
|
114
|
+
const state = within(outers, () => instance.preview(next));
|
|
115
|
+
const preview = state && {
|
|
116
|
+
options: next,
|
|
117
|
+
outers,
|
|
118
|
+
base,
|
|
119
|
+
state,
|
|
120
|
+
handed: false,
|
|
121
|
+
pending: /* @__PURE__ */ new Set()
|
|
122
|
+
};
|
|
123
|
+
React.useLayoutEffect(() => {
|
|
124
|
+
handOver(instance, next, preview, outers);
|
|
125
|
+
});
|
|
126
|
+
const life = React.useRef({ mounted: 0, destroyed: false });
|
|
127
|
+
React.useEffect(() => {
|
|
128
|
+
const own = life.current;
|
|
129
|
+
own.mounted++;
|
|
130
|
+
hidden.delete(instance);
|
|
131
|
+
owners?.unregister(own);
|
|
132
|
+
if (own.destroyed) {
|
|
133
|
+
own.destroyed = false;
|
|
134
|
+
setInstance(create(carried(primitive, instance, options)));
|
|
135
|
+
}
|
|
136
|
+
return () => {
|
|
137
|
+
own.mounted--;
|
|
138
|
+
queueMicrotask(() => {
|
|
139
|
+
if (own.mounted || own.destroyed) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
release(instance);
|
|
143
|
+
const leave = () => {
|
|
144
|
+
own.destroyed = true;
|
|
145
|
+
instance.destroy();
|
|
146
|
+
};
|
|
147
|
+
if (!anchors.has(instance)) {
|
|
148
|
+
owners?.register(own, instance, own);
|
|
149
|
+
} else if (inPage(instance)) {
|
|
150
|
+
hide(instance, leave);
|
|
151
|
+
} else {
|
|
152
|
+
leave();
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
}, [instance]);
|
|
157
|
+
const stable = React.useMemo(() => {
|
|
158
|
+
const handle = {
|
|
159
|
+
primitive,
|
|
160
|
+
instance,
|
|
161
|
+
get state() {
|
|
162
|
+
return stateIn(this);
|
|
163
|
+
},
|
|
164
|
+
// Read when used, since reading it wakes an asleep instance.
|
|
165
|
+
get api() {
|
|
166
|
+
return instance.api;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
return handle;
|
|
170
|
+
}, [instance]);
|
|
171
|
+
if (!preview) {
|
|
172
|
+
return stable;
|
|
173
|
+
}
|
|
174
|
+
const previewing = extendHandle(stable, {});
|
|
175
|
+
previews.set(previewing, preview);
|
|
176
|
+
return previewing;
|
|
177
|
+
}
|
|
178
|
+
var previews = /* @__PURE__ */ new WeakMap();
|
|
179
|
+
var handing;
|
|
180
|
+
function handOver(instance, options, preview, outers) {
|
|
181
|
+
if (preview) {
|
|
182
|
+
preview.handed = true;
|
|
183
|
+
}
|
|
184
|
+
const outer = handing;
|
|
185
|
+
handing = preview;
|
|
186
|
+
try {
|
|
187
|
+
within(outers, () => instance.setOptions(options));
|
|
188
|
+
} finally {
|
|
189
|
+
handing = outer;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
var readers = /* @__PURE__ */ new WeakMap();
|
|
193
|
+
function reading(handle, read) {
|
|
194
|
+
readers.set(read, handle);
|
|
195
|
+
return read;
|
|
196
|
+
}
|
|
197
|
+
function outersOf(options) {
|
|
198
|
+
let outers;
|
|
199
|
+
for (const key in options) {
|
|
200
|
+
const outer = readers.get(options[key]);
|
|
201
|
+
if (outer) {
|
|
202
|
+
;
|
|
203
|
+
(outers ??= []).push(outer);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return outers;
|
|
207
|
+
}
|
|
208
|
+
function within(outers, read) {
|
|
209
|
+
if (!outers) {
|
|
210
|
+
return read();
|
|
211
|
+
}
|
|
212
|
+
let run = read;
|
|
213
|
+
for (const outer of outers) {
|
|
214
|
+
const inner = run;
|
|
215
|
+
run = () => readIn(outer, inner);
|
|
216
|
+
}
|
|
217
|
+
return run();
|
|
218
|
+
}
|
|
219
|
+
function extendHandle(handle, extra) {
|
|
220
|
+
const copy = Object.defineProperties({}, {
|
|
221
|
+
...Object.getOwnPropertyDescriptors(handle),
|
|
222
|
+
...Object.getOwnPropertyDescriptors(extra),
|
|
223
|
+
state: { get: () => stateIn(copy), enumerable: true }
|
|
224
|
+
});
|
|
225
|
+
const preview = previews.get(handle);
|
|
226
|
+
if (preview) {
|
|
227
|
+
previews.set(copy, preview);
|
|
228
|
+
}
|
|
229
|
+
return copy;
|
|
230
|
+
}
|
|
231
|
+
function presentIn(handle, name, props) {
|
|
232
|
+
const part = handle.instance.part(name, props);
|
|
233
|
+
return readIn(handle, (showing) => present(part, part.props, showing));
|
|
234
|
+
}
|
|
235
|
+
function slotIn(handle, name, props, user = {}) {
|
|
236
|
+
const part = handle.instance.part(name, props);
|
|
237
|
+
return readIn(
|
|
238
|
+
handle,
|
|
239
|
+
(showing) => elementProps(part, part.props, user, showing)
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
function stateIn(handle) {
|
|
243
|
+
const { instance } = handle;
|
|
244
|
+
const current = instance.get();
|
|
245
|
+
const preview = previews.get(handle);
|
|
246
|
+
if (!preview || preview.handed) {
|
|
247
|
+
return current;
|
|
248
|
+
}
|
|
249
|
+
if (preview.base !== current) {
|
|
250
|
+
preview.base = current;
|
|
251
|
+
preview.state = within(
|
|
252
|
+
preview.outers,
|
|
253
|
+
() => instance.preview(preview.options)
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
return preview.state ?? current;
|
|
257
|
+
}
|
|
258
|
+
function readIn(handle, read, around) {
|
|
259
|
+
const state = stateIn(handle);
|
|
260
|
+
if (state === handle.instance.get() && !around) {
|
|
261
|
+
return read(state);
|
|
262
|
+
}
|
|
263
|
+
return handle.instance.view(state, () => read(state), around);
|
|
264
|
+
}
|
|
265
|
+
var anchors = /* @__PURE__ */ new WeakMap();
|
|
266
|
+
var inPage = (instance) => !!anchors.get(instance)?.isConnected;
|
|
267
|
+
var owners = typeof FinalizationRegistry === "undefined" ? void 0 : new FinalizationRegistry(
|
|
268
|
+
(instance) => instance.destroy()
|
|
269
|
+
);
|
|
270
|
+
var hidden = /* @__PURE__ */ new Map();
|
|
271
|
+
var sweeping;
|
|
272
|
+
function hide(instance, leave) {
|
|
273
|
+
hidden.set(instance, leave);
|
|
274
|
+
sweeping ??= setInterval(() => {
|
|
275
|
+
for (const [instance2, leave2] of hidden) {
|
|
276
|
+
if (inPage(instance2)) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
hidden.delete(instance2);
|
|
280
|
+
leave2();
|
|
281
|
+
}
|
|
282
|
+
if (hidden.size) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
clearInterval(sweeping);
|
|
286
|
+
sweeping = void 0;
|
|
287
|
+
}, 1e3);
|
|
288
|
+
}
|
|
289
|
+
function carried(primitive, instance, options) {
|
|
290
|
+
const schema = schemaOf(primitive).options;
|
|
291
|
+
const state = instance.get();
|
|
292
|
+
const defaults = {};
|
|
293
|
+
for (const key in state) {
|
|
294
|
+
const fallback = `default${key[0].toUpperCase()}${key.slice(1)}`;
|
|
295
|
+
if (fallback in schema && options[key] === void 0) {
|
|
296
|
+
defaults[fallback] = state[key];
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return defaults;
|
|
300
|
+
}
|
|
301
|
+
var heldRefs = /* @__PURE__ */ new WeakMap();
|
|
302
|
+
function heldRef(part) {
|
|
303
|
+
let held = heldRefs.get(part);
|
|
304
|
+
if (held) {
|
|
305
|
+
return held;
|
|
306
|
+
}
|
|
307
|
+
const bindTo = ref(part, host);
|
|
308
|
+
let releasing = false;
|
|
309
|
+
held = (el) => {
|
|
310
|
+
releasing = !el;
|
|
311
|
+
if (el) {
|
|
312
|
+
return bindTo(el);
|
|
313
|
+
}
|
|
314
|
+
queueMicrotask(() => {
|
|
315
|
+
if (releasing) {
|
|
316
|
+
bindTo(null);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
};
|
|
320
|
+
heldRefs.set(part, held);
|
|
321
|
+
return held;
|
|
322
|
+
}
|
|
323
|
+
function elementProps(part, props, user, state) {
|
|
324
|
+
takeOwnId(part, user.id);
|
|
325
|
+
const handlers = {};
|
|
326
|
+
for (const [type, handler] of Object.entries(partHandlers(part))) {
|
|
327
|
+
const prop = eventProps[type];
|
|
328
|
+
if (!prop) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
handlers[prop] = (event) => {
|
|
332
|
+
handler(event.nativeEvent);
|
|
333
|
+
if (event.nativeEvent.defaultPrevented && !event.isDefaultPrevented()) {
|
|
334
|
+
event.preventDefault();
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const own = yieldToAuthor(
|
|
339
|
+
attrs(part, props, state),
|
|
340
|
+
(name) => user[propNames[name] ?? name] != null
|
|
341
|
+
);
|
|
342
|
+
return mergeProps(handlers, user, toReactProps(own), {
|
|
343
|
+
id: user.id,
|
|
344
|
+
ref: heldRef(part)
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
function sameAttrs(a, b, skip = []) {
|
|
348
|
+
const keys = Object.keys(a);
|
|
349
|
+
return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key] || skip.includes(key));
|
|
350
|
+
}
|
|
351
|
+
var rechecks = /* @__PURE__ */ new WeakMap();
|
|
352
|
+
function changesValues(before, after) {
|
|
353
|
+
for (const key in { ...before, ...after }) {
|
|
354
|
+
if (typeof before[key] === "function" && typeof after[key] === "function") {
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
if (!sameValue(before[key], after[key])) {
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
function usePartState(handle, name, props, around) {
|
|
364
|
+
const { instance } = handle;
|
|
365
|
+
const [, rerender] = React.useReducer((count) => count + 1, 0);
|
|
366
|
+
const part = instance.part(name, props, true);
|
|
367
|
+
const rendered = readIn(
|
|
368
|
+
handle,
|
|
369
|
+
(showing) => ({
|
|
370
|
+
handle,
|
|
371
|
+
around,
|
|
372
|
+
props,
|
|
373
|
+
snapshot: partState(part, props, showing),
|
|
374
|
+
// The keys this render read, filled in as it reads them.
|
|
375
|
+
read: /* @__PURE__ */ new Set(),
|
|
376
|
+
attrs: attrs(part, props, showing),
|
|
377
|
+
present: present(part, props, showing),
|
|
378
|
+
version: renderVersion(instance)
|
|
379
|
+
}),
|
|
380
|
+
around
|
|
381
|
+
);
|
|
382
|
+
const state = new Proxy(rendered.snapshot, {
|
|
383
|
+
get(target, key) {
|
|
384
|
+
if (typeof key === "string") {
|
|
385
|
+
rendered.read.add(key);
|
|
386
|
+
}
|
|
387
|
+
return target[key];
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
const last = React.useRef(rendered);
|
|
391
|
+
const preview = previews.get(handle);
|
|
392
|
+
if (preview && !preview.handed) {
|
|
393
|
+
preview.pending.add(last);
|
|
394
|
+
}
|
|
395
|
+
const check = React.useCallback(
|
|
396
|
+
(full, props2 = false) => {
|
|
397
|
+
const shown = last.current;
|
|
398
|
+
const outdated = readIn(
|
|
399
|
+
shown.handle,
|
|
400
|
+
(now) => {
|
|
401
|
+
if (shown.read.size) {
|
|
402
|
+
const next = partState(
|
|
403
|
+
part,
|
|
404
|
+
shown.props,
|
|
405
|
+
now
|
|
406
|
+
);
|
|
407
|
+
for (const key of shown.read) {
|
|
408
|
+
if (sameSlotState(next[key], shown.snapshot[key])) {
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
shown.snapshot = next;
|
|
412
|
+
return true;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const shows = present(part, shown.props, now);
|
|
416
|
+
if (shows !== shown.present) {
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
if (renderVersion(instance) === shown.version && !props2) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
shown.version = renderVersion(instance);
|
|
423
|
+
return shows && !sameAttrs(
|
|
424
|
+
attrs(part, shown.props, now),
|
|
425
|
+
shown.attrs,
|
|
426
|
+
full ? void 0 : directNames(part)
|
|
427
|
+
);
|
|
428
|
+
},
|
|
429
|
+
shown.around
|
|
430
|
+
);
|
|
431
|
+
if (outdated) {
|
|
432
|
+
rerender();
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
[instance, part]
|
|
436
|
+
);
|
|
437
|
+
React.useLayoutEffect(() => {
|
|
438
|
+
const changed = part.props !== props && changesValues(part.props, props);
|
|
439
|
+
commit(part, props);
|
|
440
|
+
preview?.pending.delete(last);
|
|
441
|
+
if (part.el && !inPage(instance)) {
|
|
442
|
+
anchors.set(instance, part.el);
|
|
443
|
+
}
|
|
444
|
+
last.current = rendered;
|
|
445
|
+
check(true);
|
|
446
|
+
if (changed) {
|
|
447
|
+
rechecks.get(instance)?.forEach((recheck) => recheck());
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
const selected = selectedKeys(part, props);
|
|
451
|
+
React.useLayoutEffect(() => {
|
|
452
|
+
const recheck = () => check(true, true);
|
|
453
|
+
let all = rechecks.get(instance);
|
|
454
|
+
if (!all) {
|
|
455
|
+
rechecks.set(instance, all = /* @__PURE__ */ new Set());
|
|
456
|
+
}
|
|
457
|
+
all.add(recheck);
|
|
458
|
+
const unsubscribe = subscribe(
|
|
459
|
+
part,
|
|
460
|
+
() => {
|
|
461
|
+
if (!handing?.pending.has(last)) {
|
|
462
|
+
check(false);
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
last.current.props
|
|
466
|
+
);
|
|
467
|
+
return () => {
|
|
468
|
+
all.delete(recheck);
|
|
469
|
+
unsubscribe();
|
|
470
|
+
};
|
|
471
|
+
}, [part, selected, check]);
|
|
472
|
+
return state;
|
|
473
|
+
}
|
|
474
|
+
var kindOf = (spec) => typeof spec === "object" ? spec.kind : spec;
|
|
475
|
+
var fromOf = (spec, key) => {
|
|
476
|
+
if (typeof spec !== "object") {
|
|
477
|
+
return void 0;
|
|
478
|
+
}
|
|
479
|
+
const [slot, prop = key] = spec.from.split(".");
|
|
480
|
+
return { slot, prop };
|
|
481
|
+
};
|
|
482
|
+
var pascal = (name) => name.replace(/(^|-)(\w)/g, (_, _dash, char) => char.toUpperCase());
|
|
483
|
+
function split(props, schema) {
|
|
484
|
+
const named = {};
|
|
485
|
+
const rest = {};
|
|
486
|
+
for (const key in props) {
|
|
487
|
+
;
|
|
488
|
+
(key in schema ? named : rest)[key] = props[key];
|
|
489
|
+
}
|
|
490
|
+
return [named, rest];
|
|
491
|
+
}
|
|
492
|
+
var scopes = /* @__PURE__ */ new WeakMap();
|
|
493
|
+
function scopeOf(primitive) {
|
|
494
|
+
let scope = scopes.get(primitive);
|
|
495
|
+
if (!scope) {
|
|
496
|
+
scopes.set(
|
|
497
|
+
primitive,
|
|
498
|
+
scope = {
|
|
499
|
+
context: React.createContext(null),
|
|
500
|
+
provides: /* @__PURE__ */ new Set(),
|
|
501
|
+
keyed: /* @__PURE__ */ new Set()
|
|
502
|
+
}
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
return scope;
|
|
506
|
+
}
|
|
507
|
+
function HandleScope({
|
|
508
|
+
handle,
|
|
509
|
+
children
|
|
510
|
+
}) {
|
|
511
|
+
const { context } = scopeOf(handle.primitive);
|
|
512
|
+
const scope = React.useMemo(() => ({ handle, around: {} }), [handle]);
|
|
513
|
+
return /* @__PURE__ */ jsx(context.Provider, { value: scope, children });
|
|
514
|
+
}
|
|
515
|
+
function useNearest(primitive) {
|
|
516
|
+
return React.useContext(scopeOf(primitive).context)?.handle;
|
|
517
|
+
}
|
|
518
|
+
function useHandle(primitive) {
|
|
519
|
+
const handle = useNearest(primitive);
|
|
520
|
+
if (!handle) {
|
|
521
|
+
throw new Error(
|
|
522
|
+
`The ${primitive.name} parts must be used inside their root.`
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
return handle;
|
|
526
|
+
}
|
|
527
|
+
function usePart(handle, slot, slotProps, props = {}, tag = "div") {
|
|
528
|
+
const primitive = typeof handle === "function" ? handle : handle.primitive;
|
|
529
|
+
const { context, provides, keyed } = scopeOf(primitive);
|
|
530
|
+
const scope = React.useContext(context);
|
|
531
|
+
const owner = typeof handle === "function" ? scope?.handle : handle;
|
|
532
|
+
if (!owner) {
|
|
533
|
+
throw new Error(
|
|
534
|
+
`The ${primitive.name} ${slot} part must be used inside its root.`
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
const { render, ...rest } = props;
|
|
538
|
+
const own = React.useMemo(
|
|
539
|
+
() => ({ handle: owner, around: {} }),
|
|
540
|
+
[owner]
|
|
541
|
+
);
|
|
542
|
+
const inside = scope?.handle === owner ? scope : own;
|
|
543
|
+
const around = keyed.has(slot) ? { ...slotProps, value: slotProps.id } : slotProps;
|
|
544
|
+
const provided = provides.has(slot) ? {
|
|
545
|
+
handle: owner,
|
|
546
|
+
around: { ...inside.around, [slot]: around },
|
|
547
|
+
shown: { ...inside.shown, [slot]: slotProps }
|
|
548
|
+
} : inside;
|
|
549
|
+
const state = usePartState(
|
|
550
|
+
owner,
|
|
551
|
+
slot,
|
|
552
|
+
slotProps,
|
|
553
|
+
provided.shown
|
|
554
|
+
);
|
|
555
|
+
const part = owner.instance.part(slot, slotProps, true);
|
|
556
|
+
React.useLayoutEffect(() => () => ref(part, host)(null), [part]);
|
|
557
|
+
const renderId = React.isValidElement(render) ? render.props.id : void 0;
|
|
558
|
+
const user = renderId === void 0 ? rest : { ...rest, id: renderId };
|
|
559
|
+
const merged = readIn(
|
|
560
|
+
owner,
|
|
561
|
+
(showing) => present(part, slotProps, showing) ? elementProps(part, slotProps, user, showing) : void 0,
|
|
562
|
+
provided.shown
|
|
563
|
+
);
|
|
564
|
+
const element = merged ? renderElement(tag, merged, render, state) : null;
|
|
565
|
+
if (provided === scope) {
|
|
566
|
+
return element;
|
|
567
|
+
}
|
|
568
|
+
return /* @__PURE__ */ jsx(context.Provider, { value: provided, children: element });
|
|
569
|
+
}
|
|
570
|
+
function createParts(primitive, tags) {
|
|
571
|
+
const schema = schemaOf(primitive);
|
|
572
|
+
const { context, provides, keyed } = scopeOf(primitive);
|
|
573
|
+
for (const [slot, props] of Object.entries(schema.slots)) {
|
|
574
|
+
for (const key in props) {
|
|
575
|
+
const from = fromOf(props[key], key);
|
|
576
|
+
if (from) {
|
|
577
|
+
provides.add(from.slot);
|
|
578
|
+
}
|
|
579
|
+
if (kindOf(props[key]) === "key") {
|
|
580
|
+
keyed.add(slot);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
const name = pascal(primitive.name ?? "");
|
|
585
|
+
const parts = {};
|
|
586
|
+
function Root(props) {
|
|
587
|
+
const [options, rest] = split(props, schema.options);
|
|
588
|
+
const handle = usePrimitive(
|
|
589
|
+
primitive,
|
|
590
|
+
options
|
|
591
|
+
);
|
|
592
|
+
if (tags.root) {
|
|
593
|
+
return usePart(
|
|
594
|
+
handle,
|
|
595
|
+
"root",
|
|
596
|
+
...split(rest, schema.slots.root ?? {}),
|
|
597
|
+
tags.root
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
return /* @__PURE__ */ jsx(HandleScope, { handle, children: props.children });
|
|
601
|
+
}
|
|
602
|
+
Root.displayName = name;
|
|
603
|
+
parts.Root = Root;
|
|
604
|
+
for (const [slot, tag] of Object.entries(tags)) {
|
|
605
|
+
if (slot === "root") {
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
608
|
+
const own = schema.slots[slot] ?? {};
|
|
609
|
+
const ids = Object.keys(own).filter((key2) => kindOf(own[key2]) === "id");
|
|
610
|
+
const key = Object.keys(own).find((key2) => kindOf(own[key2]) === "key");
|
|
611
|
+
const Part = (props) => {
|
|
612
|
+
const [slotProps, rest] = split(props, own);
|
|
613
|
+
if (props.id !== void 0) {
|
|
614
|
+
rest.id = props.id;
|
|
615
|
+
}
|
|
616
|
+
for (const key2 of ids) {
|
|
617
|
+
const id = React.useId();
|
|
618
|
+
slotProps[key2] ??= id;
|
|
619
|
+
}
|
|
620
|
+
const scope = React.useContext(context);
|
|
621
|
+
if (key) {
|
|
622
|
+
slotProps.id ??= scope?.handle.api?.internal.keyOf(slotProps[key]);
|
|
623
|
+
}
|
|
624
|
+
for (const prop in own) {
|
|
625
|
+
const spec = own[prop];
|
|
626
|
+
const from = fromOf(spec, prop);
|
|
627
|
+
if (!from || slotProps[prop] !== void 0) {
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
const around = scope?.around[from.slot];
|
|
631
|
+
if (!around && spec.required) {
|
|
632
|
+
throw new Error(
|
|
633
|
+
`<${Part.displayName}> must be used inside <${name}${pascal(from.slot)}>.`
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
slotProps[prop] = around?.[from.prop];
|
|
637
|
+
}
|
|
638
|
+
return usePart(
|
|
639
|
+
primitive,
|
|
640
|
+
slot,
|
|
641
|
+
slotProps,
|
|
642
|
+
rest,
|
|
643
|
+
tag
|
|
644
|
+
);
|
|
645
|
+
};
|
|
646
|
+
Part.displayName = name + pascal(slot);
|
|
647
|
+
parts[pascal(slot)] = Part;
|
|
648
|
+
}
|
|
649
|
+
return parts;
|
|
650
|
+
}
|
|
651
|
+
function useAround(primitive, slot) {
|
|
652
|
+
return React.useContext(scopeOf(primitive).context)?.around[slot];
|
|
653
|
+
}
|
|
654
|
+
function sharesProps(primitive, slot) {
|
|
655
|
+
scopeOf(primitive).provides.add(slot);
|
|
656
|
+
}
|
|
657
|
+
export {
|
|
658
|
+
HandleScope,
|
|
659
|
+
createParts,
|
|
660
|
+
extendHandle,
|
|
661
|
+
mergeProps,
|
|
662
|
+
mergeRefs,
|
|
663
|
+
presentIn,
|
|
664
|
+
readIn,
|
|
665
|
+
reading,
|
|
666
|
+
renderElement,
|
|
667
|
+
sharesProps,
|
|
668
|
+
slotIn,
|
|
669
|
+
useAround,
|
|
670
|
+
useHandle,
|
|
671
|
+
useNearest,
|
|
672
|
+
usePart,
|
|
673
|
+
usePrimitive
|
|
674
|
+
};
|