@poveste/plugin-svelte 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.
Files changed (71) hide show
  1. package/LICENSE +22 -0
  2. package/assets/histoire-svelte-text.svg +89 -0
  3. package/assets/histoire-svelte.svg +52 -0
  4. package/dist/client/MountStory.js +1 -0
  5. package/dist/client/MountStory.svelte +24 -0
  6. package/dist/client/MountVariant.js +1 -0
  7. package/dist/client/MountVariant.svelte +47 -0
  8. package/dist/client/RenderStory.js +1 -0
  9. package/dist/client/RenderStory.svelte +27 -0
  10. package/dist/client/RenderVariant.js +1 -0
  11. package/dist/client/RenderVariant.svelte +32 -0
  12. package/dist/client/Stub.js +1 -0
  13. package/dist/client/Stub.svelte +0 -0
  14. package/dist/client/Wrap.js +1 -0
  15. package/dist/client/Wrap.svelte +63 -0
  16. package/dist/client/index.d.ts +8 -0
  17. package/dist/client/index.js +1 -0
  18. package/dist/client/mount.d.ts +16 -0
  19. package/dist/client/mount.js +1 -0
  20. package/dist/client/render.d.ts +34 -0
  21. package/dist/client/render.js +1 -0
  22. package/dist/client/util.d.ts +4 -0
  23. package/dist/client/util.js +1 -0
  24. package/dist/collect/Story.js +1 -0
  25. package/dist/collect/Story.svelte +34 -0
  26. package/dist/collect/Variant.js +1 -0
  27. package/dist/collect/Variant.svelte +24 -0
  28. package/dist/collect/index.d.ts +2 -0
  29. package/dist/collect/index.js +1 -0
  30. package/dist/commands/generate-story.client.d.ts +3 -0
  31. package/dist/commands/generate-story.client.js +27 -0
  32. package/dist/commands/generate-story.server.d.ts +3 -0
  33. package/dist/commands/generate-story.server.js +52 -0
  34. package/dist/helpers.d.ts +87 -0
  35. package/dist/helpers.js +6 -0
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +1 -0
  38. package/dist/index.node.d.ts +3 -0
  39. package/dist/index.node.js +90 -0
  40. package/dist/util/list-components.d.ts +1 -0
  41. package/dist/util/list-components.js +15 -0
  42. package/dist/util/story-hmr.d.ts +7 -0
  43. package/dist/util/story-hmr.js +30 -0
  44. package/dist/util/svelte.d.ts +18 -0
  45. package/dist/util/svelte.js +102 -0
  46. package/package.json +57 -0
  47. package/src/client/MountStory.svelte +24 -0
  48. package/src/client/MountVariant.svelte +47 -0
  49. package/src/client/RenderStory.svelte +27 -0
  50. package/src/client/RenderVariant.svelte +32 -0
  51. package/src/client/Stub.svelte +0 -0
  52. package/src/client/Wrap.svelte +63 -0
  53. package/src/client/index.ts +12 -0
  54. package/src/client/mount.ts +113 -0
  55. package/src/client/render.ts +191 -0
  56. package/src/client/util.ts +52 -0
  57. package/src/collect/Story.svelte +34 -0
  58. package/src/collect/Variant.svelte +24 -0
  59. package/src/collect/index.ts +53 -0
  60. package/src/commands/generate-story.client.ts +29 -0
  61. package/src/commands/generate-story.server.ts +62 -0
  62. package/src/helpers.ts +96 -0
  63. package/src/index.node.ts +101 -0
  64. package/src/index.ts +1 -0
  65. package/src/util/list-components.ts +16 -0
  66. package/src/util/story-hmr.ts +52 -0
  67. package/src/util/svelte.ts +137 -0
  68. package/svelte.config.js +5 -0
  69. package/tsconfig.build.json +7 -0
  70. package/tsconfig.json +41 -0
  71. package/vite.config.ts +103 -0
