blunt-ui 0.3.6 → 1.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.
Files changed (103) hide show
  1. package/README.md +117 -25
  2. package/dist/components/Badge/Badge.types.d.ts +4 -4
  3. package/dist/components/Badge/index.d.ts +1 -1
  4. package/dist/components/Badge/{Badge.stories.d.ts → stories/Badge.stories.d.ts} +1 -1
  5. package/dist/components/Button/Button.types.d.ts +4 -4
  6. package/dist/components/Button/index.d.ts +1 -1
  7. package/dist/components/Button/{Button.stories.d.ts → stories/Button.stories.d.ts} +1 -1
  8. package/dist/components/Checkbox/Checkbox.d.ts +5 -0
  9. package/dist/components/Checkbox/Checkbox.types.d.ts +11 -0
  10. package/dist/components/Checkbox/index.d.ts +2 -0
  11. package/dist/components/Checkbox/stories/Checkbox.stories.d.ts +11 -0
  12. package/dist/components/CollapsibleCard/{CollapsibleCard.stories.d.ts → stories/CollapsibleCard.stories.d.ts} +1 -1
  13. package/dist/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +2 -0
  14. package/dist/components/ConfirmDialog/{useConfirm.d.ts → ConfirmDialog.provider.d.ts} +2 -2
  15. package/dist/components/ConfirmDialog/ConfirmDialog.types.d.ts +14 -2
  16. package/dist/components/ConfirmDialog/index.d.ts +4 -3
  17. package/dist/components/ConfirmDialog/{ConfirmDialog.stories.d.ts → stories/ConfirmDialog.stories.d.ts} +1 -1
  18. package/dist/components/DatePicker/DatePicker.d.ts +1 -1
  19. package/dist/components/DatePicker/DatePicker.types.d.ts +14 -6
  20. package/dist/components/DatePicker/index.d.ts +2 -1
  21. package/dist/components/DatePicker/{DatePicker.stories.d.ts → stories/DatePicker.stories.d.ts} +2 -1
  22. package/dist/components/Editable/{Editable.stories.d.ts → stories/Editable.stories.d.ts} +1 -1
  23. package/dist/components/Field/{Field.stories.d.ts → stories/Field.stories.d.ts} +1 -1
  24. package/dist/components/Form/{useForm.d.ts → Form.hooks.d.ts} +1 -1
  25. package/dist/components/Form/Form.types.d.ts +19 -7
  26. package/dist/components/Form/{FormField.d.ts → FormField/FormField.d.ts} +1 -1
  27. package/dist/components/Form/FormField/FormField.types.d.ts +8 -0
  28. package/dist/components/Form/FormField/index.d.ts +2 -0
  29. package/dist/components/Form/index.d.ts +4 -3
  30. package/dist/components/Form/{Form.stories.d.ts → stories/Form.stories.d.ts} +1 -1
  31. package/dist/components/Form/tests/Form.validators.test.d.ts +1 -0
  32. package/dist/components/Form/validators/Form.validators.d.ts +9 -0
  33. package/dist/components/Input/Input.types.d.ts +6 -6
  34. package/dist/components/Input/index.d.ts +1 -1
  35. package/dist/components/Input/{Input.stories.d.ts → stories/Input.stories.d.ts} +1 -1
  36. package/dist/components/Link/Link.types.d.ts +2 -2
  37. package/dist/components/Link/index.d.ts +2 -1
  38. package/dist/components/Link/{Link.stories.d.ts → stories/Link.stories.d.ts} +1 -1
  39. package/dist/components/Link/tests/Link.test.d.ts +0 -0
  40. package/dist/components/Modal/Modal.types.d.ts +2 -2
  41. package/dist/components/Modal/index.d.ts +1 -1
  42. package/dist/components/Modal/{Modal.stories.d.ts → stories/Modal.stories.d.ts} +1 -1
  43. package/dist/components/Modal/tests/Modal.test.d.ts +0 -0
  44. package/dist/components/Radio/Radio.d.ts +5 -0
  45. package/dist/components/Radio/Radio.types.d.ts +10 -0
  46. package/dist/components/Radio/index.d.ts +2 -0
  47. package/dist/components/Radio/stories/Radio.stories.d.ts +10 -0
  48. package/dist/components/Radio/tests/Radio.test.d.ts +0 -0
  49. package/dist/components/Select/Select.d.ts +1 -1
  50. package/dist/components/Select/Select.types.d.ts +15 -6
  51. package/dist/components/Select/index.d.ts +1 -1
  52. package/dist/components/Select/{Select.stories.d.ts → stories/Select.stories.d.ts} +1 -1
  53. package/dist/components/Select/tests/Select.test.d.ts +0 -0
  54. package/dist/components/Spinner/Spinner.types.d.ts +4 -4
  55. package/dist/components/Spinner/index.d.ts +1 -1
  56. package/dist/components/Spinner/{Spinner.stories.d.ts → stories/Spinner.stories.d.ts} +1 -1
  57. package/dist/components/Spinner/tests/Spinner.test.d.ts +0 -0
  58. package/dist/components/Switch/Switch.d.ts +5 -0
  59. package/dist/components/Switch/Switch.types.d.ts +8 -0
  60. package/dist/components/Switch/index.d.ts +2 -0
  61. package/dist/components/Switch/stories/Switch.stories.d.ts +9 -0
  62. package/dist/components/Switch/tests/Switch.test.d.ts +0 -0
  63. package/dist/components/Table/Table.consts.d.ts +3 -0
  64. package/dist/components/Table/Table.d.ts +1 -1
  65. package/dist/components/Table/Table.hooks.d.ts +29 -0
  66. package/dist/components/Table/Table.types.d.ts +15 -2
  67. package/dist/components/Table/index.d.ts +2 -3
  68. package/dist/components/Table/{Table.stories.d.ts → stories/Table.stories.d.ts} +2 -6
  69. package/dist/components/Table/tests/Table.test.d.ts +0 -0
  70. package/dist/components/Textarea/Textarea.types.d.ts +4 -4
  71. package/dist/components/Textarea/index.d.ts +1 -1
  72. package/dist/components/Textarea/{Textarea.stories.d.ts → stories/Textarea.stories.d.ts} +1 -1
  73. package/dist/components/Textarea/tests/Textarea.test.d.ts +0 -0
  74. package/dist/components/Toast/Toast.hooks.d.ts +2 -0
  75. package/dist/components/Toast/{useToast.d.ts → Toast.provider.d.ts} +2 -2
  76. package/dist/components/Toast/Toast.types.d.ts +18 -2
  77. package/dist/components/Toast/index.d.ts +4 -3
  78. package/dist/components/Toast/{Toast.stories.d.ts → stories/Toast.stories.d.ts} +1 -1
  79. package/dist/components/Toast/tests/Toast.provider.test.d.ts +0 -0
  80. package/dist/components/Toast/tests/Toast.test.d.ts +0 -0
  81. package/dist/index.cjs +543 -191
  82. package/dist/index.d.ts +19 -13
  83. package/dist/index.js +2009 -1082
  84. package/dist/themes/types.d.ts +9 -0
  85. package/package.json +2 -2
  86. package/dist/components/ConfirmDialog/useConfirm.types.d.ts +0 -14
  87. package/dist/components/Form/useForm.types.d.ts +0 -20
  88. package/dist/components/Table/useTable.d.ts +0 -12
  89. package/dist/components/Table/useTablePagination.d.ts +0 -16
  90. package/dist/components/Table/useTableSort.d.ts +0 -13
  91. package/dist/components/Toast/useToast.types.d.ts +0 -17
  92. /package/dist/components/{Button/Button.test.d.ts → Badge/tests/Badge.test.d.ts} +0 -0
  93. /package/dist/components/{CollapsibleCard/CollapsibleCard.test.d.ts → Button/tests/Button.test.d.ts} +0 -0
  94. /package/dist/components/{ConfirmDialog/ConfirmDialog.test.d.ts → Checkbox/tests/Checkbox.test.d.ts} +0 -0
  95. /package/dist/components/{ConfirmDialog/useConfirm.test.d.ts → CollapsibleCard/tests/CollapsibleCard.test.d.ts} +0 -0
  96. /package/dist/components/{DatePicker/DatePicker.test.d.ts → ConfirmDialog/tests/ConfirmDialog.provider.test.d.ts} +0 -0
  97. /package/dist/components/{Form/Form.test.d.ts → ConfirmDialog/tests/ConfirmDialog.test.d.ts} +0 -0
  98. /package/dist/components/{Input/Input.test.d.ts → DatePicker/tests/DatePicker.test.d.ts} +0 -0
  99. /package/dist/components/{Modal/Modal.test.d.ts → Editable/tests/Editable.test.d.ts} +0 -0
  100. /package/dist/components/{Select/Select.test.d.ts → Field/tests/Field.test.d.ts} +0 -0
  101. /package/dist/components/Form/{useForm.test.d.ts → tests/Form.hooks.test.d.ts} +0 -0
  102. /package/dist/components/{Toast/Toast.test.d.ts → Form/tests/Form.test.d.ts} +0 -0
  103. /package/dist/components/{Toast/useToast.test.d.ts → Input/tests/Input.test.d.ts} +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # blunt-ui
