A modern collection of reusable form web components built with Lit and showcased with Storybook.
# Install dependencies
npm install
# Start development server
npm run dev
# Start Storybook (recommended for component development)
npm run storybook
# Build for production
npm run build
# Build Storybook for deployment
npm run build-storybook
# Preview production build
npm run preview- Node.js (v18 or higher)
- npm or pnpm
| Script | Description |
|---|---|
npm run dev |
Start Vite development server (http://localhost:5173) |
npm run build |
Build for production |
npm run preview |
Preview production build |
npm run storybook |
Start Storybook development server (http://localhost:6006) |
npm run build-storybook |
Build Storybook for deployment |
src/
├── components/ # Web components (co-located with stories)
│ ├── AppButton/
│ │ ├── AppButton.ts # Component implementation
│ │ ├── AppButton.stories.ts # Storybook stories
│ │ └── index.ts # Component export
│ ├── TextInput/
│ │ ├── TextInput.ts
│ │ ├── TextInput.stories.ts
│ │ └── index.ts
│ ├── SelectDropdown/
│ ├── DynamicForm/
│ ├── FormContainer/
│ ├── CompleteDemo.stories.ts # Full examples
│ └── index.ts # Main component exports
├── main.ts # Demo application entry
├── style.css # Global styles
└── vite-env.d.ts # TypeScript environment
This project includes 5 production-ready form components:
A versatile button component with multiple visual variants.
Properties:
variant:'primary' | 'secondary' | 'link'- Button style variantdisabled:boolean- Whether the button is disabled
Events:
button-click- Fired when the button is clicked
Usage:
<app-button variant="primary">Primary Button</app-button>
<app-button variant="secondary">Secondary Button</app-button>
<app-button variant="link">Link Button</app-button>A flexible text input component with label, validation, and error states.
Properties:
label:string- Label textvalue:string- Input valuetype:string- HTML input type (text, email, password, etc.)required:boolean- Whether the field is requiredplaceholder:string- Placeholder textdisabled:boolean- Whether the input is disablederror:string- Error message to display
Events:
input-change- Fired when the input value changesinput-blur- Fired when the input loses focus
Usage:
<text-input
label="Email Address"
type="email"
required
placeholder="you@example.com">
</text-input>A customizable select dropdown with support for string or object options.
Properties:
label:string- Label textvalue:string- Selected valueoptions:Array<string | SelectOption>- Available optionsrequired:boolean- Whether selection is requireddisabled:boolean- Whether the select is disabledplaceholder:string- Placeholder texterror:string- Error message to display
Events:
select-change- Fired when the selection changes
Usage:
<!-- String options -->
<select-dropdown
label="Color"
.options=${['Red', 'Green', 'Blue']}>
</select-dropdown>
<!-- Object options -->
<select-dropdown
label="Role"
.options=${[
{ value: 'admin', label: 'Administrator' },
{ value: 'user', label: 'User' }
]}>
</select-dropdown>A form container that handles submission and reset for custom web components.
Properties:
showActions:boolean- Whether to show submit/reset buttonssubmitText:string- Text for submit buttonresetText:string- Text for reset buttondisabled:boolean- Whether form actions are disabled
Events:
form-submit- Fired when form is submitted with collected dataform-reset- Fired when form is reset
Usage:
<dynamic-form>
<text-input label="Name" required></text-input>
<select-dropdown label="Department" required></select-dropdown>
</dynamic-form>A container component that provides consistent styling and layout for forms.
Properties:
title:string- Container titledescription:string- Container descriptionvariant:'default' | 'compact' | 'wide'- Size variantborderless:boolean- Whether to remove borders
Usage:
<form-container
title="User Registration"
description="Create your account">
<!-- Form content -->
</form-container>- 🎨 Modern Design System - Consistent styling and theming
- ♿ Accessibility First - ARIA support and keyboard navigation
- 📱 Responsive - Works on desktop, tablet, and mobile
- 🔧 TypeScript - Full type safety and IntelliSense
- 📖 Storybook Integration - Interactive documentation and testing
- ⚡ Performance - Optimized with Lit's efficient rendering
- 🧪 Testing Ready - Prepared for unit and integration tests
- 🎯 Path Aliases - Clean imports with
@/components
These components work in all modern browsers that support:
- Custom Elements v1
- Shadow DOM v1
- ES2017+
Supported browsers:
- Chrome 54+
- Firefox 63+
- Safari 10.1+
- Edge 79+
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-component - Make your changes
- Add/update tests and Storybook stories
- Ensure accessibility compliance
- Submit a pull request
MIT License - see LICENSE file for details.