blunt-ui 0.3.5 → 1.0.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 (102) hide show
  1. package/README.md +109 -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.hooks.d.ts +29 -0
  65. package/dist/components/Table/Table.types.d.ts +12 -2
  66. package/dist/components/Table/index.d.ts +2 -3
  67. package/dist/components/Table/{Table.stories.d.ts → stories/Table.stories.d.ts} +1 -1
  68. package/dist/components/Table/tests/Table.test.d.ts +0 -0
  69. package/dist/components/Textarea/Textarea.types.d.ts +4 -4
  70. package/dist/components/Textarea/index.d.ts +1 -1
  71. package/dist/components/Textarea/{Textarea.stories.d.ts → stories/Textarea.stories.d.ts} +1 -1
  72. package/dist/components/Textarea/tests/Textarea.test.d.ts +0 -0
  73. package/dist/components/Toast/Toast.hooks.d.ts +2 -0
  74. package/dist/components/Toast/{useToast.d.ts → Toast.provider.d.ts} +2 -2
  75. package/dist/components/Toast/Toast.types.d.ts +18 -2
  76. package/dist/components/Toast/index.d.ts +4 -3
  77. package/dist/components/Toast/{Toast.stories.d.ts → stories/Toast.stories.d.ts} +1 -1
  78. package/dist/components/Toast/tests/Toast.provider.test.d.ts +0 -0
  79. package/dist/components/Toast/tests/Toast.test.d.ts +0 -0
  80. package/dist/index.cjs +495 -186
  81. package/dist/index.d.ts +19 -13
  82. package/dist/index.js +1996 -1119
  83. package/dist/themes/types.d.ts +9 -0
  84. package/package.json +2 -2
  85. package/dist/components/ConfirmDialog/useConfirm.types.d.ts +0 -14
  86. package/dist/components/Form/useForm.types.d.ts +0 -20
  87. package/dist/components/Table/useTable.d.ts +0 -12
  88. package/dist/components/Table/useTablePagination.d.ts +0 -16
  89. package/dist/components/Table/useTableSort.d.ts +0 -13
  90. package/dist/components/Toast/useToast.types.d.ts +0 -17
  91. /package/dist/components/{Button/Button.test.d.ts → Badge/tests/Badge.test.d.ts} +0 -0
  92. /package/dist/components/{CollapsibleCard/CollapsibleCard.test.d.ts → Button/tests/Button.test.d.ts} +0 -0
  93. /package/dist/components/{ConfirmDialog/ConfirmDialog.test.d.ts → Checkbox/tests/Checkbox.test.d.ts} +0 -0
  94. /package/dist/components/{ConfirmDialog/useConfirm.test.d.ts → CollapsibleCard/tests/CollapsibleCard.test.d.ts} +0 -0
  95. /package/dist/components/{DatePicker/DatePicker.test.d.ts → ConfirmDialog/tests/ConfirmDialog.provider.test.d.ts} +0 -0
  96. /package/dist/components/{Form/Form.test.d.ts → ConfirmDialog/tests/ConfirmDialog.test.d.ts} +0 -0
  97. /package/dist/components/{Input/Input.test.d.ts → DatePicker/tests/DatePicker.test.d.ts} +0 -0
  98. /package/dist/components/{Modal/Modal.test.d.ts → Editable/tests/Editable.test.d.ts} +0 -0
  99. /package/dist/components/{Select/Select.test.d.ts → Field/tests/Field.test.d.ts} +0 -0
  100. /package/dist/components/Form/{useForm.test.d.ts → tests/Form.hooks.test.d.ts} +0 -0
  101. /package/dist/components/{Toast/Toast.test.d.ts → Form/tests/Form.test.d.ts} +0 -0
  102. /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,58 @@ 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
+ {["remote", "hybrid", "on-site"].map((option) => (
107
+ <Radio
108
+ key={option}
109
+ name="workMode"
110
+ value={option}
111
+ label={option}
112
+ checked={value === option}
113
+ onChange={(e) => setValue(e.target.value)}
114
+ />
115
+ ))}
116
+ ```
117
+
118
+ ### Switch
119
+
120
+ A toggle. Same API as Checkbox - `checked` + `onChange`. Sizes: `sm`, `md`.
121
+
122
+ ```tsx
123
+ <Switch
124
+ label="Enable notifications"
125
+ checked={enabled}
126
+ onChange={(e) => setEnabled(e.target.checked)}
127
+ />
128
+ ```
129
+
88
130
  ### Select
89
131
 
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.
132
+ 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
133
 
92
134
  ```tsx
93
135
  <Select
@@ -154,7 +196,7 @@ Opens in a portal on `document.body`. Traps focus, locks body scroll, closes on
154
196
  </Modal>
155
197
  ```
156
198
 
157
- The `footer` slot is where you put action buttons — it renders at the bottom of the modal, separated from the content.
199
+ The `footer` slot is where you put action buttons - it renders at the bottom of the modal, separated from the content.
158
200
 
159
201
  ### Toast
160
202
 
@@ -171,11 +213,11 @@ Variants: `success`, `error`, `warning`, `info`. Positions: `bottom-right`, `bot
171
213
  />
172
214
  ```
173
215
 
174
- In practice you'll probably want `useToast` instead — see hooks below.
216
+ In practice you'll probably want `useToast` instead - see hooks below.
175
217
 
176
218
  ### Form
177
219
 
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.
220
+ `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
221
 
180
222
  ```tsx
181
223
  <Form onSubmit={handleSubmit}>
@@ -192,7 +234,7 @@ In practice you'll probably want `useToast` instead — see hooks below.
192
234
  </Form>
193
235
  ```
194
236
 
