Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ jobs:
run: git push --tags

- name: Build storybook
run: npx nx build-storybook @ethnolib/language-chooser-react-mui
run: npm run --workspace components/language-chooser/react/language-chooser-react-mui build-storybook:composed

- name: Build composed Svelte storybook
shell: bash
run: |
npm run --workspace components/language-chooser/svelte/language-chooser-svelte-daisyui build-storybook -- --output-dir ../../react/language-chooser-react-mui/storybook-static/svelte

- name: Upload for deploy to github pages
uses: actions/upload-pages-artifact@v3
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ or
nx dev @ethnolib/language-chooser-svelte-daisyui
```

### Composed Storybook

The language chooser demos are also available as a composed Storybook that shows both the React MUI stories and the Svelte DaisyUI stories.

For local development, run:

```
npm run storybook:language-chooser:all
```

This starts the Svelte Storybook on port `6007`, waits for it to be ready, and then starts the React Storybook shell on port `6006`.

For GitHub Pages deployment, the React Storybook is built as the root site and the Svelte Storybook is built into its nested `storybook-static/svelte` folder. The Pages workflow uploads the entire React `storybook-static` directory, so the nested Svelte files are deployed along with it.

### Dependency Versions

We are currently having all packages manage their own dependencies in their package level `package.json` files, but keeping them all on the same versions of commonly used packages for compatibility. Current versions:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,67 @@
import type { StorybookConfig } from "@storybook/react-vite";

type ExternalStorybookRef = {
id: string;
title: string;
url: string;
};

const externalStorybookRefs = parseExternalStorybookRefs(
process.env.STORYBOOK_REFS,
);

function parseExternalStorybookRefs(
rawStorybookRefs: string | undefined,
): ExternalStorybookRef[] {
if (!rawStorybookRefs) {
return [];
}

try {
const parsedStorybookRefs = JSON.parse(rawStorybookRefs);

if (!Array.isArray(parsedStorybookRefs)) {
return [];
}

return parsedStorybookRefs.flatMap((value) => {
if (!value || typeof value !== "object") {
return [];
}

const ref = value as ExternalStorybookRef;

if (!ref.id || !ref.title || !ref.url) {
return [];
}

return [ref];
});
} catch {
return [];
}
}

const config: StorybookConfig = {
stories: ["../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))"],
stories: [
{
directory: "../src",
files: "**/*.@(mdx|stories.@(js|jsx|ts|tsx))",
titlePrefix: "React MUI",
},
],
addons: ["@storybook/addon-essentials"],
refs: externalStorybookRefs.length
? Object.fromEntries(
externalStorybookRefs.map((ref) => [
ref.id,
{
title: ref.title,
url: ref.url,
},
]),
)
: undefined,
framework: {
name: "@storybook/react-vite",
options: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"typecheck": "tsc",
"prebuild": "npm run typecheck",
"build": "nx vite:build",
"storybook:composed": "node ./scripts/run-composed-storybook.mjs dev",
"build-storybook:composed": "node ./scripts/run-composed-storybook.mjs build",
"lint": "eslint .",
"e2e": "playwright test"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { spawn } from "node:child_process";

const storybookRefsByMode = {
build: [
{
id: "svelte-daisyui",
title: "Svelte DaisyUI",
url: "./svelte",
},
],
dev: [
{
id: "svelte-daisyui",
title: "Svelte DaisyUI",
url: "http://localhost:6007",
},
],
};

const mode = process.argv[2] === "build" ? "build" : "dev";
const command =
mode === "build"
? "npx storybook build"
: "npx storybook dev -p 6006";

const child = spawn(command, {
shell: true,
stdio: "inherit",
env: {
...process.env,
STORYBOOK_REFS: JSON.stringify(storybookRefsByMode[mode]),
},
});

child.on("exit", (code) => {
process.exit(code ?? 1);
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react";
import DialogDemo from "./DialogDemo";

const meta: Meta<typeof DialogDemo> = {
title: "Demos/Dialog Demo",
component: DialogDemo,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react";
import { PageDemo } from "./PageDemo";

const meta: Meta<typeof PageDemo> = {
title: "Demos/Page Demo",
component: PageDemo,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react";
import { ThemeDemo } from "./ThemeDemo";

const meta: Meta<typeof ThemeDemo> = {
title: "Demos/Theme Demo",
component: ThemeDemo,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { StorybookConfig } from "@storybook/svelte-vite";

const config: StorybookConfig = {
stories: ["../src/**/*.@(mdx|stories.@(js|ts|svelte))"],
addons: ["@storybook/addon-essentials"],
framework: {
name: "@storybook/svelte-vite",
options: {
builder: {
viteConfigPath: "vite.config.ts",
},
},
},
};

export default config;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Preview } from "@storybook/svelte";
import "../src/app.css";

const preview: Preview = {
parameters: {
layout: "fullscreen",
},
};

export default preview;
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"check": "svelte-check --tsconfig ./tsconfig.json",
"prebuild": "npm run typecheck",
"build": "nx vite:build",
"storybook": "storybook dev -p 6007",
"build-storybook": "storybook build",
"lint": "eslint .",
"test": "nx vite:test --config vitest.config.ts",
"testonce": "nx vite:test --config vitest.config.ts --run"
Expand All @@ -25,6 +27,8 @@
"@ethnolib/state-management-svelte": "0.2.0"
},
"devDependencies": {
"@storybook/addon-essentials": "^8.2.8",
"@storybook/svelte-vite": "^8.2.8",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@tailwindcss/postcss": "^4.1.13",
"@tailwindcss/typography": "^0.5.16",
Expand All @@ -33,6 +37,7 @@
"daisyui": "^5.1.12",
"eslint-plugin-svelte": "^2.44.0",
"postcss": "^8.5.6",
"storybook": "^8.2.8",
"svelte": "^5.38.6",
"svelte-check": "^4.0.5",
"svelte-preprocess": "^6.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Meta, StoryObj } from "@storybook/svelte";
import BasicDemo from "./BasicDemo.svelte";

const meta = {
title: "Demos/Basic Demo",
component: BasicDemo,
} satisfies Meta<BasicDemo>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Primary: Story = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<script lang="ts">
import {
createTagFromOrthography,
defaultDisplayName,
type IOrthography,
} from "@ethnolib/find-language";
import LanguageChooser from "../lib/LanguageChooser.svelte";

let theme = $state("light");
let orthography: IOrthography = $state({});
let languageTag: string | undefined = $state();

function onDismiss() {
return;
}

function onOk(nextOrthography: IOrthography, nextLanguageTag?: string) {
orthography = nextOrthography;
languageTag = nextLanguageTag ?? createTagFromOrthography(nextOrthography);
}
</script>

<div class="min-h-screen bg-base-200 p-6" data-theme={theme}>
<div class="mx-auto flex max-w-7xl flex-col gap-6">
<div class="flex flex-col gap-4 rounded-box border border-base-300 bg-base-100 p-5 shadow-sm lg:flex-row lg:items-end lg:justify-between">
<div>
<h1 class="text-3xl font-semibold">Svelte Language Chooser Demo</h1>
<p class="mt-2 max-w-2xl text-sm text-base-content/70">
This Storybook example embeds the chooser directly so you can test
search, script selection, and custom tag submission without a page app
shell.
</p>
</div>

<label class="form-control w-full max-w-48">
<div class="label">
<span class="label-text">Theme</span>
</div>
<select class="select select-bordered" bind:value={theme}>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label>
</div>

<div class="grid gap-6 xl:grid-cols-[minmax(0,2fr)_20rem]">
<div class="h-[720px] overflow-hidden rounded-box border border-base-300 bg-base-100 shadow-sm">
<LanguageChooser {onDismiss} {onOk} />
</div>

<aside class="rounded-box border border-base-300 bg-base-100 p-5 shadow-sm">
<h2 class="text-lg font-semibold">Submitted selection</h2>
<div class="mt-4 space-y-3 text-sm">
<div>
<div class="text-base-content/60">Display name</div>
<div class="font-medium">
{orthography.language
? orthography.customDetails?.customDisplayName ||
defaultDisplayName(orthography.language, orthography.script)
: "No language selected yet"}
</div>
</div>

<div>
<div class="text-base-content/60">Language code</div>
<div class="font-mono">
{orthography.language?.languageSubtag || "-"}
</div>
</div>

<div>
<div class="text-base-content/60">Script</div>
<div>{orthography.script?.name || "-"}</div>
</div>

<div>
<div class="text-base-content/60">Region</div>
<div>{orthography.customDetails?.region?.name || "-"}</div>
</div>

<div>
<div class="text-base-content/60">Dialect</div>
<div>{orthography.customDetails?.dialect || "-"}</div>
</div>

<div>
<div class="text-base-content/60">Language tag</div>
<div class="font-mono break-all">{languageTag || "-"}</div>
</div>
</div>
</aside>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,18 @@ export default defineConfig({

plugins: [
nxViteTsPaths(),
svelte(),
svelte({
dynamicCompileOptions: ({ filename, compileOptions }) => {
const normalizedFilename = filename.replaceAll("\\", "/");

if (
normalizedFilename.includes("/node_modules/@storybook/svelte/") &&
compileOptions.runes
) {
return { runes: false };
}
},
}),
dts({
entryRoot: ".",
tsconfigPath: path.join(__dirname, "tsconfig.lib.json"),
Expand Down
Loading
Loading