Skip to content

Commit a077c34

Browse files
fi3eworkclaude
andcommitted
feat(framework-react-lynx-web): dispatcher-based component routing
Replace the per-component bridge-entry model with a single dispatcher entry. Users write one `.storybook/lynx-preview.tsx` that registers components via `createLynxStorybook({ components })`, and stories reference them by name via `parameters.lynx.component`. The `entry:` and `url:` forms remain as escape hatches. - Add `src/runtime.ts` exporting `createLynxStorybook` (runs inside the Lynx bundle, not in Storybook's preview iframe) - Wire `./runtime` subpath export (build-config + package.json exports + bundler.entries) - Preset auto-detects `.storybook/lynx-preview.*` and injects it as a synthetic `__storybook__` rspeedy entry alongside user entries - Preview resolves `url → entry → component` with distinct error paths - Migrate sandbox to dispatcher model, add Card component + story, make lynx.config.ts a proper app config with `source.entry` Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2bb8637 commit a077c34

File tree

16 files changed

+597
-73
lines changed

16 files changed

+597
-73
lines changed

packages/framework-react-lynx-web/README.md

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ npm install storybook-react-lynx-web-rsbuild \
1515
```
1616

1717
You also need a `lynx.config.ts` in your project root that invokes
18-
`pluginReactLynx()` and lists every component you want to render as a
19-
`source.entry` — see [Usage](#usage).
18+
`pluginReactLynx()` — see [Usage](#usage).
2019

2120
## Usage
2221

@@ -37,7 +36,8 @@ const config: StorybookConfig = {
3736
export default config
3837
```
3938

40-
In your project root `lynx.config.ts`:
39+
In your project root `lynx.config.ts` — no `source.entry` required for
40+
the common case; the framework injects its own dispatcher entry:
4141

4242
```ts
4343
import { pluginReactLynx } from '@lynx-js/react-rsbuild-plugin'
@@ -49,28 +49,27 @@ export default defineConfig({
4949
web: {},
5050
lynx: {},
5151
},
52-
source: {
53-
entry: {
54-
// One entry per component you want to render in Storybook.
55-
Button: './src/components/button-entry.tsx',
56-
},
57-
},
5852
})
5953
```
6054

61-
Each entry file simply mounts your component:
55+
Create `.storybook/lynx-preview.tsx` and register every component you
56+
want to expose to stories:
6257

6358
```tsx
64-
// src/components/button-entry.tsx
65-
import { root } from '@lynx-js/react'
59+
// .storybook/lynx-preview.tsx
60+
import { createLynxStorybook } from 'storybook-react-lynx-web-rsbuild/runtime'
6661

67-
import { Button } from './Button.tsx'
68-
import './Button.css'
62+
import { Button } from '../src/components/Button.tsx'
63+
import '../src/components/Button.css'
6964

70-
root.render(<Button />)
65+
createLynxStorybook({
66+
components: {
67+
Button: () => <Button />,
68+
},
69+
})
7170
```
7271

73-
Then write a story that points at the built `.web.bundle`:
72+
Then write a story and reference the component by name:
7473

7574
```ts
7675
// src/components/Button.stories.ts
@@ -80,7 +79,11 @@ const meta = {
8079
title: 'Example/Button',
8180
parameters: {
8281
lynx: {
83-
url: '/lynx-bundles/Button.web.bundle',
82+
// Matches a key from the `components` map in lynx-preview.tsx.
83+
// The framework dispatches to it via a single auto-injected
84+
// `__storybook__.web.bundle`, so you don't add a `source.entry`
85+
// per component.
86+
component: 'Button',
8487
},
8588
},
8689
argTypes: {
@@ -97,6 +100,26 @@ export const Primary: Story = {
97100
}
98101
```
99102

103+
### Escape hatches: `entry` and `url`
104+
105+
For advanced cases — custom prefixes, remote bundles, bundles outside
106+
the dispatcher — two lower-level forms of `parameters.lynx` are still
107+
supported. Prefer `component:` above for day-to-day use.
108+
109+
```ts
110+
// Reference a named rspeedy entry from your own lynx.config.ts:
111+
parameters: { lynx: { entry: 'LegacyApp' } }
112+
113+
// Or point at any URL directly (remote or otherwise):
114+
parameters: { lynx: { url: 'https://cdn.example.com/my.web.bundle' } }
115+
```
116+
117+
Resolution order is `url``entry``component`. If the active
118+
`component:` is not registered in `.storybook/lynx-preview.tsx`, the
119+
runtime dispatcher renders an empty placeholder; if the whole
120+
`.storybook/lynx-preview.*` file is missing, the preview shows an
121+
inline error telling you where to create it.
122+
100123
Read Storybook args inside your component via `useGlobalProps()` from
101124
`@lynx-js/react`. Augment the `GlobalProps` interface for type safety:
102125

@@ -135,8 +158,9 @@ framework: {
135158
### `lynxBundlePrefix`
136159

137160
URL prefix under which compiled `.web.bundle` files are served. Defaults
138-
to `/lynx-bundles`. Your story's `parameters.lynx.url` must start with
139-
this prefix.
161+
to `/lynx-bundles`. The dispatcher and the `entry:` shortcut pick this
162+
up automatically; stories that pass an explicit `parameters.lynx.url`
163+
must include the matching prefix themselves.
140164

141165
## Features
142166

packages/framework-react-lynx-web/build-config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ const config: BuildEntries = {
1616
entryPoint: './src/preview-runtime.ts',
1717
dts: false,
1818
},
19+
{
20+
exportEntries: ['./runtime'],
21+
entryPoint: './src/runtime.ts',
22+
},
1923
],
2024
node: [
2125
{

packages/framework-react-lynx-web/package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@
3636
"types": "./dist/preview.d.ts",
3737
"default": "./dist/preview.js"
3838
},
39-
"./preview-runtime": "./dist/preview-runtime.js"
39+
"./preview-runtime": "./dist/preview-runtime.js",
40+
"./runtime": {
41+
"types": "./dist/runtime.d.ts",
42+
"default": "./dist/runtime.js"
43+
}
4044
},
4145
"files": [
4246
"dist/**/*",
@@ -64,6 +68,7 @@
6468
"typescript": "^5.9.3"
6569
},
6670
"peerDependencies": {
71+
"@lynx-js/react": ">=0.100.0",
6772
"@lynx-js/rspeedy": ">=0.10.0",
6873
"@lynx-js/web-core": ">=0.6.0",
6974
"@lynx-js/web-elements": ">=0.6.0",
@@ -82,7 +87,8 @@
8287
"./src/index.ts",
8388
"./src/preset.ts",
8489
"./src/preview.ts",
85-
"./src/preview-runtime.ts"
90+
"./src/preview-runtime.ts",
91+
"./src/runtime.ts"
8692
],
8793
"platform": "node"
8894
}

0 commit comments

Comments
 (0)