@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 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
@@ -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 };