ql-dev-ui
v1.0.0
Published
React component library (library only — not an application). Consume in your own React app.
Readme
ql-dev-ui
React component library with theme-driven components. Consume in your own React app — this is a library, not an application.
Installation
pnpm add ql-dev-ui reactPeer dependency: React 18+
Quick Start
import { ThemeProvider, Button } from "ql-dev-ui";
function App() {
return (
<ThemeProvider>
<Button label="Save" onClick={() => console.log("saved")} />
</ThemeProvider>
);
}Theme Setup
All components use ThemeProvider for colors, spacing, radius, and typography.
Basic Usage (default light theme)
import { ThemeProvider } from "ql-dev-ui";
<ThemeProvider>
<YourApp />
</ThemeProvider>Custom Colors
import { ThemeProvider } from "ql-dev-ui";
const customTheme = {
colors: {
primary: "#094ed2",
primaryHover: "#0846bd",
primaryActive: "#073ea8",
secondary: "#f1f2f5",
secondaryHover: "#e2e4eb",
secondaryActive: "#a2a8bd",
danger: "#f04438",
dangerHover: "#d83032",
dangerActive: "#c0362d",
textLight: "#ffffff",
textDark: "#393b42",
disabledBg: "#e2e4eb",
disabledText: "#a2a8bd",
},
};
<ThemeProvider theme={customTheme}>
<YourApp />
</ThemeProvider>Built-in Light / Dark Themes
import { ThemeProvider, lightTheme, darkTheme } from "ql-dev-ui";
// Light theme
<ThemeProvider theme={lightTheme}>
<YourApp />
</ThemeProvider>
// Dark theme
<ThemeProvider theme={darkTheme}>
<YourApp />
</ThemeProvider>Theme Switching (Light ⇄ Dark)
import { ThemeSwitcherProvider, ThemeToggle } from "ql-dev-ui";
function App() {
return (
<ThemeSwitcherProvider initialTheme="light">
<ThemeToggle /> {/* Toggle button */}
<YourContent />
</ThemeSwitcherProvider>
);
}Extended Theme Overrides
<ThemeProvider
theme={{
colors: { primary: "#2563eb", primaryHover: "#1d4ed8" },
spacing: { sm: "10px", md: "14px", lg: "18px" },
radius: { sm: "4px", md: "8px", lg: "12px" },
fontSize: { sm: "13px", md: "14px", lg: "16px" },
}}
>
<YourApp />
</ThemeProvider>Theme Hook
import { useTheme } from "ql-dev-ui";
function MyComponent() {
const theme = useTheme();
const { colors, spacing, radius, fontSize } = theme ?? {};
return <div style={{ color: colors?.primary }}>Themed content</div>;
}Components
Button
import { Button } from "ql-dev-ui";
// Basic
<Button label="Save" onClick={handleSave} />
<Button onClick={handleSubmit}>Submit</Button>
// Variants: primary | secondary | danger
<Button label="Primary" variant="primary" />
<Button label="Secondary" variant="secondary" />
<Button label="Delete" variant="danger" />
// Sizes: sm | md | lg
<Button label="Small" size="sm" />
<Button label="Large" size="lg" />
// States
<Button label="Disabled" disabled />
<Button label="Loading…" loading loadingText="Saving…" />
// With icons
<Button label="Save" iconLeft={<SaveIcon />} />
<Button label="Next" iconRight={<ArrowIcon />} />
// Full width, form submit
<Button label="Submit" fullWidth type="submit" />Props: children, label, iconLeft, iconRight, variant, size, disabled, loading, loadingText, fullWidth, type, onClick, style, className, ariaLabel
Input
import { Input } from "ql-dev-ui";
// Basic
<Input
label="Username"
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Enter username"
/>
// Error state
<Input
label="Email"
error={!!errors.email}
errorMessage={errors.email}
/>
// Textarea (use rows)
<Input label="Bio" rows={4} value={bio} onChange={(e) => setBio(e.target.value)} />
// With leading icon
<Input label="Search" leftIcon={<SearchIcon />} />Props: label, type, value, defaultValue, onChange, disabled, readOnly, required, error, errorMessage, helperText, size, rows, leftIcon, id, name, className, style, ariaLabel
DateInput
Native date input with theme styling.
import { DateInput } from "ql-dev-ui";
<DateInput
label="Birth Date"
value={date}
onChange={(e) => setDate(e.target.value)}
min="2000-01-01"
max="2025-12-31"
/>Props: label, value, onChange, placeholder, min, max, disabled, required, error, errorMessage, helperText, size, id, name, className, style, ariaLabel
SelectInput
Single-select dropdown.
import { SelectInput } from "ql-dev-ui";
const options = [
{ value: "js", label: "JavaScript" },
{ value: "ts", label: "TypeScript" },
];
<SelectInput
label="Language"
value={selected}
onChange={(val) => setSelected(val)}
options={options}
placeholder="Select one"
searchable
/>Props: label, value, defaultValue, onChange, options, size, searchable, disabled, required, error, errorMessage, helperText, id, name, className, ariaLabel, leftIcon, style
MultiSelect
Multi-select dropdown (array value).
import { MulitiSelect } from "ql-dev-ui";
const options = [
{ value: "js", label: "JavaScript" },
{ value: "ts", label: "TypeScript" },
];
<MulitiSelect
label="Skills"
value={skills}
onChange={(values) => setSkills(values)}
options={options}
placeholder="Select options"
searchable
/>Props: label, value (array), defaultValue (array), onChange, options, placeholder, searchable, size, disabled, required, error, errorMessage, helperText, id, name, className, ariaLabel, leftIcon, style
Breadcrumbs
import { Breadcrumbs } from "ql-dev-ui";
const items = [
{ label: "Home", path: "/" },
{ label: "Products", path: "/products" },
{ label: "Current Page" },
];
<Breadcrumbs
items={items}
onNavigate={(crumb) => navigate(crumb.path)}
separator="›"
/>Props: items (Array<{ label, path? }>), onNavigate, separator, className, style
Pagination
import { Pagination } from "ql-dev-ui";
<Pagination
currentPage={page}
totalPages={20}
onPageChange={(newPage) => setPage(newPage)}
size="md"
/>Props: currentPage, totalPages, onPageChange, size, className, style
DatePicker
Calendar popover for single date selection.
import { DatePicker } from "ql-dev-ui";
<DatePicker
label="Birthday"
value={date}
onChange={(date) => setDate(date)}
placeholder="Pick a date"
min={minDate}
max={maxDate}
/>Props: value (Date), onChange, label, required, placeholder, readOnly, error, errorMessage, min, max, id, name
DateRangePicker
Select start and end date range.
import { DateRangePicker } from "ql-dev-ui";
<DateRangePicker
value={{ start: startDate, end: endDate }}
onChange={({ start, end }) => {
setStartDate(start);
setEndDate(end);
}}
/>TimePicker
Time selection picker.
import { TimePicker } from "ql-dev-ui";
<TimePicker value={time} onChange={(t) => setTime(t)} />Exports
// Theme
export { ThemeProvider, useTheme } from "ql-dev-ui";
export { ThemeSwitcherProvider, useThemeSwitcher, ThemeToggle } from "ql-dev-ui";
export { baseTokens, lightTheme, darkTheme } from "ql-dev-ui";
// Components
export { Button, Input, DateInput } from "ql-dev-ui";
export { SelectInput, MulitiSelect } from "ql-dev-ui";
export { Breadcrumbs, Pagination } from "ql-dev-ui";
export { DatePicker, DateRangePicker, TimePicker } from "ql-dev-ui";Development
pnpm install
pnpm buildStorybook (if configured)
pnpm storybookColor Tokens (for theme customisation)
| Token | Purpose |
|-------|---------|
| primary, primaryHover, primaryActive | Primary buttons, links |
| secondary, secondaryHover, secondaryActive | Secondary buttons, surfaces |
| danger, dangerHover, dangerActive | Destructive actions |
| textLight, textDark | Text on light/dark backgrounds |
| disabledBg, disabledText | Disabled state |
| border, borderDefault | Borders |
| background, bgMain, bgSubtle | Background surfaces |
| statusError, statusSuccess, statusWarning | Status colours |
License
ISC
