@kreativa/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/dist/index.d.mts +316 -0
- package/dist/index.d.ts +316 -0
- package/dist/index.js +1222 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1178 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +54 -0
- package/tailwind.config.js +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @kreativa/ui
|
|
2
|
+
|
|
3
|
+
Shared UI components for Kreativa applications, built with React and Tailwind CSS.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @kreativa/ui
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @kreativa/ui
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { Button, Card, Modal, Table } from '@kreativa/ui'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Tailwind Configuration
|
|
20
|
+
|
|
21
|
+
Extend your Tailwind config with the Kreativa theme:
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
// tailwind.config.js
|
|
25
|
+
import kreativaConfig from '@kreativa/ui/tailwind'
|
|
26
|
+
|
|
27
|
+
export default {
|
|
28
|
+
content: [
|
|
29
|
+
'./src/**/*.{js,ts,jsx,tsx}',
|
|
30
|
+
'./node_modules/@kreativa/ui/dist/**/*.{js,mjs}'
|
|
31
|
+
],
|
|
32
|
+
theme: {
|
|
33
|
+
extend: {
|
|
34
|
+
...kreativaConfig.theme.extend
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
plugins: []
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Components
|
|
42
|
+
|
|
43
|
+
### Layout
|
|
44
|
+
- `Layout` - Main app layout with sidebar
|
|
45
|
+
- `Sidebar` - Navigation sidebar
|
|
46
|
+
- `ServiceSwitcher` - Service/project selector
|
|
47
|
+
|
|
48
|
+
### Primitives
|
|
49
|
+
- `Button` - Button with variants (primary, secondary, danger, ghost)
|
|
50
|
+
- `Input` - Text input with label and error support
|
|
51
|
+
- `Card` - Container card with padding options
|
|
52
|
+
- `LoadingSpinner` - Animated spinner
|
|
53
|
+
- `EmptyState` - Empty state placeholder
|
|
54
|
+
- `Modal` - Dialog modal
|
|
55
|
+
|
|
56
|
+
### Forms
|
|
57
|
+
- `FormInput` - Form input with label and help text
|
|
58
|
+
- `FormTextarea` - Form textarea
|
|
59
|
+
- `FormButtonGroup` - Cancel/Submit button pair
|
|
60
|
+
|
|
61
|
+
### Data
|
|
62
|
+
- `Table` - Sortable data table
|
|
63
|
+
- `Select` - Searchable dropdown
|
|
64
|
+
- `Tabs` - Tab navigation
|
|
65
|
+
|
|
66
|
+
### Time
|
|
67
|
+
- `Timer` - Time tracking with play/stop
|
|
68
|
+
- `DatePicker` - Date/date-range picker
|
|
69
|
+
|
|
70
|
+
## Development
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Install dependencies
|
|
74
|
+
pnpm install
|
|
75
|
+
|
|
76
|
+
# Build
|
|
77
|
+
pnpm build
|
|
78
|
+
|
|
79
|
+
# Watch mode
|
|
80
|
+
pnpm dev
|
|
81
|
+
|
|
82
|
+
# Type check
|
|
83
|
+
pnpm typecheck
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode, ButtonHTMLAttributes, InputHTMLAttributes, TextareaHTMLAttributes } from 'react';
|
|
4
|
+
|
|
5
|
+
interface LayoutProps {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
sidebar?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
declare function Layout({ children, sidebar }: LayoutProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
|
|
11
|
+
interface SidebarProps {
|
|
12
|
+
header?: ReactNode;
|
|
13
|
+
navigation?: ReactNode;
|
|
14
|
+
footer?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
declare function Sidebar({ header, navigation, footer }: SidebarProps): react_jsx_runtime.JSX.Element;
|
|
17
|
+
|
|
18
|
+
interface Service {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
icon?: string;
|
|
22
|
+
}
|
|
23
|
+
interface ServiceSwitcherProps {
|
|
24
|
+
services: Service[];
|
|
25
|
+
currentServiceId: string;
|
|
26
|
+
onServiceChange: (serviceId: string) => void;
|
|
27
|
+
}
|
|
28
|
+
declare function ServiceSwitcher({ services, currentServiceId, onServiceChange }: ServiceSwitcherProps): react_jsx_runtime.JSX.Element | null;
|
|
29
|
+
|
|
30
|
+
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
31
|
+
variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
|
|
32
|
+
size?: 'sm' | 'md' | 'lg';
|
|
33
|
+
children: ReactNode;
|
|
34
|
+
}
|
|
35
|
+
declare function Button({ variant, size, className, children, disabled, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
36
|
+
|
|
37
|
+
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
38
|
+
label?: string;
|
|
39
|
+
error?: string;
|
|
40
|
+
}
|
|
41
|
+
declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
|
|
42
|
+
|
|
43
|
+
interface CardProps {
|
|
44
|
+
children: ReactNode;
|
|
45
|
+
className?: string;
|
|
46
|
+
padding?: 'none' | 'sm' | 'md' | 'lg';
|
|
47
|
+
}
|
|
48
|
+
declare function Card({ children, className, padding }: CardProps): react_jsx_runtime.JSX.Element;
|
|
49
|
+
|
|
50
|
+
interface LoadingSpinnerProps {
|
|
51
|
+
size?: 'sm' | 'md' | 'lg';
|
|
52
|
+
fullScreen?: boolean;
|
|
53
|
+
}
|
|
54
|
+
declare function LoadingSpinner({ size, fullScreen }: LoadingSpinnerProps): react_jsx_runtime.JSX.Element;
|
|
55
|
+
|
|
56
|
+
interface EmptyStateProps {
|
|
57
|
+
/** Icon to display - should be an SVG element */
|
|
58
|
+
icon?: ReactNode;
|
|
59
|
+
/** Main heading text */
|
|
60
|
+
title: string;
|
|
61
|
+
/** Supporting description text */
|
|
62
|
+
description?: string;
|
|
63
|
+
/** Optional action button or element */
|
|
64
|
+
action?: ReactNode;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* EmptyState component for displaying "no items" UI consistently across the application.
|
|
68
|
+
* Used when a list or collection has no data to display.
|
|
69
|
+
*/
|
|
70
|
+
declare function EmptyState({ icon, title, description, action }: EmptyStateProps): react_jsx_runtime.JSX.Element;
|
|
71
|
+
|
|
72
|
+
interface ModalProps {
|
|
73
|
+
/** Whether the modal is open */
|
|
74
|
+
isOpen: boolean;
|
|
75
|
+
/** Called when the modal should close (clicking backdrop or pressing Escape) */
|
|
76
|
+
onClose: () => void;
|
|
77
|
+
/** Modal title displayed in the header */
|
|
78
|
+
title: string;
|
|
79
|
+
/** Modal content */
|
|
80
|
+
children: ReactNode;
|
|
81
|
+
/** Maximum width of the modal (default: 'md') */
|
|
82
|
+
maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Modal component for displaying content in an overlay dialog.
|
|
86
|
+
* Handles backdrop click and Escape key to close.
|
|
87
|
+
*/
|
|
88
|
+
declare function Modal({ isOpen, onClose, title, children, maxWidth }: ModalProps): react_jsx_runtime.JSX.Element | null;
|
|
89
|
+
|
|
90
|
+
interface FormInputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
91
|
+
/** Label text displayed above the input */
|
|
92
|
+
label?: string;
|
|
93
|
+
/** Help text displayed below the input */
|
|
94
|
+
helpText?: string;
|
|
95
|
+
/** Error message to display */
|
|
96
|
+
error?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* FormInput component with consistent styling for form inputs across the application.
|
|
100
|
+
* Supports labels, help text, and error states.
|
|
101
|
+
*/
|
|
102
|
+
declare const FormInput: react.ForwardRefExoticComponent<FormInputProps & react.RefAttributes<HTMLInputElement>>;
|
|
103
|
+
|
|
104
|
+
interface FormTextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
105
|
+
/** Label text displayed above the textarea */
|
|
106
|
+
label?: string;
|
|
107
|
+
/** Help text displayed below the textarea */
|
|
108
|
+
helpText?: string;
|
|
109
|
+
/** Error message to display */
|
|
110
|
+
error?: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* FormTextarea component with consistent styling for textarea inputs across the application.
|
|
114
|
+
* Supports labels, help text, and error states.
|
|
115
|
+
*/
|
|
116
|
+
declare const FormTextarea: react.ForwardRefExoticComponent<FormTextareaProps & react.RefAttributes<HTMLTextAreaElement>>;
|
|
117
|
+
|
|
118
|
+
interface FormButtonGroupProps {
|
|
119
|
+
/** Text for the cancel button */
|
|
120
|
+
cancelText?: string;
|
|
121
|
+
/** Text for the submit button */
|
|
122
|
+
submitText?: string;
|
|
123
|
+
/** Loading text for submit button (when isLoading is true) */
|
|
124
|
+
loadingText?: string;
|
|
125
|
+
/** Whether the form is in a loading state */
|
|
126
|
+
isLoading?: boolean;
|
|
127
|
+
/** Whether the submit button is disabled */
|
|
128
|
+
isDisabled?: boolean;
|
|
129
|
+
/** Called when cancel button is clicked */
|
|
130
|
+
onCancel: () => void;
|
|
131
|
+
/** Called when submit button is clicked (optional, for use outside forms) */
|
|
132
|
+
onSubmit?: () => void;
|
|
133
|
+
/** Custom submit button content (overrides submitText) */
|
|
134
|
+
submitContent?: ReactNode;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* FormButtonGroup component for consistent Cancel/Submit button pairs in forms.
|
|
138
|
+
* Handles loading states and disabled states.
|
|
139
|
+
*/
|
|
140
|
+
declare function FormButtonGroup({ cancelText, submitText, loadingText, isLoading, isDisabled, onCancel, onSubmit, submitContent, }: FormButtonGroupProps): react_jsx_runtime.JSX.Element;
|
|
141
|
+
|
|
142
|
+
interface TableColumn<T> {
|
|
143
|
+
/** Unique key for the column */
|
|
144
|
+
key: string;
|
|
145
|
+
/** Column header text */
|
|
146
|
+
header: string;
|
|
147
|
+
/** Function to render cell content */
|
|
148
|
+
render: (item: T) => ReactNode;
|
|
149
|
+
/** Whether this column is sortable */
|
|
150
|
+
sortable?: boolean;
|
|
151
|
+
/** Custom sort function */
|
|
152
|
+
sortFn?: (a: T, b: T) => number;
|
|
153
|
+
/** Column width (e.g., '200px', '20%') */
|
|
154
|
+
width?: string;
|
|
155
|
+
/** Text alignment */
|
|
156
|
+
align?: 'left' | 'center' | 'right';
|
|
157
|
+
}
|
|
158
|
+
interface TableProps<T> {
|
|
159
|
+
/** Array of data items to display */
|
|
160
|
+
data: T[];
|
|
161
|
+
/** Column definitions */
|
|
162
|
+
columns: TableColumn<T>[];
|
|
163
|
+
/** Function to get unique key for each row */
|
|
164
|
+
getRowKey: (item: T) => string | number;
|
|
165
|
+
/** Called when a row is clicked */
|
|
166
|
+
onRowClick?: (item: T) => void;
|
|
167
|
+
/** Whether the table is in a loading state */
|
|
168
|
+
loading?: boolean;
|
|
169
|
+
/** Message to show when data is empty */
|
|
170
|
+
emptyMessage?: string;
|
|
171
|
+
/** Additional class names for the table container */
|
|
172
|
+
className?: string;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Table component for displaying tabular data with sorting support.
|
|
176
|
+
*/
|
|
177
|
+
declare function Table<T>({ data, columns, getRowKey, onRowClick, loading, emptyMessage, className, }: TableProps<T>): react_jsx_runtime.JSX.Element;
|
|
178
|
+
|
|
179
|
+
interface SelectOption<T = string> {
|
|
180
|
+
/** Unique value for the option */
|
|
181
|
+
value: T;
|
|
182
|
+
/** Display label */
|
|
183
|
+
label: string;
|
|
184
|
+
/** Optional icon or element to display */
|
|
185
|
+
icon?: ReactNode;
|
|
186
|
+
/** Whether this option is disabled */
|
|
187
|
+
disabled?: boolean;
|
|
188
|
+
}
|
|
189
|
+
interface SelectProps<T = string> {
|
|
190
|
+
/** Available options */
|
|
191
|
+
options: SelectOption<T>[];
|
|
192
|
+
/** Currently selected value(s) */
|
|
193
|
+
value: T | T[] | null;
|
|
194
|
+
/** Called when selection changes */
|
|
195
|
+
onChange: (value: T | T[] | null) => void;
|
|
196
|
+
/** Placeholder text when nothing selected */
|
|
197
|
+
placeholder?: string;
|
|
198
|
+
/** Label text */
|
|
199
|
+
label?: string;
|
|
200
|
+
/** Error message */
|
|
201
|
+
error?: string;
|
|
202
|
+
/** Whether search is enabled */
|
|
203
|
+
searchable?: boolean;
|
|
204
|
+
/** Whether multiple selection is allowed */
|
|
205
|
+
multiple?: boolean;
|
|
206
|
+
/** Whether the select is disabled */
|
|
207
|
+
disabled?: boolean;
|
|
208
|
+
/** Additional class names */
|
|
209
|
+
className?: string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Select component with searchable dropdown and multi-select support.
|
|
213
|
+
*/
|
|
214
|
+
declare function Select<T = string>({ options, value, onChange, placeholder, label, error, searchable, multiple, disabled, className, }: SelectProps<T>): react_jsx_runtime.JSX.Element;
|
|
215
|
+
|
|
216
|
+
interface Tab {
|
|
217
|
+
/** Unique identifier for the tab */
|
|
218
|
+
id: string;
|
|
219
|
+
/** Tab label */
|
|
220
|
+
label: string;
|
|
221
|
+
/** Optional icon */
|
|
222
|
+
icon?: ReactNode;
|
|
223
|
+
/** Whether the tab is disabled */
|
|
224
|
+
disabled?: boolean;
|
|
225
|
+
/** Tab content (for uncontrolled mode) */
|
|
226
|
+
content?: ReactNode;
|
|
227
|
+
}
|
|
228
|
+
interface TabsProps {
|
|
229
|
+
/** Tab definitions */
|
|
230
|
+
tabs: Tab[];
|
|
231
|
+
/** Currently active tab id (controlled mode) */
|
|
232
|
+
activeTab?: string;
|
|
233
|
+
/** Called when tab changes */
|
|
234
|
+
onTabChange?: (tabId: string) => void;
|
|
235
|
+
/** Default active tab (uncontrolled mode) */
|
|
236
|
+
defaultTab?: string;
|
|
237
|
+
/** Tab variant */
|
|
238
|
+
variant?: 'default' | 'pills' | 'underline';
|
|
239
|
+
/** Whether to render tab content (set to false if rendering content externally) */
|
|
240
|
+
renderContent?: boolean;
|
|
241
|
+
/** Additional class names for the tabs container */
|
|
242
|
+
className?: string;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Tabs component for tab navigation with multiple style variants.
|
|
246
|
+
*/
|
|
247
|
+
declare function Tabs({ tabs, activeTab: controlledActiveTab, onTabChange, defaultTab, variant, renderContent, className, }: TabsProps): react_jsx_runtime.JSX.Element;
|
|
248
|
+
|
|
249
|
+
interface DateRange {
|
|
250
|
+
start: Date | null;
|
|
251
|
+
end: Date | null;
|
|
252
|
+
}
|
|
253
|
+
interface DatePickerProps {
|
|
254
|
+
/** Selected date (single mode) or date range (range mode) */
|
|
255
|
+
value: Date | DateRange | null;
|
|
256
|
+
/** Called when date selection changes */
|
|
257
|
+
onChange: (value: Date | DateRange | null) => void;
|
|
258
|
+
/** Whether to enable range selection */
|
|
259
|
+
range?: boolean;
|
|
260
|
+
/** Label text */
|
|
261
|
+
label?: string;
|
|
262
|
+
/** Placeholder text */
|
|
263
|
+
placeholder?: string;
|
|
264
|
+
/** Error message */
|
|
265
|
+
error?: string;
|
|
266
|
+
/** Minimum selectable date */
|
|
267
|
+
minDate?: Date;
|
|
268
|
+
/** Maximum selectable date */
|
|
269
|
+
maxDate?: Date;
|
|
270
|
+
/** Whether the picker is disabled */
|
|
271
|
+
disabled?: boolean;
|
|
272
|
+
/** Additional class names */
|
|
273
|
+
className?: string;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* DatePicker component with single date and date range support.
|
|
277
|
+
*/
|
|
278
|
+
declare function DatePicker({ value, onChange, range, label, placeholder, error, minDate, maxDate, disabled, className, }: DatePickerProps): react_jsx_runtime.JSX.Element;
|
|
279
|
+
|
|
280
|
+
interface TimerState {
|
|
281
|
+
/** Whether the timer is currently running */
|
|
282
|
+
isRunning: boolean;
|
|
283
|
+
/** Total elapsed time in seconds */
|
|
284
|
+
elapsedSeconds: number;
|
|
285
|
+
/** When the timer was started (if running) */
|
|
286
|
+
startedAt: Date | null;
|
|
287
|
+
}
|
|
288
|
+
interface TimerProps {
|
|
289
|
+
/** Initial elapsed time in seconds (default: 0) */
|
|
290
|
+
initialSeconds?: number;
|
|
291
|
+
/** Called when timer starts */
|
|
292
|
+
onStart?: (startedAt: Date) => void;
|
|
293
|
+
/** Called when timer stops */
|
|
294
|
+
onStop?: (elapsedSeconds: number) => void;
|
|
295
|
+
/** Called when timer is reset */
|
|
296
|
+
onReset?: () => void;
|
|
297
|
+
/** Called every second while running (useful for auto-save) */
|
|
298
|
+
onTick?: (elapsedSeconds: number) => void;
|
|
299
|
+
/** Whether to show the reset button */
|
|
300
|
+
showReset?: boolean;
|
|
301
|
+
/** Size variant */
|
|
302
|
+
size?: 'sm' | 'md' | 'lg';
|
|
303
|
+
/** Additional class names */
|
|
304
|
+
className?: string;
|
|
305
|
+
/** External control - if provided, component becomes controlled */
|
|
306
|
+
isRunning?: boolean;
|
|
307
|
+
/** External elapsed seconds - for controlled mode */
|
|
308
|
+
elapsedSeconds?: number;
|
|
309
|
+
}
|
|
310
|
+
declare function formatTime(totalSeconds: number): string;
|
|
311
|
+
/**
|
|
312
|
+
* Timer component for time tracking with play/pause/stop controls.
|
|
313
|
+
*/
|
|
314
|
+
declare function Timer({ initialSeconds, onStart, onStop, onReset, onTick, showReset, size, className, isRunning: controlledIsRunning, elapsedSeconds: controlledElapsedSeconds, }: TimerProps): react_jsx_runtime.JSX.Element;
|
|
315
|
+
|
|
316
|
+
export { Button, Card, DatePicker, type DateRange, EmptyState, FormButtonGroup, FormInput, FormTextarea, Input, Layout, LoadingSpinner, Modal, Select, type SelectOption, ServiceSwitcher, Sidebar, type Tab, Table, type TableColumn, Tabs, Timer, type TimerState, formatTime };
|