Skip to content

Commit 0ddfed3

Browse files
WallgauOlfa MaslahCristhian ZanforlinOlfa Maslah
authored
Feat: add storybook setup (langflow-ai#10721)
* feat(storybook): add Storybook setup and Button component stories - Add Storybook configuration files (.storybook/main.ts, preview.ts, css.d.ts) - Add Button component stories with interaction testing - Add Storybook dependencies and scripts to package.json - Support dark mode in stories via decorator - Include play functions for automated interaction testing * ci(storybook): add GitHub Pages deployment workflow - Add automated deployment workflow for Storybook - Deploy on push to main when Storybook files change - Support manual trigger via workflow_dispatch - Use official GitHub Actions for Pages deployment * fix(storybook): align Storybook versions and fix TypeScript issues - Update all @storybook/* packages from ^8.4.7 to ^8.6.14 to match main storybook version - Fix CSS type declarations in css.d.ts (Record<string, string> instead of Record<string, never>) - Remove @ts-ignore comments from preview.ts (CSS imports now properly typed) - Fix darkMode type issue in button.stories.tsx with proper ArgTypes type assertion * feat(storybook): replace Button stories with Dropdown component stories - Remove Button stories (shadcn already has documentation) - Add comprehensive Dropdown component stories showcasing: - Default, with value, combobox mode - With metadata, disabled, loading states - Many options, searchable filtering - Dark mode support - Add store initialization decorator for Storybook - Include interaction testing with play functions * feat(storybook): add SettingsPage stories and remove dropdown stories - Remove dropdown component stories - Add SettingsPage stories with router, store, and dark mode decorators - Include variants: default, with general settings, and dark mode * feat(storybook): fix SettingsPage stories to show full page and add play functions - Fix router setup to properly render SettingsPage with nested routes - Add Routes configuration for all settings sub-pages (General, MCP Servers, Global Variables, Shortcuts, Messages) - Add play functions to test page visibility and navigation - Add stories for different routes: Default, WithGeneralSettings, NavigateToShortcuts, NavigateToGlobalVariables, DarkMode * revert(storybook): restore SettingsPage stories to original working version - Revert to simpler router setup without Routes configuration - Remove play functions and complex routing - Restore original three stories: Default, WithGeneralSettings, DarkMode * feat(storybook): add stories for ShortcutsPage and GlobalVariablesPage with tables - Add ShortcutsPage stories showing the shortcuts table - Add GlobalVariablesPage stories showing the global variables table - Include store setup for shortcuts data - Add play functions to verify table visibility - Support dark mode for both pages * fix(storybook): add QueryClientProvider to GlobalVariablesPage stories - Add QueryClientProvider decorator to support React Query hooks - Configure QueryClient with retry disabled for Storybook * fix(storybook): remove WithGeneralSettings story to fix nested router error - Remove WithGeneralSettings story that was causing nested Router error - Keep Default and DarkMode stories only * feat(storybook): enhance SettingsPage stories with multiple states and logic variations - Add stories showcasing different store configurations (autoLogin, hasStore) - Demonstrate conditional General settings visibility logic - Add interactive sidebar navigation story - Show full configuration with all features - Include play functions to verify state-based behavior - Showcase how page adapts to different user/auth states * fix(storybook): initialize Zustand stores synchronously in SettingsPage stories - Set store state before component render instead of in useEffect - Ensures stores are accessible when SettingsPage component mounts - Fixes state access errors in Storybook * feat(storybook): add story to verify store state accessibility - Add VerifyStoreState story that demonstrates accessing Zustand store state - Verify store values match expected configuration - Show that state is accessible from play functions * fix(storybook): remove router from SettingsPage stories to fix errors - Remove MemoryRouter decorator that was causing errors - Keep store setup and dark mode decorators - Stories now work without router dependency * fix(storybook): add router back to SettingsPage stories for useNavigate support - Add MemoryRouter back to support useCustomNavigate hook in PageLayout - Router is needed for navigation hooks to work properly - Keep router at decorator level to avoid nested router errors * fix(storybook): fix router decorator order in SettingsPage stories - Move router decorator to be outermost (last in array) - Decorators run bottom-to-top, so router should wrap everything - Ensures useNavigate context is available to all components * feat(storybook): add PlaygroundPage story as example for complex page stories - Add PlaygroundPage story demonstrating how to create stories for complex pages - Include darkMode toggle control as example for interactive story controls - Set up decorators for query client, router, and theme switching - Hide publish elements (Theme buttons, Built with Langflow) in story view - Center chat title header in story view - Configure Storybook preview and CSS types This story serves as a reference for creating stories for full page components rather than simple UI components, which are already documented in shadcn docs. * chore(storybook): remove SettingsPage stories Keep only PlaygroundPage story as the example for complex page stories. * chore: restore pyproject.toml to match main branch * chore: restore pyproject.toml to match main branch * Revert "chore: restore pyproject.toml to match main branch" This reverts commit a2b75a4. * chore: remove src/frontend/pyproject.toml as it doesn't exist in main * fix gitignore and add make commands * update package-json * chore(storybook): migrate from v8.6.14 to v10.1.0 - Update all Storybook packages to v10.1.0 - Replace @storybook/addon-essentials with @storybook/addon-docs - Remove @storybook/addon-interactions (moved to core) - Remove @storybook/blocks and @storybook/test (consolidated) - Fix import in PlaygroundPage.stories.tsx to use @storybook/react - Update tsconfig.json moduleResolution to 'bundler' for better compatibility - Add explicit types configuration for @storybook/react * fix: update package-lock.json to sync with package.json * fix: regenerate package-lock.json with all optional dependencies --------- Co-authored-by: Olfa Maslah <[email protected]> Co-authored-by: Cristhian Zanforlin <[email protected]> Co-authored-by: Olfa Maslah <[email protected]>
1 parent 5226daa commit 0ddfed3

File tree

12 files changed

+4505
-3135
lines changed

12 files changed

+4505
-3135
lines changed

.eslintrc.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"extends": [
33
"eslint:recommended",
44
"plugin:react/recommended",
5-
"plugin:prettier/recommended"
5+
"plugin:prettier/recommended",
6+
"plugin:storybook/recommended"
67
],
78
"plugins": [
89
"react",
@@ -87,4 +88,4 @@
8788
"node/prefer-promises/dns": "error",
8889
"node/prefer-promises/fs": "error"
8990
}
90-
}
91+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Deploy Storybook to GitHub Pages
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'src/frontend/**/*.stories.*'
9+
- 'src/frontend/.storybook/**'
10+
- 'src/frontend/package.json'
11+
- '.github/workflows/deploy-storybook.yml'
12+
workflow_dispatch: # Allow manual trigger
13+
14+
jobs:
15+
deploy:
16+
name: Deploy Storybook
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
pages: write
21+
id-token: write
22+
23+
steps:
24+
- uses: actions/checkout@v6
25+
26+
- uses: actions/setup-node@v4
27+
with:
28+
node-version: 22
29+
cache: npm
30+
cache-dependency-path: src/frontend/package-lock.json
31+
32+
- name: Install dependencies
33+
run: cd src/frontend && npm ci
34+
35+
- name: Build Storybook
36+
run: cd src/frontend && npm run build-storybook
37+
38+
- name: Setup Pages
39+
uses: actions/configure-pages@v4
40+
41+
- name: Upload artifact
42+
uses: actions/upload-pages-artifact@v3
43+
with:
44+
path: src/frontend/storybook-static
45+
46+
- name: Deploy to GitHub Pages
47+
id: deployment
48+
uses: actions/deploy-pages@v4
49+

Makefile.frontend

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
FRONTEND_DIR = src/frontend
66
NPM = npm
77

8-
.PHONY: install_frontend install_frontendci install_frontendc frontend_deps_check build_frontend run_frontend frontend frontendc format_frontend tests_frontend test_frontend test_frontend_watch test_frontend_coverage test_frontend_verbose test_frontend_ci test_frontend_clean test_frontend_file test_frontend_pattern test_frontend_snapshots test_frontend_config test_frontend_bail test_frontend_silent test_frontend_coverage_open help_frontend
8+
.PHONY: install_frontend install_frontendci install_frontendc frontend_deps_check build_frontend run_frontend frontend frontendc format_frontend tests_frontend test_frontend test_frontend_watch test_frontend_coverage test_frontend_verbose test_frontend_ci test_frontend_clean test_frontend_file test_frontend_pattern test_frontend_snapshots test_frontend_config test_frontend_bail test_frontend_silent test_frontend_coverage_open help_frontend storybook storybook_build storybook_network
99

1010
######################
1111
# FRONTEND DEPENDENCIES
@@ -166,6 +166,23 @@ test_frontend_coverage_open: test_frontend_coverage ## run tests with coverage a
166166
echo "Coverage report generated at: $(FRONTEND_DIR)/coverage/lcov-report/index.html"; \
167167
fi
168168

169+
######################
170+
# STORYBOOK
171+
######################
172+
173+
storybook: frontend_deps_check ## run Storybook development server and open in browser
174+
@echo "Starting Storybook development server on http://localhost:6006..."
175+
@cd $(FRONTEND_DIR) && $(NPM) run storybook
176+
177+
storybook_build: frontend_deps_check ## build static Storybook
178+
@echo "Building static Storybook..."
179+
@cd $(FRONTEND_DIR) && $(NPM) run build-storybook
180+
@echo "Storybook built to $(FRONTEND_DIR)/storybook-static"
181+
182+
storybook_network: frontend_deps_check ## run Storybook accessible on network (0.0.0.0:6006)
183+
@echo "Starting Storybook development server accessible on network..."
184+
@cd $(FRONTEND_DIR) && $(NPM) run storybook:network
185+
169186
######################
170187
# FRONTEND HELP
171188
######################
@@ -212,5 +229,10 @@ help_frontend: ## show frontend help
212229
@echo " $(GREEN)make test_frontend_snapshots$(NC) - Update Jest snapshots"
213230
@echo " $(GREEN)make test_frontend_config$(NC) - Show Jest configuration"
214231
@echo ''
232+
@echo "$(GREEN)Storybook:$(NC)"
233+
@echo " $(GREEN)make storybook$(NC) - Run Storybook dev server and open in browser"
234+
@echo " $(GREEN)make storybook_build$(NC) - Build static Storybook"
235+
@echo " $(GREEN)make storybook_network$(NC) - Run Storybook accessible on network"
236+
@echo ''
215237
@echo "$(GREEN)═══════════════════════════════════════════════════════════════════$(NC)"
216238
@echo ''

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ dependencies = [
135135
"fastparquet>=2024.11.0,<2025.0.0",
136136
"traceloop-sdk>=0.43.1,<1.0.0",
137137
"vlmrun[all]>=0.2.0",
138-
"cuga==0.1.11",
138+
"cuga==0.1.10",
139139
"agent-lifecycle-toolkit~=0.4.1",
140140
"astrapy>=2.1.0,<3.0.0",
141141
"aioboto3>=15.2.0,<16.0.0"

src/frontend/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
# production
1212
/build
1313

14+
# storybook
15+
/storybook-static
16+
*storybook.log
17+
1418
# misc
1519
.DS_Store
1620
.env.local

src/frontend/.storybook/css.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Type declarations for CSS imports in Storybook
2+
declare module "*.css" {
3+
const content: Record<string, string>;
4+
export default content;
5+
}

src/frontend/.storybook/main.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// This file has been automatically migrated to valid ESM format by Storybook.
2+
import { fileURLToPath } from "node:url";
3+
import type { StorybookConfig } from "@storybook/react-vite";
4+
import path, { dirname } from "path";
5+
import { mergeConfig } from "vite";
6+
7+
const __filename = fileURLToPath(import.meta.url);
8+
const __dirname = dirname(__filename);
9+
10+
const config: StorybookConfig = {
11+
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
12+
addons: ["@storybook/addon-links", "@storybook/addon-docs"],
13+
framework: {
14+
name: "@storybook/react-vite",
15+
options: {},
16+
},
17+
async viteFinal(config) {
18+
return mergeConfig(config, {
19+
resolve: {
20+
alias: {
21+
"@": path.resolve(__dirname, "../src"),
22+
},
23+
},
24+
});
25+
},
26+
typescript: {
27+
check: false,
28+
reactDocgen: "react-docgen-typescript",
29+
reactDocgenTypescriptOptions: {
30+
shouldExtractLiteralValuesFromEnum: true,
31+
propFilter: (prop) => {
32+
if (prop.parent) {
33+
return !prop.parent.fileName.includes("node_modules");
34+
}
35+
return true;
36+
},
37+
},
38+
},
39+
};
40+
41+
export default config;

src/frontend/.storybook/preview.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import type { Preview } from "@storybook/react-vite";
2+
import * as React from "react";
3+
import { useEffect } from "react";
4+
// Import all CSS files to match the app's styling
5+
import "../src/style/classes.css";
6+
import "../src/style/index.css";
7+
import "../src/App.css";
8+
import "../src/style/applies.css";
9+
import { TooltipProvider } from "../src/components/ui/tooltip";
10+
import { useDarkStore } from "../src/stores/darkStore";
11+
12+
// Global decorator to provide TooltipProvider for all stories
13+
const withTooltipProvider = (Story: React.ComponentType) => {
14+
const TooltipWrapper = (): React.ReactElement => {
15+
const storyElement = React.createElement(Story);
16+
return React.createElement(TooltipProvider, {
17+
skipDelayDuration: 0,
18+
children: storyElement,
19+
});
20+
};
21+
return React.createElement(TooltipWrapper);
22+
};
23+
24+
// Global decorator to handle dark mode for all stories
25+
const withTheme = (
26+
Story: React.ComponentType,
27+
context: {
28+
args?: { darkMode?: boolean };
29+
initialArgs?: { darkMode?: boolean };
30+
parameters?: { darkMode?: boolean };
31+
globals?: { theme?: string };
32+
},
33+
) => {
34+
const ThemeWrapper = (): React.ReactElement => {
35+
// Check for dark mode in args, parameters, or globals
36+
const dark =
37+
context.args?.darkMode === true ||
38+
context.initialArgs?.darkMode === true ||
39+
context.parameters?.darkMode === true ||
40+
context.globals?.theme === "dark";
41+
42+
useEffect(() => {
43+
const bodyElement = document.getElementById("body") || document.body;
44+
const htmlElement = document.documentElement;
45+
46+
if (dark) {
47+
bodyElement.classList.add("dark");
48+
htmlElement.classList.add("dark");
49+
useDarkStore.setState({ dark: true });
50+
} else {
51+
bodyElement.classList.remove("dark");
52+
htmlElement.classList.remove("dark");
53+
useDarkStore.setState({ dark: false });
54+
}
55+
}, [dark]);
56+
57+
// Sync immediately on render
58+
const bodyElement = document.getElementById("body") || document.body;
59+
const htmlElement = document.documentElement;
60+
if (dark) {
61+
bodyElement.classList.add("dark");
62+
htmlElement.classList.add("dark");
63+
} else {
64+
bodyElement.classList.remove("dark");
65+
htmlElement.classList.remove("dark");
66+
}
67+
68+
return React.createElement(Story);
69+
};
70+
71+
return React.createElement(ThemeWrapper);
72+
};
73+
74+
const preview: Preview = {
75+
decorators: [withTooltipProvider, withTheme],
76+
parameters: {
77+
actions: { argTypesRegex: "^on[A-Z].*" },
78+
controls: {
79+
matchers: {
80+
color: /(background|color)$/i,
81+
date: /Date$/i,
82+
},
83+
},
84+
},
85+
};
86+
87+
export default preview;

0 commit comments

Comments
 (0)