Skip to content

Commit

Permalink
more typesafe CSF3 types for svelte
Browse files Browse the repository at this point in the history
  • Loading branch information
kasperpeulen committed Oct 18, 2022
1 parent 5a2d028 commit 387630a
Show file tree
Hide file tree
Showing 27 changed files with 419 additions and 105 deletions.
6 changes: 3 additions & 3 deletions code/addons/highlight/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@
"@types/webpack-env": "^1.16.0",
"typescript": "~4.6.3"
},
"publishConfig": {
"access": "public"
},
"bundler": {
"entries": [
"./src/index.ts",
"./src/highlight.ts"
]
},
"publishConfig": {
"access": "public"
},
"gitHead": "438114fcf62a763f0e8c07e2c34890dd987ca431",
"sbmodern": "dist/modern/index.js",
"storybook": {
Expand Down
1 change: 1 addition & 0 deletions code/lib/core-common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export * from './utils/normalize-stories';
export * from './utils/readTemplate';
export * from './utils/findDistEsm';
export * from './utils/symlinks';
export * from './utils/satisfies';

export * from './types';

Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
],
"resolutions": {
"@nrwl/cli": "14.6.1",
"@storybook/csf": "portal:/Users/kasperpeulen/code/storybook/csf",
"@typescript-eslint/eslint-plugin": "^5.15.0",
"@typescript-eslint/experimental-utils": "5.3.0",
"@typescript-eslint/parser": "^5.15.0",
Expand Down Expand Up @@ -336,7 +337,7 @@
"ts-jest": "^26.4.4",
"ts-node": "^10.4.0",
"tsup": "^6.2.2",
"typescript": "4.7.4",
"typescript": "~4.6.3",
"util": "^0.12.4",
"vite": "^3.1.7",
"wait-on": "^5.2.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { KeyboardEventHandler, ReactNode } from 'react';
import { expectTypeOf } from 'expect-type';
import { describe, test } from '@jest/globals';
import { satisfies } from '@storybook/core-common';
import { StoryAnnotations } from '@storybook/csf';
import { expectTypeOf } from 'expect-type';
import React, { KeyboardEventHandler, ReactNode } from 'react';
import { SetOptional } from 'type-fest';

import { Meta, StoryObj } from '../public-types';
import { DecoratorFn } from '../public-api';
import { satisfies } from './utils';
import { ReactFramework } from '../types';
import { DecoratorFn } from './public-api';
import { Meta, StoryObj } from './public-types';
import { ReactFramework } from './types';

type ReactStory<Args, RequiredArgs> = StoryAnnotations<ReactFramework, Args, RequiredArgs>;

Expand Down Expand Up @@ -75,6 +75,11 @@ describe('Args can be provided in multiple ways', () => {
expectTypeOf(Basic).toEqualTypeOf<Expected>();
}
});

test('Component can be used as generic parameter for StoryObj', () => {
type Expected = ReactStory<ButtonProps, ButtonProps>;
expectTypeOf<StoryObj<typeof Button>>().toEqualTypeOf<Expected>();
});
});

