- Architecture
- Development Setup
- Development Workflow
- Documentation Guidelines
- Testing Guidelines
- Contribution Process
The Lumen Design System is structured as a monorepo using Nx, with the following key libraries:
lumen
├──libs/
│ ├── ui-react/ # React components
│ │ # name: @ledgerhq/lumen-ui-react
│ │
│ ├── ui-rnative/ # React Native components
│ │ # name: @ledgerhq/lumen-ui-rnative
│ │
│ ├── ui-react-visualization/ # React visualization components
│ │ # name: @ledgerhq/lumen-ui-react-visualization
│ │
│ ├── ui-rnative-visualization/ # React Native components
│ │ # name: @ledgerhq/lumen-ui-rnative-visualization
│ │
│ ├── design-core/ # Design tokens and themes
│ │ # name: @ledgerhq/lumen-design-core
│ │
│ └── utils-shared/ # Shared utilities
│ # name: @ledgerhq/lumen-utils-shared
│
└──apps/
├── app-sandbox-rnative # Demo React-Native application
└── app-sandbox-react # Demo React application- NXJS libraries are prefixed by
@ledgerhq/lumen-*- defined in the project.json - NPM package will match the name of the NXJS library, to make a library publishable a private:false needs to be set
- Monorepo Management: Nx
- Documentation & Testing: Storybook & Chromatic
- Building & Bundling: Rollup & Vite
- Clone the repository:
git clone https://github.com/your-org/lumen.git
cd lumen- Setup proto Proto is a pluggable version manager, a unified toolchain. Installation docs
You might need to run this command to sync your bashprofile, or zshrc
proto setupThen run install to synchronize tools versions
proto installThen proto use
proto use- Install dependencies:
npm install --legacy-peer-deps- Start development environment:
# Build all libraries
npx nx run-many --target=build --all
# Start React Storybook
npx nx run @ledgerhq/lumen-ui-react:serve:storybook
# Start React Native Storybook
npx nx run @ledgerhq/lumen-ui-rnative:serve:storybook# Start React components in Storybook
npx nx run @ledgerhq/lumen-ui-react:serve:storybook
# Build React components
npx nx run @ledgerhq/lumen-ui-react:build
# Build React Native components
npx nx run @ledgerhq/lumen-ui-rnative:build
- Create a new branch from main
- Make your changes
- Add tests and stories
- Submit a pull request
Components are documented using Storybook stories. Create a .stories.tsx file next to your component:
import type { Meta, StoryObj } from '@storybook/react';
import { YourComponent } from './YourComponent';
const meta: Meta<typeof YourComponent> = {
component: YourComponent,
title: 'Components/YourComponent',
tags: ['autodocs'], // Enables automatic documentation
};
export default meta;
type Story = StoryObj<typeof YourComponent>;
// Basic usage example
export const Base: Story = {
args: {
// Component props
},
};To maintain consistency across our Storybook documentation, follow these naming rules:
The default, most basic usage of the component.
- ✅ Use:
Base - ❌ Do not use:
Default,Primary,Basic
Showcase stories demonstrate variations of a single property.
- ✅ Use the pattern:
{Property}Showcase - ❌ Do not use:
States,AllStates,StatesShowcase
Stories highlighting specific features.
- ✅ Use:
With{Feature}(e.g.,WithIcon,WithTooltip)
All stories should follow these visual guidelines:
- Layout: Stories should be centered.
- Background: Stories should use white background.
Example:
export const Base: Story = {
parameters: {
layout: 'centered',
backgrounds: { default: 'light' },
},
// ...
};Component documentation should use a two-tab structure for clarity:
Intent: Provide designers and developers with a comprehensive understanding of the component's purpose, behavior, and usage patterns.
Focus: Design specifications, visual examples, anatomy, properties, and accessibility guidelines.
Intent: Give developers practical, copy-paste ready code examples and integration patterns.
Focus: Installation instructions, code examples, API usage, routing integration, and best practices.
Example Structure:
import { CustomTabs, Tab } from '../../../../.storybook/components';
<CustomTabs>
<Tab label='Overview '>{/* Design documentation, anatomy, properties, showcases */}</Tab>
<Tab label='Implementation '>{/* Installation, code examples, do's and don'ts */}</Tab>
</CustomTabs>;- Include a clear component description
- Document all props and their types
- Provide usage examples
- Include accessibility considerations
- Document any known limitations or edge cases
- Follow the story naming conventions above for consistency
- Go to your Figma account settings
- Navigate to Security section
- In the Personal access tokens section, click Generate new token
- Give it a descriptive name (e.g., "Code Connect - Local Dev")
- Copy the token (it starts with
figd_)
Add your token to a .env file at the root of your project:
FIGMA_ACCESS_TOKEN=figd_your_token_hereOnce configured, you can skip the --token flag in all commands:
# Instead of this:
figma connect publish --token $FIGMA_ACCESS_TOKEN
# You can simply use:
figma connect publishAlways dry run before publishing to catch errors early:
# Dry run with directory
figma connect publish --dry-run --dir libs/ui-react/src/lib/Components/YourComponent/When working on a single component, publish only its directory:
figma connect publish --dir libs/ui-react/src/lib/Components/YourComponent/To publish Code Connect for the Symbol Library (Icons and CryptoIcons), use the dedicated config:
npx figma connect publish --config libs/ui-react/figma.symbol-lib.config.jsonIf a component connection is broken, unpublish it by node URL, and label, specified in figma.config.json:
figma connect unpublish --node "https://figma.com/file/abc?node-id=123" --label "React"Add interaction tests in your stories using the play function:
export const WithInteraction: Story = {
args: {
// Component props
},
play: async ({ canvasElement, step }) => {
// Test steps are automatically documented
await step('Click the button', async () => {
const button = canvasElement.querySelector('button');
button?.click();
});
},
};- Unit tests for all components
- Interaction tests for complex components
- Visual regression tests via Chromatic
- Accessibility tests
- Cross-browser testing
- Check existing issues and pull requests
- Discuss major changes in an issue first
- Review our coding standards
- Set up your development environment
- Write clean, maintainable code
- Follow the existing code style
- Add or update tests as needed
- Update documentation
- Test your changes thoroughly
- Create a pull request
- Fill out the pull request template
- Reference any related issues
- Wait for code review
- Address feedback
- All changes must be reviewed
- Changes must pass automated tests
- Documentation must be updated
- Breaking changes must be clearly marked
- Join our Discord community
- Check the FAQ in the wiki
- Open an issue for bugs
- Discuss features in discussions
Thank you for contributing to Lumen! 🎉