tajo / ladle Goto Github PK
View Code? Open in Web Editor NEW๐ฅ Develop, test and document your React story components faster.
Home Page: https://www.ladle.dev
License: MIT License
๐ฅ Develop, test and document your React story components faster.
Home Page: https://www.ladle.dev
License: MIT License
Just tried out Ladle, that what I wanted to build years ago because SB is too slow and the bundle size is too big
Single story hoisting is the one I missed most
another one is how to inject preview header? I use it to inject google fonts, it would be nice that we can customise the layout
Ladle is an environment to develop, test and share your React components faster.
My question is how to test the components?
I store the font files as local assets under the /public
directory, but when I try to import them from stories I get a "failed to load resources" error.
While Ladle supports React 18, Reach Dialog (its dependency) needs to be update as well to satisfy more strict pnpm.
packages/my-package
โโโฌ @ladle/react
โโโฌ @reach/dialog
โโโ โ unmet peer react@"^16.8.0 || 17.x": found 18.0.0
โโโ โ unmet peer react-dom@"^16.8.0 || 17.x": found 18.0.0
โโโฌ @reach/portal
โ โโโ โ unmet peer react@"^16.8.0 || 17.x": found 18.0.0
โ โโโ โ unmet peer react-dom@"^16.8.0 || 17.x": found 18.0.0
โ โโโฌ @reach/utils
โ โโโ โ unmet peer react@"^16.8.0 || 17.x": found 18.0.0
โ โโโ โ unmet peer react-dom@"^16.8.0 || 17.x": found 18.0.0
โโโฌ react-focus-lock
โโโฌ react-clientside-effect
โโโ โ unmet peer react@"^15.3.0 || ^16.0.0 || ^17.0.0": found 18.0.0
CSS modules don't get inserted in the final build output (with ladle build
).
https://stackblitz.com/edit/ladle-nmhbpc
โ
Using npm run dev
(ladle serve
), you can see the code working as excepted.
Tested with *.css
and *.scss
file extension.
โ Using npm run build & npm run serve
, the CSS modules don't work.
The output file ./build/assets/basic.stories.<hash_id>.css
aren't being included at all, anywhere. I was excepting to see it being included in the <head>
tag.
On the other hand, the JS module ./build/assets/basic.stories.<hash_id>.js
do have correct generated CSS module assigned to the components property className
.
The providers section has an example that describes how to add a global provider:
import type { GlobalProvider } from "@ladle/react";
export const Provider: GlobalProvider = ({ children, globalState }) => (
<>
<h1>Theme: {globalState.theme}</h1>
{children}
</>
);
My components
file in .ladle/components.tsx
is a typescript file. The children property is not declared in the GlobalProvider
type, because of this, my IDE gives me a Property 'children' does not exist on type '{ globalState: GlobalState; }'.
error.
Here's what the GlobalProvider
looks like:
export type GlobalProvider = React.FC<{ globalState: GlobalState }>;
Since the example is using TS and it also passes in a children prop, the GlobalProvider
type should have a children prop.
Describe the bug
I'm working on a design system, and would like to replace Storybook with Ladle.
I've put together an MVP of the folder structure here: https://github.com/lukebennett88/ladle-test
Basically I want to configure Ladle inside the /docs
folder, but I want it to go up to the /packages
folder to look for .story.tsx
files. I can't seem to get Ladle to find and files. If I set it up in the root it does work, but that's not what I want.
To Reproduce
Not sure Stackblitz works with monorepos, but here is a link:
https://stackblitz.com/github/lukebennett88/ladle-test
Steps to reproduce the behavior:
Expected behavior
cd docs
yarn ladle:serve
Desktop (please complete the following information):
After installing @ladle/react-cjs
I created a custom config at .ladle/config.mjs
with
export default {
stories: 'webpack/ui/components/**/stories.{js,jsx}',
root: '../',
...
}
When I'm running the ladle with yarn ladle serve
in the opened window I can see that the configured glob pattern for stories is the same as I specified in config file, but no stories found. And if I run ladle with debug mode I can see that CLI says that no custom config found
First of all, thanks for working on this project, this looks promising !
I am unable to find a way to view the docs and code section of the stories. Do we have plans to them in the future ?
Would love to contribute on that.
Any help on this would be really appreciated, TIA.
Describe the bug
Currently when we pass --open
it will always create a new tab instead of re-using the existing tab(s)
To Reproduce
In any integration with Ladle, this is part of the core
Steps to reproduce the behavior:
--open
and it will create a new tab each time we start the serverExpected behavior
If there's already a tab on that page, simply refresh that page
@tajo I'm able to create a PR to address this
Desktop (please complete the following information):
System:
OS: macOS 12.3.1
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 18.95 GB / 64.00 GB
Shell: 3.2.2 - /usr/local/bin/fish
Binaries:
Node: 14.18.3 - ~/.nvm/versions/node/v14.18.3/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 6.14.15 - ~/.nvm/versions/node/v14.18.3/bin/npm
Browsers:
Chrome: 100.0.4896.127
Safari: 15.4
Currently I've installed the version 0.9.0 and inserted the configuration file on .ladle folder
export default {
stories: "../src/**/control.stories.{js,jsx,ts,tsx}",
};
the react version used was ^17.0.2, but on current run shows " No stories found" message,
Ps. I'm using same config on working storybook files
Looks like we can shave 20-25 seconds off CI & publish job thanks to faster installs & caching, but benefits just start here. Read more:
https://threadreaderapp.com/thread/1486318477203881985.html
I would be happy to help with the update.
Thoughts?
I have stories for simple components that work fine. But once I click on a story for a component that uses the next/image
component, nothing renders and ladle is broken until reload. Once I clock on a story with next/image
the following error occurs in the console:
react.development.js:1309 Uncaught ReferenceError: process is not defined
at node_modules/next/dist/client/normalize-trailing-slash.js (normalize-trailing-slash.ts:12:43)
at __require (chunk-MYIE5J7A.js?v=88870cd9:25:50)
at node_modules/next/dist/shared/lib/router/router.js (router.ts:13:50)
at __require (chunk-MYIE5J7A.js?v=88870cd9:25:50)
at node_modules/next/dist/client/link.js (link.tsx:11:37)
at __require (chunk-MYIE5J7A.js?v=88870cd9:25:50)
at node_modules/next/link.js (link.js:1:18)
at __require (chunk-MYIE5J7A.js?v=88870cd9:25:50)
at dep:next_link:1:16
node_modules/next/dist/client/normalize-trailing-slash.js @ normalize-trailing-slash.ts:12
__require @ chunk-MYIE5J7A.js?v=88870cd9:25
node_modules/next/dist/shared/lib/router/router.js @ router.ts:13
__require @ chunk-MYIE5J7A.js?v=88870cd9:25
node_modules/next/dist/client/link.js @ link.tsx:11
__require @ chunk-MYIE5J7A.js?v=88870cd9:25
node_modules/next/link.js @ link.js:1
__require @ chunk-MYIE5J7A.js?v=88870cd9:25
(anonymous) @ dep:next_link:1
react_devtools_backend.js:3973 The above error occurred in one of your React components:
at Lazy
at Provider (http://localhost:61000/generated/generated-list.tsx:114:28)
at Suspense
at ErrorBoundary (http://localhost:61000/src/error-boundary.tsx:4:5)
at Story (http://localhost:61000/src/story.tsx:11:18)
at main
at App (http://localhost:61000/src/app.tsx:24:41)
React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
Here is a screenshot for better readability:
Hello! This is a very exciting project, I am trying to integrate it into our project, the problem now is that we rely on some Vite plugins to render components properly, is there any plan to support more vite options such as config.plugins and config.css? Or provide a generic method to customize all vite options? Thanks!
ladle/packages/ladle/lib/cli/vite-dev.js
Lines 26 to 37 in 5b1d8f3
Storybook has broad support; any plans for allowing plugins for other libraries like Vue, etc?
errro info like:
[plugin:vite:import-analysis] Failed to resolve import "@/config/config" from "src/apktype/hooks/asyncApktypeAction.ts". Does the file exist?
[/Users/qin.....................e/hooks/asyncApktypeAction.ts:6:0]()
3 | import request from "umi-request";
4 | import { getApktpeListApi } from "./hooks";
5 | import { baseURL } from "@/config/config";
| ^
6 | const oneAtom = atom(false);
7 | export const asyncApktypeAction = () => {
....
tsconfig
{
"compilerOptions": {
"target": "ESNext",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"types": ["vite/client", "node"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": ".",
"paths": {
"*": ["node_modules/*"],
"@/*": ["src/*"]
}
},
"include": ["src", "vite.config.ts", "cypress"]
}
vite config
import react from "@vitejs/plugin-react";
import { resolve } from "path";
import { visualizer } from "rollup-plugin-visualizer";
import { UserConfig } from "vite";
import Checker from "vite-plugin-checker";
function pathResolve(dir: string) {
return resolve(__dirname, ".", dir);
}
const shouldAnalyze = process.env.ANALYZE;
const config: UserConfig = {
resolve: {
alias: [
{
find: /@\//,
replacement: pathResolve("src") + "/"
}
]
},
build: {
rollupOptions: {
plugins: !!shouldAnalyze ? [visualizer({ open: true, filename: "./bundle-size/bundle.html" })] : []
},
sourcemap: !!shouldAnalyze
},
css:{
preprocessorOptions:{
less: {
javascriptEnabled: true,
}
}
},
plugins: [
react({}),
Checker({
typescript: true,
overlay: true,
eslint: {
files: "src",
extensions: [".ts", ".tsx"]
}
})
],
};
const getConfig = () => config;
export default getConfig;
it's a bug ?
As claimed in the blog post (btw, really excited to try ladle), I tried to use ladle as a drop-in replacement, without success.
First problem is that we use a mono repo with some packages under <root>/packages
, but ladle assumes stories will be under <root>/src
, so first things first: configure where the stories are. Easily found the documentation, changed that accordingly, but when starting I got an error that no stories were found, still indicating that the default stories glob (src/**/*.stories.{js,jsx,ts,tsx}
).
Starting with DEBUG=ladle*
revealed the real problem:
ladle:vite Parsing packages/components/src/Alert/Alert.stories.tsx +2ms
ladle:vite Error when generating the list: +588ms
ladle:vite Error: Can't parse the default title and meta of packages/components/src/Alert/Alert.stories.tsx. Meta must be serializable and title a string literal.
ladle:vite at getDefaultExport (file:///home/romaia/dev/stoq/stoq-pdv/node_modules/@ladle/react/lib/cli/vite-plugin/parse/get-default-export.js:32:11)
ladle:vite at NodePath._call (/home/romaia/dev/stoq/stoq-pdv/node_modules/@ladle/react/node_modules/@babel/traverse/lib/path/context.js:53:20)
(...)
So, there is something wrong with my default exports, it seems. This are the first few lines of that story:
import React from "react";
import { Story, Meta } from "@storybook/react";
import { action } from "@storybook/addon-actions";
import { SeverityOptions } from "@xxx/types";
import { Alert } from "@xxx/components";
export default {
component: Alert,
title: "Components/Core/Alert",
argTypes: {
severity: {
options: Object.values(SeverityOptions),
control: { type: "select" },
},
},
} as Meta;
const Template: Story = (args) => {
const [open, setOpen] = React.useState(true);
return (
<Alert {...args} open={open} onClose={() => setOpen(false)}>
{args.children}
</Alert>
);
};
export const Default = Template.bind({});
Default.args = {
children: "Este รฉ um alerta",
};
Commenting out the default exports gets me a little bit further. (by now, I am isolating the stories and using just this one, since all our stories have default exports).
I now see a loading spinner with all my stories on the right side menu. Debug logs don't complain about default exports. Some vite messages, but then when it tries to reload, boom.
6:33:22 AM [vite] new dependencies found: @material-ui/icons, @material-ui/core/TextField, date-fns/locale, @material-ui/lab, @material-ui/icons/NavigateNextOutlined, formik, updating...
6:33:25 AM [vite] โจ dependencies updated, delaying reload as new dependencies have been found...
6:33:25 AM [vite] new dependencies found: @testing-library/user-event, @sentry/browser, fast-xml-parser, currency.js, updating...
/home/romaia/dev/stoq/stoq-pdv/node_modules/@ladle/react/node_modules/vite/dist/node/chunks/dep-6ae84d6b.js:51603
const err = new Error(`There is a new version of the pre-bundle for "${id}", ` +
^
Error: There is a new version of the pre-bundle for "/home/romaia/dev/stoq/stoq-pdv/node_modules/.vite/deps/@material-ui_icons.js?v=8f0250ca", a page reload is going to ask for it.
at throwOutdatedRequest (/home/romaia/dev/stoq/stoq-pdv/node_modules/@ladle/react/node_modules/vite/dist/node/chunks/dep-6ae84d6b.js:51603:17)
at Context.load (/home/romaia/dev/stoq/stoq-pdv/node_modules/@ladle/react/node_modules/vite/dist/node/chunks/dep-6ae84d6b.js:51557:29)
at Object.load (/home/romaia/dev/stoq/stoq-pdv/node_modules/@ladle/react/node_modules/vite/dist/node/chunks/dep-6ae84d6b.js:35159:50)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async doTransform (/home/romaia/dev/stoq/stoq-pdv/node_modules/@ladle/react/node_modules/vite/dist/node/chunks/dep-6ae84d6b.js:51433:24) {
code: 'ERR_OUTDATED_OPTIMIZED_DEP'
}
Important disclaimer: This project does not use vite (yet). We are currently using webpack. It was not clear from the documentation if this would be a problem or not.
It would be nice if we could have an option to see the source code for the currently viewed component, in its current state (determined by props passed to it).
I suppose it could be a button next to configuration button.
I have no idea how to do this, but if I were to start, perhaps I would leverage Espree's parse function to find a given named export value before parsing, as-is in the actual story file ๐ค
My team is interested in using this project for React component development and to build a component library.
When onboarding to this project, we hit the following errors when running npm run ladle serve
:
9:18:08 PM [vite] error while updating dependencies:
Error: Build failed with 2 errors:
error: Two output files share the same path but have different contents: node_modules/.vite/processing/lodash_cloneDeep.js.map`
error: Two output files share the same path but have different contents: node_modules/.vite/processing/lodash_cloneDeep.js
The reason for this is this project depending on and importing lodash.clonedeep
. Our project uses and imports lodash/cloneDeep
.
Within the ladle
project, optimizeDeps.include
is configured to optimize lodash.clonedeep
. This leads to an error when building via Vite. This problem has been documented before in this StackOverflow post.
If I comment out this line in the built ladle
project locally, our Ladle component previews work seamlessly.
lodash/**
import usage is common in projects today, and can easily conflict with the optimized dependencies configured currently in the ladle
project. I see 2 alternatives:
lodash.**
dependency optimizations from ladle
.ladle
to overwrite optimizeDeps.include
, vs. strictly enabling adding to this list (this is a restriction in the configuration API today to my understanding).I'm happy to help push a solution to this problem forward. I wanted to get a sense for what solution we prefer before I cut a PR. Would love thoughts!
cc: @tajo
Decided to give ladle a try on a new project. It worked fine until I tried to add a .ladle/ dir for some config bits. Below is the result of running yarn ladle serve
. Notice in particular that the config.mjs isn't detected, and the path .............ladleconfig.mjs
seems out of nowhere. Running on Windows 11, if that makes a difference.
โ node -v
v16.13.2
โ ls .ladle
Directory: C:\dev123\packages\frontend\.ladle
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 3/22/2022 5:02 PM 203 components.tsx
-a--- 3/22/2022 5:08 PM 53 config.mjs
โ cat .ladle/config.mjs
export default {
"serve":{
"port": 6000
}
}
โ yarn dev:ladle
yarn run v1.22.17
$ cross-env DEBUG=ladle* ladle serve .
ladle:cli Starting serve command +0ms
ladle:cli CLI theme: undefined +1ms
ladle:cli CLI stories: undefined +0ms
ladle:cli CLI port: undefined +0ms
ladle:cli CLI open: undefined +0ms
ladle:cli No custom config found. +1ms
ladle:cli Final config:
ladle:cli {
ladle:cli "stories": "src/**/*.stories.{js,jsx,ts,tsx}",
ladle:cli "root": "C:\\dev123\\packages\\frontend",
ladle:cli "defaultStory": "",
ladle:cli "babelPresets": [],
ladle:cli "babelPlugins": [],
ladle:cli "define": {},
ladle:cli "envPrefix": "VITE_",
ladle:cli "resolve": {
ladle:cli "alias": {}
ladle:cli },
ladle:cli "optimizeDeps": {
ladle:cli "include": []
ladle:cli },
ladle:cli "addons": {
ladle:cli "control": {
ladle:cli "enabled": true,
ladle:cli "defaultState": {}
ladle:cli },
ladle:cli "theme": {
ladle:cli "enabled": true,
ladle:cli "defaultState": "light"
ladle:cli },
ladle:cli "mode": {
ladle:cli "enabled": true,
ladle:cli "defaultState": "full"
ladle:cli },
ladle:cli "rtl": {
ladle:cli "enabled": true,
ladle:cli "defaultState": false
ladle:cli },
ladle:cli "ladle": {
ladle:cli "enabled": true
ladle:cli }
ladle:cli },
ladle:cli "serve": {
ladle:cli "open": "**Default**",
ladle:cli "port": 61000,
ladle:cli "define": {}
ladle:cli },
ladle:cli "build": {
ladle:cli "out": "build",
ladle:cli "sourcemap": false,
ladle:cli "baseUrl": "/",
ladle:cli "define": {}
ladle:cli }
ladle:cli } +0ms
ladle:cli Port set to: 61000 +5ms
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ ๐ฅ Ladle.dev served at http://localhost:61000 โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
ladle:vite transforming: C:/dev123/packages/frontend/node_modules/@ladle/react/lib/app/generated/generated-list.tsx +0ms
ladle:vite Initial generation of the list +0ms
ladle:vite Parsing src/app/components/UserIcon/UserIcon.stories.tsx +0ms
ladle:vite Parsed data for src/app/components/UserIcon/UserIcon.stories.tsx: +61ms
ladle:vite {
ladle:vite entry: 'src/app/components/UserIcon/UserIcon.stories.tsx',
ladle:vite stories: [
ladle:vite {
ladle:vite storyId: 'user-icon--default',
ladle:vite componentName: 'user$icon$$default',
ladle:vite namedExport: 'Default',
ladle:vite locStart: 3,
ladle:vite locEnd: 3
ladle:vite }
ladle:vite ],
ladle:vite exportDefaultProps: { title: undefined, meta: undefined },
ladle:vite namedExportToMeta: {},
ladle:vite namedExportToStoryName: {},
ladle:vite storyParams: {},
ladle:vite fileId: 'UserIcon'
ladle:vite } +1ms
ladle:vite C:\dev123\packages\frontend\.ladle/components.tsx found. +0ms
ladle:vite Custom provider found. +1ms
Failed to resolve import ".............ladleconfig.mjs" from "node_modules\@ladle\react\lib\app\generated\generated-list.tsx". Does the file exist?
Failed to resolve import ".............ladleconfig.mjs" from "node_modules\@ladle\react\lib\app\generated\generated-list.tsx". Does the file exist? (x2)
5:22:52 PM [vite] Internal server error: Failed to resolve import ".............ladleconfig.mjs" from "node_modules\@ladle\react\lib\app\generated\generated-list.tsx". Does the file exist?
Plugin: vite:import-analysis
File: C:/dev123/packages/frontend/node_modules/@ladle/react/lib/app/generated/generated-list.tsx
6 | export let stories = { "user-icon--default": { component: user$icon$$default } };
7 | export let config = {};
8 | import customConfig from ".............ladleconfig.mjs";
| ^
9 | config = customConfig;
10 | import { Provider as CustomProvider } from ".............ladlecomponents.tsx";
at formatError (C:\dev123\packages\frontend\node_modules\@ladle\react\node_modules\vite\dist\node\chunks\dep-5a245411.js:36027:46)
at TransformContext.error (C:\dev123\packages\frontend\node_modules\@ladle\react\node_modules\vite\dist\node\chunks\dep-5a245411.js:36023:19)
at normalizeUrl (C:\dev123\packages\frontend\node_modules\@ladle\react\node_modules\vite\dist\node\chunks\dep-5a245411.js:56731:26)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async TransformContext.transform (C:\dev123\packages\frontend\node_modules\@ladle\react\node_modules\vite\dist\node\chunks\dep-5a245411.js:56880:57)
at async Object.transform (C:\dev123\packages\frontend\node_modules\@ladle\react\node_modules\vite\dist\node\chunks\dep-5a245411.js:36262:30)
at async doTransform (C:\dev123\packages\frontend\node_modules\@ladle\react\node_modules\vite\dist\node\chunks\dep-5a245411.js:52681:29)
Failed to resolve import ".............ladleconfig.mjs" from "node_modules\@ladle\react\lib\app\generated\generated-list.tsx". Does the file exist?
Is there a way to use RNW components here?
In a fork of the default stackblitz, I am unable to use the radio button as documented in controls docs
export const Button = ({variant}: {variant: string}) => <button>Button {variant}</button>;
Button.argTypes = {
variant: {
options: ["primary", "secondary"],
control: { type: "radio" },
defaultValue: "primary",
},
};
Error message I got in the console
Uncaught TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at args-provider.tsx:13:12
chunk-M5UXS5QK.js?v=09754c74:13357 The above error occurred in the <ArgsProvider> component:
at ArgsProvider (https://ladle-a4m3ug--4123.local.webcontainer.io/src/args-provider.tsx:4:25)
at Provider (https://ladle-a4m3ug--4123.local.webcontainer.io/generated/generated-list.tsx:11:28)
at Suspense
at ErrorBoundary (https://ladle-a4m3ug--4123.local.webcontainer.io/src/error-boundary.tsx:4:5)
at Story (https://ladle-a4m3ug--4123.local.webcontainer.io/src/story.tsx:11:18)
at main
at App (https://ladle-a4m3ug--4123.local.webcontainer.io/src/app.tsx:24:41)
React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
Storybook supports a typescript: { check: true }
config option, which type checks the stories when building/developing the stories, and not only when opening a story in VSCode.
This is very helpful, and would improve Ladle a lot.
Laddel example throws error
When I run the example script and start ladle, it throws an error.
Steps to reproduce the behavior
mkdir my-ladle
cd my-ladle
yarn init --yes
yarn add @ladle/react react react-dom
mkdir src
echo "export const World = () => <p>Hey</p>;" > src/hello.stories.tsx
yarn ladle serve
Error:
[plugin:vite:import-analysis] Failed to resolve import "..
ode_modules@ladle
eactlibappsrc/story-hmr" from "src\hello.stories.tsx". Does the file exist?
C:/git/my-ladle/src/hello.stories.tsx:33:31
31 | }
32 |
33 | import { storyUpdated } from "..\node_modules\@ladle\react\lib\app\src/story-hmr";
| ^
34 | if (import.meta.hot) {
35 | import.meta.hot.accept(() => {
Expected behavior
A clear and concise description of what you expected to happen.
Desktop:
Is your feature request related to a problem? Please describe.
Support css.preprocessorOptions
as done in Vite.
Describe the solution you'd like
See above
โ
I think having the capacity to provide a middleware function to the config, e.g.
config: currentConfig => newConfig,
that will transform the vite config produced by vite-dev
, vite-prod
would enable developers to do all they need with the Vite config.
Storybook does the same with its webpack config.
Hello! It's mentioned in the docs that you have plans to add support for MDX to Ladle. Our team uses Storybook but we don't use CSF, rather we write all of our component stories in MDX and basically just use Storybook for rendering and building the stories.
Just out of curiosity, what would support for MDX look like in Ladle? Is this work already ongoing?
Thanks!
title
and component.storyName
doesn't allow to be set as variable.
const foo = 'Level / Sub level';
export default {
title: foo,
// Error: Can't parse the default title and meta of src/basic.stories.tsx.
// Meta must be serializable and title a string literal.
};
export const Button = () => <button>My Button</button>;
// Button.storyName = foo;
// Error: Button.storyName in src/basic.stories.tsx must be a string literal.
https://stackblitz.com/edit/ladle-bp6tgk?file=src%2Fbasic.stories.tsx
Hi,
is there the possibility to apply arguments to the .ladle/components.tsx
component?
I'm using a global context provider, which allows to change theme and language.
Therefore it would be great to toggle globally this properties.
Thank you for your great project!
Hello! I noticed that the base vite-config overrides the default esbuild loader for ts/tsx.
https://github.com/tajo/ladle/blob/master/packages/ladle/lib/cli/vite-base.js#L73
This causes errors in .ts
files that are using .ts
-specific syntax, for example:
The character ">" is not valid inside a JSX element
81 | value: TValue,
82 | options: UseCellOptions<TValue>
83 | ): SomeResult<TValue> => {
| ^
Is there a specific reason for this or can it be removed?
Ladle looks great, trying it as a testbed for playwright. Is there any way to access the variables in the .env
file? I noticed that doing something like VITE_VAR=foo yarn ladle serve
works.
It seems that Lerna is officially dead. It's probably a good time to modernize our setup. Tools that come in mind:
in my tsconfig I have
{
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},
}
and out of the box, when importing stories that use this import format I get "failed to resolve import" errors, which makes sense
seeing as ladle is based on vite, I looked up how to enable import aliases through vite, and found I can create a vite.config.js
like so:
import { defineConfig } from 'vite'
import path from 'path'
export default defineConfig({
resolve: {
alias: {
'~': path.resolve(__dirname, './app'),
},
},
})
however this doesn't seem to have any effect on import resolution in ladle and I still get the same error
11:50:35 AM [vite] Internal server error: Failed to resolve import "~/utils/classNames" from "app/components/Forms.tsx". Does the file exist?
Describe the bug
When developing components, Ladle does not detect correctly the changes. Cloning ladle repo and playing around with the example react project leads to this same issue.
Also, something I've noticed on the source code is that it would only watch for .stories.
and does not respect the glob we override (e.g: if I want my stories to have .fixture
instead)
To Reproduce
Expected behavior
When modifying a react component/source code it should reflect those changes, right now we only see Vite detecting those changes but nothing is actually propagated to the DOM.
Desktop (please complete the following information):
System:
OS: macOS 12.3.1
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 23.91 GB / 64.00 GB
Shell: 3.2.2 - /usr/local/bin/fish
Binaries:
Node: 16.15.0 - ~/.volta/tools/image/node/16.15.0/bin/node
Yarn: 1.22.18 - ~/.volta/tools/image/yarn/1.22.18/bin/yarn
npm: 8.5.5 - ~/.volta/tools/image/node/16.15.0/bin/npm
Browsers:
Chrome: 101.0.4951.54
Safari: 15.4
As ladle's config.mjs
will also be used in the browser environment, which did not support the Vite-only JavaScript syntax, it will throw this when importing some Vite plugins such as vite-plugin-svg-icons
:
Uncaught SyntaxError: Invalid left-hand side in assignment
Clone and configure this: https://github.com/pan93412/reproduce-ladle-config-issue
Open in any browser that supports DevTools, and we can see Uncaught SyntaxError: Invalid left-hand side in assignment
Separate the configuration for Vite from config.mjs
to vite-config.mjs
, so we only import Vite-specific plugins in the Vite environment.
Hey ๐
I love Ladle already. Its focus on performance is something I always wanted to see in Storybook. So, I wanna help it give a step forward to have a UI that matches its awesome engineering layers.
Here's is the design I made:
Here are the steps I imagined for this project:
If this layout is not what you expect, please, feel free to express your feelings.
Thanks for the attetion.
UPDATE
The PR is now open #101 as a draft
Is your feature request related to a problem? Please describe.
For @emotion/react
to work with the css={css({...style})}
feature it is needed that jsxImportSource: "@emotion/react"
is set as well as the babelPlugins: ["@emotion/babel-plugin"]
Currently you can not set the jsxImportSource
in the config because using @vite/react
is not allowed to be used twice.
Describe the solution you'd like
Expose jsxImportSource
to be set in the config.mjs
.
e.g.:
const config = {
babelPlugins: ["@emotion/babel-plugin"],
jsxImportSource: "@emotion/react",
};
export default config;
diff --git a/node_modules/@ladle/react/lib/cli/vite-base.js b/node_modules/@ladle/react/lib/cli/vite-base.js
index 1f8c430..706066d 100644
--- a/node_modules/@ladle/react/lib/cli/vite-base.js
+++ b/node_modules/@ladle/react/lib/cli/vite-base.js
@@ -110,6 +110,7 @@ const getBaseViteConfig = async (ladleConfig, configFolder, viteConfig) => {
ladlePlugin(ladleConfig, configFolder),
//@ts-ignore
react({
+ jsxImportSource: ladleConfig.jsxImportSource,
babel: {
parserOpts: ladleConfig.babelParserOpts,
presets: ladleConfig.babelPresets,
If you like I can submit a PR.
This is looking great so far, great work.
One issue, if I update a story file (e.g. by adding a new export) ladle does not auto refresh.
However, editing a component that the story references does cause a reload.
Have I missed a setting that would stop edits to a stories.tsx
file from refreshing?
Is your feature request related to a problem? Please describe.
We heavily use Storybook in Wix for screenshot testing our library components. What current storybook supports and will not deprecate until find a solution is storiesOf
function where you can generate a bunch of stories by using arrays of objects. With CSF you cannot achieve this.
Consider this story file as a way to render props permutation test stories:
const tests = [
{
describe: 'alignItems',
its: [
{
it: 'center',
props: {
alignItems: 'center',
},
},
{
it: 'right',
props: {
alignItems: 'right',
},
},
{
it: 'left',
props: {
alignItems: 'left',
},
},
],
},
tests.forEach(({ describe, its }) => {
its.forEach(({ it, props }) => {
storiesOf(`AddItem${describe ? '/' + describe : ''}`, module).add(
it,
() => <AddItem {...defaultProps} {...props} />,
);
});
});
This generates 3 stories and adding another one is easy for the next contributor.
Describe the solution you'd like
I think just by supporting similar method like storiesOf
ladle could be used for such cases or alternative solution that would support generating bunch of stories in a file based on some data structure.
Describe alternatives you've considered
For now storybook is the clear alternative or we would need to create some sort of story files with CSF generator based on mentioned data structure.
Thanks for making this tool! Excited to see the performance improvements the blog post touts.
I tried testing it out as a drop-in for Storybook in one of our projects and see the following error message. Any idea what might be going wrong? The closest relevant issue I see is this one from last November (which you happened to comment on) but theoretically that is now fixed so not sure if it's related.
โฏ yarn add --dev @ladle/react
...
โฏ DEBUG=ladle* yarn ladle serve
yarn run v1.22.17
$ /Users/nathan/work/go/src/github.com/opendoor-labs/code/js/packages/bricks-storybook/node_modules/.bin/ladle serve
ladle:cli Starting serve command +0ms
ladle:cli CLI theme: undefined +1ms
ladle:cli CLI stories: undefined +0ms
ladle:cli CLI port: undefined +0ms
ladle:cli CLI open: undefined +0ms
ladle:cli No custom config found. +4ms
ladle:cli Final config:
ladle:cli {
ladle:cli "stories": "src/**/*.stories.{js,jsx,ts,tsx}",
ladle:cli "root": "/Users/nathan/work/go/src/github.com/opendoor-labs/code/js/packages/bricks-storybook",
ladle:cli "defaultStory": "",
ladle:cli "babelPresets": [],
ladle:cli "babelPlugins": [],
ladle:cli "define": {},
ladle:cli "envPrefix": "VITE_",
ladle:cli "resolve": {
ladle:cli "alias": {}
ladle:cli },
ladle:cli "optimizeDeps": {
ladle:cli "include": []
ladle:cli },
ladle:cli "addons": {
ladle:cli "control": {
ladle:cli "enabled": true,
ladle:cli "defaultState": {}
ladle:cli },
ladle:cli "theme": {
ladle:cli "enabled": true,
ladle:cli "defaultState": "light"
ladle:cli },
ladle:cli "mode": {
ladle:cli "enabled": true,
ladle:cli "defaultState": "full"
ladle:cli },
ladle:cli "rtl": {
ladle:cli "enabled": true,
ladle:cli "defaultState": false
ladle:cli },
ladle:cli "ladle": {
ladle:cli "enabled": true
ladle:cli }
ladle:cli },
ladle:cli "serve": {
ladle:cli "open": "**Default**",
ladle:cli "port": 61000,
ladle:cli "define": {}
ladle:cli },
ladle:cli "build": {
ladle:cli "out": "build",
ladle:cli "sourcemap": false,
ladle:cli "baseUrl": "/",
ladle:cli "define": {}
ladle:cli }
ladle:cli } +0ms
ladle:cli Port set to: 61000 +3ms
Error: Failed to resolve force included dependency: react/jsx-dev-runtime
at addManuallyIncludedOptimizeDeps (/Users/nathan/work/go/src/github.com/opendoor-labs/code/js/packages/bricks-storybook/node_modules/vite/dist/node/chunks/dep-19d0f55f.js:35966:27)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async createOptimizeDepsRun (/Users/nathan/work/go/src/github.com/opendoor-labs/code/js/packages/bricks-storybook/node_modules/vite/dist/node/chunks/dep-19d0f55f.js:35721:13)
at async runOptimize (/Users/nathan/work/go/src/github.com/opendoor-labs/code/js/packages/bricks-storybook/node_modules/vite/dist/node/chunks/dep-19d0f55f.js:54927:30)
at async createServer (/Users/nathan/work/go/src/github.com/opendoor-labs/code/js/packages/bricks-storybook/node_modules/vite/dist/node/chunks/dep-19d0f55f.js:54961:9)
at async bundler (file:///Users/nathan/work/go/src/github.com/opendoor-labs/code/js/packages/bricks-storybook/node_modules/@ladle/react/lib/cli/vite-dev.js:38:18)
at async Command.serve (file:///Users/nathan/work/go/src/github.com/opendoor-labs/code/js/packages/bricks-storybook/node_modules/@ladle/react/lib/cli/serve.js:41:3)
For our aplication with css modules we enabled in webpack
exportLocalsConvention as "camelCase"
This results css like
.red-arrow {}
in import as
styles.redArrow
ladle does not seem to support this yet
Is your feature request related to a problem? Please describe.
I would like to streamline story namespaces using the Name Customization feature. However, it does not seem to be possible to use any logic exporting a story title.
Doing so a blank page is shown an I get this error in the browser console:
Uncaught SyntaxError: The requested module '/generated/generated-list.tsx' does not provide an export named 'storySource' (at source.tsx:6:1)
Working Example:
export default {
title: 'Core / Button',
};
Broken Exmaples:
export default {
title: 'Core' + ' / ' + 'Button',
};
or
export default {
title: `${'Core'} / ${'Button'}`,
};
My usecase:
// utils.ts
const getStoryName = (namespace: 'Core' | 'Features', componentName: string) =>
`${namespace} / ${componentName}`;
// button.story.ts
export default {
title: getStoryName('Core', 'Button'),
};
I've tried the example code and I'm getting an empty story:
Upon inspecting my console, there's this error:
Uncaught ReferenceError: React is not defined
...
I'm running it with npx ladle serve
, and both that and npx ladle build
+ a local webserver will render the frame properly, receive the correct data when clicking on the component (as seen in the example), but not render the component on the left. So I changed this code:
export default {
title: "Level / Sub level",
};
export const Button = () => <button>My Button</button>;
Into this one, and now it works, note the first line change:
import React from "react";
export default {
title: "Level / Sub level",
};
export const Button = () => <button>My Button</button>;
My react version is 17.0.2 (same as react-dom
) since 18.x is not yet official. Should we add the import React from "react";
to the docs? Or maybe I'm missing some config that would make it not needed? The only different thing I'm doing is running it with npx ladle serve
instead of yarn ladle serve
otherwise.
Steps to reproduce:
@ladle/react
, react
, react-dom
.src/button.jsx
.import React from 'react';
export const Provider = ({ children, globalState }) => (
<>
<h1>Theme: {globalState.theme}</h1>
{children}
</>
);
[plugin:vite:import-analysis] Failed to resolve import "............ladle.ladlecomponents.js" from "..\node_modules\@ladle\react\lib\app\generated\generated-list.tsx". Does the file exist?
C:[/packages/node_modules/@ladle/react/lib/app/generated/generated-list.tsx:17:0]()
6 | export let stories = { "button--default": { component: button$$default } };
7 | export let config = {};
8 | import { Provider as CustomProvider } from "............ladle.ladlecomponents.js";
| ^
9 | export const Provider = CustomProvider;
10 | if (import.meta.hot) {
at formatError ([packages\node_modules\vite\dist\node\chunks\dep-a7fb482c.js:36237:46]())
at TransformContext.error ([packages\node_modules\vite\dist\node\chunks\dep-a7fb482c.js:36233:19]())
at normalizeUrl ([packages\node_modules\vite\dist\node\chunks\dep-a7fb482c.js:56981:26]())
at processTicksAndRejections (node:internal[/process/task_queues:96:5]())
at async TransformContext.transform ([packages\node_modules\vite\dist\node\chunks\dep-a7fb482c.js:57130:57]())
at async Object.transform ([packages\node_modules\vite\dist\node\chunks\dep-a7fb482c.js:36474:30]())
at async doTransform ([packages\node_modules\vite\dist\node\chunks\dep-a7fb482c.]()
This is the code that generates the relative path:
However, this results in
'..\\..\\..\\..\\..\\..\\ladle\\.ladle\\components.js'
so this looks okay. However, the entire function returns
import {Provider as CustomProvider} from '..\..\..\..\..\..\ladle\.ladle\components.js';
! The double backslashes are gone.
So I monkey patched the code:
+ function escapePath(pathString) {
+ return pathString.replace(/\\/g, "\\\\");
+ }
- return `import {Provider as CustomProvider} from '${componentsRelativePath}';\nexport const Provider = CustomProvider;\n`;
+ return `import {Provider as CustomProvider} from '${escapePath(componentsRelativePath)}';\nexport const Provider = CustomProvider;\n`;
and boom, it worked!
It would be cool if we could pass alias object in the same way as define (ladleConfig.define).
Many of my projects depends on path resolving, as I can easily access nested files across project.
If I am not mistaken, the first code block should work just fine, but I've added a second solution as I don't work Vite quite often.
I would try to make a pull request, but I am not sure how to test/load Ladle from the local folder (as yarn add "/path-to-folder" does not work as I thought).
I guess you could add it just to https://github.com/tajo/ladle/blob/master/packages/ladle/lib/cli/vite-base.js
and few other places that use ladleConfig
.
// https://theroadtoenterprise.com/blog/how-to-set-up-path-resolving-in-vite
// vite.config.js
import { defineConfig } from 'vite';
import path from 'path';
export default defineConfig({
plugins: [],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@plugins': path.resolve(__dirname, './src/plugins'),
},
},
});
// https://stackoverflow.com/questions/68217795/vite-resolve-alias-how-to-resolve-paths
// vite.config.js
import { defineConfig } from 'vite';
import path from 'path';
export default defineConfig({
resolve: {
alias: [
{ find: '@', replacement: path.resolve(__dirname, './src') },
{ find: '@plugins', replacement: path.resolve(__dirname, './src/plugins') },
]
}
});
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.