@idyeah/diya 0.0.0 → 1.0.1

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 (190) hide show
  1. package/CHANGELOG.md +332 -0
  2. package/NOTICE +29 -0
  3. package/README.md +596 -5
  4. package/dist/DiyaProvider.d.ts +79 -0
  5. package/dist/DiyaProvider.js +77 -0
  6. package/dist/Icon.d.ts +10 -0
  7. package/dist/Icon.js +27 -0
  8. package/dist/accordion/Accordion.d.ts +34 -0
  9. package/dist/accordion/Accordion.js +15 -0
  10. package/dist/alert/Alert.d.ts +49 -0
  11. package/dist/alert/Alert.js +11 -0
  12. package/dist/alert/messages.d.ts +9 -0
  13. package/dist/alert/messages.js +2 -0
  14. package/dist/api.json +7277 -0
  15. package/dist/api.schema.json +214 -0
  16. package/dist/application-patterns/Chatbot.d.ts +114 -0
  17. package/dist/application-patterns/Chatbot.js +110 -0
  18. package/dist/application-patterns/SideNavigation.d.ts +74 -0
  19. package/dist/application-patterns/SideNavigation.js +31 -0
  20. package/dist/application-patterns/chatbot-messages.d.ts +20 -0
  21. package/dist/application-patterns/chatbot-messages.js +2 -0
  22. package/dist/application-patterns/side-navigation-messages.d.ts +5 -0
  23. package/dist/application-patterns/side-navigation-messages.js +2 -0
  24. package/dist/avatar/Avatar.d.ts +32 -0
  25. package/dist/avatar/Avatar.js +19 -0
  26. package/dist/avatar/messages.d.ts +7 -0
  27. package/dist/avatar/messages.js +2 -0
  28. package/dist/badge/Badge.d.ts +42 -0
  29. package/dist/badge/Badge.js +16 -0
  30. package/dist/badge/badge-utils.d.ts +6 -0
  31. package/dist/badge/badge-utils.js +24 -0
  32. package/dist/badge/messages.d.ts +4 -0
  33. package/dist/badge/messages.js +2 -0
  34. package/dist/breadcrumbs/Breadcrumbs.d.ts +34 -0
  35. package/dist/breadcrumbs/Breadcrumbs.js +19 -0
  36. package/dist/breadcrumbs/messages.d.ts +5 -0
  37. package/dist/breadcrumbs/messages.js +2 -0
  38. package/dist/button/Button.d.ts +46 -0
  39. package/dist/button/Button.js +44 -0
  40. package/dist/calendar/Calendar.d.ts +55 -0
  41. package/dist/calendar/Calendar.js +61 -0
  42. package/dist/calendar/messages.d.ts +8 -0
  43. package/dist/calendar/messages.js +2 -0
  44. package/dist/calendar/month.d.ts +61 -0
  45. package/dist/calendar/month.js +134 -0
  46. package/dist/card/Card.d.ts +46 -0
  47. package/dist/card/Card.js +8 -0
  48. package/dist/choice/Choice.d.ts +72 -0
  49. package/dist/choice/Choice.js +68 -0
  50. package/dist/choice/messages.d.ts +4 -0
  51. package/dist/choice/messages.js +2 -0
  52. package/dist/code-block/CodeBlock.d.ts +20 -0
  53. package/dist/code-block/CodeBlock.js +49 -0
  54. package/dist/code-block/messages.d.ts +8 -0
  55. package/dist/code-block/messages.js +2 -0
  56. package/dist/combobox/Combobox.d.ts +60 -0
  57. package/dist/combobox/Combobox.js +160 -0
  58. package/dist/combobox/messages.d.ts +9 -0
  59. package/dist/combobox/messages.js +2 -0
  60. package/dist/combobox/useAnchoredPopover.d.ts +5 -0
  61. package/dist/combobox/useAnchoredPopover.js +100 -0
  62. package/dist/data-viz/DataViz.d.ts +140 -0
  63. package/dist/data-viz/DataViz.js +469 -0
  64. package/dist/data-viz/index.d.ts +2 -0
  65. package/dist/data-viz/index.js +1 -0
  66. package/dist/data-viz/messages.d.ts +11 -0
  67. package/dist/data-viz/messages.js +2 -0
  68. package/dist/date-picker/DatePicker.d.ts +57 -0
  69. package/dist/date-picker/DatePicker.js +146 -0
  70. package/dist/date-picker/messages.d.ts +13 -0
  71. package/dist/date-picker/messages.js +2 -0
  72. package/dist/dialog/Dialog.d.ts +84 -0
  73. package/dist/dialog/Dialog.js +107 -0
  74. package/dist/dialog/messages.d.ts +9 -0
  75. package/dist/dialog/messages.js +2 -0
  76. package/dist/fonts/DIYASans-Italic.woff2 +0 -0
  77. package/dist/fonts/DIYASans.woff2 +0 -0
  78. package/dist/fonts/OFL.txt +94 -0
  79. package/dist/index.d.ts +50 -0
  80. package/dist/index.js +46 -0
  81. package/dist/internal/brand.d.ts +33 -0
  82. package/dist/internal/brand.js +57 -0
  83. package/dist/internal/cx.d.ts +2 -0
  84. package/dist/internal/cx.js +4 -0
  85. package/dist/internal/link.d.ts +14 -0
  86. package/dist/internal/link.js +7 -0
  87. package/dist/internal/slot.d.ts +15 -0
  88. package/dist/internal/slot.js +67 -0
  89. package/dist/layout/Inline.d.ts +4 -0
  90. package/dist/layout/Inline.js +7 -0
  91. package/dist/layout/Stack.d.ts +4 -0
  92. package/dist/layout/Stack.js +7 -0
  93. package/dist/layout/layout.d.ts +32 -0
  94. package/dist/layout/layout.js +12 -0
  95. package/dist/link/TextLink.d.ts +23 -0
  96. package/dist/link/TextLink.js +17 -0
  97. package/dist/list/List.d.ts +48 -0
  98. package/dist/list/List.js +17 -0
  99. package/dist/list/messages.d.ts +4 -0
  100. package/dist/list/messages.js +2 -0
  101. package/dist/menu/Menu.d.ts +49 -0
  102. package/dist/menu/Menu.js +54 -0
  103. package/dist/messages-defaults.d.ts +201 -0
  104. package/dist/messages-defaults.js +61 -0
  105. package/dist/messages.d.ts +12 -0
  106. package/dist/messages.js +1 -0
  107. package/dist/metric/Metric.d.ts +42 -0
  108. package/dist/metric/Metric.js +11 -0
  109. package/dist/metric/messages.d.ts +9 -0
  110. package/dist/metric/messages.js +2 -0
  111. package/dist/overlay/FloatingSurface.d.ts +29 -0
  112. package/dist/overlay/FloatingSurface.js +254 -0
  113. package/dist/page-header/PageHeader.d.ts +38 -0
  114. package/dist/page-header/PageHeader.js +10 -0
  115. package/dist/pagination/Pagination.d.ts +44 -0
  116. package/dist/pagination/Pagination.js +26 -0
  117. package/dist/pagination/messages.d.ts +11 -0
  118. package/dist/pagination/messages.js +2 -0
  119. package/dist/popover/Popover.d.ts +23 -0
  120. package/dist/popover/Popover.js +8 -0
  121. package/dist/progress/Progress.d.ts +33 -0
  122. package/dist/progress/Progress.js +14 -0
  123. package/dist/progress/messages.d.ts +4 -0
  124. package/dist/progress/messages.js +2 -0
  125. package/dist/prose/Prose.d.ts +14 -0
  126. package/dist/prose/Prose.js +7 -0
  127. package/dist/rating/Rating.d.ts +32 -0
  128. package/dist/rating/Rating.js +27 -0
  129. package/dist/rating/messages.d.ts +6 -0
  130. package/dist/rating/messages.js +2 -0
  131. package/dist/search/Search.d.ts +11 -0
  132. package/dist/search/Search.js +9 -0
  133. package/dist/select/Select.d.ts +65 -0
  134. package/dist/select/Select.js +19 -0
  135. package/dist/select/messages.d.ts +4 -0
  136. package/dist/select/messages.js +2 -0
  137. package/dist/site-header/SiteHeader.d.ts +88 -0
  138. package/dist/site-header/SiteHeader.js +211 -0
  139. package/dist/site-header/messages.d.ts +8 -0
  140. package/dist/site-header/messages.js +2 -0
  141. package/dist/slider/Slider.d.ts +54 -0
  142. package/dist/slider/Slider.js +89 -0
  143. package/dist/slider/messages.d.ts +5 -0
  144. package/dist/slider/messages.js +2 -0
  145. package/dist/styles.css +3386 -0
  146. package/dist/switch/Switch.d.ts +47 -0
  147. package/dist/switch/Switch.js +18 -0
  148. package/dist/table/Table.d.ts +99 -0
  149. package/dist/table/Table.js +158 -0
  150. package/dist/table/messages.d.ts +23 -0
  151. package/dist/table/messages.js +2 -0
  152. package/dist/tabs/Tabs.d.ts +49 -0
  153. package/dist/tabs/Tabs.js +26 -0
  154. package/dist/tag/Tag.d.ts +37 -0
  155. package/dist/tag/Tag.js +20 -0
  156. package/dist/tag/messages.d.ts +4 -0
  157. package/dist/tag/messages.js +2 -0
  158. package/dist/text-area/TextArea.d.ts +47 -0
  159. package/dist/text-area/TextArea.js +19 -0
  160. package/dist/text-input/TextInput.d.ts +53 -0
  161. package/dist/text-input/TextInput.js +35 -0
  162. package/dist/text-input/messages.d.ts +4 -0
  163. package/dist/text-input/messages.js +3 -0
  164. package/dist/text-input/native-field.d.ts +15 -0
  165. package/dist/text-input/native-field.js +56 -0
  166. package/dist/toast/Toast.d.ts +24 -0
  167. package/dist/toast/Toast.js +79 -0
  168. package/dist/toast/messages.d.ts +4 -0
  169. package/dist/toast/messages.js +2 -0
  170. package/dist/tooltip/Tooltip.d.ts +22 -0
  171. package/dist/tooltip/Tooltip.js +92 -0
  172. package/dist/workflow/ContentState.d.ts +44 -0
  173. package/dist/workflow/ContentState.js +11 -0
  174. package/dist/workflow/Drawer.d.ts +48 -0
  175. package/dist/workflow/Drawer.js +51 -0
  176. package/dist/workflow/FileUpload.d.ts +67 -0
  177. package/dist/workflow/FileUpload.js +47 -0
  178. package/dist/workflow/Form.d.ts +52 -0
  179. package/dist/workflow/Form.js +16 -0
  180. package/dist/workflow/Wizard.d.ts +76 -0
  181. package/dist/workflow/Wizard.js +31 -0
  182. package/dist/workflow/drawer-messages.d.ts +4 -0
  183. package/dist/workflow/drawer-messages.js +2 -0
  184. package/dist/workflow/file-upload-messages.d.ts +11 -0
  185. package/dist/workflow/file-upload-messages.js +2 -0
  186. package/dist/workflow/form-messages.d.ts +5 -0
  187. package/dist/workflow/form-messages.js +2 -0
  188. package/dist/workflow/wizard-messages.d.ts +9 -0
  189. package/dist/workflow/wizard-messages.js +2 -0
  190. package/package.json +82 -7
