summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorAcid Chicken (硫酸鶏) <root@acid-chicken.com>2023-03-21 13:01:40 +0900
committerAcid Chicken (硫酸鶏) <root@acid-chicken.com>2023-03-21 13:01:40 +0900
commitcc3fbefc830c5e399d2f0f86e6d566f378457bf4 (patch)
tree544d21296fd045bc46812624ae9bff6dae794e00 /packages
parentrefactor(#10336): semantics (diff)
downloadmisskey-cc3fbefc830c5e399d2f0f86e6d566f378457bf4.tar.gz
misskey-cc3fbefc830c5e399d2f0f86e6d566f378457bf4.tar.bz2
misskey-cc3fbefc830c5e399d2f0f86e6d566f378457bf4.zip
build(#10336): make .storybook as an individual TypeScript project
Diffstat (limited to 'packages')
-rw-r--r--packages/frontend/.storybook/.gitignore7
-rw-r--r--packages/frontend/.storybook/generate.tsx87
-rw-r--r--packages/frontend/.storybook/tsconfig.json22
-rw-r--r--packages/frontend/tsconfig.json3
4 files changed, 95 insertions, 24 deletions
diff --git a/packages/frontend/.storybook/.gitignore b/packages/frontend/.storybook/.gitignore
index 0de26507c6..649b36b848 100644
--- a/packages/frontend/.storybook/.gitignore
+++ b/packages/frontend/.storybook/.gitignore
@@ -1,8 +1,9 @@
-# (cd path/to/frontend; pnpm tsc --jsx react --jsxFactory h .storybook/generate.tsx && node .storybook/generate.js)
+# (cd path/to/frontend; pnpm tsc -p .storybook)
+# (cd path/to/frontend; node .storybook/generate.js)
/generate.js
-# (cd path/to/frontend; pnpm tsc .storybook/preload-locale.ts && node .storybook/preload-locale.js)
+# (cd path/to/frontend; node .storybook/preload-locale.js)
/preload-locale.js
/locale.ts
-# (cd path/to/frontend; pnpm tsc .storybook/preload-theme.ts && node .storybook/preload-theme.js)
+# (cd path/to/frontend; node .storybook/preload-theme.js)
/preload-theme.js
/themes.ts
diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx
index 0a4ec39108..8ce2af772c 100644
--- a/packages/frontend/.storybook/generate.tsx
+++ b/packages/frontend/.storybook/generate.tsx
@@ -4,7 +4,7 @@ import { basename, dirname } from 'node:path/posix';
import { promisify } from 'node:util';
import { GENERATOR, type State, generate } from 'astring';
import type * as estree from 'estree';
-import * as glob from 'glob';
+import glob from 'glob';
import { format } from 'prettier';
interface SatisfiesExpression extends estree.BaseExpression {
@@ -16,23 +16,69 @@ interface SatisfiesExpression extends estree.BaseExpression {
const generator = {
...GENERATOR,
SatisfiesExpression(node: SatisfiesExpression, state: State) {
- if (node.expression.type === 'ArrowFunctionExpression') {
- state.write('(');
- this[node.expression.type](node.expression, state);
- state.write(')');
- } else {
- this[node.expression.type](node.expression, state);
+ switch (node.expression.type) {
+ case 'ArrowFunctionExpression': {
+ state.write('(');
+ this[node.expression.type](node.expression, state);
+ state.write(')');
+ break;
+ }
+ default: {
+ // @ts-ignore
+ this[node.expression.type](node.expression, state);
+ break;
+ }
}
state.write(' satisfies ');
this[node.reference.type](node.reference, state);
},
}
+type SplitCamel<T extends string, YC extends string = '', YN extends readonly string[] = []> = T extends `${infer XH}${infer XR}`
+ ? XR extends ''
+ ? [...YN, Uncapitalize<`${YC}${XH}`>]
+ : XH extends Uppercase<XH>
+ ? SplitCamel<XR, Lowercase<XH>, [...YN, YC]>
+ : SplitCamel<XR, `${YC}${XH}`, YN>
+ : YN;
+
+// @ts-ignore
+type SplitKebab<T extends string> = T extends `${infer XH}-${infer XR}`
+ ? [XH, ...SplitKebab<XR>]
+ : [T];
+
+type ToKebab<T extends readonly string[]> = T extends readonly [infer XO extends string]
+ ? XO
+ : T extends readonly [infer XH extends string, ...infer XR extends readonly string[]]
+ ? `${XH}${XR extends readonly string[] ? `-${ToKebab<XR>}` : ''}`
+ : '';
+
+// @ts-ignore
+type ToPascal<T extends readonly string[]> = T extends readonly [infer XH extends string, ...infer XR extends readonly string[]]
+ ? `${Capitalize<XH>}${ToPascal<XR>}`
+ : '';
+
function h<T extends estree.Node>(component: T['type'], props: Omit<T, 'type'>): T {
const type = component.replace(/(?:^|-)([a-z])/g, (_, c) => c.toUpperCase());
return Object.assign(props, { type }) as T;
}
+declare global {
+ namespace JSX {
+ type Element = never;
+ type ElementClass = never;
+ type ElementAttributesProperty = never;
+ type ElementChildrenAttribute = never;
+ type IntrinsicAttributes = never;
+ type IntrinsicClassAttributes<T> = never;
+ type IntrinsicElements = {
+ [T in keyof typeof generator as ToKebab<SplitCamel<Uncapitalize<T>>>]: {
+ [K in keyof Omit<Parameters<typeof generator[T]>[0], 'type'>]?: Parameters<typeof generator[T]>[0][K];
+ };
+ };
+ }
+}
+
function toStories(component: string): string {
const msw = `${component.slice(0, -'.vue'.length)}.msw`;
const implStories = `${component.slice(0, -'.vue'.length)}.stories.impl`;
@@ -52,14 +98,14 @@ function toStories(component: string): string {
<property
key={<identifier name="layout" />}
value={<literal value={`${dir}/`.startsWith('src/pages/') ? 'fullscreen' : 'centered'} />}
- kind="init"
+ kind={"init" as const}
/>,
...hasMsw
? [
<property
key={<identifier name="msw" />}
value={<identifier name="msw" />}
- kind="init"
+ kind={"init" as const}
shorthand
/>,
]
@@ -107,13 +153,12 @@ function toStories(component: string): string {
specifiers={[
<import-default-specifier
local={identifier}
- imported={identifier}
/>,
]}
/>,
],
<variable-declaration
- kind="const"
+ kind={"const" as const}
declarations={[
<variable-declarator
id={<identifier name="meta" />}
@@ -125,12 +170,12 @@ function toStories(component: string): string {
<property
key={<identifier name="title" />}
value={literal}
- kind="init"
+ kind={"init" as const}
/>,
<property
key={<identifier name="component" />}
value={identifier}
- kind="init"
+ kind={"init" as const}
/>,
]}
/>
@@ -148,7 +193,7 @@ function toStories(component: string): string {
<export-named-declaration
declaration={
<variable-declaration
- kind="const"
+ kind={"const" as const}
declarations={[
<variable-declarator
id={<identifier name="Default" />}
@@ -169,7 +214,7 @@ function toStories(component: string): string {
<property
key={<identifier name="argTypes" />}
value={<identifier name="argTypes" />}
- kind="init"
+ kind={"init" as const}
shorthand
/>,
]}
@@ -190,13 +235,13 @@ function toStories(component: string): string {
<property
key={identifier}
value={identifier}
- kind="init"
+ kind={"init" as const}
shorthand
/>,
]}
/>
}
- kind="init"
+ kind={"init" as const}
/>,
<property
key={<identifier name="props" />}
@@ -213,12 +258,12 @@ function toStories(component: string): string {
]}
/>
}
- kind="init"
+ kind={"init" as const}
/>,
<property
key={<identifier name="template" />}
value={<literal value={`<${identifier.name} v-bind="$props" />`} />}
- kind="init"
+ kind={"init" as const}
/>,
]}
/>
@@ -230,12 +275,12 @@ function toStories(component: string): string {
/>
}
method
- kind="init"
+ kind={"init" as const}
/>,
<property
key={<identifier name="parameters" />}
value={parameters}
- kind="init"
+ kind={"init" as const}
/>,
]}
/>
diff --git a/packages/frontend/.storybook/tsconfig.json b/packages/frontend/.storybook/tsconfig.json
new file mode 100644
index 0000000000..01aa9db6eb
--- /dev/null
+++ b/packages/frontend/.storybook/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "compilerOptions": {
+ "strict": true,
+ "allowUnusedLabels": false,
+ "allowUnreachableCode": false,
+ "exactOptionalPropertyTypes": true,
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitOverride": true,
+ "noImplicitReturns": true,
+ "noPropertyAccessFromIndexSignature": true,
+ "noUncheckedIndexedAccess": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "checkJs": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "jsx": "react",
+ "jsxFactory": "h"
+ },
+ "files": ["./generate.tsx", "./preload-locale.ts", "./preload-theme.ts"]
+}
diff --git a/packages/frontend/tsconfig.json b/packages/frontend/tsconfig.json
index 54e5219b56..4d582daa3c 100644
--- a/packages/frontend/tsconfig.json
+++ b/packages/frontend/tsconfig.json
@@ -43,5 +43,8 @@
".eslintrc.js",
"./**/*.ts",
"./**/*.vue"
+ ],
+ "exclude": [
+ ".storybook/**/*",
]
}