vite-plugin-vue-forward-slots 0.1.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 ADDED
@@ -0,0 +1,78 @@
1
+ # vite-plugin-vue-forward-slots
2
+
3
+ A tiny Vite plugin that transforms `<ForwardSlots />` into native Vue slot-forwarding template syntax.
4
+
5
+ ## Why this exists
6
+
7
+ There are many `ForwardSlots` component implementations, but in real projects we kept hitting reactivity and edge-case issues that were hard to fully solve in a runtime component.
8
+
9
+ This plugin avoids that class of problems by compiling `ForwardSlots` usage directly into native Vue template syntax at build time.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ bun install vite-plugin-vue-forward-slots
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```ts
20
+ // vite.config.ts
21
+ import { defineConfig } from 'vite'
22
+ import vue from '@vitejs/plugin-vue'
23
+ import forwardSlotsPlugin from 'vite-plugin-vue-forward-slots'
24
+
25
+ export default defineConfig({
26
+ plugins: [forwardSlotsPlugin(), vue()],
27
+ })
28
+ ```
29
+
30
+ ## Supported syntax
31
+
32
+ Both forms are supported:
33
+
34
+ ```vue
35
+ <ForwardSlots />
36
+ <forward-slots></forward-slots>
37
+ ```
38
+
39
+ You can also forward from a custom slots object:
40
+
41
+ ```vue
42
+ <ForwardSlots :slots="resolvedSlots" />
43
+ ```
44
+
45
+ ## Transform example
46
+
47
+ Input:
48
+
49
+ ```vue
50
+ <template>
51
+ <ForwardSlots :slots="resolvedSlots" />
52
+ </template>
53
+ ```
54
+
55
+ Output:
56
+
57
+ ```vue
58
+ <template>
59
+ <template v-for="(slot,_idx) in Object.keys(resolvedSlots)" :key="_idx" v-slot:[slot]="slotProps">
60
+ <slot :name="slot" v-bind="slotProps"></slot>
61
+ </template>
62
+ </template>
63
+ ```
64
+
65
+ ## Development
66
+
67
+ ```bash
68
+ bun install
69
+ bun test
70
+ bun run build
71
+ ```
72
+
73
+ ## Publish checklist
74
+
75
+ ```bash
76
+ bun test
77
+ bun run build
78
+ ```
@@ -0,0 +1,12 @@
1
+ declare module '@vue/runtime-core' {
2
+ interface GlobalComponents {
3
+ ForwardSlots: DefineComponent<{
4
+ slots: Record<string, unknown>;
5
+ }>;
6
+ }
7
+ }
8
+ export default function forwardSlotsPlugin(): {
9
+ name: string;
10
+ enforce: string;
11
+ transform(code: string, id: string): string | undefined;
12
+ };
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ import { parse as parseSFC } from '@vue/compiler-sfc';
2
+ const FORWARD_SLOTS_TAG_RE = /<\s*forward-?slots\b([^>]*)\s*(?:\/>|>\s*<\/\s*forward-?slots\s*>)/gi;
3
+ function getSlotsExpression(attributes) {
4
+ const match = attributes.match(/(?:^|\s):slots\s*=\s*(?:"([^"]+)"|'([^']+)')/);
5
+ return match?.[1] || match?.[2] || '$slots';
6
+ }
7
+ export default function forwardSlotsPlugin() {
8
+ return {
9
+ name: 'vite-plugin-vue-forward-slots',
10
+ enforce: 'pre',
11
+ transform(code, id) {
12
+ if (!id.endsWith('.vue'))
13
+ return;
14
+ const { descriptor } = parseSFC(code);
15
+ if (!descriptor.template)
16
+ return;
17
+ const template = descriptor.template.content;
18
+ const replaced = template.replace(FORWARD_SLOTS_TAG_RE, (_, attributes) => {
19
+ const expr = getSlotsExpression(attributes || '');
20
+ return `
21
+ <template v-for="(slot,_idx) in Object.keys(${expr})" :key="_idx" v-slot:[slot]="slotProps">
22
+ <slot :name="slot" v-bind="slotProps"></slot>
23
+ </template>
24
+ `;
25
+ });
26
+ if (replaced === template)
27
+ return;
28
+ return code.replace(template, replaced);
29
+ },
30
+ };
31
+ }
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "vite-plugin-vue-forward-slots",
3
+ "author": "Genesis Studio LLC <studio@gnz.is> (https://studio.gnz.is)",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/021-projects/vite-plugin-vue-forward-slots.git"
7
+ },
8
+ "version": "0.1.0",
9
+ "description": "Vite plugin that compiles <ForwardSlots> into native Vue slot forwarding syntax.",
10
+ "license": "MIT",
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.build.json",
27
+ "test": "vitest run",
28
+ "typecheck": "tsc --noEmit",
29
+ "prepublishOnly": "bun run build && bun run test"
30
+ },
31
+ "devDependencies": {
32
+ "@vue/compiler-dom": "^3.5.31",
33
+ "@vue/compiler-sfc": "^3.5.31",
34
+ "typescript": "^5.8.3",
35
+ "vitest": "^3.2.4"
36
+ },
37
+ "peerDependencies": {
38
+ "vite": "^5 || ^6 || ^7",
39
+ "vue": "^3.3.0"
40
+ },
41
+ "funding": [
42
+ {
43
+ "type": "individual",
44
+ "url": "https://btcpay.gnz.is/apps/2iTijXXYdXMZstbGV8RtdXceWDEc/crowdfund"
45
+ }
46
+ ]
47
+ }