@uniaria/vue 0.0.0-stage → 0.2.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrey Yamanov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,52 @@
1
- # Temporary Holding Version
1
+ # @uniaria/vue
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The Vue adapter for UniAria: one generic composable, `useComponent`, binds any
4
+ component definition from [`@uniaria/core`](https://www.npmjs.com/package/@uniaria/core)
5
+ to your elements. Vue 3.5 or later.
6
+
7
+ > **Pre-release.** The API can change in any 0.x version.
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ pnpm add @uniaria/core @uniaria/vue
13
+ ```
14
+
15
+ ## Use
16
+
17
+ Pass a definition and its props to `useComponent`, then bind each part's
18
+ props onto your element with `v-bind`:
19
+
20
+ ```vue
21
+ <script setup lang="ts">
22
+ import { toggleSwitch } from '@uniaria/core/switch';
23
+ import { useComponent } from '@uniaria/vue';
24
+
25
+ const wifi = useComponent(toggleSwitch, {
26
+ defaultSelected: true,
27
+ labelElementType: 'span',
28
+ });
29
+ </script>
30
+
31
+ <template>
32
+ <label v-bind="wifi.parts.root">
33
+ <input v-bind="wifi.parts.input" name="wifi" />
34
+ <span v-bind="wifi.parts.indicator" />
35
+ <span v-bind="wifi.parts.label">Wi-Fi</span>
36
+ </label>
37
+ </template>
38
+ ```
39
+
40
+ Hovering, pressing or toggling doesn't render your component again: UniAria
41
+ writes the new state straight to the elements. When your render needs a
42
+ value, select it with `useComponentState`.
43
+
44
+ ## Documentation
45
+
46
+ [Getting started](https://uniaria.tenphi.me/guide/getting-started/), the
47
+ [Vue API](https://uniaria.tenphi.me/api/vue/) and every component's page are on
48
+ [uniaria.tenphi.me](https://uniaria.tenphi.me).
49
+
50
+ ## License
51
+
52
+ [MIT](https://github.com/tenphi/uniaria/blob/main/LICENSE)
@@ -0,0 +1,45 @@
1
+ import { ActionsOf, AnyDefinition, Instance, ItemPartOf, PartOf, PropsOf, StateOf } from "@uniaria/core";
2
+ import { MaybeRefOrGetter, Ref } from "vue";
3
+ //#region src/use-component.d.ts
4
+ /** Props to bind onto a part element: attributes, stable handlers, a ref. */
5
+ type VuePartProps = Readonly<Record<string, unknown>> & {
6
+ readonly ref: (target: unknown) => void;
7
+ };
8
+ interface ComponentHandle<D extends AnyDefinition> {
9
+ /** The stable instance: pass it to `useComponentState` or as an `owner`. */
10
+ readonly instance: Instance<D>;
11
+ /** The component's public actions, such as a popover's `open()` and `close()`. */
12
+ readonly actions: ActionsOf<D>;
13
+ /** Props for each part, read when the render reads them. */
14
+ readonly parts: Readonly<Record<PartOf<D>, VuePartProps>>;
15
+ /**
16
+ * Props for one item part of one item (Listbox spec, Item parts), read
17
+ * when the render reads them. Later changes reach the element through the
18
+ * binder, so the component rendering the rows doesn't render again for
19
+ * them.
20
+ */
21
+ getItemProps(part: ItemPartOf<D>, key: string): VuePartProps;
22
+ }
23
+ /**
24
+ * What `useComponent` takes as props: a getter, a ref, a reactive object
25
+ * such as the component's own `defineProps()`, or a plain object read once.
26
+ */
27
+ type ComponentProps<D extends AnyDefinition> = MaybeRefOrGetter<PropsOf<D>>;
28
+ /**
29
+ * Creates an instance of `definition` for this component and returns props
30
+ * for its parts. Call it in `setup()`. Props are stored silently before the
31
+ * render reads them and synced after the patch; internal state changes
32
+ * never re-render this component.
33
+ */
34
+ export declare function useComponent<D extends AnyDefinition>(definition: D, ...[props]: Partial<PropsOf<D>> extends PropsOf<D> ? [props?: NoInfer<ComponentProps<D>>] : [props: NoInfer<ComponentProps<D>>]): ComponentHandle<D>;
35
+ //#endregion
36
+ //#region src/use-component-state.d.ts
37
+ /**
38
+ * Reads one value of an instance's public state as a ref that triggers only
39
+ * when the value changes (`Object.is`, or `isEqual`). Takes the instance or
40
+ * the handle `useComponent` returned.
41
+ */
42
+ export declare function useComponentState<D extends AnyDefinition, T>(source: Instance<D> | ComponentHandle<D>, selector: (state: StateOf<D>) => T, isEqual?: (a: T, b: T) => boolean): Readonly<Ref<T>>;
43
+ //#endregion
44
+ export type { ComponentHandle, ComponentProps, VuePartProps };
45
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,383 @@
1
+ import { createInstance, isOwnerDefinition } from "@uniaria/core";
2
+ import { createBinder, isDevelopment, provideOwner, requestOwner, warn } from "@uniaria/core/dom";
3
+ import { customRef, getCurrentInstance, getCurrentScope, inject, isProxy, isRef, markRaw, onActivated, onBeforeUnmount, onDeactivated, onMounted, onScopeDispose, provide, queuePostFlushCb, useId, watch } from "vue";
4
+ //#region src/owner.ts
5
+ /** Shared by duplicate installs, like the core's global singletons. */
6
+ const OWNER_SCOPE = Symbol.for("@uniaria/vue owner");
7
+ /**
8
+ * The scope each component provides last. `inject()` reads the parent's
9
+ * provides, so a second `useComponent` in one component chains onto the
10
+ * first through this, not through `inject()`.
11
+ */
12
+ const provided = /* @__PURE__ */ new WeakMap();
13
+ /** The scope the current component's parent provides, if any. */
14
+ function injectScope() {
15
+ return inject(OWNER_SCOPE, null);
16
+ }
17
+ /** Provides `instance` to the current component's descendants. */
18
+ function provideScope(instance, parent) {
19
+ const component = getCurrentInstance();
20
+ const scope = {
21
+ instance,
22
+ parent: (component && provided.get(component)) ?? parent
23
+ };
24
+ if (component) provided.set(component, scope);
25
+ provide(OWNER_SCOPE, scope);
26
+ }
27
+ /** The nearest owner of `definition` in the scope, if any. */
28
+ function findOwner(scope, definition) {
29
+ for (let current = scope; current; current = current.parent) if (current.instance.definition === definition) return current.instance;
30
+ }
31
+ //#endregion
32
+ //#region src/props.ts
33
+ /**
34
+ * Live DOM properties rendered once with Vue's attribute-only binding, so
35
+ * the element starts with them and Vue never controls it after that.
36
+ */
37
+ const LIVE_PROPS = {
38
+ value: "^value",
39
+ checked: "^checked"
40
+ };
41
+ /**
42
+ * The Vue handler prop for a DOM event name: `keydown` → `onKeydown`. Vue
43
+ * listens to the event named by the rest, lowercased, and DOM event names
44
+ * have no capitals for it to split on.
45
+ */
46
+ function vueEventName(type) {
47
+ return `on${type.charAt(0).toUpperCase()}${type.slice(1)}`;
48
+ }
49
+ /**
50
+ * The attribute-only props for a part's live values, from the first render:
51
+ * `^value` as a string, and `^checked` only while checked (its attribute
52
+ * holds no value).
53
+ */
54
+ function liveDefaults(props) {
55
+ const result = {};
56
+ for (const [name, value] of Object.entries(props.properties ?? {})) {
57
+ const prop = LIVE_PROPS[name];
58
+ if (!prop || value === void 0 || value === false) continue;
59
+ result[prop] = value === true ? "" : String(value);
60
+ }
61
+ return result;
62
+ }
63
+ /** Attributes and style as Vue props, leaving out what is `undefined`. */
64
+ function toVueAttrs(props, result) {
65
+ for (const [name, value] of Object.entries(props.attrs)) if (value !== void 0) result[name] = value;
66
+ if (props.style) {
67
+ const style = {};
68
+ for (const [name, value] of Object.entries(props.style)) if (value !== void 0) style[name] = value;
69
+ result.style = style;
70
+ }
71
+ return result;
72
+ }
73
+ //#endregion
74
+ //#region src/use-component.ts
75
+ /**
76
+ * The element a ref target stands for: the element, or for a component
77
+ * bound as a part (a router link), its root element.
78
+ */
79
+ function toElement(target) {
80
+ let node = target;
81
+ if (node && typeof node === "object" && "$el" in node) node = node.$el;
82
+ return node && typeof node === "object" && node.nodeType === 1 ? node : null;
83
+ }
84
+ /**
85
+ * Warns when the element's attributes differ from the part props Vue
86
+ * rendered: the template, or a parent's fallthrough attributes, wrote an
87
+ * attribute the binder owns, which the binder would silently overwrite.
88
+ */
89
+ function checkOwnership(internal, part, element, rendered) {
90
+ const isItem = internal.instance.definition.itemParts?.includes(part) ?? false;
91
+ for (const [name, value] of Object.entries(rendered?.attrs ?? {})) {
92
+ if (name === "id" && !isItem) continue;
93
+ const actual = element.getAttribute(name);
94
+ if (actual === (value ?? null)) continue;
95
+ warn(`${internal.instance.definition.name}: "${name}" on the ${part} part is written by UniAria, but the element has ${actual === null ? "none" : `"${actual}"`}. Pass it as a prop, or drop it from the template.`);
96
+ }
97
+ }
98
+ /** Hands the binder every element Vue set or cleared since the last flush. */
99
+ function flushAttaching(internal) {
100
+ if (internal.attaching.size === 0) return;
101
+ const list = Array.from(internal.attaching);
102
+ internal.attaching.clear();
103
+ internal.instance.batch(() => {
104
+ for (const [id, { part, key, element, rendered }] of list) {
105
+ if (element && isDevelopment() && !internal.checked.has(element)) {
106
+ internal.checked.add(element);
107
+ checkOwnership(internal, part, element, rendered);
108
+ }
109
+ internal.attached.set(id, element);
110
+ if (key === void 0) internal.binder.attach(part, element);
111
+ else internal.binder.attachItem(part, key, element);
112
+ }
113
+ });
114
+ }
115
+ /**
116
+ * Records an element for the binder. Vue calls a ref again on every patch of
117
+ * its element, so the same element again is a no-op.
118
+ */
119
+ function queueAttaching(internal, id, entry) {
120
+ const pending = internal.attaching.get(id);
121
+ if (pending) {
122
+ pending.element = entry.element;
123
+ pending.rendered = entry.rendered;
124
+ return;
125
+ }
126
+ if (internal.attached.get(id) === entry.element) return;
127
+ if (internal.attaching.size === 0) queuePostFlushCb(internal.flush);
128
+ internal.attaching.set(id, entry);
129
+ }
130
+ /**
131
+ * `getItemProps` for one instance: Vue props from the cached
132
+ * `connectItem()`, reused while it returns the same object, with handlers
133
+ * stable per part and event type and a ref stable per part and key.
134
+ */
135
+ function createGetItemProps(internal) {
136
+ return (part, key) => {
137
+ const { instance, binder, itemHandlers, items } = internal();
138
+ const props = instance.connectItem(part, key);
139
+ const id = `${part}\n${key}`;
140
+ let item = items.get(id);
141
+ if (!item) {
142
+ const ref = (target) => {
143
+ const current = internal();
144
+ const element = toElement(target);
145
+ const entry = current.items.get(id);
146
+ queueAttaching(current, id, {
147
+ part,
148
+ key,
149
+ element,
150
+ rendered: entry?.rendered?.props
151
+ });
152
+ if (!element && entry?.ref === ref) current.items.delete(id);
153
+ };
154
+ item = { ref };
155
+ items.set(id, item);
156
+ }
157
+ if (item.rendered?.props === props) return item.rendered.vue;
158
+ const result = toVueAttrs(props, {});
159
+ for (const type of Object.keys(props.on ?? {})) {
160
+ const handlerKey = `${part}:${type}`;
161
+ let handler = itemHandlers.get(handlerKey);
162
+ if (!handler) {
163
+ handler = (event) => {
164
+ const target = binder.itemOf(event.currentTarget);
165
+ if (!target) return;
166
+ instance.connectItem(target.part, target.key).on?.[type]?.(event);
167
+ };
168
+ itemHandlers.set(handlerKey, handler);
169
+ }
170
+ result[vueEventName(type)] = handler;
171
+ }
172
+ const vue = {
173
+ ...result,
174
+ ref: item.ref
175
+ };
176
+ item.rendered = {
177
+ props,
178
+ vue
179
+ };
180
+ return vue;
181
+ };
182
+ }
183
+ function toVueParts(internal, connected) {
184
+ const { instance, handlers, refs, defaults } = internal;
185
+ const parts = {};
186
+ for (const [part, props] of Object.entries(connected)) {
187
+ let initial = defaults.get(part);
188
+ if (!initial) {
189
+ initial = liveDefaults(props);
190
+ defaults.set(part, initial);
191
+ }
192
+ const result = toVueAttrs(props, { ...initial });
193
+ for (const type of Object.keys(props.on ?? {})) {
194
+ const key = `${part}:${type}`;
195
+ let handler = handlers.get(key);
196
+ if (!handler) {
197
+ handler = (event) => {
198
+ instance.connect()[part]?.on?.[type]?.(event);
199
+ };
200
+ handlers.set(key, handler);
201
+ }
202
+ result[vueEventName(type)] = handler;
203
+ }
204
+ let ref = refs.get(part);
205
+ if (!ref) {
206
+ ref = (target) => queueAttaching(internal, part, {
207
+ part,
208
+ element: toElement(target),
209
+ rendered: (internal.rendered?.connected)?.[part]
210
+ });
211
+ refs.set(part, ref);
212
+ }
213
+ parts[part] = {
214
+ ...result,
215
+ ref
216
+ };
217
+ }
218
+ return parts;
219
+ }
220
+ /** A getter for the props, whichever form they came in. */
221
+ function propsReader(source) {
222
+ if (typeof source === "function") return source;
223
+ if (isRef(source)) return () => source.value;
224
+ if (isProxy(source)) return () => ({ ...source });
225
+ const props = source ?? {};
226
+ return () => props;
227
+ }
228
+ /**
229
+ * Creates an instance of `definition` for this component and returns props
230
+ * for its parts. Call it in `setup()`. Props are stored silently before the
231
+ * render reads them and synced after the patch; internal state changes
232
+ * never re-render this component.
233
+ */
234
+ function useComponent(definition, ...[props]) {
235
+ const read = propsReader(props);
236
+ const instance = createInstance(definition, {
237
+ props: read(),
238
+ id: useId()
239
+ });
240
+ markRaw(instance);
241
+ const internal = {
242
+ instance,
243
+ binder: createBinder(instance),
244
+ handlers: /* @__PURE__ */ new Map(),
245
+ refs: /* @__PURE__ */ new Map(),
246
+ itemHandlers: /* @__PURE__ */ new Map(),
247
+ items: /* @__PURE__ */ new Map(),
248
+ getItemProps: createGetItemProps(() => internal),
249
+ attaching: /* @__PURE__ */ new Map(),
250
+ attached: /* @__PURE__ */ new Map(),
251
+ flush: () => flushAttaching(internal),
252
+ defaults: /* @__PURE__ */ new Map(),
253
+ checked: /* @__PURE__ */ new WeakSet()
254
+ };
255
+ const { binder } = internal;
256
+ const scope = injectScope();
257
+ const ownerLink = definition.owner;
258
+ const scopeOwner = ownerLink ? findOwner(scope, ownerLink.definition) : void 0;
259
+ if (scopeOwner) instance.link(scopeOwner);
260
+ provideScope(instance, scope);
261
+ let isRunning = false;
262
+ let lookup = null;
263
+ const isLinkedByDom = () => ownerLink !== void 0 && scopeOwner === void 0 && instance.getProps().owner === void 0;
264
+ const updateLookup = () => {
265
+ if (isLinkedByDom() === (lookup !== null)) return;
266
+ if (lookup) {
267
+ lookup();
268
+ lookup = null;
269
+ return;
270
+ }
271
+ const element = definition.parts.map((part) => instance.element(part)).find(Boolean);
272
+ if (!element) return;
273
+ const forget = requestOwner(element, ownerLink.definition, (owner) => {
274
+ instance.link(owner);
275
+ instance.sync();
276
+ });
277
+ lookup = () => {
278
+ forget();
279
+ instance.link(void 0);
280
+ instance.sync();
281
+ };
282
+ };
283
+ const sync = () => {
284
+ flushAttaching(internal);
285
+ instance.sync();
286
+ if (isRunning) updateLookup();
287
+ };
288
+ watch(read, (next) => {
289
+ instance.setProps(next);
290
+ queuePostFlushCb(sync);
291
+ }, { flush: "pre" });
292
+ let stop = null;
293
+ const begin = () => {
294
+ if (stop) return;
295
+ flushAttaching(internal);
296
+ instance.batch(() => {
297
+ instance.start();
298
+ binder.start();
299
+ });
300
+ const unprovide = isOwnerDefinition(definition) ? definition.parts.flatMap((part) => {
301
+ const element = instance.element(part);
302
+ return element ? [provideOwner(instance, element)] : [];
303
+ }) : [];
304
+ isRunning = true;
305
+ updateLookup();
306
+ instance.sync();
307
+ stop = () => {
308
+ isRunning = false;
309
+ lookup?.();
310
+ lookup = null;
311
+ for (const forget of unprovide) forget();
312
+ binder.stop();
313
+ instance.stop();
314
+ };
315
+ };
316
+ const end = () => {
317
+ stop?.();
318
+ stop = null;
319
+ };
320
+ onMounted(begin);
321
+ onActivated(begin);
322
+ onDeactivated(end);
323
+ onBeforeUnmount(end);
324
+ return markRaw({
325
+ instance,
326
+ actions: instance.actions,
327
+ get parts() {
328
+ const connected = instance.connect();
329
+ if (internal.rendered?.connected !== connected) internal.rendered = {
330
+ connected,
331
+ parts: toVueParts(internal, connected)
332
+ };
333
+ return internal.rendered.parts;
334
+ },
335
+ getItemProps: internal.getItemProps
336
+ });
337
+ }
338
+ //#endregion
339
+ //#region src/use-component-state.ts
340
+ /**
341
+ * Reads one value of an instance's public state as a ref that triggers only
342
+ * when the value changes (`Object.is`, or `isEqual`). Takes the instance or
343
+ * the handle `useComponent` returned.
344
+ */
345
+ function useComponentState(source, selector, isEqual = Object.is) {
346
+ const instance = "instance" in source ? source.instance : source;
347
+ let cache = null;
348
+ const select = () => {
349
+ const state = instance.getState();
350
+ if (cache?.state === state) return cache.value;
351
+ const value = selector(state);
352
+ const stable = cache && isEqual(cache.value, value) ? cache.value : value;
353
+ cache = {
354
+ state,
355
+ value: stable
356
+ };
357
+ return stable;
358
+ };
359
+ return customRef((track, trigger) => {
360
+ let read = null;
361
+ if (typeof document !== "undefined") {
362
+ const unsubscribe = instance.subscribe(() => {
363
+ if (!read || !Object.is(read.value, select())) trigger();
364
+ });
365
+ if (getCurrentScope()) onScopeDispose(unsubscribe);
366
+ }
367
+ return {
368
+ get() {
369
+ track();
370
+ const value = select();
371
+ read = { value };
372
+ return value;
373
+ },
374
+ set() {
375
+ warn(`${instance.definition.name}: useComponentState returns a read-only ref.`);
376
+ }
377
+ };
378
+ });
379
+ }
380
+ //#endregion
381
+ export { useComponent, useComponentState };
382
+
383
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/owner.ts","../src/props.ts","../src/use-component.ts","../src/use-component-state.ts"],"sourcesContent":["/**\n * Owners in Vue (decision 11, Vue adapter spec: Owners and links): every\n * `useComponent` provides its instance to the component's descendants, slot\n * content included, through `provide()`, which holds only the stable\n * instance and renders nothing. A component finds its owner during setup,\n * so the first render and the server HTML have the owner's state. Scopes\n * nest: each component takes the nearest owner of the definition it names.\n */\n\nimport type { AnyDefinition, Instance } from '@uniaria/core';\nimport type { InjectionKey } from 'vue';\nimport { getCurrentInstance, inject, provide } from 'vue';\n\nexport interface Scope {\n readonly instance: Instance;\n readonly parent: Scope | null;\n}\n\n/** Shared by duplicate installs, like the core's global singletons. */\nexport const OWNER_SCOPE: InjectionKey<Scope | null> = Symbol.for(\n '@uniaria/vue owner',\n) as InjectionKey<Scope | null>;\n\n/**\n * The scope each component provides last. `inject()` reads the parent's\n * provides, so a second `useComponent` in one component chains onto the\n * first through this, not through `inject()`.\n */\nconst provided = new WeakMap<object, Scope>();\n\n/** The scope the current component's parent provides, if any. */\nexport function injectScope(): Scope | null {\n return inject(OWNER_SCOPE, null);\n}\n\n/** Provides `instance` to the current component's descendants. */\nexport function provideScope(instance: Instance, parent: Scope | null): void {\n const component = getCurrentInstance();\n const scope: Scope = {\n instance,\n parent: (component && provided.get(component)) ?? parent,\n };\n if (component) provided.set(component, scope);\n provide(OWNER_SCOPE, scope);\n}\n\n/** The nearest owner of `definition` in the scope, if any. */\nexport function findOwner(\n scope: Scope | null,\n definition: AnyDefinition,\n): Instance | undefined {\n for (let current = scope; current; current = current.parent) {\n if (current.instance.definition === definition) return current.instance;\n }\n return undefined;\n}\n","/**\n * Neutral part props → Vue props (Vue adapter spec, Part props in Vue).\n * Vue's `v-bind` takes DOM names, so attributes and styles pass through as\n * they are, events become `on` and the capitalized DOM name, and live values\n * render once as attributes.\n */\n\nimport type { PartProps } from '@uniaria/core';\n\n/**\n * Live DOM properties rendered once with Vue's attribute-only binding, so\n * the element starts with them and Vue never controls it after that.\n */\nconst LIVE_PROPS: Readonly<Record<string, string>> = {\n value: '^value',\n checked: '^checked',\n};\n\n/**\n * The Vue handler prop for a DOM event name: `keydown` → `onKeydown`. Vue\n * listens to the event named by the rest, lowercased, and DOM event names\n * have no capitals for it to split on.\n */\nexport function vueEventName(type: string): string {\n return `on${type.charAt(0).toUpperCase()}${type.slice(1)}`;\n}\n\n/**\n * The attribute-only props for a part's live values, from the first render:\n * `^value` as a string, and `^checked` only while checked (its attribute\n * holds no value).\n */\nexport function liveDefaults(props: PartProps): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(props.properties ?? {})) {\n const prop = LIVE_PROPS[name];\n if (!prop || value === undefined || value === false) continue;\n result[prop] = value === true ? '' : String(value);\n }\n return result;\n}\n\n/** Attributes and style as Vue props, leaving out what is `undefined`. */\nexport function toVueAttrs(\n props: PartProps,\n result: Record<string, unknown>,\n): Record<string, unknown> {\n for (const [name, value] of Object.entries(props.attrs)) {\n if (value !== undefined) result[name] = value;\n }\n if (props.style) {\n const style: Record<string, string> = {};\n for (const [name, value] of Object.entries(props.style)) {\n if (value !== undefined) style[name] = value;\n }\n result.style = style;\n }\n return result;\n}\n","/**\n * The Vue adapter (design decisions 2 and 9, Vue adapter spec). Internal\n * state never re-renders: each render reads the current part props, and the\n * DOM binder from `@uniaria/core/dom` writes later changes straight to the\n * elements. The store isn't reactive, so reading part props subscribes a\n * render to nothing; a component renders again for state only through\n * `useComponentState`, and only when the selected value changes.\n */\n\nimport type {\n ActionsOf,\n AnyDefinition,\n Instance,\n ItemPartOf,\n OwnerLink,\n PartOf,\n PartProps,\n PropsOf,\n} from '@uniaria/core';\nimport { createInstance, isOwnerDefinition } from '@uniaria/core';\nimport type { Binder } from '@uniaria/core/dom';\nimport {\n createBinder,\n isDevelopment,\n provideOwner,\n requestOwner,\n warn,\n} from '@uniaria/core/dom';\nimport type { MaybeRefOrGetter } from 'vue';\nimport {\n isProxy,\n isRef,\n markRaw,\n onActivated,\n onBeforeUnmount,\n onDeactivated,\n onMounted,\n queuePostFlushCb,\n useId,\n watch,\n} from 'vue';\n\nimport { findOwner, injectScope, provideScope } from './owner';\nimport { liveDefaults, toVueAttrs, vueEventName } from './props';\n\n/** Props to bind onto a part element: attributes, stable handlers, a ref. */\nexport type VuePartProps = Readonly<Record<string, unknown>> & {\n readonly ref: (target: unknown) => void;\n};\n\nexport interface ComponentHandle<D extends AnyDefinition> {\n /** The stable instance: pass it to `useComponentState` or as an `owner`. */\n readonly instance: Instance<D>;\n /** The component's public actions, such as a popover's `open()` and `close()`. */\n readonly actions: ActionsOf<D>;\n /** Props for each part, read when the render reads them. */\n readonly parts: Readonly<Record<PartOf<D>, VuePartProps>>;\n /**\n * Props for one item part of one item (Listbox spec, Item parts), read\n * when the render reads them. Later changes reach the element through the\n * binder, so the component rendering the rows doesn't render again for\n * them.\n */\n getItemProps(part: ItemPartOf<D>, key: string): VuePartProps;\n}\n\n/**\n * What `useComponent` takes as props: a getter, a ref, a reactive object\n * such as the component's own `defineProps()`, or a plain object read once.\n */\nexport type ComponentProps<D extends AnyDefinition> = MaybeRefOrGetter<\n PropsOf<D>\n>;\n\n/** An element the binder will get, and the part props it rendered with. */\ninterface Attaching {\n readonly part: string;\n /** An item part's key; none for a named part. */\n readonly key?: string;\n element: Element | null;\n rendered: PartProps | undefined;\n}\n\ninterface Internal<D extends AnyDefinition> {\n readonly instance: Instance<D>;\n readonly binder: Binder;\n readonly handlers: Map<string, (event: Event) => void>;\n readonly refs: Map<string, (target: unknown) => void>;\n /** Per item part and event type; the key comes from the element. */\n readonly itemHandlers: Map<string, (event: Event) => void>;\n /** Per item part and key: its ref, and the props it last rendered. */\n readonly items: Map<\n string,\n {\n readonly ref: (target: unknown) => void;\n rendered?: { readonly props: PartProps; readonly vue: VuePartProps };\n }\n >;\n readonly getItemProps: (part: string, key: string) => VuePartProps;\n /**\n * Elements Vue set or cleared through a ref since the last flush, per\n * part, or per item part and key. On first mount Vue calls a ref before\n * the element is in the document, so the binder gets them only once the\n * patch is done (Vue adapter spec, Refs).\n */\n readonly attaching: Map<string, Attaching>;\n /** The element the binder has, per part, or per item part and key. */\n readonly attached: Map<string, Element | null>;\n /** Hands `attaching` to the binder; stable, so Vue queues it once. */\n readonly flush: () => void;\n /** Live values from the first render, kept stable after it. */\n readonly defaults: Map<string, Readonly<Record<string, unknown>>>;\n /** Elements whose attributes were checked against the render. */\n readonly checked: WeakSet<Element>;\n rendered?: {\n readonly connected: unknown;\n readonly parts: Record<string, VuePartProps>;\n };\n}\n\n/**\n * The element a ref target stands for: the element, or for a component\n * bound as a part (a router link), its root element.\n */\nfunction toElement(target: unknown): Element | null {\n let node = target;\n if (node && typeof node === 'object' && '$el' in node) node = node.$el;\n return node && typeof node === 'object' && (node as Node).nodeType === 1\n ? (node as Element)\n : null;\n}\n\n/**\n * Warns when the element's attributes differ from the part props Vue\n * rendered: the template, or a parent's fallthrough attributes, wrote an\n * attribute the binder owns, which the binder would silently overwrite.\n */\nfunction checkOwnership<D extends AnyDefinition>(\n internal: Internal<D>,\n part: string,\n element: Element,\n rendered: PartProps | undefined,\n): void {\n // A named part keeps an id the template gives it after `v-bind`, and the\n // binder points every reference at it; an item's id is made from its key.\n const isItem =\n internal.instance.definition.itemParts?.includes(part) ?? false;\n for (const [name, value] of Object.entries(rendered?.attrs ?? {})) {\n if (name === 'id' && !isItem) continue;\n const actual = element.getAttribute(name);\n if (actual === (value ?? null)) continue;\n warn(\n `${internal.instance.definition.name}: \"${name}\" on the ${part} part is ` +\n `written by UniAria, but the element has ${actual === null ? 'none' : `\"${actual}\"`}. ` +\n 'Pass it as a prop, or drop it from the template.',\n );\n }\n}\n\n/** Hands the binder every element Vue set or cleared since the last flush. */\nfunction flushAttaching<D extends AnyDefinition>(internal: Internal<D>): void {\n if (internal.attaching.size === 0) return;\n const list = Array.from(internal.attaching);\n internal.attaching.clear();\n internal.instance.batch(() => {\n for (const [id, { part, key, element, rendered }] of list) {\n if (element && isDevelopment() && !internal.checked.has(element)) {\n internal.checked.add(element);\n checkOwnership(internal, part, element, rendered);\n }\n internal.attached.set(id, element);\n if (key === undefined) internal.binder.attach(part, element);\n else internal.binder.attachItem(part, key, element);\n }\n });\n}\n\n/**\n * Records an element for the binder. Vue calls a ref again on every patch of\n * its element, so the same element again is a no-op.\n */\nfunction queueAttaching<D extends AnyDefinition>(\n internal: Internal<D>,\n id: string,\n entry: Attaching,\n): void {\n const pending = internal.attaching.get(id);\n if (pending) {\n pending.element = entry.element;\n pending.rendered = entry.rendered;\n return;\n }\n if (internal.attached.get(id) === entry.element) return;\n if (internal.attaching.size === 0) queuePostFlushCb(internal.flush);\n internal.attaching.set(id, entry);\n}\n\n/**\n * `getItemProps` for one instance: Vue props from the cached\n * `connectItem()`, reused while it returns the same object, with handlers\n * stable per part and event type and a ref stable per part and key.\n */\nfunction createGetItemProps<D extends AnyDefinition>(\n internal: () => Internal<D>,\n): (part: string, key: string) => VuePartProps {\n return (part, key) => {\n const { instance, binder, itemHandlers, items } = internal();\n const props = instance.connectItem(part as never, key);\n const id = `${part}\\n${key}`;\n let item = items.get(id);\n if (!item) {\n const ref = (target: unknown) => {\n const current = internal();\n const element = toElement(target);\n const entry = current.items.get(id);\n queueAttaching(current, id, {\n part,\n key,\n element,\n rendered: entry?.rendered?.props,\n });\n // An item that unmounts takes its cache with it; a remount gets a\n // new ref.\n if (!element && entry?.ref === ref) current.items.delete(id);\n };\n item = { ref };\n items.set(id, item);\n }\n if (item.rendered?.props === props) return item.rendered.vue;\n const result = toVueAttrs(props, {});\n for (const type of Object.keys(props.on ?? {})) {\n const handlerKey = `${part}:${type}`;\n let handler = itemHandlers.get(handlerKey);\n if (!handler) {\n handler = (event: Event) => {\n const target = binder.itemOf(event.currentTarget as Element);\n if (!target) return;\n instance\n .connectItem(target.part as never, target.key)\n .on?.[type]?.(event as never);\n };\n itemHandlers.set(handlerKey, handler);\n }\n result[vueEventName(type)] = handler;\n }\n const vue = { ...result, ref: item.ref } as VuePartProps;\n item.rendered = { props, vue };\n return vue;\n };\n}\n\nfunction toVueParts<D extends AnyDefinition>(\n internal: Internal<D>,\n connected: Readonly<Record<string, PartProps>>,\n): Record<string, VuePartProps> {\n const { instance, handlers, refs, defaults } = internal;\n const parts: Record<string, VuePartProps> = {};\n for (const [part, props] of Object.entries(connected)) {\n // From the first render only: a later one would reset the value\n // attribute, which a form reset goes back to.\n let initial = defaults.get(part);\n if (!initial) {\n initial = liveDefaults(props);\n defaults.set(part, initial);\n }\n const result = toVueAttrs(props, { ...initial });\n // Handlers keep their identity across renders and call the handler from\n // the latest connect() with the native event.\n for (const type of Object.keys(props.on ?? {})) {\n const key = `${part}:${type}`;\n let handler = handlers.get(key);\n if (!handler) {\n handler = (event: Event) => {\n const latest = instance.connect() as Readonly<\n Record<string, PartProps>\n >;\n latest[part]?.on?.[type]?.(event as never);\n };\n handlers.set(key, handler);\n }\n result[vueEventName(type)] = handler;\n }\n let ref = refs.get(part);\n if (!ref) {\n ref = (target: unknown) =>\n queueAttaching(internal, part, {\n part,\n element: toElement(target),\n rendered: (\n internal.rendered?.connected as\n Readonly<Record<string, PartProps>> | undefined\n )?.[part],\n });\n refs.set(part, ref);\n }\n parts[part] = { ...result, ref } as VuePartProps;\n }\n return parts;\n}\n\n/** A getter for the props, whichever form they came in. */\nfunction propsReader<P>(source: MaybeRefOrGetter<P> | undefined): () => P {\n if (typeof source === 'function') return source as () => P;\n if (isRef(source)) return () => source.value;\n // A reactive object, such as `defineProps()`: spreading it reads, and so\n // tracks, every key.\n if (isProxy(source)) return () => ({ ...source }) as P;\n const props = (source ?? {}) as P;\n return () => props;\n}\n\n/**\n * Creates an instance of `definition` for this component and returns props\n * for its parts. Call it in `setup()`. Props are stored silently before the\n * render reads them and synced after the patch; internal state changes\n * never re-render this component.\n */\nexport function useComponent<D extends AnyDefinition>(\n definition: D,\n // Optional when every prop is.\n ...[props]: Partial<PropsOf<D>> extends PropsOf<D>\n ? [props?: NoInfer<ComponentProps<D>>]\n : [props: NoInfer<ComponentProps<D>>]\n): ComponentHandle<D> {\n const read = propsReader(props);\n const instance = createInstance(definition, { props: read(), id: useId() });\n markRaw(instance);\n const internal: Internal<D> = {\n instance,\n binder: createBinder(instance),\n handlers: new Map(),\n refs: new Map(),\n itemHandlers: new Map(),\n items: new Map(),\n getItemProps: createGetItemProps(() => internal),\n attaching: new Map(),\n attached: new Map(),\n flush: () => flushAttaching(internal),\n defaults: new Map(),\n checked: new WeakSet(),\n };\n const { binder } = internal;\n\n // Decision 11: the `owner` prop, else the nearest provided owner during\n // setup (so the first render and the server HTML have it), else the DOM\n // after mount.\n const scope = injectScope();\n const ownerLink = (definition as { owner?: OwnerLink }).owner;\n const scopeOwner = ownerLink\n ? findOwner(scope, ownerLink.definition)\n : undefined;\n if (scopeOwner) instance.link(scopeOwner);\n provideScope(instance as unknown as Instance, scope);\n\n let isRunning = false;\n let lookup: (() => void) | null = null;\n const isLinkedByDom = () =>\n ownerLink !== undefined &&\n scopeOwner === undefined &&\n (instance.getProps() as { owner?: unknown }).owner === undefined;\n // Looks for the owner through the DOM while neither the `owner` prop nor\n // a provided owner gives one.\n const updateLookup = () => {\n if (isLinkedByDom() === (lookup !== null)) return;\n if (lookup) {\n lookup();\n lookup = null;\n return;\n }\n const element = definition.parts\n .map((part: string) => instance.element(part as PartOf<D>))\n .find(Boolean) as Element | undefined;\n if (!element) return;\n const forget = requestOwner(element, ownerLink!.definition, (owner) => {\n instance.link(owner);\n instance.sync();\n });\n lookup = () => {\n forget();\n instance.link(undefined);\n instance.sync();\n };\n };\n\n const sync = () => {\n flushAttaching(internal);\n instance.sync();\n if (isRunning) updateLookup();\n };\n watch(\n read,\n (next) => {\n instance.setProps(next);\n queuePostFlushCb(sync);\n },\n { flush: 'pre' },\n );\n\n let stop: (() => void) | null = null;\n const begin = () => {\n if (stop) return;\n flushAttaching(internal);\n // In one batch, so the start's element effects run once the binder has\n // written the parts: an overlay open from the start is `data-entering`\n // as it shows.\n instance.batch(() => {\n instance.start();\n binder.start();\n });\n // Answers owner requests from custom elements and components that find\n // their owner through the DOM.\n const unprovide = isOwnerDefinition(definition)\n ? definition.parts.flatMap((part: string) => {\n const element = instance.element(part as PartOf<D>);\n return element\n ? [\n provideOwner(\n instance as unknown as Instance,\n element as Element,\n ),\n ]\n : [];\n })\n : [];\n isRunning = true;\n updateLookup();\n instance.sync();\n stop = () => {\n isRunning = false;\n lookup?.();\n lookup = null;\n for (const forget of unprovide) forget();\n binder.stop();\n instance.stop();\n };\n };\n const end = () => {\n stop?.();\n stop = null;\n };\n onMounted(begin);\n onActivated(begin);\n onDeactivated(end);\n onBeforeUnmount(end);\n\n return markRaw({\n instance,\n actions: instance.actions,\n get parts() {\n const connected = instance.connect();\n if (internal.rendered?.connected !== connected) {\n internal.rendered = {\n connected,\n parts: toVueParts(internal, connected),\n };\n }\n return internal.rendered.parts as ComponentHandle<D>['parts'];\n },\n getItemProps: internal.getItemProps as ComponentHandle<D>['getItemProps'],\n });\n}\n","/**\n * `useComponentState` (Vue adapter spec): one selected value of an\n * instance's public state as a read-only ref. The ref reads the state when\n * it is read, so a render after a prop change already shows the new value,\n * and it triggers only when the store's notification changes the value a\n * render last read.\n */\n\nimport type { AnyDefinition, Instance, StateOf } from '@uniaria/core';\nimport { warn } from '@uniaria/core/dom';\nimport type { Ref } from 'vue';\nimport { customRef, getCurrentScope, onScopeDispose } from 'vue';\n\nimport type { ComponentHandle } from './use-component';\n\n/**\n * Reads one value of an instance's public state as a ref that triggers only\n * when the value changes (`Object.is`, or `isEqual`). Takes the instance or\n * the handle `useComponent` returned.\n */\nexport function useComponentState<D extends AnyDefinition, T>(\n source: Instance<D> | ComponentHandle<D>,\n selector: (state: StateOf<D>) => T,\n isEqual: (a: T, b: T) => boolean = Object.is,\n): Readonly<Ref<T>> {\n const instance = 'instance' in source ? source.instance : source;\n let cache: { readonly state: StateOf<D>; readonly value: T } | null = null;\n\n // The selection stays the same object while the state object is, or while\n // the new selection is equal to the last one.\n const select = (): T => {\n const state = instance.getState();\n if (cache?.state === state) return cache.value;\n const value = selector(state);\n const stable = cache && isEqual(cache.value, value) ? cache.value : value;\n cache = { state, value: stable };\n return stable;\n };\n\n return customRef<T>((track, trigger) => {\n // The value a reader last got; a notification that brings the same one\n // (the sync after a prop change the render already showed) stays quiet.\n let read: { readonly value: T } | null = null;\n // Never on the server, where nothing would unsubscribe.\n if (typeof document !== 'undefined') {\n const unsubscribe = instance.subscribe(() => {\n if (!read || !Object.is(read.value, select())) trigger();\n });\n if (getCurrentScope()) onScopeDispose(unsubscribe);\n }\n return {\n get() {\n track();\n const value = select();\n read = { value };\n return value;\n },\n set() {\n warn(\n `${instance.definition.name}: useComponentState returns a read-only ref.`,\n );\n },\n };\n });\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,59 @@
1
1
  {
2
2
  "name": "@uniaria/vue",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "Vue adapter for UniAria: one generic useComponent composable over any UniAria component definition",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "exports": {
8
+ ".": {
9
+ "uniaria-source": "./src/index.ts",
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/tenphi/uniaria.git",
21
+ "directory": "packages/vue"
22
+ },
23
+ "keywords": [
24
+ "headless",
25
+ "ui",
26
+ "vue",
27
+ "accessibility",
28
+ "a11y",
29
+ "aria"
30
+ ],
31
+ "author": "Andrey Yamanov",
32
+ "license": "MIT",
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/tenphi/uniaria/issues"
38
+ },
39
+ "homepage": "https://github.com/tenphi/uniaria#readme",
40
+ "engines": {
41
+ "node": ">=22"
42
+ },
43
+ "dependencies": {
44
+ "@uniaria/core": "0.2.0"
45
+ },
46
+ "peerDependencies": {
47
+ "vue": "^3.5.0"
48
+ },
49
+ "devDependencies": {
50
+ "@uniaria/conformance": "0.0.0",
51
+ "@uniaria/elements": "0.2.0",
52
+ "@uniaria/testing": "0.2.0",
53
+ "vue": "^3.5.43"
54
+ },
55
+ "scripts": {
56
+ "build": "tsdown",
57
+ "typecheck": "tsc -p tsconfig.json"
58
+ }
6
59
  }