test('✅ All void functions are optional', () => {
Expand Down
34 changes: 16 additions & 18 deletions code/renderers/react/src/public-types.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import type {
AnnotatedStoryFn,
Args,
ArgsFromMeta,
ArgsStoryFn,
ComponentAnnotations,
LoaderFunction,
StoryAnnotations,
} from '@storybook/csf';
import { SetOptional, Simplify, UnionToIntersection } from 'type-fest';
import { ComponentProps, ComponentType, JSXElementConstructor } from 'react';
import { SetOptional, Simplify } from 'type-fest';

import { ReactFramework } from './types';
import { DecoratorFn } from './public-api';

type JSXElement = keyof JSX.IntrinsicElements | JSXElementConstructor<any>;

Expand All @@ -36,29 +35,28 @@ export type StoryFn<TArgs = Args> = AnnotatedStoryFn<ReactFramework, TArgs>;
* @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports)
*/

export type StoryObj<MetaOrArgs = Args> = MetaOrArgs extends {
render?: ArgsStoryFn<ReactFramework, infer RArgs>;
component?: ComponentType<infer CmpArgs>;
loaders?: (infer Loaders)[];
export type StoryObj<MetaOrCmpOrArgs = Args> = MetaOrCmpOrArgs extends {
render?: ArgsStoryFn<ReactFramework, any>;
component?: infer Component;
args?: infer DefaultArgs;
decorators?: (infer Decorators)[];
}
? Simplify<CmpArgs & RArgs & DecoratorsArgs<Decorators> & LoaderArgs<Loaders>> extends infer TArgs
? Simplify<
(Component extends ComponentType<any> ? ComponentProps<Component> : unknown) &
ArgsFromMeta<ReactFramework, MetaOrCmpOrArgs>
> extends infer TArgs
? StoryAnnotations<
ReactFramework,
TArgs,
SetOptional<TArgs, Extract<keyof TArgs, keyof (DefaultArgs & ActionArgs<TArgs>)>>
>
: never
: StoryAnnotations<ReactFramework, MetaOrArgs>;

type DecoratorsArgs<Decorators> = UnionToIntersection<
Decorators extends DecoratorFn<infer Args> ? Args : unknown
>;

type LoaderArgs<Loaders> = UnionToIntersection<
Loaders extends LoaderFunction<ReactFramework, infer Args> ? Args : unknown
>;
: MetaOrCmpOrArgs extends ComponentType<any>
? StoryAnnotations<
ReactFramework,
ComponentProps<MetaOrCmpOrArgs>,
ComponentProps<MetaOrCmpOrArgs>
>
: StoryAnnotations<ReactFramework, MetaOrCmpOrArgs>;

type ActionArgs<Args> = {
[P in keyof Args as ((...args: any[]) => void) extends Args[P] ? P : never]: Args[P];
Expand Down
7 changes: 5 additions & 2 deletions code/renderers/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"*.d.ts"
],
"scripts": {
"check": "../../../scripts/node_modules/.bin/tsc --noEmit",
"check": "svelte-check --tsconfig ./tsconfig.json",
"prep": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
Expand All @@ -63,10 +63,13 @@
"global": "^4.4.0",
"react": "16.14.0",
"react-dom": "16.14.0",
"sveltedoc-parser": "^4.2.1"
"sveltedoc-parser": "^4.2.1",
"type-fest": "2.19.0"
},
"devDependencies": {
"expect-type": "^0.14.2",
"svelte": "^3.31.2",
"svelte-check": "^2.9.2",
"typescript": "~4.6.3"
},
"peerDependencies": {
Expand Down
12 changes: 12 additions & 0 deletions code/renderers/svelte/src/___test___/Button.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
export let disabled: boolean;
export let label: string;
const dispatch = createEventDispatcher();
</script>

<button on:click={(e) => dispatch('clicked', e)} on:dblclick on:mousemove {disabled}>
{label}
</button>
8 changes: 8 additions & 0 deletions code/renderers/svelte/src/___test___/Decorator.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script lang="ts">
export let decoratorArg: string;
</script>

<div>
Decorator: {decoratorArg}
<slot />
</div>
8 changes: 8 additions & 0 deletions code/renderers/svelte/src/___test___/Decorator2.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script lang="ts">
export let decoratorArg2: string;
</script>

<div>
Decorator: {decoratorArg2}
<slot />
</div>
1 change: 1 addition & 0 deletions code/renderers/svelte/src/docs/extractArgTypes.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { describe, expect } from '@jest/globals';
import svelteDoc from 'sveltedoc-parser';
import * as fs from 'fs';
import { createArgTypes } from './extractArgTypes';
Expand Down
2 changes: 1 addition & 1 deletion code/renderers/svelte/src/docs/extractArgTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const createArgTypes = (docgen: SvelteComponentDoc) => {

/**
* Function to convert the type from sveltedoc-parser to a storybook type
* @param typeName
* @param type
* @returns string
*/
const parseTypeToControl = (type: JSDocType | undefined): any => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { describe, expect, test } from '@jest/globals';
import { extractComponentDescription } from './extractComponentDescription';

describe('extractComponentDescription', () => {
Expand Down
7 changes: 4 additions & 3 deletions code/renderers/svelte/src/docs/sourceDecorator.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { describe, expect, test } from '@jest/globals';
import type { Args } from '@storybook/api';
import { generateSvelteSource } from './sourceDecorator';

expect.addSnapshotSerializer({
print: (val: any) => val,
test: (val) => typeof val === 'string',
test: (val: unknown) => typeof val === 'string',
});

function generateForArgs(args: Args, slotProperty: string = null) {
function generateForArgs(args: Args, slotProperty: string | null = null) {
return generateSvelteSource({ name: 'Component' }, args, {}, slotProperty);
}

Expand Down Expand Up @@ -42,6 +43,6 @@ describe('generateSvelteSource', () => {
`);
});
test('component is not set', () => {
expect(generateSvelteSource(null, null, null, null)).toBeNull();
expect(generateSvelteSource(null, {}, {}, null)).toBeNull();
});
});
2 changes: 1 addition & 1 deletion code/renderers/svelte/src/docs/sourceDecorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function generateSvelteSource(
component: any,
args: Args,
argTypes: ArgTypes,
slotProperty?: string
slotProperty?: string | null
): string | null {
const name = getComponentName(component);

Expand Down
1 change: 0 additions & 1 deletion code/renderers/svelte/src/globals.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-expect-error (Converted from ts-ignore)
import global from 'global';

const { window: globalWindow } = global;
Expand Down
Loading

0 comments on commit 387630a

Please sign in to comment.