diff --git a/code/frameworks/sveltekit/README.md b/code/frameworks/sveltekit/README.md index 467643ee1ae5..fd103c8764b1 100644 --- a/code/frameworks/sveltekit/README.md +++ b/code/frameworks/sveltekit/README.md @@ -29,7 +29,7 @@ However SvelteKit has some [Kit-specific modules](https://kit.svelte.dev/docs/mo | [`$app/forms`](https://kit.svelte.dev/docs/modules#$app-forms) | ⏳ Future | Will use mocks. Tracked in [#20999](https://github.com/storybookjs/storybook/issues/20999) | | [`$app/navigation`](https://kit.svelte.dev/docs/modules#$app-navigation) | ⏳ Future | Will use mocks. Tracked in [#20999](https://github.com/storybookjs/storybook/issues/20999) | | [`$app/paths`](https://kit.svelte.dev/docs/modules#$app-paths) | ✅ Supported | Requires SvelteKit 1.4.0 or newer | -| [`$app/stores`](https://kit.svelte.dev/docs/modules#$app-stores) | ✅ Supported | Mocks planned, so you can set different store values per story. | +| [`$app/stores`](https://kit.svelte.dev/docs/modules#$app-stores) | ✅ Supported | Mocks planned, so you can set different store values per story. | | [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. | | [`$env/dynamic/public`](https://kit.svelte.dev/docs/modules#$env-dynamic-public) | 🚧 Partially supported | Only supported in development mode. Storybook is built as a static app with no server-side API so cannot dynamically serve content. | | [`$env/static/private`](https://kit.svelte.dev/docs/modules#$env-static-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. | diff --git a/code/renderers/vue3/src/docs/sourceDecorator.ts b/code/renderers/vue3/src/docs/sourceDecorator.ts index f0e254f082ae..d1721024d7cb 100644 --- a/code/renderers/vue3/src/docs/sourceDecorator.ts +++ b/code/renderers/vue3/src/docs/sourceDecorator.ts @@ -247,6 +247,7 @@ export function generateTemplateSource( .map((child) => child.content) .join('') : ''; + const name = typeof type === 'string' ? type diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/UnionTypeProp.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/UnionTypeProp.stories.ts new file mode 100644 index 000000000000..b620d5c4eda0 --- /dev/null +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/UnionTypeProp.stories.ts @@ -0,0 +1,21 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import MyComponent from './UnionTypeProp.vue'; + +const meta: Meta = { + component: MyComponent, + argTypes: {}, + tags: ['autodocs'], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const UnionType: Story = { + args: { + label: 'UnionType', + stringOrNumber: 12, + booleanOrNumber: true, + multiple: { a: 1, b: 2 }, + }, +}; diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/UnionTypeProp.vue b/code/renderers/vue3/template/stories_vue3-vite-default-ts/UnionTypeProp.vue new file mode 100644 index 000000000000..59381b096a23 --- /dev/null +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/UnionTypeProp.vue @@ -0,0 +1,29 @@ + + + diff --git a/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx b/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx index be9b7e1c8a46..d56b9ca3d8e9 100644 --- a/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx +++ b/code/ui/blocks/src/components/ArgsTable/ArgControl.tsx @@ -81,6 +81,55 @@ export const ArgControl: FC = ({ row, arg, updateArgs, isHovere // row.name is a display name and not a suitable DOM input id or name - i might contain whitespace etc. // row.key is a hash key and therefore a much safer choice const props = { name: key, argType: row, value: boxedValue.value, onChange, onBlur, onFocus }; - const Control = Controls[control.type] || NoControl; - return ; + + const controls = getControlTypesFromArgType(row); + + const tsTypes: string[] = + row.type?.name === 'union' + ? row.type.value.map((t: { name: any }) => t.name) + : [row.type?.name]; + + return ( +
+ {controls.map((controlType: string) => { + const UninonControl = Controls[controlType] || NoControl; + const argValueType = typeof boxedValue.value; + const controlValue = [tsTypes.shift(), controlType].includes(argValueType) + ? boxedValue.value + : undefined; + + const controlKey = controls.length > 1 ? `${controlType}-${key}` : key; + + return ( + + ); + })} +
+ ); }; +/** + * function to get control types from union arg type + * example : argType = { name: 'union', value: [{ name: 'string' }, { name: 'number' }] } + * @param argType + * @returns + */ +function getControlTypesFromArgType(argType: ArgType) { + return argType.type?.value && argType.type?.name === 'union' && !argType.options + ? argType.type.value.map((t: { name: any }) => { + switch (t.name) { + case 'string': + return 'text'; + + default: + return t.name; + } + }) + : [argType.control.type]; +} diff --git a/code/ui/blocks/src/controls/Number.tsx b/code/ui/blocks/src/controls/Number.tsx index 551d5fb7417e..c1531b7d48c4 100644 --- a/code/ui/blocks/src/controls/Number.tsx +++ b/code/ui/blocks/src/controls/Number.tsx @@ -64,6 +64,10 @@ export const NumberControl: FC = ({ if (inputValue !== newInputValue) { setInputValue(value); } + + if (!value && newInputValue === '') { + setForceVisible(false); + } }, [value]); if (!forceVisible && value === undefined) { diff --git a/code/ui/components/src/components/form/input/input.tsx b/code/ui/components/src/components/form/input/input.tsx index 83d99e4d8a8d..15f3a33eb2af 100644 --- a/code/ui/components/src/components/form/input/input.tsx +++ b/code/ui/components/src/components/form/input/input.tsx @@ -39,6 +39,11 @@ const styles = ({ theme }: { theme: Theme }): CSSObject => ({ height: 'auto', }, + '&[type="number"]': { + /* without this we will have inconsistant height */ + padding: '0px 10px', + }, + '&:focus': { boxShadow: `${theme.color.secondary} 0 0 0 1px inset`, outline: 'none',