@@ -0,0 +1,52 @@
1
+ import fs from 'node:fs';
2
+ import launchEditor from 'launch-editor';
3
+ import path from 'pathe';
4
+ export default {
5
+ id: 'histoire:plugin-svelte:generate-story',
6
+ label: 'Generate Svelte story from component',
7
+ icon: 'https://svelte.dev/favicon.png',
8
+ searchText: 'generate create',
9
+ async serverAction(params) {
10
+ const targetFile = path.join(path.dirname(params.component), params.fileName);
11
+ if (fs.existsSync(targetFile)) {
12
+ throw new Error(`File ${targetFile} already exists`);
13
+ }
14
+ const { component, componentName, isTs } = await getComponentInfo(params.component);
15
+ const content = `<script${isTs ? ' lang="ts"' : ''}>
16
+ ${isTs
17
+ ? `import type { Hst } from '@poveste/plugin-svelte'\n
18
+ `
19
+ : ''}import ${componentName} from './${component}'
20
+
21
+ export let Hst${isTs ? ': Hst' : ''}
22
+ </script>
23
+
24
+ <Hst.Story>
25
+ <Hst.Variant title="Default">
26
+ <${componentName} />
27
+
28
+ <svelte:fragment slot="controls">
29
+ <!-- Put controls here -->
30
+ </svelte:fragment>
31
+ </Hst.Variant>
32
+ </Hst.Story>
33
+ `;
34
+ await fs.promises.writeFile(targetFile, content, 'utf-8');
35
+ launchEditor(targetFile);
36
+ },
37
+ clientSetupFile: '@poveste/plugin-svelte/dist/commands/generate-story.client.js',
38
+ };
39
+ async function isComponentTs(component) {
40
+ const componentContent = await fs.promises.readFile(component, 'utf-8');
41
+ return componentContent.includes('lang="ts"');
42
+ }
43
+ async function getComponentInfo(file) {
44
+ const component = path.basename(file);
45
+ const componentName = component.replace(path.extname(component), '');
46
+ const isTs = await isComponentTs(file);
47
+ return {
48
+ component,
49
+ componentName,
50
+ isTs,
51
+ };
52
+ }
@@ -0,0 +1,87 @@
1
+ import type { HstControlOption } from '@poveste/controls';
2
+ import type { Story, StoryProps, Variant, VariantProps } from '@poveste/shared';
3
+ import type { SvelteComponentTyped } from 'svelte';
4
+ export interface SvelteStorySetupApi {
5
+ app: any;
6
+ story?: Story;
7
+ variant?: Variant;
8
+ }
9
+ export type SvelteStorySetupHandler = (api: SvelteStorySetupApi) => Promise<void> | void;
10
+ export declare function defineSetupSvelte(handler: SvelteStorySetupHandler): SvelteStorySetupHandler;
11
+ export declare const defineSetupSvelte3: typeof defineSetupSvelte;
12
+ export declare const defineSetupSvelte4: typeof defineSetupSvelte;
13
+ export declare const defineSetupSvelte5: typeof defineSetupSvelte;
14
+ export interface Hst {
15
+ Story: typeof SvelteComponentTyped<StoryProps>;
16
+ Variant: typeof SvelteComponentTyped<VariantProps>;
17
+ Button: typeof SvelteComponentTyped;
18
+ ButtonGroup: typeof SvelteComponentTyped<{
19
+ value?: string;
20
+ options: (string | HstControlOption)[];
21
+ title?: string;
22
+ }>;
23
+ Checkbox: typeof SvelteComponentTyped<{
24
+ value?: boolean;
25
+ title: string;
26
+ }>;
27
+ CheckboxList: typeof SvelteComponentTyped<{
28
+ value: string[];
29
+ options: (string | HstControlOption)[];
30
+ title?: string;
31
+ }>;
32
+ Text: typeof SvelteComponentTyped<{
33
+ value?: string;
34
+ title: string;
35
+ }>;
36
+ Number: typeof SvelteComponentTyped<{
37
+ value?: number;
38
+ title: string;
39
+ step?: number;
40
+ }>;
41
+ Slider: typeof SvelteComponentTyped<{
42
+ value?: number;
43
+ title: string;
44
+ min: number;
45
+ max: number;
46
+ step?: number;
47
+ }>;
48
+ Textarea: typeof SvelteComponentTyped<{
49
+ value?: string;
50
+ title: string;
51
+ }>;
52
+ Select: typeof SvelteComponentTyped<{
53
+ value?: string;
54
+ title: string;
55
+ options: Record<string, any> | string[] | HstControlOption[];
56
+ }>;
57
+ Radio: typeof SvelteComponentTyped<{
58
+ value?: string;
59
+ options: HstControlOption[];
60
+ title?: string;
61
+ }>;
62
+ Json: typeof SvelteComponentTyped<{
63
+ value: unknown;
64
+ title: string;
65
+ }>;
66
+ Shades: typeof SvelteComponentTyped<{
67
+ shades: Record<string, any>;
68
+ getName?: (key: string, color: string) => string;
69
+ search?: string;
70
+ }>;
71
+ TokenList: typeof SvelteComponentTyped<{
72
+ tokens: Record<string, string | number | any[] | Record<string, any>>;
73
+ getName?: (key: string, value: string | number | any[] | Record<string, any>) => string;
74
+ }>;
75
+ TokenGrid: typeof SvelteComponentTyped<{
76
+ tokens: Record<string, string | number | any[] | Record<string, any>>;
77
+ getName?: (key: string, value: string | number | any[] | Record<string, any>) => string;
78
+ colSize?: number;
79
+ }>;
80
+ CopyIcon: typeof SvelteComponentTyped<{
81
+ content: string;
82
+ }>;
83
+ ColorSelect: typeof SvelteComponentTyped<{
84
+ value?: string;
85
+ title: string;
86
+ }>;
87
+ }
@@ -0,0 +1,6 @@
1
+ export function defineSetupSvelte(handler) {
2
+ return handler;
3
+ }
4
+ export const defineSetupSvelte3 = defineSetupSvelte;
5
+ export const defineSetupSvelte4 = defineSetupSvelte;
6
+ export const defineSetupSvelte5 = defineSetupSvelte;
@@ -0,0 +1 @@
1
+ export * from './helpers.js';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './helpers.js';
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from 'poveste';
2
+ export declare function HstSvelte(): Plugin;
3
+ export * from './helpers.js';
@@ -0,0 +1,90 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { createRequire } from 'node:module';
3
+ import { dirname, join } from 'pathe';
4
+ import { defaultColors } from 'poveste';
5
+ import generateStoryCommand from './commands/generate-story.server.js';
6
+ import { listComponentFiles } from './util/list-components.js';
7
+ import { disableStoryComponentHmr } from './util/story-hmr.js';
8
+ export function HstSvelte() {
9
+ return {
10
+ name: '@poveste/plugin-svelte',
11
+ defaultConfig() {
12
+ const svelteClientAliases = getSvelteClientAliases();
13
+ return {
14
+ supportMatch: [
15
+ {
16
+ id: 'svelte',
17
+ patterns: ['**/*.svelte'],
18
+ pluginIds: ['svelte4'],
19
+ },
20
+ ],
21
+ theme: {
22
+ colors: {
23
+ primary: defaultColors.orange,
24
+ },
25
+ logo: {
26
+ square: '@poveste/plugin-svelte/assets/histoire-svelte.svg',
27
+ light: '@poveste/plugin-svelte/assets/histoire-svelte-text.svg',
28
+ dark: '@poveste/plugin-svelte/assets/histoire-svelte-text.svg',
29
+ },
30
+ },
31
+ viteIgnorePlugins: [
32
+ 'vite-plugin-sveltekit-compile',
33
+ ],
34
+ vite: svelteClientAliases.length
35
+ ? {
36
+ plugins: [
37
+ disableStoryComponentHmr(),
38
+ ],
39
+ resolve: {
40
+ alias: svelteClientAliases,
41
+ },
42
+ }
43
+ : {
44
+ plugins: [
45
+ disableStoryComponentHmr(),
46
+ ],
47
+ },
48
+ };
49
+ },
50
+ supportPlugin: {
51
+ id: 'svelte4',
52
+ moduleName: '@poveste/plugin-svelte',
53
+ setupFn: ['setupSvelte3', 'setupSvelte4', 'setupSvelte5'],
54
+ importStoryComponent: (file, index) => `import Comp${index} from ${JSON.stringify(file.moduleId)}`,
55
+ },
56
+ commands: [
57
+ generateStoryCommand,
58
+ ],
59
+ async onDevEvent(api) {
60
+ switch (api.event) {
61
+ case 'listSvelteComponents': {
62
+ return listComponentFiles(api.payload.search, api.getConfig().storyMatch);
63
+ }
64
+ }
65
+ },
66
+ };
67
+ }
68
+ export * from './helpers.js';
69
+ function getSvelteClientAliases() {
70
+ try {
71
+ const require = createRequire(join(process.cwd(), 'package.json'));
72
+ const sveltePackagePath = require.resolve('svelte/package.json');
73
+ const svelteDir = dirname(sveltePackagePath);
74
+ const aliasEntries = [
75
+ [/^svelte$/, join(svelteDir, 'src/index-client.js')],
76
+ [/^svelte\/legacy$/, join(svelteDir, 'src/legacy/legacy-client.js')],
77
+ [/^svelte\/store$/, join(svelteDir, 'src/store/index-client.js')],
78
+ [/^svelte\/reactivity$/, join(svelteDir, 'src/reactivity/index-client.js')],
79
+ ];
80
+ return aliasEntries
81
+ .filter(([, replacement]) => existsSync(replacement))
82
+ .map(([find, replacement]) => ({
83
+ find,
84
+ replacement,
85
+ }));
86
+ }
87
+ catch {
88
+ return [];
89
+ }
90
+ }
@@ -0,0 +1 @@
1
+ export declare function listComponentFiles(search?: string, ignore?: string[], limit?: number): Promise<string[]>;
@@ -0,0 +1,15 @@
1
+ import { globby } from 'globby';
2
+ export async function listComponentFiles(search = '', ignore = [], limit = 10) {
3
+ let files = await globby('**/*.svelte', {
4
+ gitignore: true,
5
+ ignore: [
6
+ 'node_modules',
7
+ ...ignore,
8
+ ],
9
+ });
10
+ if (search) {
11
+ const searchText = search.toLowerCase();
12
+ files = files.filter(file => file.toLowerCase().includes(searchText));
13
+ }
14
+ return files.slice(0, limit);
15
+ }
@@ -0,0 +1,7 @@
1
+ export declare function disableStoryComponentHmr(): {
2
+ name: string;
3
+ apply: "serve";
4
+ configResolved(config: {
5
+ readonly plugins: readonly unknown[];
6
+ }): void;
7
+ };
@@ -0,0 +1,30 @@
1
+ const storyFileRE = /\.story\.svelte$/;
2
+ export function disableStoryComponentHmr() {
3
+ return {
4
+ name: 'histoire:svelte-story-hmr',
5
+ apply: 'serve',
6
+ configResolved(config) {
7
+ for (const plugin of config.plugins) {
8
+ if (plugin.name !== 'vite-plugin-svelte:config' || plugin.__histoireStoryHmrPatched) {
9
+ continue;
10
+ }
11
+ const options = plugin.api?.options;
12
+ if (!options) {
13
+ continue;
14
+ }
15
+ const originalDynamicCompileOptions = options.dynamicCompileOptions;
16
+ options.dynamicCompileOptions = async (data) => {
17
+ const result = await originalDynamicCompileOptions?.(data);
18
+ if (!storyFileRE.test(data.filename)) {
19
+ return result;
20
+ }
21
+ return {
22
+ ...result,
23
+ hmr: false,
24
+ };
25
+ };
26
+ plugin.__histoireStoryHmrPatched = true;
27
+ }
28
+ },
29
+ };
30
+ }
@@ -0,0 +1,18 @@
1
+ import type { SvelteStorySetupApi, SvelteStorySetupHandler } from '../helpers.js';
2
+ type SetupModule = Record<string, unknown>;
3
+ export interface MountedSvelteComponent {
4
+ app: any;
5
+ destroy: () => void;
6
+ }
7
+ export interface LegacyStateApi {
8
+ captureState: () => Record<string, any> | null;
9
+ injectState: (state: Record<string, any>) => void;
10
+ }
11
+ export declare function mountSvelteComponent(component: any, options: Record<string, any>, mode?: 'auto' | 'client' | 'server-compat'): Promise<MountedSvelteComponent>;
12
+ export declare function getLegacyStateApi(app: any): LegacyStateApi | null;
13
+ export declare function callSetupFunctions(generatedSetup: SetupModule, setup: SetupModule, setupApi: SvelteStorySetupApi, variantSetupApp?: SvelteStorySetupHandler | null): Promise<void>;
14
+ export declare function createWrappedComponent(Wrap: any, controlComponent: any): {
15
+ (anchorOrOptions: any, props?: any): any;
16
+ element: any;
17
+ };
18
+ export {};
@@ -0,0 +1,102 @@
1
+ import * as svelte from 'svelte';
2
+ const setupHookNames = [
3
+ 'setupSvelte3',
4
+ 'setupSvelte4',
5
+ 'setupSvelte5',
6
+ ];
7
+ function loadSvelteModule(moduleId) {
8
+ return import(/* @vite-ignore */ moduleId);
9
+ }
10
+ export async function mountSvelteComponent(component, options, mode = 'auto') {
11
+ if (mode !== 'server-compat') {
12
+ if (typeof svelte?.mount === 'function') {
13
+ const app = svelte.mount(component, options);
14
+ return {
15
+ app,
16
+ destroy: () => {
17
+ if (typeof svelte.unmount === 'function') {
18
+ ;
19
+ svelte.unmount(app);
20
+ }
21
+ else {
22
+ app?.$destroy?.();
23
+ }
24
+ },
25
+ };
26
+ }
27
+ }
28
+ try {
29
+ // eslint-disable-next-line new-cap
30
+ const app = new component(options);
31
+ return {
32
+ app,
33
+ destroy: () => {
34
+ app?.$destroy?.();
35
+ },
36
+ };
37
+ }
38
+ catch (error) {
39
+ const legacyModuleId = ['svelte', 'legacy'].join('/');
40
+ const legacy = await loadSvelteModule(legacyModuleId).catch(() => null);
41
+ if (typeof legacy?.createClassComponent === 'function') {
42
+ const app = legacy.createClassComponent({
43
+ component,
44
+ ...options,
45
+ });
46
+ return {
47
+ app,
48
+ destroy: () => {
49
+ app?.$destroy?.();
50
+ },
51
+ };
52
+ }
53
+ throw error;
54
+ }
55
+ }
56
+ export function getLegacyStateApi(app) {
57
+ if (typeof app?.$capture_state !== 'function' || typeof app?.$inject_state !== 'function') {
58
+ return null;
59
+ }
60
+ return {
61
+ captureState: () => app.$capture_state(),
62
+ injectState: (state) => {
63
+ app.$inject_state(state);
64
+ },
65
+ };
66
+ }
67
+ export async function callSetupFunctions(generatedSetup, setup, setupApi, variantSetupApp) {
68
+ for (const hookName of setupHookNames) {
69
+ const generatedHook = generatedSetup[hookName];
70
+ if (typeof generatedHook === 'function') {
71
+ await generatedHook(setupApi);
72
+ }
73
+ const setupHook = setup[hookName];
74
+ if (typeof setupHook === 'function') {
75
+ await setupHook(setupApi);
76
+ }
77
+ }
78
+ if (typeof variantSetupApp === 'function') {
79
+ await variantSetupApp(setupApi);
80
+ }
81
+ }
82
+ export function createWrappedComponent(Wrap, controlComponent) {
83
+ function ProxyWrap(anchorOrOptions, props) {
84
+ if (new.target) {
85
+ return new Wrap({
86
+ ...anchorOrOptions,
87
+ props: {
88
+ ...anchorOrOptions?.props,
89
+ controlComponent,
90
+ },
91
+ });
92
+ }
93
+ return Wrap(anchorOrOptions, {
94
+ ...props,
95
+ controlComponent,
96
+ });
97
+ }
98
+ if (Wrap?.element) {
99
+ ProxyWrap.element = Wrap.element;
100
+ }
101
+ return ProxyWrap;
102
+ }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@poveste/plugin-svelte",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "description": "Poveste plugin for Svelte 4/5 and SvelteKit support",
6
+ "author": {
7
+ "name": "Sorin Gitlan"
8
+ },
9
+ "license": "MIT",
10
+ "repository": {
11
+ "url": "https://github.com/poveste-dev/poveste.git",
12
+ "type": "git",
13
+ "directory": "packages/poveste-plugin-svelte"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "exports": {
19
+ "./client": "./dist/client/index.js",
20
+ "./collect": "./dist/collect/index.js",
21
+ ".": "./dist/index.node.js",
22
+ "./*": "./*"
23
+ },
24
+ "main": "./dist/index.node.js",
25
+ "module": "./dist/index.node.js",
26
+ "types": "./dist/index.node.d.ts",
27
+ "peerDependencies": {
28
+ "svelte": "^4.0.0 || ^5.0.0",
29
+ "poveste": "^0.1.0"
30
+ },
31
+ "dependencies": {
32
+ "change-case": "^5.4.4",
33
+ "globby": "^14.0.2",
34
+ "launch-editor": "^2.9.1",
35
+ "pathe": "^1.1.2",
36
+ "@poveste/shared": "^0.1.0",
37
+ "@poveste/controls": "^0.1.0",
38
+ "@poveste/vendors": "^0.1.0"
39
+ },
40
+ "devDependencies": {
41
+ "@sveltejs/vite-plugin-svelte": "^7.0.0",
42
+ "@types/node": "^22.10.1",
43
+ "concurrently": "^9.1.0",
44
+ "fs-extra": "^11.2.0",
45
+ "globby": "^14.0.2",
46
+ "svelte": "5.55.0",
47
+ "svelte-preprocess": "^6.0.3",
48
+ "typescript": "5.6.3",
49
+ "vite": "^8.0.0",
50
+ "poveste": "0.1.0"
51
+ },
52
+ "scripts": {
53
+ "build": "rimraf dist && vite build && tsc -d -P tsconfig.build.json && pnpm run build:types",
54
+ "build:types": "tsc --declaration --emitDeclarationOnly",
55
+ "watch": "concurrently \"vite build --watch\" \"tsc -d -P tsconfig.build.json --watch\" \"pnpm run build:types --watch\""
56
+ }
57
+ }
@@ -0,0 +1,24 @@
1
+ <script>
2
+ import { omitInheritStoryProps } from '@poveste/shared'
3
+ import { getContext, setContext } from 'svelte'
4
+ import MountVariant from './MountVariant.svelte'
5
+
6
+ const story = getContext('__hstStory')
7
+ let index = { value: 0 }
8
+ setContext('__hstIndex', index)
9
+ setContext('__hstSlots', $$slots)
10
+
11
+ $: inheritedFromStory = Object.keys(story).filter(key => !omitInheritStoryProps.includes(key)).reduce((acc, key) => {
12
+ acc[key] = story[key]
13
+ return acc
14
+ }, {})
15
+ </script>
16
+
17
+ {#if story.variants.length === 1 && story.variants[0].id === '_default'}
18
+ <MountVariant {...inheritedFromStory} {...$$restProps} implicit>
19
+ <slot />
20
+ <slot name="controls" slot="controls" />
21
+ </MountVariant>
22
+ {:else}
23
+ <slot />
24
+ {/if}
@@ -0,0 +1,47 @@
1
+ <script>
2
+ import { afterUpdate, getContext } from 'svelte'
3
+
4
+ export let source = null
5
+ export let responsiveDisabled = false
6
+ export let autoPropsDisabled = false
7
+ export let setupApp = null
8
+ export let implicit = false
9
+
10
+ const story = getContext('__hstStory')
11
+ const index = getContext('__hstIndex')
12
+ const storySlots = getContext('__hstSlots')
13
+
14
+ const variant = story.variants[index.value]
15
+ index.value++
16
+
17
+ function updateVariant () {
18
+ Object.assign(variant, {
19
+ slots: () => ({
20
+ default: true,
21
+ controls: $$slots.controls ?? storySlots.controls,
22
+ }),
23
+ source,
24
+ responsiveDisabled,
25
+ autoPropsDisabled,
26
+ setupApp,
27
+ configReady: true,
28
+ })
29
+
30
+ if (!implicit && !story.meta?.hasVariantChildComponents) {
31
+ story.meta = story.meta || {}
32
+ Object.assign(story.meta, {
33
+ hasVariantChildComponents: true,
34
+ })
35
+ }
36
+ }
37
+ updateVariant()
38
+
39
+ afterUpdate(() => {
40
+ updateVariant()
41
+ })
42
+ </script>
43
+
44
+ {#if false}
45
+ <slot />
46
+ <slot name="controls" />
47
+ {/if}
@@ -0,0 +1,27 @@
1
+ <script>
2
+ import { getContext, setContext } from 'svelte'
3
+
4
+ const story = getContext('__hstStory')
5
+ const currentVariant = getContext('__hstVariant')
6
+ const slotName = getContext('__hstSlot')
7
+
8
+ let index = { value: 0 }
9
+ setContext('__hstIndex', index)
10
+
11
+ export let source = null
12
+
13
+ $: {
14
+ if (source != null) {
15
+ Object.assign(currentVariant, {
16
+ source,
17
+ })
18
+ }
19
+ }
20
+ </script>
21
+
22
+ {#if slotName === 'controls'}
23
+ <slot name="controls" />
24
+ {/if}
25
+ {#if slotName === 'default' || story.meta?.hasVariantChildComponents}
26
+ <slot />
27
+ {/if}
@@ -0,0 +1,32 @@
1
+ <script>
2
+ import { getContext } from 'svelte'
3
+
4
+ const story = getContext('__hstStory')
5
+ const currentVariant = getContext('__hstVariant')
6
+ const slotName = getContext('__hstSlot')
7
+ const index = getContext('__hstIndex')
8
+
9
+ const variant = story.variants[index.value]
10
+ index.value++
11
+
12
+ $: shouldRender = currentVariant.id === variant.id
13
+
14
+ export let source = null
15
+
16
+ $: {
17
+ if (source != null) {
18
+ Object.assign(currentVariant, {
19
+ source,
20
+ })
21
+ }
22
+ }
23
+ </script>
24
+
25
+ {#if shouldRender}
26
+ {#if slotName === 'default'}
27
+ <slot />
28
+ {/if}
29
+ {#if slotName === 'controls'}
30
+ <slot name="controls" />
31
+ {/if}
32
+ {/if}
File without changes