vue-unwrap 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -13
- package/dist/index.d.ts +12 -31
- package/dist/index.js +14 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,11 +31,14 @@ import { getNodeElement, Unwrap } from 'vue-unwrap'
|
|
|
31
31
|
|
|
32
32
|
const ctx = useTemplateRef<typeof Unwrap>('ctx')
|
|
33
33
|
|
|
34
|
-
const
|
|
34
|
+
const childElements = computed(() => ctx.value?.children.map(getNodeElement))
|
|
35
|
+
const rootElement = computed(() => ctx.value?.root)
|
|
35
36
|
</script>
|
|
36
37
|
|
|
37
38
|
<template>
|
|
38
|
-
<Unwrap ref="ctx"
|
|
39
|
+
<Unwrap ref="ctx" is="div">
|
|
40
|
+
<p>Lorem ipsum</p>
|
|
41
|
+
</Unwrap>
|
|
39
42
|
</template>
|
|
40
43
|
|
|
41
44
|
```
|
|
@@ -45,25 +48,21 @@ const $children = computed(() => ctx.value?.children.map(getNodeElement))
|
|
|
45
48
|
```vue
|
|
46
49
|
<script setup lang="ts">
|
|
47
50
|
import type { ComponentPublicInstance } from 'vue'
|
|
48
|
-
import {
|
|
51
|
+
import { computed } from 'vue'
|
|
52
|
+
import { useUnwrap, type NodeRef } from 'vue-unwrap'
|
|
49
53
|
|
|
50
54
|
// your component props definition
|
|
51
|
-
type PropsType = { foo: string }
|
|
55
|
+
type PropsType = { foo: string }
|
|
52
56
|
|
|
53
57
|
// your child nodes definition
|
|
54
|
-
type CustomNodeType =
|
|
55
|
-
| ComponentPublicInstance<{ bar: string }>
|
|
56
|
-
| ComponentPublicInstance
|
|
57
|
-
| Element
|
|
58
|
-
| null
|
|
59
|
-
)
|
|
58
|
+
type CustomNodeType = ComponentPublicInstance<{ bar: string }> | NodeRef
|
|
60
59
|
|
|
61
60
|
const props = defineProps<PropsType>()
|
|
62
61
|
|
|
63
|
-
const {
|
|
62
|
+
const { root, children, Unwrap } = useUnwrap<CustomNodeType, PropsType>()
|
|
64
63
|
|
|
65
64
|
const bars = computed(() => (
|
|
66
|
-
children
|
|
65
|
+
children
|
|
67
66
|
.map(child => (
|
|
68
67
|
(child && 'bar' in child)
|
|
69
68
|
? `${props.foo}-${child.bar}`
|
|
@@ -79,6 +78,63 @@ const bars = computed(() => (
|
|
|
79
78
|
|
|
80
79
|
```
|
|
81
80
|
|
|
81
|
+
## API
|
|
82
|
+
|
|
83
|
+
### `Unwrap`
|
|
84
|
+
|
|
85
|
+
Conditional wrapper component. Pass **`is`** to render a wrapper element or component; omit it to render slot children directly with no extra DOM node.
|
|
86
|
+
|
|
87
|
+
When used with a template ref, the component instance exposes:
|
|
88
|
+
|
|
89
|
+
| Property | Type | Description |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| `children` | `NodeRef[]` | Reactive refs to each unwrapped child node |
|
|
92
|
+
| `root` | `Element \| null` | The wrapper DOM element when `is` is set; otherwise `null` |
|
|
93
|
+
|
|
94
|
+
Remaining attributes (except `is`) are forwarded to the wrapper when one is rendered.
|
|
95
|
+
|
|
96
|
+
### `useUnwrap<N, P>(propTypes?)`
|
|
97
|
+
|
|
98
|
+
Composable for building custom wrapper components. Returns `{ children, root, Unwrap }` with the same semantics as the component above.
|
|
99
|
+
|
|
100
|
+
- **`N`** — type of each entry in `children` (defaults to `NodeRef`)
|
|
101
|
+
- **`P`** — props type passed to the default slot render function
|
|
102
|
+
- **`propTypes`** — optional Vue props definition merged onto the returned `Unwrap` render function, so declared props are forwarded to slot content
|
|
103
|
+
|
|
104
|
+
```vue
|
|
105
|
+
<script setup lang="ts">
|
|
106
|
+
import { useUnwrap, type NodeRef } from 'vue-unwrap'
|
|
107
|
+
|
|
108
|
+
const { Unwrap } = useUnwrap<NodeRef, { count: number }>({
|
|
109
|
+
count: { type: Number, default: 0 },
|
|
110
|
+
})
|
|
111
|
+
</script>
|
|
112
|
+
|
|
113
|
+
<template>
|
|
114
|
+
<Unwrap :count="3" v-slot="{ count }">
|
|
115
|
+
<span>{{ count }} items</span>
|
|
116
|
+
</Unwrap>
|
|
117
|
+
</template>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Use the returned **`Unwrap`** in your template as the render target (typically with `<Unwrap />` and a default slot).
|
|
121
|
+
|
|
122
|
+
### `NodeRef`
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
type NodeRef = Element | ComponentPublicInstance | null
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Default type for entries in `children`.
|
|
129
|
+
|
|
130
|
+
### `getNodeElement(node)`
|
|
131
|
+
|
|
132
|
+
Resolves a child ref to its DOM `Element`. For component instances, returns `$el`; for plain elements, returns the element itself; otherwise returns `null`.
|
|
133
|
+
|
|
134
|
+
### `unwrapVNodes(vnodes)`
|
|
135
|
+
|
|
136
|
+
Utility that flattens slot VNodes into a flat array, unwrapping `Fragment` nodes and skipping comments and empty values. Used internally by `useUnwrap`; exported for advanced custom render logic.
|
|
137
|
+
|
|
82
138
|
## Development
|
|
83
139
|
|
|
84
140
|
- Install dependencies:
|
|
@@ -90,7 +146,7 @@ npm install
|
|
|
90
146
|
- Run the playground:
|
|
91
147
|
|
|
92
148
|
```bash
|
|
93
|
-
npm run
|
|
149
|
+
npm run play
|
|
94
150
|
```
|
|
95
151
|
|
|
96
152
|
- Run the unit tests:
|
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
import * as _$vue from "vue";
|
|
2
2
|
import { ComponentPublicInstance, SetupContext, VNode, VNodeArrayChildren } from "vue";
|
|
3
3
|
|
|
4
|
-
//#region src/
|
|
4
|
+
//#region src/types.d.ts
|
|
5
5
|
type NodeRef = Element | ComponentPublicInstance | null;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/useUnwrap.d.ts
|
|
8
8
|
declare function useUnwrap<N = NodeRef, P = Record<string, any>>(propTypes?: Record<string, any>): {
|
|
9
|
-
$el: _$vue.ShallowRef<Element | null, Element | null>;
|
|
10
9
|
children: _$vue.ShallowReactive<N[]>;
|
|
11
|
-
|
|
12
|
-
el: Element | null;
|
|
13
|
-
children: _$vue.ShallowReactive<N[]>;
|
|
14
|
-
}>;
|
|
10
|
+
root: _$vue.ShallowRef<Element | null, Element | null>;
|
|
15
11
|
Unwrap: {
|
|
16
|
-
(props: P, context: SetupContext): VNode<_$vue.RendererNode, _$vue.RendererElement, {
|
|
12
|
+
(props: P, context: SetupContext): _$vue.VNode<_$vue.RendererNode, _$vue.RendererElement, {
|
|
17
13
|
[key: string]: any;
|
|
18
|
-
}> | VNode<_$vue.RendererNode, _$vue.RendererElement, {
|
|
14
|
+
}> | _$vue.VNode<_$vue.RendererNode, _$vue.RendererElement, {
|
|
19
15
|
[key: string]: any;
|
|
20
16
|
}>[];
|
|
21
17
|
inheritAttrs: boolean;
|
|
@@ -25,30 +21,15 @@ declare function useUnwrap<N = NodeRef, P = Record<string, any>>(propTypes?: Rec
|
|
|
25
21
|
};
|
|
26
22
|
};
|
|
27
23
|
//#endregion
|
|
24
|
+
//#region src/utils.d.ts
|
|
25
|
+
declare function getNodeElement<N = NodeRef>(node: N): Element | null;
|
|
26
|
+
declare function unwrapVNodes(vnodes: VNodeArrayChildren): VNode[];
|
|
27
|
+
//#endregion
|
|
28
28
|
//#region src/Unwrap.vue.d.ts
|
|
29
|
-
declare const
|
|
30
|
-
el: Element | null;
|
|
31
|
-
children: _$vue.ShallowReactive<NodeRef[]>;
|
|
32
|
-
}>;
|
|
33
|
-
type __VLS_Slots = {
|
|
34
|
-
default(props: {
|
|
35
|
-
dom: typeof dom;
|
|
36
|
-
}): any;
|
|
37
|
-
};
|
|
38
|
-
declare const __VLS_base: _$vue.DefineComponent<{}, {
|
|
39
|
-
$el: _$vue.ShallowRef<Element | null, Element | null>;
|
|
29
|
+
declare const __VLS_export: _$vue.DefineComponent<{}, {
|
|
40
30
|
children: _$vue.ShallowReactive<NodeRef[]>;
|
|
41
|
-
|
|
42
|
-
el: Element | null;
|
|
43
|
-
children: _$vue.ShallowReactive<NodeRef[]>;
|
|
44
|
-
}>;
|
|
31
|
+
root: _$vue.ShallowRef<Element | null, Element | null>;
|
|
45
32
|
}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
|
|
46
|
-
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
47
33
|
declare const _default: typeof __VLS_export;
|
|
48
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
49
|
-
new (): {
|
|
50
|
-
$slots: S;
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
34
|
//#endregion
|
|
54
35
|
export { NodeRef, _default as Unwrap, getNodeElement, unwrapVNodes, useUnwrap };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Comment, Fragment, cloneVNode,
|
|
2
|
-
//#region src/
|
|
1
|
+
import { Comment, Fragment, cloneVNode, createBlock, defineComponent, h, isVNode, openBlock, shallowReactive, shallowRef, unref, useSlots } from "vue";
|
|
2
|
+
//#region src/utils.ts
|
|
3
3
|
function getNodeElement(node) {
|
|
4
4
|
const el = node?.$el || node;
|
|
5
5
|
return el instanceof Element ? el : null;
|
|
@@ -18,29 +18,26 @@ function unwrapVNodes(vnodes) {
|
|
|
18
18
|
}
|
|
19
19
|
return nodes;
|
|
20
20
|
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/useUnwrap.ts
|
|
21
23
|
function useUnwrap(propTypes) {
|
|
22
|
-
const $el = shallowRef(null);
|
|
23
24
|
const children = shallowReactive([]);
|
|
24
|
-
const
|
|
25
|
-
el: $el.value,
|
|
26
|
-
children
|
|
27
|
-
}));
|
|
25
|
+
const root = shallowRef(null);
|
|
28
26
|
const slots = useSlots();
|
|
29
27
|
const trackChildRef = (index) => (node) => children[index] = node;
|
|
30
|
-
const
|
|
28
|
+
const trackRootRef = (node) => root.value = getNodeElement(node);
|
|
31
29
|
function Unwrap(props, context) {
|
|
32
30
|
const { is, ...attrs } = context.attrs;
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
children.splice(
|
|
36
|
-
return
|
|
31
|
+
const childNodes = unwrapVNodes(slots.default?.(props) ?? []).map((node, i) => cloneVNode(node, { ref: trackChildRef(i) }, true));
|
|
32
|
+
const rootNode = is ? cloneVNode(h(is, attrs, childNodes), { ref: trackRootRef }, true) : null;
|
|
33
|
+
children.splice(childNodes.length);
|
|
34
|
+
return rootNode || childNodes;
|
|
37
35
|
}
|
|
38
36
|
Unwrap.inheritAttrs = false;
|
|
39
37
|
Unwrap.props = { ...propTypes };
|
|
40
38
|
return {
|
|
41
|
-
$el,
|
|
42
39
|
children,
|
|
43
|
-
|
|
40
|
+
root,
|
|
44
41
|
Unwrap
|
|
45
42
|
};
|
|
46
43
|
}
|
|
@@ -49,14 +46,13 @@ function useUnwrap(propTypes) {
|
|
|
49
46
|
var Unwrap_default = /* @__PURE__ */ defineComponent({
|
|
50
47
|
__name: "Unwrap",
|
|
51
48
|
setup(__props, { expose: __expose }) {
|
|
52
|
-
const {
|
|
49
|
+
const { children, root, Unwrap } = useUnwrap();
|
|
53
50
|
__expose({
|
|
54
|
-
$el,
|
|
55
51
|
children,
|
|
56
|
-
|
|
52
|
+
root
|
|
57
53
|
});
|
|
58
54
|
return (_ctx, _cache) => {
|
|
59
|
-
return openBlock(), createBlock(unref(Unwrap)
|
|
55
|
+
return openBlock(), createBlock(unref(Unwrap));
|
|
60
56
|
};
|
|
61
57
|
}
|
|
62
58
|
});
|
package/package.json
CHANGED