@@ -0,0 +1,47 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useRef, useState } from 'react';
4
+ import { Button } from '../button/Button.js';
5
+ import { Icon } from '../Icon.js';
6
+ import { useDiyaLocale, useDiyaMessages } from '../DiyaProvider.js';
7
+ import { cx } from '../internal/cx.js';
8
+ import { fileUploadMessages } from './file-upload-messages.js';
9
+ /** A drop zone and file picker with a removable file list. Selects local files; upload, persistence and server validation belong to the caller. */
10
+ export const FileUpload = forwardRef(function FileUpload({ files, onFilesChange, accept = '', maxBytes, multiple = false, disabled = false, title: titleProp, headingLevel = 3, description: descriptionProp, helperText, chooseLabel, onReject, className, ...props }, ref) {
11
+ const t = useDiyaMessages('fileUpload', fileUploadMessages);
12
+ const locale = useDiyaLocale();
13
+ const title = titleProp ?? t.title;
14
+ const Heading = `h${headingLevel}`;
15
+ const description = descriptionProp === undefined ? t.description : descriptionProp;
16
+ const picker = useRef(null);
17
+ const chooseButton = useRef(null);
18
+ const [error, setError] = useState('');
19
+ const [dragging, setDragging] = useState(false);
20
+ const rules = accept.split(',').map(rule => rule.trim().toLowerCase()).filter(Boolean);
21
+ function add(incoming) {
22
+ if (!incoming || disabled)
23
+ return;
24
+ const accepted = [];
25
+ const rejected = [];
26
+ for (const file of Array.from(incoming)) {
27
+ const name = file.name.toLowerCase();
28
+ const mime = file.type.toLowerCase();
29
+ const matches = !rules.length || rules.some(rule => rule.startsWith('.') ? name.endsWith(rule) : rule.endsWith('/*') ? mime.startsWith(rule.slice(0, -1)) : mime === rule);
30
+ if (!matches)
31
+ rejected.push({ file, reason: 'type' });
32
+ else if (maxBytes !== undefined && Number.isFinite(maxBytes) && maxBytes >= 0 && file.size > maxBytes)
33
+ rejected.push({ file, reason: 'size' });
34
+ else
35
+ accepted.push(file);
36
+ }
37
+ if (accepted.length) {
38
+ const next = multiple ? [...files, ...accepted].filter((file, index, all) => all.findIndex(other => other.name === file.name && other.size === file.size && other.lastModified === file.lastModified) === index) : accepted.slice(0, 1);
39
+ onFilesChange(next);
40
+ }
41
+ setError(rejected.length ? t.rejected(rejected.length) : '');
42
+ if (rejected.length)
43
+ onReject?.(rejected);
44
+ }
45
+ return _jsxs("section", { ...props, ref: ref, className: cx('diya-workflow-surface diya-upload', className), "aria-label": title, "aria-disabled": disabled || undefined, children: [_jsxs("div", { className: "diya-upload-drop", "data-dragging": dragging || undefined, onDragOver: event => { event.preventDefault(); if (!disabled)
46
+ setDragging(true); }, onDragLeave: () => setDragging(false), onDrop: event => { event.preventDefault(); setDragging(false); add(event.dataTransfer.files); }, children: [_jsx("span", { className: "diya-workflow-symbol", children: _jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.6", "aria-hidden": "true", children: _jsx("path", { d: "M12 16V3m-5 5 5-5 5 5M4 15v6h16v-6" }) }) }), _jsx(Heading, { className: "diya-upload-title", children: title }), description && _jsx("p", { children: description }), _jsx(Button, { ref: chooseButton, variant: "outline", disabled: disabled, onClick: () => picker.current?.click(), children: chooseLabel ?? t.choose }), _jsx("input", { ref: picker, type: "file", hidden: true, disabled: disabled, accept: accept || undefined, multiple: multiple, onChange: event => { add(event.target.files); event.target.value = ''; } }), helperText && _jsx("small", { children: helperText })] }), error && _jsx("p", { className: "diya-workflow-error", role: "alert", children: error }), !!files.length && _jsx("ul", { className: "diya-upload-files", children: files.map(file => _jsxs("li", { children: [_jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.6", "aria-hidden": "true", children: _jsx("path", { d: "M5 3h9l5 5v13H5V3Zm9 0v6h5" }) }), _jsxs("span", { children: [_jsx("strong", { children: file.name }), _jsx("small", { children: file.size < 1024 * 1024 ? t.kilobytes(Math.max(1, Math.round(file.size / 1024)).toLocaleString(locale, { useGrouping: false })) : t.megabytes((file.size / 1024 / 1024).toLocaleString(locale, { minimumFractionDigits: 1, maximumFractionDigits: 1, useGrouping: false })) })] }), _jsx(Button, { variant: "quiet", iconOnly: true, disabled: disabled, "aria-label": t.remove(file.name), onClick: () => { onFilesChange(files.filter(item => item !== file)); chooseButton.current?.focus(); }, children: _jsx(Icon, { name: "close" }) })] }, `${file.name}-${file.size}-${file.lastModified}`)) }), _jsx("span", { className: "diya-workflow-sr", role: "status", children: t.selected(files.length) })] });
47
+ });
@@ -0,0 +1,52 @@
1
+ import { type FormHTMLAttributes, type FormEvent, type ReactNode } from 'react';
2
+ import { formMessages } from './form-messages.js';
3
+ declare module '../messages.js' {
4
+ interface DiyaMessages {
5
+ form: typeof formMessages;
6
+ }
7
+ }
8
+ export type FormProps = Omit<FormHTMLAttributes<HTMLFormElement>, 'title' | 'onSubmit' | 'children'> & {
9
+ /** Visible heading; it is also the form's accessible name. Leave it out when the page already has a heading, and name the form with `aria-label` instead. */
10
+ title?: string;
11
+ /** Heading level of the title, 1–6; defaults to 3. */
12
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
13
+ /** Supporting text under the title. */
14
+ description?: ReactNode;
15
+ /** The form's fields. */
16
+ children: ReactNode;
17
+ /** Replaces the default Cancel and Submit buttons; pass null for no footer. */
18
+ actions?: ReactNode;
19
+ /** Called on submit with the event (default already prevented); not called while loading. */
20
+ onSubmit: (event: FormEvent<HTMLFormElement>) => void;
21
+ /** Shows a Cancel button that calls this. */
22
+ onCancel?: () => void;
23
+ /** Submit button text; defaults to "Submit". */
24
+ submitLabel?: string;
25
+ /** Cancel button text; defaults to "Cancel". */
26
+ cancelLabel?: string;
27
+ /** Shows a spinner on Submit, disables Cancel and blocks resubmission; defaults to false. */
28
+ loading?: boolean;
29
+ };
30
+ /** A form with an optional title, Submit and optional Cancel. Composes caller-owned fields and validation; it never invents a successful submission. */
31
+ export declare const Form: import("react").ForwardRefExoticComponent<Omit<FormHTMLAttributes<HTMLFormElement>, "children" | "title" | "onSubmit"> & {
32
+ /** Visible heading; it is also the form's accessible name. Leave it out when the page already has a heading, and name the form with `aria-label` instead. */
33
+ title?: string;
34
+ /** Heading level of the title, 1–6; defaults to 3. */
35
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
36
+ /** Supporting text under the title. */
37
+ description?: ReactNode;
38
+ /** The form's fields. */
39
+ children: ReactNode;
40
+ /** Replaces the default Cancel and Submit buttons; pass null for no footer. */
41
+ actions?: ReactNode;
42
+ /** Called on submit with the event (default already prevented); not called while loading. */
43
+ onSubmit: (event: FormEvent<HTMLFormElement>) => void;
44
+ /** Shows a Cancel button that calls this. */
45
+ onCancel?: () => void;
46
+ /** Submit button text; defaults to "Submit". */
47
+ submitLabel?: string;
48
+ /** Cancel button text; defaults to "Cancel". */
49
+ cancelLabel?: string;
50
+ /** Shows a spinner on Submit, disables Cancel and blocks resubmission; defaults to false. */
51
+ loading?: boolean;
52
+ } & import("react").RefAttributes<HTMLFormElement>>;
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useId } from 'react';
4
+ import { Button } from '../button/Button.js';
5
+ import { useDiyaMessages } from '../DiyaProvider.js';
6
+ import { cx } from '../internal/cx.js';
7
+ import { formMessages } from './form-messages.js';
8
+ /** A form with an optional title, Submit and optional Cancel. Composes caller-owned fields and validation; it never invents a successful submission. */
9
+ export const Form = forwardRef(function Form({ title, headingLevel = 3, description, children, actions, onSubmit, onCancel, submitLabel, cancelLabel, loading = false, className, ...props }, ref) {
10
+ const t = useDiyaMessages('form', formMessages);
11
+ const id = useId();
12
+ const Heading = `h${headingLevel}`;
13
+ const footer = actions === undefined ? _jsxs(_Fragment, { children: [onCancel && _jsx(Button, { variant: "quiet", disabled: loading, onClick: onCancel, children: cancelLabel ?? t.cancel }), _jsx(Button, { type: "submit", loading: loading, children: submitLabel ?? t.submit })] }) : actions;
14
+ return _jsxs("form", { ...props, ref: ref, className: cx('diya-workflow-surface diya-project-form', className), "aria-labelledby": title ? id : props['aria-labelledby'], "aria-busy": loading || undefined, onSubmit: event => { event.preventDefault(); if (!loading)
15
+ onSubmit(event); }, children: [(title || description) && _jsxs("header", { children: [title && _jsx(Heading, { id: id, className: "diya-project-form-title", children: title }), description && _jsx("p", { children: description })] }), children, footer && _jsx("footer", { children: footer })] });
16
+ });
@@ -0,0 +1,76 @@
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
+ import { wizardMessages } from './wizard-messages.js';
3
+ declare module '../messages.js' {
4
+ interface DiyaMessages {
5
+ wizard: typeof wizardMessages;
6
+ }
7
+ }
8
+ export type WizardStep = {
9
+ /** Stable key for the step. */
10
+ id: string;
11
+ /** Short name shown in the step list. */
12
+ label: string;
13
+ /** Heading above the step's content; defaults to `label`. */
14
+ title?: string;
15
+ /** Supporting text under the step heading. */
16
+ description?: ReactNode;
17
+ /** The step's fields; plain fields, not a nested form. */
18
+ content: ReactNode;
19
+ };
20
+ export type WizardProps = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
21
+ /** The steps, in order. */
22
+ steps: readonly WizardStep[];
23
+ /** Zero-based index of the current step; the caller owns this state. */
24
+ activeStep: number;
25
+ /** Called with the requested zero-based step index on Back or Continue; set `activeStep` to accept it. */
26
+ onStepChange: (step: number) => void;
27
+ /** Called when the last step is submitted. */
28
+ onComplete: () => void;
29
+ /** Step list above the content ('horizontal', the default) or beside it ('vertical'). */
30
+ orientation?: 'horizontal' | 'vertical';
31
+ /** Shows "Step N of M" above the buttons; defaults to true. */
32
+ showStepCount?: boolean;
33
+ /** Shows a spinner on the forward button and blocks navigation; defaults to false. */
34
+ loading?: boolean;
35
+ /** Accessible name for the whole wizard (not shown); defaults to "Wizard". */
36
+ label?: string;
37
+ /** Back button text; defaults to "Back". */
38
+ backLabel?: string;
39
+ /** Forward button text on every step but the last; defaults to "Continue". */
40
+ nextLabel?: string;
41
+ /** Forward button text on the last step; defaults to "Complete". */
42
+ completeLabel?: string;
43
+ /** Skips the browser's built-in field validation on submit; defaults to true. */
44
+ noValidate?: boolean;
45
+ /** Heading level of each step's title, h1 to h6. Defaults to 3. */
46
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
47
+ };
48
+ /** A multi-step flow with a step list, Back and Continue. Step content contains fields, not nested forms. The caller accepts or rejects navigation. */
49
+ export declare const Wizard: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLElement>, "children"> & {
50
+ /** The steps, in order. */
51
+ steps: readonly WizardStep[];
52
+ /** Zero-based index of the current step; the caller owns this state. */
53
+ activeStep: number;
54
+ /** Called with the requested zero-based step index on Back or Continue; set `activeStep` to accept it. */
55
+ onStepChange: (step: number) => void;
56
+ /** Called when the last step is submitted. */
57
+ onComplete: () => void;
58
+ /** Step list above the content ('horizontal', the default) or beside it ('vertical'). */
59
+ orientation?: "horizontal" | "vertical";
60
+ /** Shows "Step N of M" above the buttons; defaults to true. */
61
+ showStepCount?: boolean;
62
+ /** Shows a spinner on the forward button and blocks navigation; defaults to false. */
63
+ loading?: boolean;
64
+ /** Accessible name for the whole wizard (not shown); defaults to "Wizard". */
65
+ label?: string;
66
+ /** Back button text; defaults to "Back". */
67
+ backLabel?: string;
68
+ /** Forward button text on every step but the last; defaults to "Continue". */
69
+ nextLabel?: string;
70
+ /** Forward button text on the last step; defaults to "Complete". */
71
+ completeLabel?: string;
72
+ /** Skips the browser's built-in field validation on submit; defaults to true. */
73
+ noValidate?: boolean;
74
+ /** Heading level of each step's title, h1 to h6. Defaults to 3. */
75
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
76
+ } & import("react").RefAttributes<HTMLElement>>;
@@ -0,0 +1,31 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useEffect, useRef } from 'react';
4
+ import { Button } from '../button/Button.js';
5
+ import { Icon } from '../Icon.js';
6
+ import { cx } from '../internal/cx.js';
7
+ import { useDiyaMessages } from '../DiyaProvider.js';
8
+ import { wizardMessages } from './wizard-messages.js';
9
+ /** A multi-step flow with a step list, Back and Continue. Step content contains fields, not nested forms. The caller accepts or rejects navigation. */
10
+ export const Wizard = forwardRef(function Wizard({ steps, activeStep, onStepChange, onComplete, orientation = 'horizontal', showStepCount = true, loading = false, label, backLabel, nextLabel, completeLabel, noValidate = true, headingLevel = 3, className, ...props }, ref) {
11
+ const t = useDiyaMessages('wizard', wizardMessages);
12
+ const index = Math.max(0, Math.min(Math.max(0, steps.length - 1), Number.isFinite(activeStep) ? Math.floor(activeStep) : 0));
13
+ const heading = useRef(null);
14
+ const previousStep = useRef(index);
15
+ useEffect(() => {
16
+ if (previousStep.current !== index)
17
+ heading.current?.focus();
18
+ previousStep.current = index;
19
+ }, [index]);
20
+ if (!steps.length)
21
+ return null;
22
+ const step = steps[index];
23
+ const Heading = `h${headingLevel}`;
24
+ const last = index === steps.length - 1;
25
+ return _jsxs("section", { "aria-label": label ?? t.label, ...props, ref: ref, className: cx('diya-workflow-surface diya-wizard', className), "data-orientation": orientation, "aria-busy": loading || undefined, children: [_jsx("ol", { className: "diya-wizard-steps", "aria-label": t.progress, children: steps.map((item, position) => _jsxs("li", { "aria-current": index === position ? 'step' : undefined, "data-complete": position < index, children: [_jsx("span", { children: position < index ? _jsx(Icon, { name: "check", size: 14 }) : position + 1 }), _jsx("strong", { children: item.label })] }, item.id)) }), _jsx("div", { className: "diya-wizard-body", children: _jsxs("form", { noValidate: noValidate, onSubmit: event => { event.preventDefault(); if (!loading) {
26
+ if (last)
27
+ onComplete();
28
+ else
29
+ onStepChange(index + 1);
30
+ } }, children: [_jsxs("header", { children: [_jsx(Heading, { ref: heading, tabIndex: -1, className: "diya-wizard-title", children: step.title ?? step.label }), step.description && _jsx("p", { children: step.description })] }), step.content, showStepCount && _jsx("small", { className: "diya-wizard-summary", children: t.step(index + 1, steps.length) }), _jsxs("footer", { children: [_jsx(Button, { variant: "quiet", disabled: index === 0 || loading, onClick: () => onStepChange(index - 1), children: backLabel ?? t.back }), _jsx(Button, { type: "submit", loading: loading, children: last ? completeLabel ?? t.complete : nextLabel ?? t.next })] })] }) })] });
31
+ });
@@ -0,0 +1,4 @@
1
+ /** drawer: English defaults, overridable through DiyaProvider `messages`. */
2
+ export declare const drawerMessages: {
3
+ close: string;
4
+ };
@@ -0,0 +1,2 @@
1
+ /** drawer: English defaults, overridable through DiyaProvider `messages`. */
2
+ export const drawerMessages = { close: 'Close drawer' };
@@ -0,0 +1,11 @@
1
+ /** fileUpload: English defaults, overridable through DiyaProvider `messages`. */
2
+ export declare const fileUploadMessages: {
3
+ title: string;
4
+ description: string;
5
+ choose: string;
6
+ remove: (name: string) => string;
7
+ rejected: (count: number) => string;
8
+ selected: (count: number) => string;
9
+ kilobytes: (size: string) => string;
10
+ megabytes: (size: string) => string;
11
+ };
@@ -0,0 +1,2 @@
1
+ /** fileUpload: English defaults, overridable through DiyaProvider `messages`. */
2
+ export const fileUploadMessages = { title: 'Add your files', description: 'Drop files here or choose from your device.', choose: 'Choose files', remove: (name) => `Remove ${name}`, rejected: (count) => `${count} ${count === 1 ? 'file could' : 'files could'} not be added. Check the accepted file types and size limit.`, selected: (count) => `${count} ${count === 1 ? 'file' : 'files'} selected.`, kilobytes: (size) => `${size} KB`, megabytes: (size) => `${size} MB` };
@@ -0,0 +1,5 @@
1
+ /** form: English defaults, overridable through DiyaProvider `messages`. */
2
+ export declare const formMessages: {
3
+ submit: string;
4
+ cancel: string;
5
+ };
@@ -0,0 +1,2 @@
1
+ /** form: English defaults, overridable through DiyaProvider `messages`. */
2
+ export const formMessages = { submit: 'Submit', cancel: 'Cancel' };
@@ -0,0 +1,9 @@
1
+ /** wizard: English defaults, overridable through DiyaProvider `messages`. */
2
+ export declare const wizardMessages: {
3
+ label: string;
4
+ progress: string;
5
+ back: string;
6
+ next: string;
7
+ complete: string;
8
+ step: (step: number, total: number) => string;
9
+ };
@@ -0,0 +1,2 @@
1
+ /** wizard: English defaults, overridable through DiyaProvider `messages`. */
2
+ export const wizardMessages = { label: 'Wizard', progress: 'Progress', back: 'Back', next: 'Continue', complete: 'Complete', step: (step, total) => `Step ${step} of ${total}` };
package/package.json CHANGED
@@ -1,11 +1,86 @@
1
1
  {
2
2
  "name": "@idyeah/diya",
3
- "version": "0.0.0",
4
- "description": "DIYA: React components and patterns in Light, Dark and Glass. Launches 7 November 2026.",
3
+ "version": "1.0.1",
5
4
  "license": "MIT",
6
- "author": "IDYeah Studio LLC",
7
- "homepage": "https://diya.keya.studio",
8
- "keywords": ["react", "components", "design-system", "ui"],
9
- "files": ["README.md", "LICENSE"],
10
- "publishConfig": { "access": "public" }
5
+ "type": "module",
6
+ "description": "React components and patterns: Light, Dark and Glass. MIT.",
7
+ "keywords": [
8
+ "react",
9
+ "react-components",
10
+ "components",
11
+ "ui",
12
+ "ui-components",
13
+ "component-library",
14
+ "design-system",
15
+ "dark-mode",
16
+ "glassmorphism",
17
+ "nextjs",
18
+ "vite",
19
+ "typescript",
20
+ "accessibility"
21
+ ],
22
+ "sideEffects": [
23
+ "**/*.css"
24
+ ],
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js"
30
+ },
31
+ "./charts": {
32
+ "types": "./dist/data-viz/index.d.ts",
33
+ "import": "./dist/data-viz/index.js"
34
+ },
35
+ "./styles.css": "./dist/styles.css",
36
+ "./api.json": "./dist/api.json",
37
+ "./api.schema.json": "./dist/api.schema.json",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "NOTICE",
43
+ "CHANGELOG.md"
44
+ ],
45
+ "scripts": {
46
+ "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json && node scripts/build-styles.mjs && node scripts/build-api.mjs",
47
+ "typecheck": "tsc -p tsconfig.json --noEmit",
48
+ "test": "pnpm build && vitest run --config tests/vitest.config.mjs"
49
+ },
50
+ "peerDependencies": {
51
+ "react": "^18.3.1 || ^19.0.0",
52
+ "react-dom": "^18.3.1 || ^19.0.0",
53
+ "echarts": "^6.1.0"
54
+ },
55
+ "peerDependenciesMeta": {
56
+ "echarts": {
57
+ "optional": true
58
+ }
59
+ },
60
+ "devDependencies": {
61
+ "@types/react": "18.3.28",
62
+ "@types/react-dom": "18.3.7",
63
+ "react": "18.3.1",
64
+ "react-dom": "18.3.1",
65
+ "typescript": "5.9.3",
66
+ "echarts": "6.1.0",
67
+ "vitest": "4.1.0",
68
+ "happy-dom": "20.9.0",
69
+ "@testing-library/react": "16.3.2",
70
+ "@testing-library/user-event": "14.6.1",
71
+ "@vitejs/plugin-react": "6.0.1",
72
+ "vite": "8.0.1",
73
+ "ajv": "8.20.0",
74
+ "react-hook-form": "7.90.0"
75
+ },
76
+ "repository": {
77
+ "type": "git",
78
+ "url": "git+https://github.com/idyeah-studio/diya.git",
79
+ "directory": "packages/diya"
80
+ },
81
+ "homepage": "https://diya13.ai",
82
+ "bugs": "https://github.com/idyeah-studio/diya/issues",
83
+ "publishConfig": {
84
+ "access": "public"
85
+ }
11
86
  }