@idyeah/diya 0.0.0 → 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 (190) hide show
  1. package/CHANGELOG.md +317 -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 +3379 -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
package/README.md CHANGED
@@ -1,9 +1,600 @@
1
- # DIYA
1
+ <h1>
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://diya13.ai/brand/diya-dark.svg">
4
+ <img src="https://diya13.ai/brand/diya.svg" alt="DIYA" width="136">
5
+ </picture>
6
+ </h1>
2
7
 
3
- React components and patterns in Light, Dark and Glass. Free and open source (MIT).
8
+ **A library for your next app.** 30 components and 13 patterns for React. Free, MIT, yours to own.
4
9
 
5
- **DIYA launches on 7 November 2026.** This early release only holds the name, and it has no code yet. Please wait for 1.0.
10
+ [Catalog](https://diya13.ai/explore) ·
11
+ [Components](https://diya13.ai/explore?area=components) ·
12
+ [Patterns](https://diya13.ai/explore?area=patterns) ·
13
+ [Screens](https://diya13.ai/explore?area=screens) ·
14
+ [Changelog](https://github.com/idyeah-studio/diya/blob/main/CHANGELOG.md)
6
15
 
7
- See it first at [diya.keya.studio](https://diya.keya.studio).
16
+ ## Start a new app
8
17
 
9
- Made by IDYeah Studio.
18
+ ```sh
19
+ npm create diya@latest
20
+ # pnpm create diya · yarn create diya · bun create diya
21
+ ```
22
+
23
+ It asks four things: a name, where to start, Next.js or Vite, and your brand
24
+ color. Then it installs with the package manager you ran it with and tells you
25
+ the one command left. The provider, the styles, Light and Dark, and notes for
26
+ your coding agent are already in place. Start from **Minimal**, one page with
27
+ a few pieces, or **Dashboard**, which is Oriel: a four-screen invoicing app on
28
+ Next.js.
29
+
30
+ For CI or a coding agent, pass the answers and it asks nothing:
31
+
32
+ ```sh
33
+ npx --yes create-diya@latest my-app --template dashboard --brand "#2F6FEB"
34
+ ```
35
+
36
+ `create-diya` is released with `@idyeah/diya`, on the same version.
37
+
38
+ ## Install
39
+
40
+ Adding DIYA to an app you already have:
41
+
42
+ ```sh
43
+ npm install @idyeah/diya
44
+ # pnpm add @idyeah/diya
45
+ # yarn add @idyeah/diya
46
+ # bun add @idyeah/diya
47
+ ```
48
+
49
+ Works with React 18.3 and 19. TypeScript types are included, and DIYA Sans,
50
+ our typeface, ships inside the package.
51
+
52
+ ## Use it
53
+
54
+ Import the styles once, wrap your app in `DiyaProvider` once, and use any
55
+ component inside it.
56
+
57
+ ```tsx
58
+ import { useState } from 'react'
59
+ import { Button, DiyaProvider, Stack, TextInput } from '@idyeah/diya'
60
+ import '@idyeah/diya/styles.css'
61
+
62
+ export default function App() {
63
+ const [name, setName] = useState('')
64
+ return (
65
+ <DiyaProvider>
66
+ <Stack gap={4} align="start" style={{ maxWidth: 400, padding: 32 }}>
67
+ <TextInput label="Project name" value={name} onValueChange={setName} />
68
+ <Button disabled={!name.trim()} onClick={() => console.log(name)}>
69
+ Continue
70
+ </Button>
71
+ </Stack>
72
+ </DiyaProvider>
73
+ )
74
+ }
75
+ ```
76
+
77
+ No Tailwind, no account and no backend. The provider follows the visitor's
78
+ Light or Dark setting and paints its own background and text color, so the
79
+ first render reads on any page. It scopes DIYA's look and its popups to the
80
+ region it wraps; it changes nothing outside, sets no cookies and makes no
81
+ network calls. Your app owns state, navigation and what happens when someone
82
+ presses Continue.
83
+
84
+ `Stack` lays things out top to bottom and `Inline` side by side, with even
85
+ space between them. See [Layout](#layout).
86
+
87
+ Props, behavior and examples for every piece are in the
88
+ [component guide](https://github.com/idyeah-studio/diya/blob/main/packages/diya/docs/components.md)
89
+ and the [pattern guide](https://github.com/idyeah-studio/diya/blob/main/packages/diya/docs/patterns.md).
90
+ Your editor shows the full prop types.
91
+
92
+ Want to see a whole screen first? **[Oriel](https://oriel.diya13.ai)** is a small invoicing app made only from DIYA. Its source is in [`examples/oriel`](https://github.com/idyeah-studio/diya/tree/main/examples/oriel).
93
+
94
+ Want a whole page to start from? **[Screens](https://diya13.ai/explore?area=screens)** are whole pages, from sign-in to checkout, each one file you copy into your app.
95
+
96
+ ## Use it with an AI editor
97
+
98
+ Connect DIYA once and Claude Code, Cursor or VS Code look it up while they
99
+ write: the right component, its real props, code that compiles. Read-only, no
100
+ account.
101
+
102
+ ```sh
103
+ claude mcp add --transport http diya https://diya13.ai/mcp
104
+ ```
105
+
106
+ - **Cursor:** add `{ "mcpServers": { "diya": { "url": "https://diya13.ai/mcp" } } }` to `.cursor/mcp.json`.
107
+ - **VS Code:** `code --add-mcp '{"name":"diya","type":"http","url":"https://diya13.ai/mcp"}'`
108
+
109
+ Then ask it: "Build a settings page with DIYA." Prefer files?
110
+ [`/llms.txt`](https://diya13.ai/llms.txt) and `@idyeah/diya/api.json`
111
+ carry the same API.
112
+
113
+ ## Notes for your coding agent
114
+
115
+ Apps made with `npm create diya` come with an `AGENTS.md` (and a one-line
116
+ `CLAUDE.md` that points to it) and a `.mcp.json` that connects Claude Code.
117
+ In an app you already have, a few lines in your own `AGENTS.md` do the same
118
+ job:
119
+
120
+ ```md
121
+ ## UI
122
+ This app uses DIYA (`@idyeah/diya`). Before writing UI, look components up in
123
+ https://diya13.ai/llms.txt or node_modules/@idyeah/diya/dist/api.json,
124
+ and use DIYA's components, with Stack and Inline for layout, before writing
125
+ your own markup or CSS.
126
+ ```
127
+
128
+ ## Next.js (App Router)
129
+
130
+ Import the styles in `app/layout.tsx` and wrap the app in `DiyaProvider`. The
131
+ layout can stay a Server Component: every DIYA component, `DiyaProvider`
132
+ included, is marked `'use client'` inside the package, so Next.js renders it as
133
+ a client component for you.
134
+
135
+ ```tsx
136
+ // app/layout.tsx
137
+ import type { ReactNode } from 'react'
138
+ import { DiyaProvider } from '@idyeah/diya'
139
+ import '@idyeah/diya/styles.css'
140
+
141
+ export default function RootLayout({ children }: { children: ReactNode }) {
142
+ return (
143
+ <html lang="en">
144
+ <body>
145
+ <DiyaProvider>{children}</DiyaProvider>
146
+ </body>
147
+ </html>
148
+ )
149
+ }
150
+ ```
151
+
152
+ `theme="system"`, the default, follows the visitor's OS in CSS alone, so the
153
+ server's HTML is already in the right colors: no flash, no script.
154
+
155
+ A Server Component can render DIYA components with plain props: text, numbers
156
+ and arrays of plain objects. Functions can't cross from the server, so
157
+ anything with a handler (`onClick`, `onValueChange`, a table column's `render`,
158
+ a filter's `getValue`) goes in a file that starts with `'use client'`:
159
+
160
+ ```tsx
161
+ // app/project-name.tsx
162
+ 'use client'
163
+ import { useState } from 'react'
164
+ import { Button, TextInput } from '@idyeah/diya'
165
+
166
+ export function ProjectName() {
167
+ const [name, setName] = useState('')
168
+ return (
169
+ <>
170
+ <TextInput label="Project name" value={name} onValueChange={setName} />
171
+ <Button disabled={!name.trim()} onClick={() => console.log(name)}>
172
+ Continue
173
+ </Button>
174
+ </>
175
+ )
176
+ }
177
+ ```
178
+
179
+ ```tsx
180
+ // app/page.tsx (a Server Component)
181
+ import { PageHeader } from '@idyeah/diya'
182
+ import { ProjectName } from './project-name'
183
+
184
+ export default function Page() {
185
+ return (
186
+ <main>
187
+ <PageHeader headingLevel={1} title="New project" description="Name it now; you can change it later." />
188
+ <ProjectName />
189
+ </main>
190
+ )
191
+ }
192
+ ```
193
+
194
+ The same rule covers the provider. A component, such as Next.js `Link` for
195
+ `linkComponent`, and translated strings that are functions, such as
196
+ `tag.remove`, can't be passed to `DiyaProvider` from a Server Component; Next.js
197
+ stops with "Functions cannot be passed directly to Client Components". Move the
198
+ provider into your own `'use client'` file and render that from the layout:
199
+
200
+ ```tsx
201
+ // app/providers.tsx
202
+ 'use client'
203
+ import type { ReactNode } from 'react'
204
+ import Link from 'next/link'
205
+ import { DiyaProvider } from '@idyeah/diya'
206
+
207
+ export function Providers({ children }: { children: ReactNode }) {
208
+ return (
209
+ <DiyaProvider linkComponent={Link} messages={{ tag: { remove: (label) => `Retirer ${label}` } }}>
210
+ {children}
211
+ </DiyaProvider>
212
+ )
213
+ }
214
+ ```
215
+
216
+ ```tsx
217
+ // app/layout.tsx
218
+ import type { ReactNode } from 'react'
219
+ import { Providers } from './providers'
220
+ import '@idyeah/diya/styles.css'
221
+
222
+ export default function RootLayout({ children }: { children: ReactNode }) {
223
+ return (
224
+ <html lang="en">
225
+ <body>
226
+ <Providers>{children}</Providers>
227
+ </body>
228
+ </html>
229
+ )
230
+ }
231
+ ```
232
+
233
+ `defaultMessages` and the types are plain values, so Server Components can
234
+ import them too.
235
+
236
+ ## Vite
237
+
238
+ ```tsx
239
+ // src/main.tsx
240
+ import { StrictMode } from 'react'
241
+ import { createRoot } from 'react-dom/client'
242
+ import { DiyaProvider } from '@idyeah/diya'
243
+ import '@idyeah/diya/styles.css'
244
+ import './index.css'
245
+ import App from './App'
246
+
247
+ createRoot(document.getElementById('root')!).render(
248
+ <StrictMode>
249
+ <DiyaProvider>
250
+ <App />
251
+ </DiyaProvider>
252
+ </StrictMode>,
253
+ )
254
+ ```
255
+
256
+ Then use any component inside `App`. Import DIYA's styles before your own, as
257
+ here; with Tailwind, see [Tailwind CSS](#tailwind-css).
258
+
259
+ ## Layout
260
+
261
+ `Stack` puts its children in a column and `Inline` in a row, with even space
262
+ between them. Both take a `gap` from DIYA's spacing scale (`0` to `8`: 0, 4,
263
+ 8, 12, 16, 24, 32, 48 and 64px) or any CSS length, plus `align`, `justify`,
264
+ `wrap` and `as`.
265
+
266
+ ```tsx
267
+ <Stack gap={5} as="section">
268
+ <PageHeader title="Billing" />
269
+ <Inline gap={2} justify="end">
270
+ <Button variant="outline">Cancel</Button>
271
+ <Button>Save</Button>
272
+ </Inline>
273
+ </Stack>
274
+ ```
275
+
276
+ `Inline` centers its children and wraps them onto the next line when the row
277
+ runs out of room. Their styles are deliberately weak, so your own `className`
278
+ or `style` can change any of it. The same scale is public as `--diya-space-1`
279
+ to `--diya-space-8` for your own CSS.
280
+
281
+ ## Your CSS wins
282
+
283
+ Everything in `styles.css` sits in a CSS cascade layer named `diya`. Rules
284
+ outside a layer beat every layered rule, so your own CSS, and any `className`
285
+ or `style` you pass to a component, wins over DIYA's without `!important`.
286
+ DIYA's base styles reach its own elements and what sits inside them. Your
287
+ headings, paragraphs, links and buttons placed straight in the provider keep the
288
+ styles you give them. Inside a DIYA component or layout, such as Stack, Card or
289
+ Drawer, plain ones start the way DIYA's own do: links in the text color with no
290
+ underline, buttons with no border or fill, paragraphs muted, and no margins. Your
291
+ CSS still wins, so give them a class, or use `TextLink` and `Button`. To give
292
+ your own articles DIYA's type, wrap them in `Prose`.
293
+
294
+ One thing to watch: a global reset of your own, such as
295
+ `button { background: none; border: 0 }` or `* { margin: 0; padding: 0 }`,
296
+ also beats DIYA when it isn't layered. Put it in a layer that comes before
297
+ DIYA's:
298
+
299
+ ```css
300
+ /* At the top of your first stylesheet */
301
+ @layer reset, diya;
302
+
303
+ @layer reset {
304
+ * { margin: 0; padding: 0; box-sizing: border-box; }
305
+ button { background: none; border: 0; }
306
+ }
307
+ ```
308
+
309
+ ## Tailwind CSS
310
+
311
+ DIYA works with Tailwind v4. Name the layer order once, before Tailwind and
312
+ DIYA load, so DIYA sits above Tailwind's base styles and below its utilities:
313
+
314
+ ```css
315
+ /* src/index.css */
316
+ @layer theme, base, diya, components, utilities;
317
+ @import "tailwindcss";
318
+ @import "@idyeah/diya/styles.css";
319
+ ```
320
+
321
+ Utilities then win: `<Button className="w-full mt-6">` is full width, and
322
+ `<Stack className="gap-2">` changes the gap. Your own `p`, `h1` and `a` keep
323
+ Tailwind's styles. If you'd rather import DIYA's styles from JavaScript, keep
324
+ the `@layer` line at the top of your CSS and import `@idyeah/diya/styles.css`
325
+ before it.
326
+
327
+ ## Links and routers
328
+
329
+ Anything DIYA renders from an `href` (Button, Menu items, Breadcrumbs, Side
330
+ Navigation and Site Header items) is a plain `<a>` unless you give the
331
+ provider your router's link with `linkComponent`. With Next.js, set it in a
332
+ client file, as in [Next.js](#nextjs-app-router):
333
+
334
+ ```tsx
335
+ <DiyaProvider linkComponent={Link}>
336
+ <Button href="/billing">Billing</Button>
337
+ </DiyaProvider>
338
+ ```
339
+
340
+ `asChild` styles your own element instead of rendering one. Button and
341
+ TextLink take it:
342
+
343
+ ```tsx
344
+ <Button asChild>
345
+ <Link href="/billing">Billing</Link>
346
+ </Button>
347
+ ```
348
+
349
+ DIYA's classes, attributes and handlers merge into your child, and the ref
350
+ reaches it. TextLink never uses `linkComponent`: with `href` it's a plain
351
+ `<a>`, so for client-side routing give it your router's link with `asChild`.
352
+ Either way it needs no provider, so it renders in a Server Component.
353
+
354
+ ## Forms
355
+
356
+ Fields work controlled (`value` with `onValueChange`, `checked` with
357
+ `onCheckedChange`) or uncontrolled (`defaultValue`, `defaultChecked`). Native
358
+ `name`, `onChange`, `onBlur` and the ref reach the native control, and
359
+ `onValueChange` still fires, so a plain `<form>` posts every field and a form
360
+ reset puts them back.
361
+
362
+ react-hook-form's `register()` works on TextInput, TextArea, Select, Switch,
363
+ Choice and Slider with no `Controller`: values come back on submit, and an
364
+ error moves focus to its field.
365
+
366
+ ```tsx
367
+ const { register, handleSubmit } = useForm<{ name: string; volume: number; alerts: boolean }>()
368
+
369
+ <form onSubmit={handleSubmit(save)}>
370
+ <Stack gap={4}>
371
+ <TextInput label="Name" {...register('name', { required: 'Add a name' })} />
372
+ <Slider label="Volume" {...register('volume', { valueAsNumber: true })} />
373
+ <Switch label="Email alerts" {...register('alerts')} />
374
+ <Button type="submit">Save</Button>
375
+ </Stack>
376
+ </form>
377
+ ```
378
+
379
+ Slider needs `valueAsNumber: true` to give you a number. Combobox and
380
+ DatePicker need a `Controller`; in a plain form they post their value through
381
+ `name`. Calendar takes no `name`, so it always goes through a `Controller`.
382
+
383
+ ## Charts
384
+
385
+ Charts have their own entry point, `@idyeah/diya/charts`, and draw with
386
+ [Apache ECharts](https://echarts.apache.org). ECharts is an optional peer
387
+ dependency, so apps without charts don't carry it. Install it when you need a
388
+ chart:
389
+
390
+ ```sh
391
+ npm install echarts
392
+ ```
393
+
394
+ ```tsx
395
+ import { DataViz } from '@idyeah/diya/charts'
396
+
397
+ export function WeeklyActivity() {
398
+ return (
399
+ <DataViz
400
+ title="Weekly activity"
401
+ type="line"
402
+ categories={['Mon', 'Tue', 'Wed']}
403
+ series={[{ name: 'Visits', values: [32, 54, 48] }]}
404
+ valueDomain={[0, 100]}
405
+ />
406
+ )
407
+ }
408
+ ```
409
+
410
+ Render it inside the same `DiyaProvider`. `DataViz` is a chart in a titled
411
+ card, with an optional table of the exact values; `Chart` is the bare chart.
412
+ Charts are experimental in 1.0: their props may still change in a minor
413
+ release.
414
+ Both draw `line`, `area`, `bar`, `combo`, `pie`, `donut` and `treemap`. Charts
415
+ use the data you pass and render as SVG. They don't fetch anything.
416
+
417
+ ## Theme
418
+
419
+ Four props on `DiyaProvider` cover most apps: `theme`, `brandColor`,
420
+ `fontFamily` and `glass`.
421
+
422
+ ```tsx
423
+ <DiyaProvider brandColor="#2F6FEB" fontFamily="'Inter', sans-serif">
424
+ ```
425
+
426
+ - `theme` is `"system"` by default: Light or Dark follows the visitor's OS
427
+ setting, in CSS, from the first paint. Set `"light"` or `"dark"` to fix it.
428
+ `useDiyaAppearance()` tells your own code which one is showing (on the
429
+ server it says Light, then follows the OS once mounted).
430
+ - `brandColor` is your one brand color. It fills the main Button, selected
431
+ pill Tabs, an on Switch, Slider and Progress, leads chart series 1 when it
432
+ has color (otherwise charts use DIYA's Vivid palette), and tints
433
+ brand-tone Tags and Badges. Text on it is white whenever white reads at
434
+ 4.5:1, otherwise near-black. Pass `{ light, dark }` to use a different color
435
+ in each theme, such as a lighter one for Dark.
436
+ - The provider paints its own background and text color. Set
437
+ `surface={false}` when your layout already paints the page.
438
+ - `fontFamily` names a font; it doesn't load one. DIYA Sans needs nothing,
439
+ since it comes with the styles. For any other font, load it first
440
+ (`next/font`, Fontsource or a `<link>`), then name it here.
441
+
442
+ | To change | Do this |
443
+ | --- | --- |
444
+ | Brand | Set `brandColor`. It sets `--diya-color-accent`, `--diya-color-accent-text`, `--diya-color-accent-soft` and `--diya-color-accent-ink` for you. |
445
+ | Surfaces | Set `--diya-color-surface`, `--diya-color-raised` and `--diya-color-text` as a readable group. |
446
+ | Corners | Set `--diya-corner-scale` (`0` is square, `2` is twice as round). Fields, selects and rounded Buttons share `--diya-radius-control`; Card, chart cards, Page Header, Form and Table share `--diya-radius-surface`. |
447
+ | Chart series | Pass `palette`, or a `color` on a series or data item. |
448
+ | Size and behavior | Use each component's props. |
449
+
450
+ For deeper changes, override the [public tokens](#tokens). Or build a theme in
451
+ the [catalog](https://diya13.ai/explore) with Customize, then press
452
+ Get theme: you get one `diya-theme.css` file to import after the styles, and a
453
+ few props.
454
+
455
+ A nested `DiyaProvider` can give one region its own look. It inherits
456
+ `locale`, `messages` and `linkComponent` from the provider around it, but not
457
+ `theme`, `glass`, `brandColor` or `fontFamily`, so set those on each provider.
458
+
459
+ ## Glass
460
+
461
+ Glass is one prop: `glass`.
462
+
463
+ ```tsx
464
+ <DiyaProvider theme="dark" glass>
465
+ ```
466
+
467
+ It's a finish, not a theme, so it works over Light and Dark. Headers, popups
468
+ and tabs get a translucent, blurred surface. Glass wants something behind it:
469
+ over a flat background it looks solid. Where the browser can't blur, or the
470
+ reader has asked for less transparency, DIYA uses its solid surfaces instead.
471
+ Keep the backdrop quiet enough that text stays readable.
472
+
473
+ ## Translation
474
+
475
+ Every built-in string (button labels, empty states, screen-reader text) can
476
+ be replaced through `DiyaProvider`. Pass only the strings you want to change,
477
+ grouped by component. Anything you leave out stays in English.
478
+
479
+ ```tsx
480
+ <DiyaProvider
481
+ locale="fr-FR"
482
+ messages={{
483
+ table: { emptyTitle: 'Rien pour le moment', noMatches: 'Aucun résultat' },
484
+ pagination: { previous: 'Précédent', next: 'Suivant' },
485
+ tag: { remove: (label) => `Retirer ${label}` },
486
+ }}
487
+ >
488
+ ```
489
+
490
+ - `defaultMessages` lists every key with its English default; use it as the
491
+ template for a full translation. `DiyaMessages` is its type, and
492
+ `DiyaMessagesInput` is the partial shape `messages` accepts.
493
+ - A value is a string, or a function when the string includes something, such
494
+ as a label or a count. In Next.js, pass functions from a client file (see
495
+ [Next.js](#nextjs-app-router)).
496
+ - A label prop on one component (`openLabel`, `loadingLabel`, `confirmLabel`,
497
+ `backLabel`, `userLabel` and the like) still wins over `messages` for that
498
+ instance.
499
+ - `locale` formats dates and numbers, for example the DatePicker field and
500
+ calendar month. It defaults to `en-US`. Your own content, such as table
501
+ cells, stays as you render it.
502
+ - A nested `DiyaProvider` adds to the strings and locale of the one around it
503
+ and changes only what it sets; a key set to `undefined` keeps the inherited
504
+ string.
505
+
506
+ ## Tokens
507
+
508
+ These CSS custom properties are public. They are safe to override on
509
+ `DiyaProvider`'s `style`. To change one region, wrap it in a nested
510
+ `DiyaProvider` with its own `style`: a few values, such as table shadows and
511
+ header edges, are worked out once per provider from these tokens.
512
+
513
+ | Group | Tokens |
514
+ | --- | --- |
515
+ | Text | `--diya-color-text`, `--diya-color-muted` |
516
+ | Surfaces | `--diya-color-surface`, `--diya-color-recessed`, `--diya-color-raised` |
517
+ | Lines | `--diya-color-line` |
518
+ | Brand | `--diya-color-accent` (fills), `--diya-color-accent-text` (text on the fill), `--diya-color-accent-soft` (a quiet tint) and `--diya-color-accent-ink` (brand-colored text on the page). `brandColor` sets all four; set them together if you override them. |
519
+ | States | `--diya-color-hover`, `--diya-color-selected` |
520
+ | Destructive actions | `--diya-color-destructive` |
521
+ | Statuses | For each of `success`, `warning`, `error` and `info`: `--diya-color-{status}` for text and icons on a surface, `--diya-color-{status}-surface` behind them, and `--diya-color-{status}-fill` with `--diya-color-{status}-on-fill` for solid badges. `--diya-color-error` also colors error messages, the border of every invalid field and a falling Metric. |
522
+ | Neutral badge | `--diya-color-neutral-fill`, `--diya-color-neutral-on-fill` |
523
+ | Glass and overlays | `--diya-color-glass` (the translucent fill when Glass is on), `--diya-color-scrim` (the dimming behind dialogs and drawers, and for your own overlays; `#00000088`, lighter under Glass) |
524
+ | Font | `--diya-font`, set by `DiyaProvider` from `fontFamily` |
525
+ | Type scale | `--diya-text-caption`, `--diya-text-body`, `--diya-text-large`, `--diya-text-title`, `--diya-text-heading`, `--diya-text-display`, `--diya-text-hero` |
526
+ | Line height | `--diya-leading-tight`, `--diya-leading-body` |
527
+ | Space | `--diya-space-1` to `--diya-space-8`: 4, 8, 12, 16, 24, 32, 48 and 64px |
528
+ | Shape and depth | `--diya-corner-scale`; `--diya-radius-control`, the one corner every control shares; `--diya-radius-surface`, the one corner every in-page surface shares; `--diya-shadow-raised` for cards, dialogs, drawers, toasts, menus and popups; `--diya-elevation` scales table, tooltip and floating chat shadows (`0` removes them). For a flat look, set `--diya-shadow-raised: none` as well |
529
+
530
+ ```tsx
531
+ <DiyaProvider
532
+ brandColor="#2F6FEB"
533
+ style={{
534
+ '--diya-color-surface': '#F7F7F5',
535
+ '--diya-corner-scale': 1.5,
536
+ } as React.CSSProperties}
537
+ >
538
+ ```
539
+
540
+ Set `brandColor` and `fontFamily` as props rather than overriding the accent
541
+ tokens and `--diya-font` directly. In your own CSS, `.diya-root` is the
542
+ provider; with `theme="system"` its `data-theme` is `system`, so write Light
543
+ and Dark overrides inside `@media (prefers-color-scheme: …)` as well as for
544
+ `[data-theme='light']` and `[data-theme='dark']`. Set a status family's four tokens
545
+ together, and check each pair in Light, Dark and Glass. Every public token,
546
+ with its defaults and the tokens it pairs with, is also listed in
547
+ `@idyeah/diya/api.json`.
548
+
549
+ ## Stability
550
+
551
+ DIYA follows [semver](https://semver.org). In 1.x, these change only in a
552
+ major version:
553
+
554
+ - entry points and export names, both values and types;
555
+ - prop names, types, whether a prop is required, defaults and controlled pairs
556
+ (such as `value` with `onValueChange`);
557
+ - documented keyboard and screen-reader behavior;
558
+ - `DiyaProvider` props;
559
+ - public token names and what they mean (their values may be tuned in a minor
560
+ release);
561
+ - message keys and their arguments;
562
+ - `api.json` within `schemaVersion: 1`, where only additions are allowed;
563
+ - peer dependency ranges.
564
+
565
+ Not covered, so don't build on them: `.diya-*` class names, DOM structure,
566
+ the `data-*` attributes components set on their own elements (the provider's
567
+ `data-theme` is covered), anything named `--diya-internal-*`, file paths inside
568
+ `dist`, and anything marked `"stability": "experimental"` in `api.json`, with
569
+ its own messages and types. In 1.0 that's Chatbot and the charts (`DataViz`
570
+ and `Chart`).
571
+
572
+ ## License and fonts
573
+
574
+ DIYA is MIT licensed; see
575
+ [LICENSE](https://github.com/idyeah-studio/diya/blob/main/LICENSE). DIYA Sans
576
+ is a modified version of Mona Sans, licensed under the SIL Open Font License
577
+ 1.1 rather than MIT. Its license, `OFL.txt`, ships beside the font files in
578
+ `dist/fonts`. ECharts is an optional Apache-2.0 peer dependency and isn't
579
+ bundled. Details are in
580
+ [NOTICE](https://github.com/idyeah-studio/diya/blob/main/NOTICE).
581
+
582
+ ## Coming from the preview?
583
+
584
+ Swap <code>&#64;diya/ui</code> for `@idyeah/diya` in your imports and remove
585
+ the vendored `.tgz`. Some props were renamed for 1.0; the
586
+ [changelog](https://github.com/idyeah-studio/diya/blob/main/CHANGELOG.md)
587
+ lists each one.
588
+
589
+ ## Relight, coming to DIYA Pro
590
+
591
+ We're building Relight: upload any picture of a screen from your own product
592
+ (a screenshot, a wireframe, a whiteboard photo, even a napkin sketch), answer a
593
+ few questions, and get it back as React code made from DIYA components, for any
594
+ kind of app: dashboards, settings, sign-up flows, landing pages, admin tools. It isn't ready yet; for now it's a
595
+ [list](https://diya13.ai/#pro). While we build it, four promises:
596
+
597
+ 1. The library stays MIT.
598
+ 2. Pro never gets a component the library lacks.
599
+ 3. Pro's code needs nothing from us but `@idyeah/diya`.
600
+ 4. Library screens stay free and MIT. Relight's screens are yours.
@@ -0,0 +1,79 @@
1
+ import { type CSSProperties, type HTMLAttributes, type ReactNode } from 'react';
2
+ import type { DiyaMessages, DiyaMessagesInput } from './messages.js';
3
+ import { type DiyaLinkComponent } from './internal/link.js';
4
+ import { type DiyaBrandTokens } from './internal/brand.js';
5
+ /** DIYA Sans ships with the stylesheet; a metric-matched Arial covers the moment before it loads. */
6
+ export declare const DEFAULT_FONT_FAMILY = "\"DIYA Sans\", \"DIYA Sans Fallback\", Arial, sans-serif";
7
+ /** What a DIYA provider resolved, for code that draws its own pixels, such as charts. */
8
+ export type DiyaAppearance = {
9
+ /** The theme in effect. With `theme="system"` it is 'light' on the server and follows the OS from mount. */
10
+ theme: 'light' | 'dark';
11
+ /** Whether Glass is on. */
12
+ glass: boolean;
13
+ /** The CSS font-family stack components use. */
14
+ fontFamily: string;
15
+ /** The accent tokens for the theme in effect, as hex. */
16
+ brand: DiyaBrandTokens;
17
+ };
18
+ export declare function useDiyaPortal(): HTMLElement | null;
19
+ /** The nearest provider's resolved theme, Glass, font and brand accent. */
20
+ export declare function useDiyaAppearance(): DiyaAppearance;
21
+ /** A component's built-in strings, with any provider overrides applied. */
22
+ export declare function useDiyaMessages<K extends keyof DiyaMessages>(component: K, defaults: DiyaMessages[K]): DiyaMessages[K];
23
+ /** BCP 47 locale for dates and numbers. */
24
+ export declare function useDiyaLocale(): string;
25
+ export type DiyaProviderProps = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
26
+ /** The app or section that uses DIYA components; popups, tooltips and toasts render only inside a provider. */
27
+ children: ReactNode;
28
+ /** Color scheme for everything inside. 'system' follows the visitor's OS setting in CSS, with no flash. Defaults to 'system'. */
29
+ theme?: 'light' | 'dark' | 'system';
30
+ /** Paints the provider's own background and text color, so DIYA reads on any page. Set false when your layout paints the ground. Defaults to true. */
31
+ surface?: boolean;
32
+ /** Gives headers, popups and tabs a translucent, blurred finish where the browser supports it. Defaults to false. */
33
+ glass?: boolean;
34
+ /** Your brand as a hex color, or one per theme as `{ light, dark }`. It fills main buttons, selected pills, switches, sliders and progress, and leads chart series 1 when it has color; text on it is white whenever that reads. Defaults to DIYA's neutral ink. */
35
+ brandColor?: string | {
36
+ light: string;
37
+ dark: string;
38
+ };
39
+ /** CSS font-family stack for every component. Defaults to DIYA Sans with a metric-matched fallback. */
40
+ fontFamily?: string;
41
+ /** Replace any built-in string, by component: `{ table: { emptyTitle: 'Nothing here' } }`. A nested provider inherits its parent's strings and overrides only what it sets. */
42
+ messages?: DiyaMessagesInput;
43
+ /** Locale for dates and numbers, e.g. 'en-GB'. Defaults to the parent provider's, then 'en-US'. */
44
+ locale?: string;
45
+ /** Router link for every DIYA item with an `href` (Side Navigation, Breadcrumbs, Menu, Button), such as Next.js `Link`. Defaults to a plain anchor; a nested provider inherits it. */
46
+ linkComponent?: DiyaLinkComponent;
47
+ /** Extra class on the provider's wrapper element. */
48
+ className?: string;
49
+ /** Inline styles on the wrapper, such as public `--diya-*` token overrides. */
50
+ style?: CSSProperties;
51
+ };
52
+ /** Scoped appearance; no document mutation, cookies, network calls or global CSS. */
53
+ export declare const DiyaProvider: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
54
+ /** The app or section that uses DIYA components; popups, tooltips and toasts render only inside a provider. */
55
+ children: ReactNode;
56
+ /** Color scheme for everything inside. 'system' follows the visitor's OS setting in CSS, with no flash. Defaults to 'system'. */
57
+ theme?: "light" | "dark" | "system";
58
+ /** Paints the provider's own background and text color, so DIYA reads on any page. Set false when your layout paints the ground. Defaults to true. */
59
+ surface?: boolean;
60
+ /** Gives headers, popups and tabs a translucent, blurred finish where the browser supports it. Defaults to false. */
61
+ glass?: boolean;
62
+ /** Your brand as a hex color, or one per theme as `{ light, dark }`. It fills main buttons, selected pills, switches, sliders and progress, and leads chart series 1 when it has color; text on it is white whenever that reads. Defaults to DIYA's neutral ink. */
63
+ brandColor?: string | {
64
+ light: string;
65
+ dark: string;
66
+ };
67
+ /** CSS font-family stack for every component. Defaults to DIYA Sans with a metric-matched fallback. */
68
+ fontFamily?: string;
69
+ /** Replace any built-in string, by component: `{ table: { emptyTitle: 'Nothing here' } }`. A nested provider inherits its parent's strings and overrides only what it sets. */
70
+ messages?: DiyaMessagesInput;
71
+ /** Locale for dates and numbers, e.g. 'en-GB'. Defaults to the parent provider's, then 'en-US'. */
72
+ locale?: string;
73
+ /** Router link for every DIYA item with an `href` (Side Navigation, Breadcrumbs, Menu, Button), such as Next.js `Link`. Defaults to a plain anchor; a nested provider inherits it. */
74
+ linkComponent?: DiyaLinkComponent;
75
+ /** Extra class on the provider's wrapper element. */
76
+ className?: string;
77
+ /** Inline styles on the wrapper, such as public `--diya-*` token overrides. */
78
+ style?: CSSProperties;
79
+ } & import("react").RefAttributes<HTMLDivElement>>;