195
- Pair with `useForm` for validation — they're designed to work together.
237
+ Pair with `useForm` for validation - they're designed to work together.
196
238
 
197
239
  ### Link
198
240
 
@@ -205,7 +247,7 @@ Styled anchor. Variants: `default` and `subtle` (less prominent, for secondary l
205
247
 
206
248
  ### CollapsibleCard
207
249
 
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`.
250
+ 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
251
 
210
252
  ```tsx
211
253
  <CollapsibleCard title="Details" subtitle="Optional subtitle" defaultOpen>
@@ -213,7 +255,7 @@ A card with a header you can click to show/hide the content. Works uncontrolled
213
255
  </CollapsibleCard>
214
256
  ```
215
257
 
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.
258
+ `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
259
 
218
260
  ```tsx
219
261
  <CollapsibleCard
@@ -240,7 +282,7 @@ Loading indicator. Sizes: `sm`, `md`, `lg`. Weights: `thin`, `normal`, `bold`. Y
240
282
 
241
283
  ### Table
242
284
 
243
- Read-only table with sorting and pagination built in. Define columns, pass data — that's the basic case.
285
+ Read-only table with sorting and pagination built in. Define columns, pass data - that's the basic case.
244
286
 
245
287
  ```tsx
246
288
  const columns = [
@@ -260,11 +302,11 @@ const columns = [
260
302
  />;
261
303
  ```
262
304
 
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.
305
+ **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
306
 
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.
307
+ **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
308
 
267
- **Other props** — `loading` shows skeleton rows while data loads. `stickyHeader` keeps the header visible on scroll. `caption` adds an accessible `<caption>`.
309
+ **Other props** - `loading` shows skeleton rows while data loads. `stickyHeader` keeps the header visible on scroll. `caption` adds an accessible `<caption>`.
268
310
 
269
311
  Color props if you need to match a specific theme: `borderColor`, `headerColor`, `rowColor`, `stripeColor`.
270
312
 
@@ -286,19 +328,39 @@ A specialized modal for destructive actions. Two variants: `default` and `danger
286
328
 
287
329
  ### DatePicker
288
330
 
289
- Calendar-based date input. Sizes: `sm`, `md`, `lg`. Supports `minDate`, `maxDate`, and `clearable`.
331
+ 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`.
332
+
333
+ Sizes: `sm`, `md`, `lg`. Supports `minDate`, `maxDate`, `clearable`, `label`, `error`, `helperText`.
290
334
 
291
335
  ```tsx
292
- <DatePicker value={date} onChange={setDate} placeholder="Pick a date" />
293
- <DatePicker value={date} onChange={setDate} minDate={new Date()} clearable />
336
+ // Standalone
337
+ const [date, setDate] = useState("");
338
+
339
+ <DatePicker name="date" value={date} onChange={(_, v) => setDate(v)} />;
294
340
  ```
295
341
 
296
- `formatDate` controls how the selected date is displayed in the input field:
342
+ With `useForm`, just pass `setFieldValue` straight in:
297
343
 
298
344
  ```tsx
345
+ const { values, setFieldValue } = useForm({
346
+ initialValues: { dateApplied: "" },
347
+ });
348
+
299
349
  <DatePicker
350
+ name="dateApplied"
351
+ label="Date applied"
352
+ value={values.dateApplied}
353
+ onChange={setFieldValue}
354
+ />;
355
+ ```
356
+
357
+ `formatDate` changes how the picked date shows in the trigger:
358
+
359
+ ```tsx
360
+ <DatePicker
361
+ name="date"
300
362
  value={date}
301
- onChange={setDate}
363
+ onChange={(_, v) => setDate(v)}
302
364
  formatDate={(d) => d.toLocaleDateString("pl-PL")}
303
365
  />
304
366
  ```
@@ -329,7 +391,7 @@ toast.info("New version available.");
329
391
 
330
392
  ### useConfirm
331
393
 
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.
394
+ 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
395
 
334
396
  ```tsx
335
397
  <ConfirmProvider>
@@ -355,7 +417,7 @@ Much cleaner than managing open/close state for every confirm dialog in your app
355
417
 
356
418
  ### useForm
357
419
 
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.
420
+ 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
421
 
360
422
  ```tsx
361
423
  const { values, errors, handleChange, handleBlur, handleSubmit, reset } =
@@ -376,6 +438,20 @@ const { values, errors, handleChange, handleBlur, handleSubmit, reset } =
376
438
 
377
439
  Each input's `name` needs to match a key in `initialValues`. `reset()` puts everything back to the initial state.
378
440
 
441
+ The library ships with validators you can use in the `validate` function:
442
+
443
+ ```tsx
444
+ import { required, minLength, isEmail, isUrl, composeValidators } from "blunt-ui";
445
+
446
+ validate: (v) => ({
447
+ email: composeValidators(required(), isEmail())(v.email),
448
+ password: minLength(8)(v.password),
449
+ website: isUrl()(v.website),
450
+ })
451
+ ```
452
+
453
+ `composeValidators` runs validators left to right and returns the first error. Available validators: `required`, `minLength`, `maxLength`, `isEmail`, `isUrl`, `pattern`.
454
+
379
455
  ### useTable
380
456
 
381
457
  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 +475,18 @@ useEffect(() => {
399
475
  />;
400
476
  ```
401
477
 
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.
478
+ 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
479
 
404
480
  ---
405
481
 
406
482
  ## Design tokens
407
483
 
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.
484
+ 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.
485
+
486
+ The accent color is the only thing I designed to be easily swappable:
487
+
488
+ ```ts
489
+ import { createNeoBrutalTheme } from "blunt-ui";
490
+
491
+ const theme = createNeoBrutalTheme("#f97316"); // swap yellow for orange
492
+ ```
@@ -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>;