2
2
 
3
- A React component library I built for myself and started using across projects. Neo-brutalism aesthetic — thick borders, offset shadows, high contrast. No animations, no gradients, no magic. Just components that do what they say.
3
+ A React component library I built for myself and started using across projects. Neo-brutalism aesthetic - thick borders, offset shadows, high contrast. No animations, no gradients, no magic. Just components that do what they say.
4
4
 
5
5
  Built with React, TypeScript, and styled-components.
6
6
 
@@ -27,7 +27,7 @@ import { ThemeProvider, GlobalStyles } from "blunt-ui";
27
27
  </ThemeProvider>;
28
28
  ```
29
29
 
30
- If you're using `useToast` or `useConfirm`, add their providers here too — more on those below.
30
+ If you're using `useToast` or `useConfirm`, add their providers here too - more on those below.
31
31
 
32
32
  ## Running locally
33
33
 
@@ -45,7 +45,7 @@ npm run build
45
45
 
46
46
  ### Badge
47
47
 
48
- Small inline label for statuses, tags, counts — wherever you need a bit of color-coded context.
48
+ Small inline label for statuses, tags, counts - wherever you need a bit of color-coded context.
49
49
 
50
50
  Variants: `primary`, `neutral`, `success`, `error`, `warning`, `info`. Sizes: `sm` (default), `md`.
51
51
 
@@ -63,7 +63,7 @@ Three variants: `primary` (filled), `secondary` (muted fill), `outline` (border
63
63
  <Button variant="outline" isLoading={submitting}>Submit</Button>
64
64
  ```
