Skip to content

Commit

Permalink
Add ladle plugin (#728)
Browse files Browse the repository at this point in the history
Co-authored-by: Lars Kappert <lars@webpro.nl>
  • Loading branch information
justb3a and webpro authored Jul 22, 2024
1 parent ae5c341 commit ebd79d4
Show file tree
Hide file tree
Showing 16 changed files with 225 additions and 4 deletions.
1 change: 0 additions & 1 deletion .bun-version

This file was deleted.

3 changes: 1 addition & 2 deletions .github/workflows/ci-bun.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version-file: '.bun-version'
- run: bun upgrade --canary
- name: Install dependencies
run: bun install --ignore-scripts --frozen-lockfile
- name: Run formatter, linter, import sorter
Expand Down
5 changes: 5 additions & 0 deletions packages/knip/fixtures/plugins/ladle/.ladle/components.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { type GlobalProvider } from "@ladle/react";
import React from "react";

// For details see https://ladle.dev/docs/providers
export const Provider: GlobalProvider = ({ children }) => <div>{children}</div>;
6 changes: 6 additions & 0 deletions packages/knip/fixtures/plugins/ladle/.ladle/config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// For details see https://ladle.dev/docs/config
/** @type {import('@ladle/react').UserConfig} */
export default {
stories: "app/**/*.stories.{tsx,mdx}",
viteConfig: "./.ladle/vite.config.ts",
};
7 changes: 7 additions & 0 deletions packages/knip/fixtures/plugins/ladle/.ladle/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from "vite";

export default defineConfig({
server: {
open: false,
},
});
39 changes: 39 additions & 0 deletions packages/knip/fixtures/plugins/ladle/app/basic.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export const Hello = () => <h2>Simple Story</h2>;

export const Responsive = () => {
return (
<>
<div
style={{
width: '100',
background: '#000',
color: '#FFF',
padding: '32px 32px',
border: '1px solid black',
fontFamily: 'arial',
fontSize: 28,
}}
>
Header
</div>
<button
style={{
padding: '16px 102px',
fontFamily: 'arial',
fontSize: 22,
margin: 32,
borderRadius: 8,
color: '#174291',
border: '2px solid #174291',
background: '#FFF',
}}
>
Ladle v4
</button>
</>
);
};
Responsive.meta = {
width: 'xsmall',
};

37 changes: 37 additions & 0 deletions packages/knip/fixtures/plugins/ladle/app/control.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { Story } from "@ladle/react";

export const Controls: Story<{
label: string;
disabled: boolean;
count: number;
colors: string[];
variant: string;
size: string;
}> = ({ count, disabled, label, colors, variant, size }) => (
<>
<p>Count: {count}</p>
<p>Disabled: {disabled ? "yes" : "no"}</p>
<p>Label: {label}</p>
<p>Colors: {colors.join(",")}</p>
<p>Variant: {variant}</p>
<p>Size: {size}</p>
</>
);

Controls.args = {
label: "Hello world",
disabled: false,
count: 2,
colors: ["Red", "Blue"],
};
Controls.argTypes = {
variant: {
options: ["primary", "secondary"],
control: { type: "radio" },
defaultValue: "primary",
},
size: {
options: ["small", "medium", "big", "huuuuge"],
control: { type: "select" },
},
};
19 changes: 19 additions & 0 deletions packages/knip/fixtures/plugins/ladle/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@fixtures/ladle",
"type": "module",
"scripts": {
"dev": "ladle serve --port 4123",
"build": "ladle build"
},
"dependencies": {
"@ladle/react": "*",
"react": "*",
"react-dom": "*"
},
"devDependencies": {
"@types/node": "*",
"@types/react": "*",
"@types/react-dom": "*",
"typescript": "*"
}
}
20 changes: 20 additions & 0 deletions packages/knip/fixtures/plugins/ladle/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src"]
}
4 changes: 4 additions & 0 deletions packages/knip/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,10 @@
"title": "Jest plugin configuration (https://knip.dev/reference/plugins/jest)",
"$ref": "#/definitions/plugin"
},
"ladle": {
"title": "ladle plugin configuration (https://knip.dev/reference/plugins/ladle)",
"$ref": "#/definitions/plugin"
},
"lefthook": {
"title": "lefthook plugin configuration (https://knip.dev/reference/plugins/lefthook)",
"$ref": "#/definitions/plugin"
Expand Down
1 change: 1 addition & 0 deletions packages/knip/src/ConfigurationValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const pluginsSchema = z.object({
'graphql-codegen': pluginSchema,
husky: pluginSchema,
jest: pluginSchema,
ladle: pluginSchema,
lefthook: pluginSchema,
'lint-staged': pluginSchema,
linthtml: pluginSchema,
Expand Down
2 changes: 1 addition & 1 deletion packages/knip/src/binaries/resolvers/bun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import parseArgs from 'minimist';
import type { Resolver } from '../types.js';
import { tryResolveFilePath } from '../util.js';

const commands = ['add', 'create', 'init', 'install', 'link', 'pm', 'remove', 'run', 'test', 'update'];
const commands = ['add', 'create', 'init', 'install', 'link', 'pm', 'remove', 'run', 'test', 'update', 'upgrade'];

export const resolve: Resolver = (_binary, args, { manifestScriptNames, cwd, fromArgs }) => {
const parsed = parseArgs(args);
Expand Down
1 change: 1 addition & 0 deletions packages/knip/src/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export { default as githubActions } from './github-actions/index.js';
export { default as graphqlCodegen } from './graphql-codegen/index.js';
export { default as husky } from './husky/index.js';
export { default as jest } from './jest/index.js';
export { default as ladle } from './ladle/index.js';
export { default as lefthook } from './lefthook/index.js';
export { default as linthtml } from './linthtml/index.js';
export { default as lintStaged } from './lint-staged/index.js';
Expand Down
50 changes: 50 additions & 0 deletions packages/knip/src/plugins/ladle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { EnablerPatterns } from '#p/types/config.js';
import type { IsPluginEnabled, Plugin, ResolveConfig, ResolveEntryPaths } from '#p/types/plugins.js';
import { toAbsolute } from '#p/util/path.js';
import { hasDependency, load } from '#p/util/plugin.js';
import { toEntryPattern } from '../../util/protocols.js';
import { resolveConfig as resolveVitestConfig } from '../vitest/index.js';
import type { LadleConfig } from './types.js';

// https://ladle.dev/docs/config

const title = 'Ladle';

const enablers: EnablerPatterns = ['@ladle/react'];

const isEnabled: IsPluginEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);

const config = ['.ladle/config.{mjs,js,ts}'];

const stories = ['src/**/*.stories.{js,jsx,ts,tsx,mdx}'];
const restEntry = ['.ladle/components.{js,jsx,ts,tsx}'];
const entry = [...restEntry, ...stories];

const project = ['.ladle/**/*.{js,jsx,ts,tsx}'];

const resolveEntryPaths: ResolveEntryPaths<LadleConfig> = (localConfig, options) => {
const localStories = typeof localConfig.stories === 'string' ? [localConfig.stories] : localConfig.stories;
const viteConfig = localConfig.viteConfig ? [toAbsolute(localConfig.viteConfig, options.cwd)] : [];
const patterns = [...restEntry, ...(localStories ?? stories), ...viteConfig];
return patterns.map(toEntryPattern);
};

const resolveConfig: ResolveConfig<LadleConfig> = async (localConfig, options) => {
if (localConfig.viteConfig) {
const viteConfigPath = toAbsolute(localConfig.viteConfig, options.cwd);
const viteConfig = await load(viteConfigPath);
return resolveVitestConfig(viteConfig, options);
}
return [];
};

export default {
title,
enablers,
isEnabled,
config,
entry,
project,
resolveEntryPaths,
resolveConfig,
} satisfies Plugin;
4 changes: 4 additions & 0 deletions packages/knip/src/plugins/ladle/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type LadleConfig = {
stories?: string | string[];
viteConfig?: string;
};
30 changes: 30 additions & 0 deletions packages/knip/test/plugins/ladle.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { test } from 'bun:test';
import assert from 'node:assert/strict';
import { main } from '../../src/index.js';
import { resolve } from '../../src/util/path.js';
import baseArguments from '../helpers/baseArguments.js';
import baseCounters from '../helpers/baseCounters.js';

const cwd = resolve('fixtures/plugins/ladle');

test('Find dependencies with the ladle plugin', async () => {
const { issues, counters } = await main({
...baseArguments,
cwd,
});

assert(issues.dependencies['package.json']['react-dom']);
assert(issues.devDependencies['package.json']['@types/react-dom']);
assert(issues.binaries['package.json']['ladle']);
assert(issues.unlisted['.ladle/vite.config.ts']['vite']);

assert.deepEqual(counters, {
...baseCounters,
binaries: 1,
dependencies: 1,
devDependencies: 1,
unlisted: 1,
processed: 5,
total: 5,
});
});

0 comments on commit ebd79d4

Please sign in to comment.