@zeus-js/output-vue-wrapper 0.1.0-beta.4 → 0.1.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/output-vue-wrapper.cjs.js +147 -6
- package/dist/output-vue-wrapper.cjs.prod.js +147 -6
- package/dist/output-vue-wrapper.d.ts +31 -3
- package/dist/output-vue-wrapper.esm-bundler.js +147 -7
- package/dist/runtime/index.cjs.js +114 -0
- package/dist/runtime/index.cjs.prod.js +114 -0
- package/dist/runtime/index.d.ts +26 -0
- package/dist/runtime/index.js +110 -0
- package/dist/runtime/index.prod.js +110 -0
- package/package.json +44 -28
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* output-vue-wrapper v0.1.0-beta.
|
|
2
|
+
* output-vue-wrapper v0.1.0-beta.6
|
|
3
3
|
* (c) 2026 baicie
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
**/
|
|
@@ -9,6 +9,7 @@ Object.defineProperties(exports, {
|
|
|
9
9
|
});
|
|
10
10
|
let _zeus_js_bundler_plugin = require("@zeus-js/bundler-plugin");
|
|
11
11
|
let _zeus_js_component_dts = require("@zeus-js/component-dts");
|
|
12
|
+
let vue = require("vue");
|
|
12
13
|
//#region packages/web-c/output-vue-wrapper/src/generateVueIndex.ts
|
|
13
14
|
function generateVueIndex(components, options) {
|
|
14
15
|
const lines = [];
|
|
@@ -23,7 +24,7 @@ function generateVueIndex(components, options) {
|
|
|
23
24
|
//#region packages/web-c/output-vue-wrapper/src/generateVueWrapper.ts
|
|
24
25
|
function generateVueWrapper(input) {
|
|
25
26
|
var _input$component$mode;
|
|
26
|
-
return input.mode === "event-bridge" || ((_input$component$mode = input.component.models) === null || _input$component$mode === void 0 ? void 0 : _input$component$mode.length) ? generateEventBridgeVueWrapper(input) : generateMinimalVueWrapper(input);
|
|
27
|
+
return input.mode === "runtime" ? generateRuntimeVueWrapper(input) : input.mode === "event-bridge" || ((_input$component$mode = input.component.models) === null || _input$component$mode === void 0 ? void 0 : _input$component$mode.length) ? generateEventBridgeVueWrapper(input) : generateMinimalVueWrapper(input);
|
|
27
28
|
}
|
|
28
29
|
function generateMinimalVueWrapper(input) {
|
|
29
30
|
const { component, wcModuleId } = input;
|
|
@@ -55,7 +56,7 @@ function generateEventBridgeVueWrapper(input) {
|
|
|
55
56
|
if (!propNames.length && !eventNames.length) return generateMinimalVueWrapper(input);
|
|
56
57
|
const hasProps = propNames.length > 0;
|
|
57
58
|
const hasEvents = eventNames.length > 0;
|
|
58
|
-
const emitNames = Array.from(new Set([...eventNames, ...models.map((model) => model.updateEvent)]));
|
|
59
|
+
const emitNames = Array.from(/* @__PURE__ */ new Set([...eventNames, ...models.map((model) => model.updateEvent)]));
|
|
59
60
|
const hasNamedSlots = slotNames.length > 0;
|
|
60
61
|
return `
|
|
61
62
|
import {
|
|
@@ -108,7 +109,7 @@ function getCapabilities(component) {
|
|
|
108
109
|
}));
|
|
109
110
|
return {
|
|
110
111
|
propNames: Object.keys(component.props),
|
|
111
|
-
eventNames: Array.from(new Set([...Object.entries(component.events).map(([key, event]) => {
|
|
112
|
+
eventNames: Array.from(/* @__PURE__ */ new Set([...Object.entries(component.events).map(([key, event]) => {
|
|
112
113
|
var _event$name, _event$key;
|
|
113
114
|
return (_event$name = event.name) !== null && _event$name !== void 0 ? _event$name : toKebabCase((_event$key = event.key) !== null && _event$key !== void 0 ? _event$key : key);
|
|
114
115
|
}), ...models.map((model) => model.event)])),
|
|
@@ -224,6 +225,42 @@ function generateVueProps(component) {
|
|
|
224
225
|
return `${JSON.stringify(name)}: ${toVuePropOption(prop)}`;
|
|
225
226
|
}).join(",\n ");
|
|
226
227
|
}
|
|
228
|
+
function generateRuntimeVueWrapper(input) {
|
|
229
|
+
var _component$models2;
|
|
230
|
+
const { component } = input;
|
|
231
|
+
const propNames = Object.keys(component.props);
|
|
232
|
+
const eventNames = getEventNames(component);
|
|
233
|
+
const slotNames = Object.keys(component.slots).filter((name) => name !== "default");
|
|
234
|
+
const model = (_component$models2 = component.models) === null || _component$models2 === void 0 ? void 0 : _component$models2[0];
|
|
235
|
+
return [
|
|
236
|
+
`import { defineContainer } from '@zeus-js/output-vue-wrapper/runtime'`,
|
|
237
|
+
`import { defineCustomElement } from '../wc/loader.js'`,
|
|
238
|
+
``,
|
|
239
|
+
`export const ${component.name} = defineContainer({`,
|
|
240
|
+
` tagName: ${JSON.stringify(component.tag)},`,
|
|
241
|
+
` displayName: ${JSON.stringify(component.name)},`,
|
|
242
|
+
` defineCustomElement: () => defineCustomElement(${JSON.stringify(component.tag)}),`,
|
|
243
|
+
` props: ${JSON.stringify(propNames)},`,
|
|
244
|
+
` events: ${JSON.stringify(eventNames)},`,
|
|
245
|
+
` slots: ${JSON.stringify(slotNames)},`,
|
|
246
|
+
` model: ${model ? formatModel(model) : "undefined"},`,
|
|
247
|
+
`})`,
|
|
248
|
+
``
|
|
249
|
+
].join("\n");
|
|
250
|
+
}
|
|
251
|
+
function getEventNames(component) {
|
|
252
|
+
return Array.from(new Set(Object.entries(component.events).map(([key, event]) => {
|
|
253
|
+
var _event$name2, _event$key2;
|
|
254
|
+
return (_event$name2 = event.name) !== null && _event$name2 !== void 0 ? _event$name2 : toKebabCase((_event$key2 = event.key) !== null && _event$key2 !== void 0 ? _event$key2 : key);
|
|
255
|
+
})));
|
|
256
|
+
}
|
|
257
|
+
function formatModel(model) {
|
|
258
|
+
return `{
|
|
259
|
+
prop: ${JSON.stringify(model.prop)},
|
|
260
|
+
event: ${JSON.stringify(model.event)},
|
|
261
|
+
eventPath: ${JSON.stringify(model.eventPath)},
|
|
262
|
+
}`;
|
|
263
|
+
}
|
|
227
264
|
function toVuePropOption(prop) {
|
|
228
265
|
var _typeMap$prop$type;
|
|
229
266
|
return `{ type: ${(_typeMap$prop$type = {
|
|
@@ -237,7 +274,7 @@ function toVuePropOption(prop) {
|
|
|
237
274
|
}[prop.type]) !== null && _typeMap$prop$type !== void 0 ? _typeMap$prop$type : "null"}, required: ${prop.required === true ? "true" : "false"} }`;
|
|
238
275
|
}
|
|
239
276
|
function createVuePropInputKeys(propNames) {
|
|
240
|
-
return Object.fromEntries(propNames.map((name) => [name, Array.from(new Set([name, toKebabCase(name)]))]));
|
|
277
|
+
return Object.fromEntries(propNames.map((name) => [name, Array.from(/* @__PURE__ */ new Set([name, toKebabCase(name)]))]));
|
|
241
278
|
}
|
|
242
279
|
function toKebabCase(value) {
|
|
243
280
|
return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
@@ -279,6 +316,109 @@ function readEventPath(event, path) {
|
|
|
279
316
|
}
|
|
280
317
|
`;
|
|
281
318
|
//#endregion
|
|
319
|
+
//#region packages/web-c/output-vue-wrapper/src/runtime/defineContainer.ts
|
|
320
|
+
const EMPTY_PROP = Symbol();
|
|
321
|
+
const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP };
|
|
322
|
+
const UPDATE_MODEL_VALUE_EVENT = "update:modelValue";
|
|
323
|
+
const MODEL_VALUE = "modelValue";
|
|
324
|
+
function defineContainer(options) {
|
|
325
|
+
const { tagName, displayName, defineCustomElement, props: componentProps = [], events: emitProps = [], slots: slotNames = [], model, transformTag } = options;
|
|
326
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
327
|
+
const emits = [...emitProps];
|
|
328
|
+
const componentPropsMap = {};
|
|
329
|
+
for (const prop of componentProps) componentPropsMap[prop] = DEFAULT_EMPTY_PROP;
|
|
330
|
+
if (model) {
|
|
331
|
+
const updateEvent = getModelUpdateEvent(model.prop);
|
|
332
|
+
emits.push(updateEvent);
|
|
333
|
+
if (updateEvent !== UPDATE_MODEL_VALUE_EVENT) emits.push(UPDATE_MODEL_VALUE_EVENT);
|
|
334
|
+
componentPropsMap[MODEL_VALUE] = DEFAULT_EMPTY_PROP;
|
|
335
|
+
}
|
|
336
|
+
return (0, vue.defineComponent)((propsValue, { attrs, slots: allSlots, emit }) => {
|
|
337
|
+
const containerRef = (0, vue.ref)();
|
|
338
|
+
const listeners = [];
|
|
339
|
+
(0, vue.onMounted)(() => {
|
|
340
|
+
const el = containerRef.value;
|
|
341
|
+
if (!el) return;
|
|
342
|
+
for (const eventName of emitProps) {
|
|
343
|
+
const listener = (event) => {
|
|
344
|
+
emit(eventName, event);
|
|
345
|
+
};
|
|
346
|
+
el.addEventListener(eventName, listener);
|
|
347
|
+
listeners.push({
|
|
348
|
+
eventName,
|
|
349
|
+
listener
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
(0, vue.onBeforeUnmount)(() => {
|
|
354
|
+
const el = containerRef.value;
|
|
355
|
+
if (!el) return;
|
|
356
|
+
for (const item of listeners) el.removeEventListener(item.eventName, item.listener);
|
|
357
|
+
listeners.length = 0;
|
|
358
|
+
});
|
|
359
|
+
const vModelDirective = { created: (el) => {
|
|
360
|
+
if (!model) return;
|
|
361
|
+
for (const eventName of toArray(model.event)) el.addEventListener(eventName, (event) => {
|
|
362
|
+
var _model$eventPath;
|
|
363
|
+
if (event.target.tagName !== el.tagName) return;
|
|
364
|
+
const value = readEventPath(event, (_model$eventPath = model.eventPath) !== null && _model$eventPath !== void 0 ? _model$eventPath : `target.${model.prop}`);
|
|
365
|
+
emit(getModelUpdateEvent(model.prop), value);
|
|
366
|
+
if (propsValue[MODEL_VALUE] !== EMPTY_PROP) emit(UPDATE_MODEL_VALUE_EVENT, value);
|
|
367
|
+
});
|
|
368
|
+
} };
|
|
369
|
+
return () => {
|
|
370
|
+
const propsToAdd = { ref: containerRef };
|
|
371
|
+
for (const key in propsValue) {
|
|
372
|
+
const value = propsValue[key];
|
|
373
|
+
if (value !== EMPTY_PROP) propsToAdd[key] = value;
|
|
374
|
+
}
|
|
375
|
+
for (const key in attrs) propsToAdd[key] = attrs[key];
|
|
376
|
+
if (model) {
|
|
377
|
+
const modelValue = propsValue[MODEL_VALUE];
|
|
378
|
+
const modelPropValue = propsValue[model.prop];
|
|
379
|
+
if (modelValue !== EMPTY_PROP) propsToAdd[model.prop] = modelValue;
|
|
380
|
+
else if (modelPropValue !== EMPTY_PROP) propsToAdd[model.prop] = modelPropValue;
|
|
381
|
+
}
|
|
382
|
+
const children = createChildren(allSlots, slotNames);
|
|
383
|
+
const node = (0, vue.h)(transformTag ? transformTag(tagName) : tagName, propsToAdd, children);
|
|
384
|
+
return model ? (0, vue.withDirectives)(node, [[vModelDirective]]) : node;
|
|
385
|
+
};
|
|
386
|
+
}, {
|
|
387
|
+
name: displayName !== null && displayName !== void 0 ? displayName : tagName,
|
|
388
|
+
props: componentPropsMap,
|
|
389
|
+
emits
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
function createChildren(slots, slotNames) {
|
|
393
|
+
const children = slots.default ? slots.default() : [];
|
|
394
|
+
for (const name of slotNames) {
|
|
395
|
+
const slot = slots[name];
|
|
396
|
+
if (!slot) continue;
|
|
397
|
+
for (const vnode of slot()) children.push(withSlot(name, vnode));
|
|
398
|
+
}
|
|
399
|
+
return children;
|
|
400
|
+
}
|
|
401
|
+
function withSlot(name, vnode) {
|
|
402
|
+
if (!vnode) return vnode;
|
|
403
|
+
if (typeof vnode === "string") return (0, vue.h)("span", {
|
|
404
|
+
slot: name,
|
|
405
|
+
style: "display: contents"
|
|
406
|
+
}, vnode);
|
|
407
|
+
return (0, vue.cloneVNode)(vnode, { slot: name });
|
|
408
|
+
}
|
|
409
|
+
function getModelUpdateEvent(prop) {
|
|
410
|
+
return `update:${prop}`;
|
|
411
|
+
}
|
|
412
|
+
function toArray(value) {
|
|
413
|
+
return Array.isArray(value) ? value : [value];
|
|
414
|
+
}
|
|
415
|
+
function readEventPath(event, path) {
|
|
416
|
+
return path.split(".").reduce((value, key) => {
|
|
417
|
+
if (value == null) return void 0;
|
|
418
|
+
return value[key];
|
|
419
|
+
}, event);
|
|
420
|
+
}
|
|
421
|
+
//#endregion
|
|
282
422
|
//#region packages/web-c/output-vue-wrapper/src/index.ts
|
|
283
423
|
function vueWrapper(options = {}) {
|
|
284
424
|
var _options$outDir, _options$stripPrefix, _options$dts, _options$globalDts, _options$index, _options$wrapper;
|
|
@@ -289,7 +429,7 @@ function vueWrapper(options = {}) {
|
|
|
289
429
|
dts: (_options$dts = options.dts) !== null && _options$dts !== void 0 ? _options$dts : true,
|
|
290
430
|
globalDts: (_options$globalDts = options.globalDts) !== null && _options$globalDts !== void 0 ? _options$globalDts : true,
|
|
291
431
|
index: (_options$index = options.index) !== null && _options$index !== void 0 ? _options$index : true,
|
|
292
|
-
wrapper: (_options$wrapper = options.wrapper) !== null && _options$wrapper !== void 0 ? _options$wrapper : "
|
|
432
|
+
wrapper: (_options$wrapper = options.wrapper) !== null && _options$wrapper !== void 0 ? _options$wrapper : "runtime"
|
|
293
433
|
};
|
|
294
434
|
return {
|
|
295
435
|
name: "zeus-output-vue-wrapper",
|
|
@@ -338,3 +478,4 @@ function vueWrapper(options = {}) {
|
|
|
338
478
|
}
|
|
339
479
|
//#endregion
|
|
340
480
|
exports.default = vueWrapper;
|
|
481
|
+
exports.defineContainer = defineContainer;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* output-vue-wrapper v0.1.0-beta.
|
|
2
|
+
* output-vue-wrapper v0.1.0-beta.6
|
|
3
3
|
* (c) 2026 baicie
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
**/
|
|
@@ -9,6 +9,7 @@ Object.defineProperties(exports, {
|
|
|
9
9
|
});
|
|
10
10
|
let _zeus_js_bundler_plugin = require("@zeus-js/bundler-plugin");
|
|
11
11
|
let _zeus_js_component_dts = require("@zeus-js/component-dts");
|
|
12
|
+
let vue = require("vue");
|
|
12
13
|
//#region packages/web-c/output-vue-wrapper/src/generateVueIndex.ts
|
|
13
14
|
function generateVueIndex(components, options) {
|
|
14
15
|
const lines = [];
|
|
@@ -23,7 +24,7 @@ function generateVueIndex(components, options) {
|
|
|
23
24
|
//#region packages/web-c/output-vue-wrapper/src/generateVueWrapper.ts
|
|
24
25
|
function generateVueWrapper(input) {
|
|
25
26
|
var _input$component$mode;
|
|
26
|
-
return input.mode === "event-bridge" || ((_input$component$mode = input.component.models) === null || _input$component$mode === void 0 ? void 0 : _input$component$mode.length) ? generateEventBridgeVueWrapper(input) : generateMinimalVueWrapper(input);
|
|
27
|
+
return input.mode === "runtime" ? generateRuntimeVueWrapper(input) : input.mode === "event-bridge" || ((_input$component$mode = input.component.models) === null || _input$component$mode === void 0 ? void 0 : _input$component$mode.length) ? generateEventBridgeVueWrapper(input) : generateMinimalVueWrapper(input);
|
|
27
28
|
}
|
|
28
29
|
function generateMinimalVueWrapper(input) {
|
|
29
30
|
const { component, wcModuleId } = input;
|
|
@@ -55,7 +56,7 @@ function generateEventBridgeVueWrapper(input) {
|
|
|
55
56
|
if (!propNames.length && !eventNames.length) return generateMinimalVueWrapper(input);
|
|
56
57
|
const hasProps = propNames.length > 0;
|
|
57
58
|
const hasEvents = eventNames.length > 0;
|
|
58
|
-
const emitNames = Array.from(new Set([...eventNames, ...models.map((model) => model.updateEvent)]));
|
|
59
|
+
const emitNames = Array.from(/* @__PURE__ */ new Set([...eventNames, ...models.map((model) => model.updateEvent)]));
|
|
59
60
|
const hasNamedSlots = slotNames.length > 0;
|
|
60
61
|
return `
|
|
61
62
|
import {
|
|
@@ -108,7 +109,7 @@ function getCapabilities(component) {
|
|
|
108
109
|
}));
|
|
109
110
|
return {
|
|
110
111
|
propNames: Object.keys(component.props),
|
|
111
|
-
eventNames: Array.from(new Set([...Object.entries(component.events).map(([key, event]) => {
|
|
112
|
+
eventNames: Array.from(/* @__PURE__ */ new Set([...Object.entries(component.events).map(([key, event]) => {
|
|
112
113
|
var _event$name, _event$key;
|
|
113
114
|
return (_event$name = event.name) !== null && _event$name !== void 0 ? _event$name : toKebabCase((_event$key = event.key) !== null && _event$key !== void 0 ? _event$key : key);
|
|
114
115
|
}), ...models.map((model) => model.event)])),
|
|
@@ -224,6 +225,42 @@ function generateVueProps(component) {
|
|
|
224
225
|
return `${JSON.stringify(name)}: ${toVuePropOption(prop)}`;
|
|
225
226
|
}).join(",\n ");
|
|
226
227
|
}
|
|
228
|
+
function generateRuntimeVueWrapper(input) {
|
|
229
|
+
var _component$models2;
|
|
230
|
+
const { component } = input;
|
|
231
|
+
const propNames = Object.keys(component.props);
|
|
232
|
+
const eventNames = getEventNames(component);
|
|
233
|
+
const slotNames = Object.keys(component.slots).filter((name) => name !== "default");
|
|
234
|
+
const model = (_component$models2 = component.models) === null || _component$models2 === void 0 ? void 0 : _component$models2[0];
|
|
235
|
+
return [
|
|
236
|
+
`import { defineContainer } from '@zeus-js/output-vue-wrapper/runtime'`,
|
|
237
|
+
`import { defineCustomElement } from '../wc/loader.js'`,
|
|
238
|
+
``,
|
|
239
|
+
`export const ${component.name} = defineContainer({`,
|
|
240
|
+
` tagName: ${JSON.stringify(component.tag)},`,
|
|
241
|
+
` displayName: ${JSON.stringify(component.name)},`,
|
|
242
|
+
` defineCustomElement: () => defineCustomElement(${JSON.stringify(component.tag)}),`,
|
|
243
|
+
` props: ${JSON.stringify(propNames)},`,
|
|
244
|
+
` events: ${JSON.stringify(eventNames)},`,
|
|
245
|
+
` slots: ${JSON.stringify(slotNames)},`,
|
|
246
|
+
` model: ${model ? formatModel(model) : "undefined"},`,
|
|
247
|
+
`})`,
|
|
248
|
+
``
|
|
249
|
+
].join("\n");
|
|
250
|
+
}
|
|
251
|
+
function getEventNames(component) {
|
|
252
|
+
return Array.from(new Set(Object.entries(component.events).map(([key, event]) => {
|
|
253
|
+
var _event$name2, _event$key2;
|
|
254
|
+
return (_event$name2 = event.name) !== null && _event$name2 !== void 0 ? _event$name2 : toKebabCase((_event$key2 = event.key) !== null && _event$key2 !== void 0 ? _event$key2 : key);
|
|
255
|
+
})));
|
|
256
|
+
}
|
|
257
|
+
function formatModel(model) {
|
|
258
|
+
return `{
|
|
259
|
+
prop: ${JSON.stringify(model.prop)},
|
|
260
|
+
event: ${JSON.stringify(model.event)},
|
|
261
|
+
eventPath: ${JSON.stringify(model.eventPath)},
|
|
262
|
+
}`;
|
|
263
|
+
}
|
|
227
264
|
function toVuePropOption(prop) {
|
|
228
265
|
var _typeMap$prop$type;
|
|
229
266
|
return `{ type: ${(_typeMap$prop$type = {
|
|
@@ -237,7 +274,7 @@ function toVuePropOption(prop) {
|
|
|
237
274
|
}[prop.type]) !== null && _typeMap$prop$type !== void 0 ? _typeMap$prop$type : "null"}, required: ${prop.required === true ? "true" : "false"} }`;
|
|
238
275
|
}
|
|
239
276
|
function createVuePropInputKeys(propNames) {
|
|
240
|
-
return Object.fromEntries(propNames.map((name) => [name, Array.from(new Set([name, toKebabCase(name)]))]));
|
|
277
|
+
return Object.fromEntries(propNames.map((name) => [name, Array.from(/* @__PURE__ */ new Set([name, toKebabCase(name)]))]));
|
|
241
278
|
}
|
|
242
279
|
function toKebabCase(value) {
|
|
243
280
|
return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
@@ -279,6 +316,109 @@ function readEventPath(event, path) {
|
|
|
279
316
|
}
|
|
280
317
|
`;
|
|
281
318
|
//#endregion
|
|
319
|
+
//#region packages/web-c/output-vue-wrapper/src/runtime/defineContainer.ts
|
|
320
|
+
const EMPTY_PROP = Symbol();
|
|
321
|
+
const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP };
|
|
322
|
+
const UPDATE_MODEL_VALUE_EVENT = "update:modelValue";
|
|
323
|
+
const MODEL_VALUE = "modelValue";
|
|
324
|
+
function defineContainer(options) {
|
|
325
|
+
const { tagName, displayName, defineCustomElement, props: componentProps = [], events: emitProps = [], slots: slotNames = [], model, transformTag } = options;
|
|
326
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
327
|
+
const emits = [...emitProps];
|
|
328
|
+
const componentPropsMap = {};
|
|
329
|
+
for (const prop of componentProps) componentPropsMap[prop] = DEFAULT_EMPTY_PROP;
|
|
330
|
+
if (model) {
|
|
331
|
+
const updateEvent = getModelUpdateEvent(model.prop);
|
|
332
|
+
emits.push(updateEvent);
|
|
333
|
+
if (updateEvent !== UPDATE_MODEL_VALUE_EVENT) emits.push(UPDATE_MODEL_VALUE_EVENT);
|
|
334
|
+
componentPropsMap[MODEL_VALUE] = DEFAULT_EMPTY_PROP;
|
|
335
|
+
}
|
|
336
|
+
return (0, vue.defineComponent)((propsValue, { attrs, slots: allSlots, emit }) => {
|
|
337
|
+
const containerRef = (0, vue.ref)();
|
|
338
|
+
const listeners = [];
|
|
339
|
+
(0, vue.onMounted)(() => {
|
|
340
|
+
const el = containerRef.value;
|
|
341
|
+
if (!el) return;
|
|
342
|
+
for (const eventName of emitProps) {
|
|
343
|
+
const listener = (event) => {
|
|
344
|
+
emit(eventName, event);
|
|
345
|
+
};
|
|
346
|
+
el.addEventListener(eventName, listener);
|
|
347
|
+
listeners.push({
|
|
348
|
+
eventName,
|
|
349
|
+
listener
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
(0, vue.onBeforeUnmount)(() => {
|
|
354
|
+
const el = containerRef.value;
|
|
355
|
+
if (!el) return;
|
|
356
|
+
for (const item of listeners) el.removeEventListener(item.eventName, item.listener);
|
|
357
|
+
listeners.length = 0;
|
|
358
|
+
});
|
|
359
|
+
const vModelDirective = { created: (el) => {
|
|
360
|
+
if (!model) return;
|
|
361
|
+
for (const eventName of toArray(model.event)) el.addEventListener(eventName, (event) => {
|
|
362
|
+
var _model$eventPath;
|
|
363
|
+
if (event.target.tagName !== el.tagName) return;
|
|
364
|
+
const value = readEventPath(event, (_model$eventPath = model.eventPath) !== null && _model$eventPath !== void 0 ? _model$eventPath : `target.${model.prop}`);
|
|
365
|
+
emit(getModelUpdateEvent(model.prop), value);
|
|
366
|
+
if (propsValue[MODEL_VALUE] !== EMPTY_PROP) emit(UPDATE_MODEL_VALUE_EVENT, value);
|
|
367
|
+
});
|
|
368
|
+
} };
|
|
369
|
+
return () => {
|
|
370
|
+
const propsToAdd = { ref: containerRef };
|
|
371
|
+
for (const key in propsValue) {
|
|
372
|
+
const value = propsValue[key];
|
|
373
|
+
if (value !== EMPTY_PROP) propsToAdd[key] = value;
|
|
374
|
+
}
|
|
375
|
+
for (const key in attrs) propsToAdd[key] = attrs[key];
|
|
376
|
+
if (model) {
|
|
377
|
+
const modelValue = propsValue[MODEL_VALUE];
|
|
378
|
+
const modelPropValue = propsValue[model.prop];
|
|
379
|
+
if (modelValue !== EMPTY_PROP) propsToAdd[model.prop] = modelValue;
|
|
380
|
+
else if (modelPropValue !== EMPTY_PROP) propsToAdd[model.prop] = modelPropValue;
|
|
381
|
+
}
|
|
382
|
+
const children = createChildren(allSlots, slotNames);
|
|
383
|
+
const node = (0, vue.h)(transformTag ? transformTag(tagName) : tagName, propsToAdd, children);
|
|
384
|
+
return model ? (0, vue.withDirectives)(node, [[vModelDirective]]) : node;
|
|
385
|
+
};
|
|
386
|
+
}, {
|
|
387
|
+
name: displayName !== null && displayName !== void 0 ? displayName : tagName,
|
|
388
|
+
props: componentPropsMap,
|
|
389
|
+
emits
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
function createChildren(slots, slotNames) {
|
|
393
|
+
const children = slots.default ? slots.default() : [];
|
|
394
|
+
for (const name of slotNames) {
|
|
395
|
+
const slot = slots[name];
|
|
396
|
+
if (!slot) continue;
|
|
397
|
+
for (const vnode of slot()) children.push(withSlot(name, vnode));
|
|
398
|
+
}
|
|
399
|
+
return children;
|
|
400
|
+
}
|
|
401
|
+
function withSlot(name, vnode) {
|
|
402
|
+
if (!vnode) return vnode;
|
|
403
|
+
if (typeof vnode === "string") return (0, vue.h)("span", {
|
|
404
|
+
slot: name,
|
|
405
|
+
style: "display: contents"
|
|
406
|
+
}, vnode);
|
|
407
|
+
return (0, vue.cloneVNode)(vnode, { slot: name });
|
|
408
|
+
}
|
|
409
|
+
function getModelUpdateEvent(prop) {
|
|
410
|
+
return `update:${prop}`;
|
|
411
|
+
}
|
|
412
|
+
function toArray(value) {
|
|
413
|
+
return Array.isArray(value) ? value : [value];
|
|
414
|
+
}
|
|
415
|
+
function readEventPath(event, path) {
|
|
416
|
+
return path.split(".").reduce((value, key) => {
|
|
417
|
+
if (value == null) return void 0;
|
|
418
|
+
return value[key];
|
|
419
|
+
}, event);
|
|
420
|
+
}
|
|
421
|
+
//#endregion
|
|
282
422
|
//#region packages/web-c/output-vue-wrapper/src/index.ts
|
|
283
423
|
function vueWrapper(options = {}) {
|
|
284
424
|
var _options$outDir, _options$stripPrefix, _options$dts, _options$globalDts, _options$index, _options$wrapper;
|
|
@@ -289,7 +429,7 @@ function vueWrapper(options = {}) {
|
|
|
289
429
|
dts: (_options$dts = options.dts) !== null && _options$dts !== void 0 ? _options$dts : true,
|
|
290
430
|
globalDts: (_options$globalDts = options.globalDts) !== null && _options$globalDts !== void 0 ? _options$globalDts : true,
|
|
291
431
|
index: (_options$index = options.index) !== null && _options$index !== void 0 ? _options$index : true,
|
|
292
|
-
wrapper: (_options$wrapper = options.wrapper) !== null && _options$wrapper !== void 0 ? _options$wrapper : "
|
|
432
|
+
wrapper: (_options$wrapper = options.wrapper) !== null && _options$wrapper !== void 0 ? _options$wrapper : "runtime"
|
|
293
433
|
};
|
|
294
434
|
return {
|
|
295
435
|
name: "zeus-output-vue-wrapper",
|
|
@@ -338,3 +478,4 @@ function vueWrapper(options = {}) {
|
|
|
338
478
|
}
|
|
339
479
|
//#endregion
|
|
340
480
|
exports.default = vueWrapper;
|
|
481
|
+
exports.defineContainer = defineContainer;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DtsMode, ZeusComponentPlugin } from '@zeus-js/bundler-plugin';
|
|
2
|
+
import * as vue from 'vue';
|
|
2
3
|
|
|
3
|
-
type VueWrapperMode = 'minimal' | 'event-bridge';
|
|
4
|
+
type VueWrapperMode = 'runtime' | 'minimal' | 'event-bridge';
|
|
4
5
|
export interface OutputVueWrapperOptions {
|
|
5
6
|
/**
|
|
6
7
|
* Vue wrapper output directory.
|
|
@@ -37,16 +38,43 @@ export interface OutputVueWrapperOptions {
|
|
|
37
38
|
*/
|
|
38
39
|
index?: boolean;
|
|
39
40
|
/**
|
|
41
|
+
* runtime:
|
|
42
|
+
* Default. Generates thin proxies powered by @zeus-js/output-vue-wrapper/runtime.
|
|
43
|
+
* No watch, no onMounted, no addEventListener — Vue-native props/events/model/slots.
|
|
44
|
+
*
|
|
40
45
|
* minimal:
|
|
41
|
-
*
|
|
46
|
+
* Vue wrapper only renders the custom element tag.
|
|
42
47
|
* No watch, no prop sync, no event listeners.
|
|
43
48
|
*
|
|
44
49
|
* event-bridge:
|
|
45
|
-
* Additional mode
|
|
50
|
+
* Additional mode with explicit prop syncing and CustomEvent bridging.
|
|
46
51
|
*/
|
|
47
52
|
wrapper?: VueWrapperMode;
|
|
48
53
|
}
|
|
49
54
|
|
|
55
|
+
export interface ZeusVueModelOptions {
|
|
56
|
+
prop: string;
|
|
57
|
+
event: string | string[];
|
|
58
|
+
eventPath?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface ZeusVueContainerOptions {
|
|
61
|
+
tagName: string;
|
|
62
|
+
displayName?: string;
|
|
63
|
+
defineCustomElement?: () => void;
|
|
64
|
+
props?: string[];
|
|
65
|
+
events?: string[];
|
|
66
|
+
slots?: string[];
|
|
67
|
+
model?: ZeusVueModelOptions;
|
|
68
|
+
transformTag?: (tagName: string) => string;
|
|
69
|
+
}
|
|
70
|
+
export declare function defineContainer(options: ZeusVueContainerOptions): vue.DefineSetupFnComponent<{
|
|
71
|
+
[x: string]: /*elided*/ any;
|
|
72
|
+
}, string[], {}, {
|
|
73
|
+
[x: string]: /*elided*/ any;
|
|
74
|
+
} & {
|
|
75
|
+
[x: `on${Capitalize<string>}`]: ((...args: any[]) => any) | undefined;
|
|
76
|
+
}, vue.PublicProps>;
|
|
77
|
+
|
|
50
78
|
export declare function vueWrapper(options?: OutputVueWrapperOptions): ZeusComponentPlugin;
|
|
51
79
|
|
|
52
80
|
export { vueWrapper as default };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* output-vue-wrapper v0.1.0-beta.
|
|
2
|
+
* output-vue-wrapper v0.1.0-beta.6
|
|
3
3
|
* (c) 2026 baicie
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
**/
|
|
6
6
|
import { resolvePluginDts } from "@zeus-js/bundler-plugin";
|
|
7
7
|
import { generateVueDts, generateVueGlobalDts } from "@zeus-js/component-dts";
|
|
8
|
+
import { cloneVNode, defineComponent, h, onBeforeUnmount, onMounted, ref, withDirectives } from "vue";
|
|
8
9
|
//#region packages/web-c/output-vue-wrapper/src/generateVueIndex.ts
|
|
9
10
|
function generateVueIndex(components, options) {
|
|
10
11
|
const lines = [];
|
|
@@ -19,7 +20,7 @@ function generateVueIndex(components, options) {
|
|
|
19
20
|
//#region packages/web-c/output-vue-wrapper/src/generateVueWrapper.ts
|
|
20
21
|
function generateVueWrapper(input) {
|
|
21
22
|
var _input$component$mode;
|
|
22
|
-
return input.mode === "event-bridge" || ((_input$component$mode = input.component.models) === null || _input$component$mode === void 0 ? void 0 : _input$component$mode.length) ? generateEventBridgeVueWrapper(input) : generateMinimalVueWrapper(input);
|
|
23
|
+
return input.mode === "runtime" ? generateRuntimeVueWrapper(input) : input.mode === "event-bridge" || ((_input$component$mode = input.component.models) === null || _input$component$mode === void 0 ? void 0 : _input$component$mode.length) ? generateEventBridgeVueWrapper(input) : generateMinimalVueWrapper(input);
|
|
23
24
|
}
|
|
24
25
|
function generateMinimalVueWrapper(input) {
|
|
25
26
|
const { component, wcModuleId } = input;
|
|
@@ -51,7 +52,7 @@ function generateEventBridgeVueWrapper(input) {
|
|
|
51
52
|
if (!propNames.length && !eventNames.length) return generateMinimalVueWrapper(input);
|
|
52
53
|
const hasProps = propNames.length > 0;
|
|
53
54
|
const hasEvents = eventNames.length > 0;
|
|
54
|
-
const emitNames = Array.from(new Set([...eventNames, ...models.map((model) => model.updateEvent)]));
|
|
55
|
+
const emitNames = Array.from(/* @__PURE__ */ new Set([...eventNames, ...models.map((model) => model.updateEvent)]));
|
|
55
56
|
const hasNamedSlots = slotNames.length > 0;
|
|
56
57
|
return `
|
|
57
58
|
import {
|
|
@@ -104,7 +105,7 @@ function getCapabilities(component) {
|
|
|
104
105
|
}));
|
|
105
106
|
return {
|
|
106
107
|
propNames: Object.keys(component.props),
|
|
107
|
-
eventNames: Array.from(new Set([...Object.entries(component.events).map(([key, event]) => {
|
|
108
|
+
eventNames: Array.from(/* @__PURE__ */ new Set([...Object.entries(component.events).map(([key, event]) => {
|
|
108
109
|
var _event$name, _event$key;
|
|
109
110
|
return (_event$name = event.name) !== null && _event$name !== void 0 ? _event$name : toKebabCase((_event$key = event.key) !== null && _event$key !== void 0 ? _event$key : key);
|
|
110
111
|
}), ...models.map((model) => model.event)])),
|
|
@@ -220,6 +221,42 @@ function generateVueProps(component) {
|
|
|
220
221
|
return `${JSON.stringify(name)}: ${toVuePropOption(prop)}`;
|
|
221
222
|
}).join(",\n ");
|
|
222
223
|
}
|
|
224
|
+
function generateRuntimeVueWrapper(input) {
|
|
225
|
+
var _component$models2;
|
|
226
|
+
const { component } = input;
|
|
227
|
+
const propNames = Object.keys(component.props);
|
|
228
|
+
const eventNames = getEventNames(component);
|
|
229
|
+
const slotNames = Object.keys(component.slots).filter((name) => name !== "default");
|
|
230
|
+
const model = (_component$models2 = component.models) === null || _component$models2 === void 0 ? void 0 : _component$models2[0];
|
|
231
|
+
return [
|
|
232
|
+
`import { defineContainer } from '@zeus-js/output-vue-wrapper/runtime'`,
|
|
233
|
+
`import { defineCustomElement } from '../wc/loader.js'`,
|
|
234
|
+
``,
|
|
235
|
+
`export const ${component.name} = defineContainer({`,
|
|
236
|
+
` tagName: ${JSON.stringify(component.tag)},`,
|
|
237
|
+
` displayName: ${JSON.stringify(component.name)},`,
|
|
238
|
+
` defineCustomElement: () => defineCustomElement(${JSON.stringify(component.tag)}),`,
|
|
239
|
+
` props: ${JSON.stringify(propNames)},`,
|
|
240
|
+
` events: ${JSON.stringify(eventNames)},`,
|
|
241
|
+
` slots: ${JSON.stringify(slotNames)},`,
|
|
242
|
+
` model: ${model ? formatModel(model) : "undefined"},`,
|
|
243
|
+
`})`,
|
|
244
|
+
``
|
|
245
|
+
].join("\n");
|
|
246
|
+
}
|
|
247
|
+
function getEventNames(component) {
|
|
248
|
+
return Array.from(new Set(Object.entries(component.events).map(([key, event]) => {
|
|
249
|
+
var _event$name2, _event$key2;
|
|
250
|
+
return (_event$name2 = event.name) !== null && _event$name2 !== void 0 ? _event$name2 : toKebabCase((_event$key2 = event.key) !== null && _event$key2 !== void 0 ? _event$key2 : key);
|
|
251
|
+
})));
|
|
252
|
+
}
|
|
253
|
+
function formatModel(model) {
|
|
254
|
+
return `{
|
|
255
|
+
prop: ${JSON.stringify(model.prop)},
|
|
256
|
+
event: ${JSON.stringify(model.event)},
|
|
257
|
+
eventPath: ${JSON.stringify(model.eventPath)},
|
|
258
|
+
}`;
|
|
259
|
+
}
|
|
223
260
|
function toVuePropOption(prop) {
|
|
224
261
|
var _typeMap$prop$type;
|
|
225
262
|
return `{ type: ${(_typeMap$prop$type = {
|
|
@@ -233,7 +270,7 @@ function toVuePropOption(prop) {
|
|
|
233
270
|
}[prop.type]) !== null && _typeMap$prop$type !== void 0 ? _typeMap$prop$type : "null"}, required: ${prop.required === true ? "true" : "false"} }`;
|
|
234
271
|
}
|
|
235
272
|
function createVuePropInputKeys(propNames) {
|
|
236
|
-
return Object.fromEntries(propNames.map((name) => [name, Array.from(new Set([name, toKebabCase(name)]))]));
|
|
273
|
+
return Object.fromEntries(propNames.map((name) => [name, Array.from(/* @__PURE__ */ new Set([name, toKebabCase(name)]))]));
|
|
237
274
|
}
|
|
238
275
|
function toKebabCase(value) {
|
|
239
276
|
return value.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
@@ -275,6 +312,109 @@ function readEventPath(event, path) {
|
|
|
275
312
|
}
|
|
276
313
|
`;
|
|
277
314
|
//#endregion
|
|
315
|
+
//#region packages/web-c/output-vue-wrapper/src/runtime/defineContainer.ts
|
|
316
|
+
const EMPTY_PROP = Symbol();
|
|
317
|
+
const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP };
|
|
318
|
+
const UPDATE_MODEL_VALUE_EVENT = "update:modelValue";
|
|
319
|
+
const MODEL_VALUE = "modelValue";
|
|
320
|
+
function defineContainer(options) {
|
|
321
|
+
const { tagName, displayName, defineCustomElement, props: componentProps = [], events: emitProps = [], slots: slotNames = [], model, transformTag } = options;
|
|
322
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
323
|
+
const emits = [...emitProps];
|
|
324
|
+
const componentPropsMap = {};
|
|
325
|
+
for (const prop of componentProps) componentPropsMap[prop] = DEFAULT_EMPTY_PROP;
|
|
326
|
+
if (model) {
|
|
327
|
+
const updateEvent = getModelUpdateEvent(model.prop);
|
|
328
|
+
emits.push(updateEvent);
|
|
329
|
+
if (updateEvent !== UPDATE_MODEL_VALUE_EVENT) emits.push(UPDATE_MODEL_VALUE_EVENT);
|
|
330
|
+
componentPropsMap[MODEL_VALUE] = DEFAULT_EMPTY_PROP;
|
|
331
|
+
}
|
|
332
|
+
return defineComponent((propsValue, { attrs, slots: allSlots, emit }) => {
|
|
333
|
+
const containerRef = ref();
|
|
334
|
+
const listeners = [];
|
|
335
|
+
onMounted(() => {
|
|
336
|
+
const el = containerRef.value;
|
|
337
|
+
if (!el) return;
|
|
338
|
+
for (const eventName of emitProps) {
|
|
339
|
+
const listener = (event) => {
|
|
340
|
+
emit(eventName, event);
|
|
341
|
+
};
|
|
342
|
+
el.addEventListener(eventName, listener);
|
|
343
|
+
listeners.push({
|
|
344
|
+
eventName,
|
|
345
|
+
listener
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
onBeforeUnmount(() => {
|
|
350
|
+
const el = containerRef.value;
|
|
351
|
+
if (!el) return;
|
|
352
|
+
for (const item of listeners) el.removeEventListener(item.eventName, item.listener);
|
|
353
|
+
listeners.length = 0;
|
|
354
|
+
});
|
|
355
|
+
const vModelDirective = { created: (el) => {
|
|
356
|
+
if (!model) return;
|
|
357
|
+
for (const eventName of toArray(model.event)) el.addEventListener(eventName, (event) => {
|
|
358
|
+
var _model$eventPath;
|
|
359
|
+
if (event.target.tagName !== el.tagName) return;
|
|
360
|
+
const value = readEventPath(event, (_model$eventPath = model.eventPath) !== null && _model$eventPath !== void 0 ? _model$eventPath : `target.${model.prop}`);
|
|
361
|
+
emit(getModelUpdateEvent(model.prop), value);
|
|
362
|
+
if (propsValue[MODEL_VALUE] !== EMPTY_PROP) emit(UPDATE_MODEL_VALUE_EVENT, value);
|
|
363
|
+
});
|
|
364
|
+
} };
|
|
365
|
+
return () => {
|
|
366
|
+
const propsToAdd = { ref: containerRef };
|
|
367
|
+
for (const key in propsValue) {
|
|
368
|
+
const value = propsValue[key];
|
|
369
|
+
if (value !== EMPTY_PROP) propsToAdd[key] = value;
|
|
370
|
+
}
|
|
371
|
+
for (const key in attrs) propsToAdd[key] = attrs[key];
|
|
372
|
+
if (model) {
|
|
373
|
+
const modelValue = propsValue[MODEL_VALUE];
|
|
374
|
+
const modelPropValue = propsValue[model.prop];
|
|
375
|
+
if (modelValue !== EMPTY_PROP) propsToAdd[model.prop] = modelValue;
|
|
376
|
+
else if (modelPropValue !== EMPTY_PROP) propsToAdd[model.prop] = modelPropValue;
|
|
377
|
+
}
|
|
378
|
+
const children = createChildren(allSlots, slotNames);
|
|
379
|
+
const node = h(transformTag ? transformTag(tagName) : tagName, propsToAdd, children);
|
|
380
|
+
return model ? withDirectives(node, [[vModelDirective]]) : node;
|
|
381
|
+
};
|
|
382
|
+
}, {
|
|
383
|
+
name: displayName !== null && displayName !== void 0 ? displayName : tagName,
|
|
384
|
+
props: componentPropsMap,
|
|
385
|
+
emits
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
function createChildren(slots, slotNames) {
|
|
389
|
+
const children = slots.default ? slots.default() : [];
|
|
390
|
+
for (const name of slotNames) {
|
|
391
|
+
const slot = slots[name];
|
|
392
|
+
if (!slot) continue;
|
|
393
|
+
for (const vnode of slot()) children.push(withSlot(name, vnode));
|
|
394
|
+
}
|
|
395
|
+
return children;
|
|
396
|
+
}
|
|
397
|
+
function withSlot(name, vnode) {
|
|
398
|
+
if (!vnode) return vnode;
|
|
399
|
+
if (typeof vnode === "string") return h("span", {
|
|
400
|
+
slot: name,
|
|
401
|
+
style: "display: contents"
|
|
402
|
+
}, vnode);
|
|
403
|
+
return cloneVNode(vnode, { slot: name });
|
|
404
|
+
}
|
|
405
|
+
function getModelUpdateEvent(prop) {
|
|
406
|
+
return `update:${prop}`;
|
|
407
|
+
}
|
|
408
|
+
function toArray(value) {
|
|
409
|
+
return Array.isArray(value) ? value : [value];
|
|
410
|
+
}
|
|
411
|
+
function readEventPath(event, path) {
|
|
412
|
+
return path.split(".").reduce((value, key) => {
|
|
413
|
+
if (value == null) return void 0;
|
|
414
|
+
return value[key];
|
|
415
|
+
}, event);
|
|
416
|
+
}
|
|
417
|
+
//#endregion
|
|
278
418
|
//#region packages/web-c/output-vue-wrapper/src/index.ts
|
|
279
419
|
function vueWrapper(options = {}) {
|
|
280
420
|
var _options$outDir, _options$stripPrefix, _options$dts, _options$globalDts, _options$index, _options$wrapper;
|
|
@@ -285,7 +425,7 @@ function vueWrapper(options = {}) {
|
|
|
285
425
|
dts: (_options$dts = options.dts) !== null && _options$dts !== void 0 ? _options$dts : true,
|
|
286
426
|
globalDts: (_options$globalDts = options.globalDts) !== null && _options$globalDts !== void 0 ? _options$globalDts : true,
|
|
287
427
|
index: (_options$index = options.index) !== null && _options$index !== void 0 ? _options$index : true,
|
|
288
|
-
wrapper: (_options$wrapper = options.wrapper) !== null && _options$wrapper !== void 0 ? _options$wrapper : "
|
|
428
|
+
wrapper: (_options$wrapper = options.wrapper) !== null && _options$wrapper !== void 0 ? _options$wrapper : "runtime"
|
|
289
429
|
};
|
|
290
430
|
return {
|
|
291
431
|
name: "zeus-output-vue-wrapper",
|
|
@@ -333,4 +473,4 @@ function vueWrapper(options = {}) {
|
|
|
333
473
|
};
|
|
334
474
|
}
|
|
335
475
|
//#endregion
|
|
336
|
-
export { vueWrapper as default };
|
|
476
|
+
export { vueWrapper as default, defineContainer };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* output-vue-wrapper v0.1.0-beta.6
|
|
3
|
+
* (c) 2026 baicie
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
**/
|
|
6
|
+
Object.defineProperties(exports, {
|
|
7
|
+
__esModule: { value: true },
|
|
8
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
9
|
+
});
|
|
10
|
+
let vue = require("vue");
|
|
11
|
+
//#region packages/web-c/output-vue-wrapper/src/runtime/defineContainer.ts
|
|
12
|
+
const EMPTY_PROP = Symbol();
|
|
13
|
+
const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP };
|
|
14
|
+
const UPDATE_MODEL_VALUE_EVENT = "update:modelValue";
|
|
15
|
+
const MODEL_VALUE = "modelValue";
|
|
16
|
+
function defineContainer(options) {
|
|
17
|
+
const { tagName, displayName, defineCustomElement, props: componentProps = [], events: emitProps = [], slots: slotNames = [], model, transformTag } = options;
|
|
18
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
19
|
+
const emits = [...emitProps];
|
|
20
|
+
const componentPropsMap = {};
|
|
21
|
+
for (const prop of componentProps) componentPropsMap[prop] = DEFAULT_EMPTY_PROP;
|
|
22
|
+
if (model) {
|
|
23
|
+
const updateEvent = getModelUpdateEvent(model.prop);
|
|
24
|
+
emits.push(updateEvent);
|
|
25
|
+
if (updateEvent !== UPDATE_MODEL_VALUE_EVENT) emits.push(UPDATE_MODEL_VALUE_EVENT);
|
|
26
|
+
componentPropsMap[MODEL_VALUE] = DEFAULT_EMPTY_PROP;
|
|
27
|
+
}
|
|
28
|
+
return (0, vue.defineComponent)((propsValue, { attrs, slots: allSlots, emit }) => {
|
|
29
|
+
const containerRef = (0, vue.ref)();
|
|
30
|
+
const listeners = [];
|
|
31
|
+
(0, vue.onMounted)(() => {
|
|
32
|
+
const el = containerRef.value;
|
|
33
|
+
if (!el) return;
|
|
34
|
+
for (const eventName of emitProps) {
|
|
35
|
+
const listener = (event) => {
|
|
36
|
+
emit(eventName, event);
|
|
37
|
+
};
|
|
38
|
+
el.addEventListener(eventName, listener);
|
|
39
|
+
listeners.push({
|
|
40
|
+
eventName,
|
|
41
|
+
listener
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
(0, vue.onBeforeUnmount)(() => {
|
|
46
|
+
const el = containerRef.value;
|
|
47
|
+
if (!el) return;
|
|
48
|
+
for (const item of listeners) el.removeEventListener(item.eventName, item.listener);
|
|
49
|
+
listeners.length = 0;
|
|
50
|
+
});
|
|
51
|
+
const vModelDirective = { created: (el) => {
|
|
52
|
+
if (!model) return;
|
|
53
|
+
for (const eventName of toArray(model.event)) el.addEventListener(eventName, (event) => {
|
|
54
|
+
var _model$eventPath;
|
|
55
|
+
if (event.target.tagName !== el.tagName) return;
|
|
56
|
+
const value = readEventPath(event, (_model$eventPath = model.eventPath) !== null && _model$eventPath !== void 0 ? _model$eventPath : `target.${model.prop}`);
|
|
57
|
+
emit(getModelUpdateEvent(model.prop), value);
|
|
58
|
+
if (propsValue[MODEL_VALUE] !== EMPTY_PROP) emit(UPDATE_MODEL_VALUE_EVENT, value);
|
|
59
|
+
});
|
|
60
|
+
} };
|
|
61
|
+
return () => {
|
|
62
|
+
const propsToAdd = { ref: containerRef };
|
|
63
|
+
for (const key in propsValue) {
|
|
64
|
+
const value = propsValue[key];
|
|
65
|
+
if (value !== EMPTY_PROP) propsToAdd[key] = value;
|
|
66
|
+
}
|
|
67
|
+
for (const key in attrs) propsToAdd[key] = attrs[key];
|
|
68
|
+
if (model) {
|
|
69
|
+
const modelValue = propsValue[MODEL_VALUE];
|
|
70
|
+
const modelPropValue = propsValue[model.prop];
|
|
71
|
+
if (modelValue !== EMPTY_PROP) propsToAdd[model.prop] = modelValue;
|
|
72
|
+
else if (modelPropValue !== EMPTY_PROP) propsToAdd[model.prop] = modelPropValue;
|
|
73
|
+
}
|
|
74
|
+
const children = createChildren(allSlots, slotNames);
|
|
75
|
+
const node = (0, vue.h)(transformTag ? transformTag(tagName) : tagName, propsToAdd, children);
|
|
76
|
+
return model ? (0, vue.withDirectives)(node, [[vModelDirective]]) : node;
|
|
77
|
+
};
|
|
78
|
+
}, {
|
|
79
|
+
name: displayName !== null && displayName !== void 0 ? displayName : tagName,
|
|
80
|
+
props: componentPropsMap,
|
|
81
|
+
emits
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function createChildren(slots, slotNames) {
|
|
85
|
+
const children = slots.default ? slots.default() : [];
|
|
86
|
+
for (const name of slotNames) {
|
|
87
|
+
const slot = slots[name];
|
|
88
|
+
if (!slot) continue;
|
|
89
|
+
for (const vnode of slot()) children.push(withSlot(name, vnode));
|
|
90
|
+
}
|
|
91
|
+
return children;
|
|
92
|
+
}
|
|
93
|
+
function withSlot(name, vnode) {
|
|
94
|
+
if (!vnode) return vnode;
|
|
95
|
+
if (typeof vnode === "string") return (0, vue.h)("span", {
|
|
96
|
+
slot: name,
|
|
97
|
+
style: "display: contents"
|
|
98
|
+
}, vnode);
|
|
99
|
+
return (0, vue.cloneVNode)(vnode, { slot: name });
|
|
100
|
+
}
|
|
101
|
+
function getModelUpdateEvent(prop) {
|
|
102
|
+
return `update:${prop}`;
|
|
103
|
+
}
|
|
104
|
+
function toArray(value) {
|
|
105
|
+
return Array.isArray(value) ? value : [value];
|
|
106
|
+
}
|
|
107
|
+
function readEventPath(event, path) {
|
|
108
|
+
return path.split(".").reduce((value, key) => {
|
|
109
|
+
if (value == null) return void 0;
|
|
110
|
+
return value[key];
|
|
111
|
+
}, event);
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
exports.defineContainer = defineContainer;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* output-vue-wrapper v0.1.0-beta.6
|
|
3
|
+
* (c) 2026 baicie
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
**/
|
|
6
|
+
Object.defineProperties(exports, {
|
|
7
|
+
__esModule: { value: true },
|
|
8
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
9
|
+
});
|
|
10
|
+
let vue = require("vue");
|
|
11
|
+
//#region packages/web-c/output-vue-wrapper/src/runtime/defineContainer.ts
|
|
12
|
+
const EMPTY_PROP = Symbol();
|
|
13
|
+
const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP };
|
|
14
|
+
const UPDATE_MODEL_VALUE_EVENT = "update:modelValue";
|
|
15
|
+
const MODEL_VALUE = "modelValue";
|
|
16
|
+
function defineContainer(options) {
|
|
17
|
+
const { tagName, displayName, defineCustomElement, props: componentProps = [], events: emitProps = [], slots: slotNames = [], model, transformTag } = options;
|
|
18
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
19
|
+
const emits = [...emitProps];
|
|
20
|
+
const componentPropsMap = {};
|
|
21
|
+
for (const prop of componentProps) componentPropsMap[prop] = DEFAULT_EMPTY_PROP;
|
|
22
|
+
if (model) {
|
|
23
|
+
const updateEvent = getModelUpdateEvent(model.prop);
|
|
24
|
+
emits.push(updateEvent);
|
|
25
|
+
if (updateEvent !== UPDATE_MODEL_VALUE_EVENT) emits.push(UPDATE_MODEL_VALUE_EVENT);
|
|
26
|
+
componentPropsMap[MODEL_VALUE] = DEFAULT_EMPTY_PROP;
|
|
27
|
+
}
|
|
28
|
+
return (0, vue.defineComponent)((propsValue, { attrs, slots: allSlots, emit }) => {
|
|
29
|
+
const containerRef = (0, vue.ref)();
|
|
30
|
+
const listeners = [];
|
|
31
|
+
(0, vue.onMounted)(() => {
|
|
32
|
+
const el = containerRef.value;
|
|
33
|
+
if (!el) return;
|
|
34
|
+
for (const eventName of emitProps) {
|
|
35
|
+
const listener = (event) => {
|
|
36
|
+
emit(eventName, event);
|
|
37
|
+
};
|
|
38
|
+
el.addEventListener(eventName, listener);
|
|
39
|
+
listeners.push({
|
|
40
|
+
eventName,
|
|
41
|
+
listener
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
(0, vue.onBeforeUnmount)(() => {
|
|
46
|
+
const el = containerRef.value;
|
|
47
|
+
if (!el) return;
|
|
48
|
+
for (const item of listeners) el.removeEventListener(item.eventName, item.listener);
|
|
49
|
+
listeners.length = 0;
|
|
50
|
+
});
|
|
51
|
+
const vModelDirective = { created: (el) => {
|
|
52
|
+
if (!model) return;
|
|
53
|
+
for (const eventName of toArray(model.event)) el.addEventListener(eventName, (event) => {
|
|
54
|
+
var _model$eventPath;
|
|
55
|
+
if (event.target.tagName !== el.tagName) return;
|
|
56
|
+
const value = readEventPath(event, (_model$eventPath = model.eventPath) !== null && _model$eventPath !== void 0 ? _model$eventPath : `target.${model.prop}`);
|
|
57
|
+
emit(getModelUpdateEvent(model.prop), value);
|
|
58
|
+
if (propsValue[MODEL_VALUE] !== EMPTY_PROP) emit(UPDATE_MODEL_VALUE_EVENT, value);
|
|
59
|
+
});
|
|
60
|
+
} };
|
|
61
|
+
return () => {
|
|
62
|
+
const propsToAdd = { ref: containerRef };
|
|
63
|
+
for (const key in propsValue) {
|
|
64
|
+
const value = propsValue[key];
|
|
65
|
+
if (value !== EMPTY_PROP) propsToAdd[key] = value;
|
|
66
|
+
}
|
|
67
|
+
for (const key in attrs) propsToAdd[key] = attrs[key];
|
|
68
|
+
if (model) {
|
|
69
|
+
const modelValue = propsValue[MODEL_VALUE];
|
|
70
|
+
const modelPropValue = propsValue[model.prop];
|
|
71
|
+
if (modelValue !== EMPTY_PROP) propsToAdd[model.prop] = modelValue;
|
|
72
|
+
else if (modelPropValue !== EMPTY_PROP) propsToAdd[model.prop] = modelPropValue;
|
|
73
|
+
}
|
|
74
|
+
const children = createChildren(allSlots, slotNames);
|
|
75
|
+
const node = (0, vue.h)(transformTag ? transformTag(tagName) : tagName, propsToAdd, children);
|
|
76
|
+
return model ? (0, vue.withDirectives)(node, [[vModelDirective]]) : node;
|
|
77
|
+
};
|
|
78
|
+
}, {
|
|
79
|
+
name: displayName !== null && displayName !== void 0 ? displayName : tagName,
|
|
80
|
+
props: componentPropsMap,
|
|
81
|
+
emits
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function createChildren(slots, slotNames) {
|
|
85
|
+
const children = slots.default ? slots.default() : [];
|
|
86
|
+
for (const name of slotNames) {
|
|
87
|
+
const slot = slots[name];
|
|
88
|
+
if (!slot) continue;
|
|
89
|
+
for (const vnode of slot()) children.push(withSlot(name, vnode));
|
|
90
|
+
}
|
|
91
|
+
return children;
|
|
92
|
+
}
|
|
93
|
+
function withSlot(name, vnode) {
|
|
94
|
+
if (!vnode) return vnode;
|
|
95
|
+
if (typeof vnode === "string") return (0, vue.h)("span", {
|
|
96
|
+
slot: name,
|
|
97
|
+
style: "display: contents"
|
|
98
|
+
}, vnode);
|
|
99
|
+
return (0, vue.cloneVNode)(vnode, { slot: name });
|
|
100
|
+
}
|
|
101
|
+
function getModelUpdateEvent(prop) {
|
|
102
|
+
return `update:${prop}`;
|
|
103
|
+
}
|
|
104
|
+
function toArray(value) {
|
|
105
|
+
return Array.isArray(value) ? value : [value];
|
|
106
|
+
}
|
|
107
|
+
function readEventPath(event, path) {
|
|
108
|
+
return path.split(".").reduce((value, key) => {
|
|
109
|
+
if (value == null) return void 0;
|
|
110
|
+
return value[key];
|
|
111
|
+
}, event);
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
exports.defineContainer = defineContainer;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as vue from 'vue';
|
|
2
|
+
|
|
3
|
+
export interface ZeusVueModelOptions {
|
|
4
|
+
prop: string;
|
|
5
|
+
event: string | string[];
|
|
6
|
+
eventPath?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ZeusVueContainerOptions {
|
|
9
|
+
tagName: string;
|
|
10
|
+
displayName?: string;
|
|
11
|
+
defineCustomElement?: () => void;
|
|
12
|
+
props?: string[];
|
|
13
|
+
events?: string[];
|
|
14
|
+
slots?: string[];
|
|
15
|
+
model?: ZeusVueModelOptions;
|
|
16
|
+
transformTag?: (tagName: string) => string;
|
|
17
|
+
}
|
|
18
|
+
export declare function defineContainer(options: ZeusVueContainerOptions): vue.DefineSetupFnComponent<{
|
|
19
|
+
[x: string]: /*elided*/ any;
|
|
20
|
+
}, string[], {}, {
|
|
21
|
+
[x: string]: /*elided*/ any;
|
|
22
|
+
} & {
|
|
23
|
+
[x: `on${Capitalize<string>}`]: ((...args: any[]) => any) | undefined;
|
|
24
|
+
}, vue.PublicProps>;
|
|
25
|
+
|
|
26
|
+
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* output-vue-wrapper v0.1.0-beta.6
|
|
3
|
+
* (c) 2026 baicie
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
**/
|
|
6
|
+
import { cloneVNode, defineComponent, h, onBeforeUnmount, onMounted, ref, withDirectives } from "vue";
|
|
7
|
+
//#region packages/web-c/output-vue-wrapper/src/runtime/defineContainer.ts
|
|
8
|
+
const EMPTY_PROP = Symbol();
|
|
9
|
+
const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP };
|
|
10
|
+
const UPDATE_MODEL_VALUE_EVENT = "update:modelValue";
|
|
11
|
+
const MODEL_VALUE = "modelValue";
|
|
12
|
+
function defineContainer(options) {
|
|
13
|
+
const { tagName, displayName, defineCustomElement, props: componentProps = [], events: emitProps = [], slots: slotNames = [], model, transformTag } = options;
|
|
14
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
15
|
+
const emits = [...emitProps];
|
|
16
|
+
const componentPropsMap = {};
|
|
17
|
+
for (const prop of componentProps) componentPropsMap[prop] = DEFAULT_EMPTY_PROP;
|
|
18
|
+
if (model) {
|
|
19
|
+
const updateEvent = getModelUpdateEvent(model.prop);
|
|
20
|
+
emits.push(updateEvent);
|
|
21
|
+
if (updateEvent !== UPDATE_MODEL_VALUE_EVENT) emits.push(UPDATE_MODEL_VALUE_EVENT);
|
|
22
|
+
componentPropsMap[MODEL_VALUE] = DEFAULT_EMPTY_PROP;
|
|
23
|
+
}
|
|
24
|
+
return defineComponent((propsValue, { attrs, slots: allSlots, emit }) => {
|
|
25
|
+
const containerRef = ref();
|
|
26
|
+
const listeners = [];
|
|
27
|
+
onMounted(() => {
|
|
28
|
+
const el = containerRef.value;
|
|
29
|
+
if (!el) return;
|
|
30
|
+
for (const eventName of emitProps) {
|
|
31
|
+
const listener = (event) => {
|
|
32
|
+
emit(eventName, event);
|
|
33
|
+
};
|
|
34
|
+
el.addEventListener(eventName, listener);
|
|
35
|
+
listeners.push({
|
|
36
|
+
eventName,
|
|
37
|
+
listener
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
onBeforeUnmount(() => {
|
|
42
|
+
const el = containerRef.value;
|
|
43
|
+
if (!el) return;
|
|
44
|
+
for (const item of listeners) el.removeEventListener(item.eventName, item.listener);
|
|
45
|
+
listeners.length = 0;
|
|
46
|
+
});
|
|
47
|
+
const vModelDirective = { created: (el) => {
|
|
48
|
+
if (!model) return;
|
|
49
|
+
for (const eventName of toArray(model.event)) el.addEventListener(eventName, (event) => {
|
|
50
|
+
var _model$eventPath;
|
|
51
|
+
if (event.target.tagName !== el.tagName) return;
|
|
52
|
+
const value = readEventPath(event, (_model$eventPath = model.eventPath) !== null && _model$eventPath !== void 0 ? _model$eventPath : `target.${model.prop}`);
|
|
53
|
+
emit(getModelUpdateEvent(model.prop), value);
|
|
54
|
+
if (propsValue[MODEL_VALUE] !== EMPTY_PROP) emit(UPDATE_MODEL_VALUE_EVENT, value);
|
|
55
|
+
});
|
|
56
|
+
} };
|
|
57
|
+
return () => {
|
|
58
|
+
const propsToAdd = { ref: containerRef };
|
|
59
|
+
for (const key in propsValue) {
|
|
60
|
+
const value = propsValue[key];
|
|
61
|
+
if (value !== EMPTY_PROP) propsToAdd[key] = value;
|
|
62
|
+
}
|
|
63
|
+
for (const key in attrs) propsToAdd[key] = attrs[key];
|
|
64
|
+
if (model) {
|
|
65
|
+
const modelValue = propsValue[MODEL_VALUE];
|
|
66
|
+
const modelPropValue = propsValue[model.prop];
|
|
67
|
+
if (modelValue !== EMPTY_PROP) propsToAdd[model.prop] = modelValue;
|
|
68
|
+
else if (modelPropValue !== EMPTY_PROP) propsToAdd[model.prop] = modelPropValue;
|
|
69
|
+
}
|
|
70
|
+
const children = createChildren(allSlots, slotNames);
|
|
71
|
+
const node = h(transformTag ? transformTag(tagName) : tagName, propsToAdd, children);
|
|
72
|
+
return model ? withDirectives(node, [[vModelDirective]]) : node;
|
|
73
|
+
};
|
|
74
|
+
}, {
|
|
75
|
+
name: displayName !== null && displayName !== void 0 ? displayName : tagName,
|
|
76
|
+
props: componentPropsMap,
|
|
77
|
+
emits
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function createChildren(slots, slotNames) {
|
|
81
|
+
const children = slots.default ? slots.default() : [];
|
|
82
|
+
for (const name of slotNames) {
|
|
83
|
+
const slot = slots[name];
|
|
84
|
+
if (!slot) continue;
|
|
85
|
+
for (const vnode of slot()) children.push(withSlot(name, vnode));
|
|
86
|
+
}
|
|
87
|
+
return children;
|
|
88
|
+
}
|
|
89
|
+
function withSlot(name, vnode) {
|
|
90
|
+
if (!vnode) return vnode;
|
|
91
|
+
if (typeof vnode === "string") return h("span", {
|
|
92
|
+
slot: name,
|
|
93
|
+
style: "display: contents"
|
|
94
|
+
}, vnode);
|
|
95
|
+
return cloneVNode(vnode, { slot: name });
|
|
96
|
+
}
|
|
97
|
+
function getModelUpdateEvent(prop) {
|
|
98
|
+
return `update:${prop}`;
|
|
99
|
+
}
|
|
100
|
+
function toArray(value) {
|
|
101
|
+
return Array.isArray(value) ? value : [value];
|
|
102
|
+
}
|
|
103
|
+
function readEventPath(event, path) {
|
|
104
|
+
return path.split(".").reduce((value, key) => {
|
|
105
|
+
if (value == null) return void 0;
|
|
106
|
+
return value[key];
|
|
107
|
+
}, event);
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
export { defineContainer };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* output-vue-wrapper v0.1.0-beta.6
|
|
3
|
+
* (c) 2026 baicie
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
**/
|
|
6
|
+
import { cloneVNode, defineComponent, h, onBeforeUnmount, onMounted, ref, withDirectives } from "vue";
|
|
7
|
+
//#region packages/web-c/output-vue-wrapper/src/runtime/defineContainer.ts
|
|
8
|
+
const EMPTY_PROP = Symbol();
|
|
9
|
+
const DEFAULT_EMPTY_PROP = { default: EMPTY_PROP };
|
|
10
|
+
const UPDATE_MODEL_VALUE_EVENT = "update:modelValue";
|
|
11
|
+
const MODEL_VALUE = "modelValue";
|
|
12
|
+
function defineContainer(options) {
|
|
13
|
+
const { tagName, displayName, defineCustomElement, props: componentProps = [], events: emitProps = [], slots: slotNames = [], model, transformTag } = options;
|
|
14
|
+
defineCustomElement === null || defineCustomElement === void 0 || defineCustomElement();
|
|
15
|
+
const emits = [...emitProps];
|
|
16
|
+
const componentPropsMap = {};
|
|
17
|
+
for (const prop of componentProps) componentPropsMap[prop] = DEFAULT_EMPTY_PROP;
|
|
18
|
+
if (model) {
|
|
19
|
+
const updateEvent = getModelUpdateEvent(model.prop);
|
|
20
|
+
emits.push(updateEvent);
|
|
21
|
+
if (updateEvent !== UPDATE_MODEL_VALUE_EVENT) emits.push(UPDATE_MODEL_VALUE_EVENT);
|
|
22
|
+
componentPropsMap[MODEL_VALUE] = DEFAULT_EMPTY_PROP;
|
|
23
|
+
}
|
|
24
|
+
return defineComponent((propsValue, { attrs, slots: allSlots, emit }) => {
|
|
25
|
+
const containerRef = ref();
|
|
26
|
+
const listeners = [];
|
|
27
|
+
onMounted(() => {
|
|
28
|
+
const el = containerRef.value;
|
|
29
|
+
if (!el) return;
|
|
30
|
+
for (const eventName of emitProps) {
|
|
31
|
+
const listener = (event) => {
|
|
32
|
+
emit(eventName, event);
|
|
33
|
+
};
|
|
34
|
+
el.addEventListener(eventName, listener);
|
|
35
|
+
listeners.push({
|
|
36
|
+
eventName,
|
|
37
|
+
listener
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
onBeforeUnmount(() => {
|
|
42
|
+
const el = containerRef.value;
|
|
43
|
+
if (!el) return;
|
|
44
|
+
for (const item of listeners) el.removeEventListener(item.eventName, item.listener);
|
|
45
|
+
listeners.length = 0;
|
|
46
|
+
});
|
|
47
|
+
const vModelDirective = { created: (el) => {
|
|
48
|
+
if (!model) return;
|
|
49
|
+
for (const eventName of toArray(model.event)) el.addEventListener(eventName, (event) => {
|
|
50
|
+
var _model$eventPath;
|
|
51
|
+
if (event.target.tagName !== el.tagName) return;
|
|
52
|
+
const value = readEventPath(event, (_model$eventPath = model.eventPath) !== null && _model$eventPath !== void 0 ? _model$eventPath : `target.${model.prop}`);
|
|
53
|
+
emit(getModelUpdateEvent(model.prop), value);
|
|
54
|
+
if (propsValue[MODEL_VALUE] !== EMPTY_PROP) emit(UPDATE_MODEL_VALUE_EVENT, value);
|
|
55
|
+
});
|
|
56
|
+
} };
|
|
57
|
+
return () => {
|
|
58
|
+
const propsToAdd = { ref: containerRef };
|
|
59
|
+
for (const key in propsValue) {
|
|
60
|
+
const value = propsValue[key];
|
|
61
|
+
if (value !== EMPTY_PROP) propsToAdd[key] = value;
|
|
62
|
+
}
|
|
63
|
+
for (const key in attrs) propsToAdd[key] = attrs[key];
|
|
64
|
+
if (model) {
|
|
65
|
+
const modelValue = propsValue[MODEL_VALUE];
|
|
66
|
+
const modelPropValue = propsValue[model.prop];
|
|
67
|
+
if (modelValue !== EMPTY_PROP) propsToAdd[model.prop] = modelValue;
|
|
68
|
+
else if (modelPropValue !== EMPTY_PROP) propsToAdd[model.prop] = modelPropValue;
|
|
69
|
+
}
|
|
70
|
+
const children = createChildren(allSlots, slotNames);
|
|
71
|
+
const node = h(transformTag ? transformTag(tagName) : tagName, propsToAdd, children);
|
|
72
|
+
return model ? withDirectives(node, [[vModelDirective]]) : node;
|
|
73
|
+
};
|
|
74
|
+
}, {
|
|
75
|
+
name: displayName !== null && displayName !== void 0 ? displayName : tagName,
|
|
76
|
+
props: componentPropsMap,
|
|
77
|
+
emits
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function createChildren(slots, slotNames) {
|
|
81
|
+
const children = slots.default ? slots.default() : [];
|
|
82
|
+
for (const name of slotNames) {
|
|
83
|
+
const slot = slots[name];
|
|
84
|
+
if (!slot) continue;
|
|
85
|
+
for (const vnode of slot()) children.push(withSlot(name, vnode));
|
|
86
|
+
}
|
|
87
|
+
return children;
|
|
88
|
+
}
|
|
89
|
+
function withSlot(name, vnode) {
|
|
90
|
+
if (!vnode) return vnode;
|
|
91
|
+
if (typeof vnode === "string") return h("span", {
|
|
92
|
+
slot: name,
|
|
93
|
+
style: "display: contents"
|
|
94
|
+
}, vnode);
|
|
95
|
+
return cloneVNode(vnode, { slot: name });
|
|
96
|
+
}
|
|
97
|
+
function getModelUpdateEvent(prop) {
|
|
98
|
+
return `update:${prop}`;
|
|
99
|
+
}
|
|
100
|
+
function toArray(value) {
|
|
101
|
+
return Array.isArray(value) ? value : [value];
|
|
102
|
+
}
|
|
103
|
+
function readEventPath(event, path) {
|
|
104
|
+
return path.split(".").reduce((value, key) => {
|
|
105
|
+
if (value == null) return void 0;
|
|
106
|
+
return value[key];
|
|
107
|
+
}, event);
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
export { defineContainer };
|
package/package.json
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeus-js/output-vue-wrapper",
|
|
3
|
-
"version": "0.1.0-beta.4",
|
|
4
|
-
"description": "Zeus Vue wrapper output plugin",
|
|
5
3
|
"type": "module",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
4
|
+
"version": "0.1.0-beta.6",
|
|
5
|
+
"description": "Zeus Vue wrapper output plugin",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/baicie/zeus.git",
|
|
10
|
+
"directory": "packages/web-c/output-vue-wrapper"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public",
|
|
14
|
+
"provenance": true
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": false,
|
|
13
17
|
"exports": {
|
|
14
18
|
".": {
|
|
15
19
|
"types": "./dist/output-vue-wrapper.d.ts",
|
|
@@ -21,25 +25,17 @@
|
|
|
21
25
|
"development": "./dist/output-vue-wrapper.cjs.js",
|
|
22
26
|
"default": "./index.js"
|
|
23
27
|
}
|
|
28
|
+
},
|
|
29
|
+
"./runtime": {
|
|
30
|
+
"types": "./dist/runtime/index.d.ts",
|
|
31
|
+
"import": "./dist/runtime/index.js",
|
|
32
|
+
"require": "./dist/runtime/index.cjs.js"
|
|
24
33
|
}
|
|
25
34
|
},
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
"buildOptions": {
|
|
32
|
-
"name": "ZeusOutputVueWrapper",
|
|
33
|
-
"formats": [
|
|
34
|
-
"esm-bundler",
|
|
35
|
-
"cjs"
|
|
36
|
-
]
|
|
37
|
-
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"@zeus-js/bundler-plugin": "0.1.0-beta.4",
|
|
40
|
-
"@zeus-js/component-dts": "0.1.0-beta.4",
|
|
41
|
-
"@zeus-js/component-analyzer": "0.1.0-beta.4"
|
|
42
|
-
},
|
|
35
|
+
"files": [
|
|
36
|
+
"index.js",
|
|
37
|
+
"dist"
|
|
38
|
+
],
|
|
43
39
|
"peerDependencies": {
|
|
44
40
|
"vue": ">=3"
|
|
45
41
|
},
|
|
@@ -48,11 +44,31 @@
|
|
|
48
44
|
"optional": true
|
|
49
45
|
}
|
|
50
46
|
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@zeus-js/bundler-plugin": "0.1.0-beta.6",
|
|
49
|
+
"@zeus-js/component-analyzer": "0.1.0-beta.6",
|
|
50
|
+
"@zeus-js/component-dts": "0.1.0-beta.6"
|
|
51
|
+
},
|
|
52
|
+
"author": "Baicie",
|
|
53
|
+
"buildOptions": {
|
|
54
|
+
"name": "ZeusOutputVueWrapper",
|
|
55
|
+
"formats": [
|
|
56
|
+
"esm-bundler",
|
|
57
|
+
"cjs"
|
|
58
|
+
],
|
|
59
|
+
"additionalEntries": [
|
|
60
|
+
{
|
|
61
|
+
"entry": "runtime/index.ts",
|
|
62
|
+
"output": "dist/runtime/index.js"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
},
|
|
51
66
|
"keywords": [
|
|
52
67
|
"zeus",
|
|
53
68
|
"vue",
|
|
54
69
|
"web-components"
|
|
55
70
|
],
|
|
56
|
-
"
|
|
57
|
-
"
|
|
71
|
+
"main": "index.js",
|
|
72
|
+
"module": "dist/output-vue-wrapper.esm-bundler.js",
|
|
73
|
+
"types": "dist/output-vue-wrapper.d.ts"
|
|
58
74
|
}
|