65
65
 
66
- `isLoading` disables the button and swaps the label for "Loading..." — no spinner, keeps the layout stable. The `as` prop lets you swap the underlying element, which is useful when you want a `<Link>` from your router but with button styles.
66
+ `isLoading` disables the button and swaps the label for "Loading..." - no spinner, keeps the layout stable. The `as` prop lets you swap the underlying element, which is useful when you want a `<Link>` from your router but with button styles.
67
67
 
68
68
  ### Input
69
69
 
@@ -78,16 +78,60 @@ Standard text input with a label, optional helper text, error state, left/right
78
78
 
79
79
  ### Textarea
80
80
 
81
- Multi-line input. Same props as Input — `label`, `helperText`, `error`, `fullWidth`. Variants: `default`, `outlined`. Sizes: `sm`, `md`, `lg`.
81
+ Multi-line input. Same props as Input - `label`, `helperText`, `error`, `fullWidth`. Variants: `default`, `outlined`. Sizes: `sm`, `md`, `lg`.
82
82
 
83
83
  ```tsx
84
84
  <Textarea label="Notes" helperText="Max 500 chars" />
85
85
  <Textarea label="Bio" variant="outlined" error="Required" rows={4} />
86
86
  ```
87
87
 
88
+ ### Checkbox
89
+
90
+ ```tsx
91
+ <Checkbox
92
+ label="Accept terms and conditions"
93
+ checked={checked}
94
+ onChange={(e) => setChecked(e.target.checked)}
95
+ />
96
+ <Checkbox label="Required field" error="You must accept the terms" />
97
+ ```
98
+
99
+ Sizes: `sm`, `md`. Shows an error message below when `error` is a string, turns the border red when `error` is a boolean.
100
+
101
+ ### Radio
102
+
103
+ Same hidden-input pattern as Checkbox, but circular. Use multiple radios with the same `name` for a group, or manage `checked` yourself.
104
+
105
+ ```tsx
106
+ {
107
+ ["remote", "hybrid", "on-site"].map((option) => (
108
+ <Radio
109
+ key={option}
110
+ name="workMode"
111
+ value={option}
112
+ label={option}
113
+ checked={value === option}
114
+ onChange={(e) => setValue(e.target.value)}
115
+ />
116
+ ));
117
+ }
118
+ ```
119
+
120
+ ### Switch
121
+
122
+ A toggle. Same API as Checkbox - `checked` + `onChange`. Sizes: `sm`, `md`.
123
+
124
+ ```tsx
125
+ <Switch
126
+ label="Enable notifications"
127
+ checked={enabled}
128
+ onChange={(e) => setEnabled(e.target.checked)}
129
+ />
130
+ ```
131
+
88
132
  ### Select
89
133
 
90
- Styled native `<select>`. I kept it native because custom dropdowns are more trouble than they're worth for most use cases. Same sizes and error handling as Input.
134
+ Custom dropdown - full keyboard navigation (arrow keys, Enter, Escape, Home/End), styled to match the rest of the library. `onChange` fires a synthetic event with `name` and `value`, so it works with `useForm.handleChange` without any changes.
91
135
 
92
136
  ```tsx
93
137
  <Select
@@ -154,7 +198,7 @@ Opens in a portal on `document.body`. Traps focus, locks body scroll, closes on
154
198
  </Modal>
155
199
  ```
156
200
 
157
- The `footer` slot is where you put action buttons — it renders at the bottom of the modal, separated from the content.
201
+ The `footer` slot is where you put action buttons - it renders at the bottom of the modal, separated from the content.
158
202
 
159
203
  ### Toast
160
204
 
@@ -171,11 +215,11 @@ Variants: `success`, `error`, `warning`, `info`. Positions: `bottom-right`, `bot
171
215
  />
172
216
  ```
173
217
 
174
- In practice you'll probably want `useToast` instead — see hooks below.
218
+ In practice you'll probably want `useToast` instead - see hooks below.
175
219
 
176
220
  ### Form
177
221
 
178
- `Form` is a flex column wrapper that calls `e.preventDefault()` for you. `FormField` handles the label, error message, helper text, and `htmlFor` wiring — so you don't have to manage IDs manually.
222
+ `Form` is a flex column wrapper that calls `e.preventDefault()` for you. `FormField` handles the label, error message, helper text, and `htmlFor` wiring - so you don't have to manage IDs manually.
179
223
 
180
224
  ```tsx
181
225
  <Form onSubmit={handleSubmit}>
@@ -192,7 +236,7 @@ In practice you'll probably want `useToast` instead — see hooks below.
192
236
  </Form>
193
237
  ```
194
238
 
195
- Pair with `useForm` for validation — they're designed to work together.
239
+ Pair with `useForm` for validation - they're designed to work together.
196
240
 
197
241
  ### Link
198
242
 
@@ -205,7 +249,7 @@ Styled anchor. Variants: `default` and `subtle` (less prominent, for secondary l
205
249
 
206
250
  ### CollapsibleCard
207
251
 
208
- A card with a header you can click to show/hide the content. Works uncontrolled out of the box — just use `defaultOpen` and forget about it. For controlled mode, pass `open` + `onToggle`.
252
+ A card with a header you can click to show/hide the content. Works uncontrolled out of the box - just use `defaultOpen` and forget about it. For controlled mode, pass `open` + `onToggle`.
209
253
 
210
254
  ```tsx
211
255
  <CollapsibleCard title="Details" subtitle="Optional subtitle" defaultOpen>
@@ -213,7 +257,7 @@ A card with a header you can click to show/hide the content. Works uncontrolled
213
257
  </CollapsibleCard>
214
258
  ```
215
259
 
216
- `accentColor` tints the left border and the chevron icon. `headerActions` is a slot for extra stuff in the header — a badge, a button, whatever.
260
+ `accentColor` tints the left border and the chevron icon. `headerActions` is a slot for extra stuff in the header - a badge, a button, whatever.
217
261
 
218
262
  ```tsx
219
263
  <CollapsibleCard
@@ -240,7 +284,7 @@ Loading indicator. Sizes: `sm`, `md`, `lg`. Weights: `thin`, `normal`, `bold`. Y
240
284
 
241
285
  ### Table
242
286
 
243
- Read-only table with sorting and pagination built in. Define columns, pass data — that's the basic case.
287
+ Read-only table with sorting and pagination built in. Define columns, pass data - that's the basic case.
244
288
 
245
289
  ```tsx
246
290
  const columns = [
@@ -260,11 +304,11 @@ const columns = [
260
304
  />;
261
305
  ```
262
306
 
263
- **Sorting** — add `sortable: true` to a column. Client-side by default. To sort server-side, pass `sort` + `onSortChange` — the table just shows the indicator and tells you what changed, you handle the data.
307
+ **Sorting** - add `sortable: true` to a column. Client-side by default. To sort server-side, pass `sort` + `onSortChange` - the table just shows the indicator and tells you what changed, you handle the data.
264
308
 
265
- **Pagination** — set `pageSize` and the table slices the data automatically. For server-side pagination, also pass `totalRows` (so it knows how many pages exist) and control `page` + `onPageChange` yourself. Use `onChange` if you need both sort and page changes in one callback.
309
+ **Pagination** - set `pageSize` and the table slices the data automatically. For server-side pagination, also pass `totalRows` (so it knows how many pages exist) and control `page` + `onPageChange` yourself. Use `onChange` if you need both sort and page changes in one callback.
266
310
 
267
- **Other props** — `loading` shows skeleton rows while data loads. `stickyHeader` keeps the header visible on scroll. `caption` adds an accessible `<caption>`.
311
+ **Other props** - `loading` shows skeleton rows while data loads. `stickyHeader` keeps the header visible on scroll. `caption` adds an accessible `<caption>`.
268
312
 
269
313
  Color props if you need to match a specific theme: `borderColor`, `headerColor`, `rowColor`, `stripeColor`.
270
314
 
@@ -286,19 +330,39 @@ A specialized modal for destructive actions. Two variants: `default` and `danger
286
330
 
287
331
  ### DatePicker
288
332
 
289
- Calendar-based date input. Sizes: `sm`, `md`, `lg`. Supports `minDate`, `maxDate`, and `clearable`.
333
+ Calendar date picker. Stores the value as an ISO string (`"YYYY-MM-DD"` or `""`) so it plays nicely with `useForm` without any conversion. `onChange` fires `(name, value)` - same as `setFieldValue`.
334
+
335
+ Sizes: `sm`, `md`, `lg`. Supports `minDate`, `maxDate`, `clearable`, `label`, `error`, `helperText`.
290
336
 
291
337
  ```tsx
292
- <DatePicker value={date} onChange={setDate} placeholder="Pick a date" />
293
- <DatePicker value={date} onChange={setDate} minDate={new Date()} clearable />
338
+ // Standalone
339
+ const [date, setDate] = useState("");
340
+
341
+ <DatePicker name="date" value={date} onChange={(_, v) => setDate(v)} />;
342
+ ```
343
+
344
+ With `useForm`, just pass `setFieldValue` straight in:
345
+
346
+ ```tsx
347
+ const { values, setFieldValue } = useForm({
348
+ initialValues: { dateApplied: "" },
349
+ });
350
+
351
+ <DatePicker
352
+ name="dateApplied"
353
+ label="Date applied"
354
+ value={values.dateApplied}
355
+ onChange={setFieldValue}
356
+ />;
294
357
  ```
295
358
 
296
- `formatDate` controls how the selected date is displayed in the input field:
359
+ `formatDate` changes how the picked date shows in the trigger:
297
360
 
298
361
  ```tsx
299
362
  <DatePicker
363
+ name="date"
300
364
  value={date}
301
- onChange={setDate}
365
+ onChange={(_, v) => setDate(v)}
302
366
  formatDate={(d) => d.toLocaleDateString("pl-PL")}
303
367
  />
304
368
  ```
@@ -329,7 +393,7 @@ toast.info("New version available.");
329
393
 
330
394
  ### useConfirm
331
395
 
332
- Same pattern as `useToast` — provider at the top, hook wherever you need it. Returns a promise so you can `await` the user's decision.
396
+ Same pattern as `useToast` - provider at the top, hook wherever you need it. Returns a promise so you can `await` the user's decision.
333
397
 
334
398
  ```tsx
335
399
  <ConfirmProvider>
@@ -355,7 +419,7 @@ Much cleaner than managing open/close state for every confirm dialog in your app
355
419
 
356
420
  ### useForm
357
421
 
358
- Handles values, touched state, validation, and errors. Errors only show after a field has been touched or a submit was attempted — no red borders on page load.
422
+ Handles values, touched state, validation, and errors. Errors only show after a field has been touched or a submit was attempted - no red borders on page load.
359
423
 
360
424
  ```tsx
361
425
  const { values, errors, handleChange, handleBlur, handleSubmit, reset } =
@@ -376,6 +440,26 @@ const { values, errors, handleChange, handleBlur, handleSubmit, reset } =
376
440
 
377
441
  Each input's `name` needs to match a key in `initialValues`. `reset()` puts everything back to the initial state.
378
442
 
443
+ The library ships with validators you can use in the `validate` function:
444
+
445
+ ```tsx
446
+ import {
447
+ required,
448
+ minLength,
449
+ isEmail,
450
+ isUrl,
451
+ composeValidators,
452
+ } from "blunt-ui";
453
+
454
+ validate: (v) => ({
455
+ email: composeValidators(required(), isEmail())(v.email),
456
+ password: minLength(8)(v.password),
457
+ website: isUrl()(v.website),
458
+ });
459
+ ```
460
+
461
+ `composeValidators` runs validators left to right and returns the first error. Available validators: `required`, `minLength`, `maxLength`, `isEmail`, `isUrl`, `pattern`.
462
+
379
463
  ### useTable
380
464
 
381
465
  A small helper for server-side table state. Tracks the current sort and page so you can pass them to a fetch call, then hands everything back to `<Table>` as controlled props.
@@ -399,10 +483,18 @@ useEffect(() => {
399
483
  />;
400
484
  ```
401
485
 
402
- Changing the sort resets the page to 1 automatically — saves you from ending up on page 5 of a different sort order. Pass `defaultSort` if you need a column pre-sorted on first load.
486
+ Changing the sort resets the page to 1 automatically - saves you from ending up on page 5 of a different sort order. Pass `defaultSort` if you need a column pre-sorted on first load.
403
487
 
404
488
  ---
405
489
 
406
490
  ## Design tokens
407
491
 
408
- Everything lives in `src/consts.ts` — colors, spacing, font sizes, border radius. All components reference these, so updating a single token changes the look across the whole library.
492
+ Everything lives in `src/themes/neo-brutal.ts` - colors, spacing, font sizes, font weights, border radius. All components pull from the theme, so changing a single token updates the look everywhere.
493
+
494
+ The accent color is the only thing I designed to be easily swappable:
495
+
496
+ ```ts
497
+ import { createNeoBrutalTheme } from "blunt-ui";
498
+
499
+ const theme = createNeoBrutalTheme("#f97316"); // swap yellow for orange
500
+ ```
@@ -1,7 +1,7 @@
1
1
  import { ComponentPropsWithRef } from 'react';
2
- export type BadgeVariants = "primary" | "neutral" | "success" | "error" | "warning" | "info";
3
- export type BadgeSizes = "sm" | "md";
2
+ export type BadgeVariant = "primary" | "neutral" | "success" | "error" | "warning" | "info";
3
+ export type BadgeSize = "sm" | "md";
4
4
  export type BadgeProps = ComponentPropsWithRef<"span"> & {
5
- variant?: BadgeVariants;
6
- size?: BadgeSizes;
5
+ variant?: BadgeVariant;
6
+ size?: BadgeSize;
7
7
  };
@@ -1,2 +1,2 @@
1
1
  export { Badge } from './Badge';
2
- export type { BadgeProps, BadgeVariants, BadgeSizes } from './Badge.types';
2
+ export type { BadgeVariant, BadgeSize, BadgeProps } from './Badge.types';
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { Badge } from './Badge';
2
+ import { Badge } from '../Badge';
3
3
  declare const meta: Meta<typeof Badge>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof Badge>;
@@ -1,9 +1,9 @@
1
1
  import { ComponentPropsWithRef, ElementType } from 'react';
2
- export type ButtonVariants = "primary" | "secondary" | "outline";
3
- export type ButtonSizes = "sm" | "md" | "lg";
2
+ export type ButtonVariant = "primary" | "secondary" | "outline";
3
+ export type ButtonSize = "sm" | "md" | "lg";
4
4
  type ButtonOwnProps = {
5
- variant?: ButtonVariants;
6
- size?: ButtonSizes;
5
+ variant?: ButtonVariant;
6
+ size?: ButtonSize;
7
7
  isLoading?: boolean;
8
8
  href?: string;
9
9
  target?: string;
@@ -1,2 +1,2 @@
1
1
  export { Button } from './Button';
2
- export type { ButtonProps, ButtonVariants, ButtonSizes } from './Button.types';
2
+ export type { ButtonVariant, ButtonSize, ButtonProps } from './Button.types';
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { Button } from './Button';
2
+ import { Button } from '../Button';
3
3
  declare const meta: Meta<typeof Button>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof Button>;
@@ -0,0 +1,5 @@
1
+ import { CheckboxProps } from './Checkbox.types';
2
+ export declare function Checkbox({ ref, label, size, error, helperText, disabled, checked, id, color, borderColor, checkColor, ...props }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
3
+ export declare namespace Checkbox {
4
+ var displayName: string;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { ComponentPropsWithRef } from 'react';
2
+ export type CheckboxSize = "sm" | "md";
3
+ export interface CheckboxProps extends Omit<ComponentPropsWithRef<"input">, "type" | "size"> {
4
+ label?: string;
5
+ size?: CheckboxSize;
6
+ error?: boolean | string;
7
+ helperText?: string;
8
+ color?: string;
9
+ borderColor?: string;
10
+ checkColor?: string;
11
+ }
@@ -0,0 +1,2 @@
1
+ export { Checkbox } from './Checkbox';
2
+ export type { CheckboxProps, CheckboxSize } from './Checkbox.types';
@@ -0,0 +1,11 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { Checkbox } from '../Checkbox';
3
+ declare const meta: Meta<typeof Checkbox>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof Checkbox>;
6
+ export declare const Default: Story;
7
+ export declare const Checked: Story;
8
+ export declare const WithError: Story;
9
+ export declare const WithHelperText: Story;
10
+ export declare const Disabled: Story;
11
+ export declare const Small: Story;
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
2
  import { ComponentProps } from 'react';
3
- import { CollapsibleCard } from './CollapsibleCard';
3
+ import { CollapsibleCard } from '../CollapsibleCard';
4
4
  type StoryArgs = ComponentProps<typeof CollapsibleCard> & {
5
5
  text: string;
6
6
  };
@@ -0,0 +1,2 @@
1
+ import { ConfirmFn } from './ConfirmDialog.types';
2
+ export declare function useConfirm(): ConfirmFn;
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
- import { ConfirmFn } from './useConfirm.types';
2
+ import { ConfirmContextValue } from './ConfirmDialog.types';
3
+ export declare const ConfirmContext: import('react').Context<ConfirmContextValue | null>;
3
4
  export declare function ConfirmProvider({ children }: {
4
5
  children: ReactNode;
5
6
  }): import("react/jsx-runtime").JSX.Element;
6
- export declare function useConfirm(): ConfirmFn;
@@ -1,4 +1,4 @@
1
- import { ModalSizes } from '../Modal';
1
+ import { ModalSize } from '../Modal';
2
2
  export type ConfirmVariant = "default" | "danger";
3
3
  export interface ConfirmDialogProps {
4
4
  open: boolean;
@@ -7,7 +7,19 @@ export interface ConfirmDialogProps {
7
7
  confirmLabel?: string;
8
8
  cancelLabel?: string;
9
9
  variant?: ConfirmVariant;
10
- size?: ModalSizes;
10
+ size?: ModalSize;
11
11
  onConfirm: () => void;
12
12
  onCancel: () => void;
13
13
  }
14
+ export interface ConfirmOptions {
15
+ title?: string;
16
+ message: string;
17
+ confirmLabel?: string;
18
+ cancelLabel?: string;
19
+ variant?: ConfirmVariant;
20
+ size?: ModalSize;
21
+ }
22
+ export type ConfirmFn = (options: ConfirmOptions) => Promise<boolean>;
23
+ export interface ConfirmContextValue {
24
+ confirm: ConfirmFn;
25
+ }
@@ -1,4 +1,5 @@
1
1
  export { ConfirmDialog } from './ConfirmDialog';
2
- export type { ConfirmDialogProps, ConfirmVariant } from './ConfirmDialog.types';
3
- export { useConfirm, ConfirmProvider } from './useConfirm';
4
- export type { ConfirmOptions, ConfirmFn, ConfirmContextValue, } from './useConfirm.types';
2
+ export type { ConfirmVariant } from './ConfirmDialog.types';
3
+ export type { ConfirmDialogProps, ConfirmOptions, ConfirmFn, ConfirmContextValue, } from './ConfirmDialog.types';
4
+ export { ConfirmProvider } from './ConfirmDialog.provider';
5
+ export { useConfirm } from './ConfirmDialog.hooks';
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { ConfirmDialog } from './ConfirmDialog';
2
+ import { ConfirmDialog } from '../ConfirmDialog';
3
3
  declare const meta: Meta<typeof ConfirmDialog>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof ConfirmDialog>;
@@ -1,5 +1,5 @@
1
1
  import { DatePickerProps } from './DatePicker.types';
2
- export declare function DatePicker({ value, onChange, placeholder, size, disabled, clearable, minDate, maxDate, formatDate, id, error, }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function DatePicker({ name, label, value, onChange, placeholder, size, disabled, clearable, minDate, maxDate, formatDate, error, required, helperText, mode, nameFrom, nameTo, valueFrom, valueTo, }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
3
3
  export declare namespace DatePicker {
4
4
  var displayName: string;
5
5
  }
@@ -1,14 +1,22 @@
1
- export type DatePickerSizes = "sm" | "md" | "lg";
1
+ export type DatePickerSize = "sm" | "md" | "lg";
2
2
  export interface DatePickerProps {
3
- value?: Date | null;
4
- onChange?: (date: Date | null) => void;
5
- placeholder?: string;
6
- size?: DatePickerSizes;
3
+ name?: string;
4
+ value?: string;
5
+ onChange: (name: string, value: string) => void;
6
+ label?: string;
7
+ size?: DatePickerSize;
7
8
  disabled?: boolean;
8
9
  clearable?: boolean;
9
10
  minDate?: Date;
10
11
  maxDate?: Date;
11
12
  formatDate?: (date: Date) => string;
12
- id?: string;
13
+ placeholder?: string;
13
14
  error?: boolean | string;
15
+ required?: boolean;
16
+ helperText?: string;
17
+ mode?: "single" | "range";
18
+ nameFrom?: string;
19
+ nameTo?: string;
20
+ valueFrom?: string;
21
+ valueTo?: string;
14
22
  }
@@ -1,2 +1,3 @@
1
1
  export { DatePicker } from './DatePicker';
2
- export type { DatePickerProps, DatePickerSizes } from './DatePicker.types';
2
+ export type { DatePickerSize } from './DatePicker.types';
3
+ export type { DatePickerProps } from './DatePicker.types';
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { DatePicker } from './DatePicker';
2
+ import { DatePicker } from '../DatePicker';
3
3
  declare const meta: Meta<typeof DatePicker>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof DatePicker>;
@@ -9,3 +9,4 @@ export declare const WithMinMax: Story;
9
9
  export declare const Sizes: Story;
10
10
  export declare const Disabled: Story;
11
11
  export declare const WithError: Story;
12
+ export declare const WithLabel: Story;
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { Editable } from './Editable';
2
+ import { Editable } from '../Editable';
3
3
  declare const meta: Meta<typeof Editable>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof Editable>;
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { Field } from './Field';
2
+ import { Field } from '../Field';
3
3
  declare const meta: Meta<typeof Field>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof Field>;
@@ -1,2 +1,2 @@
1
- import { UseFormOptions, UseFormReturn } from './useForm.types';
1
+ import { UseFormOptions, UseFormReturn } from './Form.types';
2
2
  export declare function useForm<T extends Record<string, string>>({ initialValues, validate, onSubmit, onError, }: UseFormOptions<T>): UseFormReturn<T>;
@@ -1,11 +1,23 @@
1
- import { ComponentPropsWithRef, FormEvent, ReactNode } from 'react';
1
+ import { ChangeEvent, ComponentPropsWithRef, FocusEvent, FormEvent } from 'react';
2
2
  export interface FormProps extends Omit<ComponentPropsWithRef<"form">, "onSubmit"> {
3
3
  onSubmit?: (event: FormEvent<HTMLFormElement>) => void;
4
4
  }
5
- export interface FormFieldProps {
6
- label?: string;
7
- error?: string | boolean;
8
- helperText?: string;
9
- required?: boolean;
10
- children: ReactNode;
5
+ type FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
6
+ export interface UseFormOptions<T extends Record<string, string>> {
7
+ initialValues: T;
8
+ validate?: (values: T) => Partial<Record<keyof T, string | undefined>>;
9
+ onSubmit?: (values: T) => void | Promise<void>;
10
+ onError?: (errors: Partial<Record<keyof T, string>>) => void;
11
11
  }
12
+ export interface UseFormReturn<T extends Record<string, string>> {
13
+ values: T;
14
+ errors: Partial<Record<keyof T, string>>;
15
+ touched: Partial<Record<keyof T, boolean>>;
16
+ handleChange: (e: ChangeEvent<FieldElement>) => void;
17
+ handleBlur: (e: FocusEvent<FieldElement>) => void;
18
+ handleSubmit: (e?: FormEvent) => void;
19
+ setFieldValue: (field: keyof T, value: string) => void;
20
+ reset: (newValues?: T) => void;
21
+ isSubmitting: boolean;
22
+ }
23
+ export {};
@@ -1,4 +1,4 @@
1
- import { FormFieldProps } from './Form.types';
1
+ import { FormFieldProps } from './FormField.types';
2
2
  export declare function FormField({ label, error, helperText, required, children, }: FormFieldProps): import("react/jsx-runtime").JSX.Element;
3
3
  export declare namespace FormField {
4
4
  var displayName: string;
@@ -0,0 +1,8 @@
1
+ import { ReactNode } from 'react';
2
+ export interface FormFieldProps {
3
+ label?: string;
4
+ error?: string | boolean;
5
+ helperText?: string;
6
+ required?: boolean;
7
+ children: ReactNode;
8
+ }
@@ -0,0 +1,2 @@
1
+ export { FormField } from './FormField';
2
+ export type { FormFieldProps } from './FormField.types';
@@ -1,5 +1,6 @@
1
1
  export { Form } from './Form';
2
+ export type { FormProps, UseFormOptions, UseFormReturn } from './Form.types';
2
3
  export { FormField } from './FormField';
3
- export type { FormProps, FormFieldProps } from './Form.types';
4
- export { useForm } from './useForm';
5
- export type { UseFormOptions, UseFormReturn } from './useForm.types';
4
+ export type { FormFieldProps } from './FormField';
5
+ export { useForm } from './Form.hooks';
6
+ export { required, minLength, maxLength, isEmail, isUrl, pattern, composeValidators, } from './validators/Form.validators';
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { Form } from './Form';
2
+ import { Form } from '../Form';
3
3
  declare const meta: Meta<typeof Form>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof Form>;
@@ -0,0 +1,9 @@
1
+ type Validator = (value: string) => string | undefined;
2
+ export declare const required: (message?: string) => Validator;
3
+ export declare const minLength: (n: number, message?: string) => Validator;
4
+ export declare const maxLength: (n: number, message?: string) => Validator;
5
+ export declare const isEmail: (message?: string) => Validator;
6
+ export declare const isUrl: (message?: string) => Validator;
7
+ export declare const pattern: (regex: RegExp, message: string) => Validator;
8
+ export declare function composeValidators(...validators: Validator[]): Validator;
9
+ export {};
@@ -1,11 +1,11 @@
1
1
  import { ComponentPropsWithRef, ReactNode } from 'react';
2
- export type InputTypes = "text" | "email" | "password" | "number" | "search" | "tel" | "url";
3
- export type InputSizes = "sm" | "md" | "lg";
4
- export type InputVariants = "default" | "outlined";
2
+ export type InputType = "text" | "email" | "password" | "number" | "search" | "tel" | "url";
3
+ export type InputSize = "sm" | "md" | "lg";
4
+ export type InputVariant = "default" | "outlined";
5
5
  export interface InputProps extends Omit<ComponentPropsWithRef<"input">, "size" | "type"> {
6
- type?: InputTypes;
7
- size?: InputSizes;
8
- variant?: InputVariants;
6
+ type?: InputType;
7
+ size?: InputSize;
8
+ variant?: InputVariant;
9
9
  label?: string;
10
10
  helperText?: string;
11
11
  error?: boolean | string;
@@ -1,2 +1,2 @@
1
1
  export { Input } from './Input';
2
- export type { InputProps, InputTypes, InputSizes, InputVariants, } from './Input.types';
2
+ export type { InputType, InputSize, InputVariant, InputProps, } from './Input.types';
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { Input } from './Input';
2
+ import { Input } from '../Input';
3
3
  declare const meta: Meta<typeof Input>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof Input>;