@ankhorage/zora 0.0.3 โ 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +876 -18
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,32 +1,890 @@
|
|
|
1
1
|
# zora
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<!-- markdownlint-disable MD013 MD033 -->
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- Consistent spacing and typography
|
|
8
|
-
- Works out of the box with Expo + Web
|
|
5
|
+
Opinionated React Native and React Native Web UI kit built on
|
|
6
|
+
`@ankhorage/surface`.
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
|
|
8
|
+
ZORA sits above Surface. Surface provides the foundation primitives, theme system,
|
|
9
|
+
and low-level controls; ZORA adds product-facing components, app layouts, and
|
|
10
|
+
ready-made patterns with stronger defaults.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
14
13
|
|
|
15
|
-
## ๐ Installation
|
|
16
14
|
```bash
|
|
17
15
|
bun add @ankhorage/zora
|
|
18
16
|
```
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
Peer dependencies:
|
|
19
|
+
|
|
20
|
+
- `react >=18.2.0`
|
|
21
|
+
- `react-native >=0.72.0`
|
|
22
|
+
- `@expo/vector-icons >=14.0.0` when using icon specs
|
|
23
|
+
- `expo-font >=14.0.4` when using runtime font registration
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
Wrap your app in `ZoraProvider`, then import components from
|
|
28
|
+
`@ankhorage/zora`.
|
|
29
|
+
|
|
21
30
|
```tsx
|
|
22
|
-
import
|
|
31
|
+
import React from 'react';
|
|
32
|
+
import { Button, Card, Page, PageHeader, ZoraProvider } from '@ankhorage/zora';
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
export function App() {
|
|
35
|
+
return (
|
|
36
|
+
<ZoraProvider>
|
|
37
|
+
<Page header={<PageHeader title="Dashboard" description="Ready to build." />}>
|
|
38
|
+
<Card
|
|
39
|
+
actions={<Button>Continue</Button>}
|
|
40
|
+
description="ZORA provides composed UI surfaces for apps."
|
|
41
|
+
title="Welcome"
|
|
42
|
+
/>
|
|
43
|
+
</Page>
|
|
44
|
+
</ZoraProvider>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
25
47
|
```
|
|
26
48
|
|
|
27
|
-
##
|
|
28
|
-
|
|
29
|
-
|
|
49
|
+
## Shared Types
|
|
50
|
+
|
|
51
|
+
These unions appear across the catalogue:
|
|
52
|
+
|
|
53
|
+
- `ZoraTone` comes from Surface `ButtonProps['tone']`.
|
|
54
|
+
- `ZoraEmphasis` comes from Surface `ButtonProps['variant']`.
|
|
55
|
+
- `ZoraBadgeEmphasis` comes from Surface `BadgeProps['variant']`.
|
|
56
|
+
- `ZoraControlSize` comes from Surface `ButtonProps['size']`.
|
|
57
|
+
- `ZoraCardTone = 'default' | 'subtle' | 'outline'`.
|
|
58
|
+
- `ZoraContentWidth = 'narrow' | 'default' | 'wide'`.
|
|
59
|
+
|
|
60
|
+
Width presets:
|
|
61
|
+
|
|
62
|
+
- Dialog widths: `narrow=420`, `default=520`, `wide=560`.
|
|
63
|
+
- Page widths: `narrow=760`, `default=1040`, `wide=1280`.
|
|
64
|
+
|
|
65
|
+
## Components
|
|
66
|
+
|
|
67
|
+
### `Button`
|
|
68
|
+
|
|
69
|
+
Action button with ZORA defaults for tone, emphasis, size, and icons.
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<Button leadingIcon={{ name: 'checkmark-circle-outline' }}>Save</Button>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
<details>
|
|
76
|
+
<summary>Props</summary>
|
|
77
|
+
|
|
78
|
+
ZORA props:
|
|
79
|
+
|
|
80
|
+
| Prop | Type | Default | Notes |
|
|
81
|
+
| --- | --- | --- | --- |
|
|
82
|
+
| `children` | `React.ReactNode` | - | Button label or content. |
|
|
83
|
+
| `tone` | `ZoraTone` | `'primary'` | Passed to Surface as `tone`. |
|
|
84
|
+
| `emphasis` | `ZoraEmphasis` | `'solid'` | Passed to Surface as `variant`. |
|
|
85
|
+
| `size` | `ZoraControlSize` | `'l'` | Passed to Surface as `size`. |
|
|
86
|
+
| `leadingIcon` | `ButtonIconSpec` | - | Surface icon spec rendered before content. |
|
|
87
|
+
| `trailingIcon` | `ButtonIconSpec` | - | Surface icon spec rendered after content. |
|
|
88
|
+
|
|
89
|
+
Inherited props:
|
|
90
|
+
|
|
91
|
+
Inherits all Surface `ButtonProps` except `children`, `size`, `tone`, and
|
|
92
|
+
`variant`. This includes Surface button behavior such as `loading`,
|
|
93
|
+
`fullWidth`, pressability props, disabled state, accessibility props allowed by
|
|
94
|
+
Surface, and `testID`.
|
|
95
|
+
|
|
96
|
+
</details>
|
|
97
|
+
|
|
98
|
+
### `Badge`
|
|
99
|
+
|
|
100
|
+
Small status label with ZORA tone, emphasis, and size defaults.
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
<Badge tone="success">Active</Badge>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
<details>
|
|
107
|
+
<summary>Props</summary>
|
|
108
|
+
|
|
109
|
+
ZORA props:
|
|
110
|
+
|
|
111
|
+
| Prop | Type | Default | Notes |
|
|
112
|
+
| --- | --- | --- | --- |
|
|
113
|
+
| `children` | `React.ReactNode` | - | Rendered as Surface badge `content`. |
|
|
114
|
+
| `tone` | `ZoraTone` | `'primary'` | Passed to Surface as `tone`. |
|
|
115
|
+
| `emphasis` | `ZoraBadgeEmphasis` | `'soft'` | Passed to Surface as `variant`. |
|
|
116
|
+
| `size` | `ZoraControlSize` | `'m'` | Passed to Surface as `size`. |
|
|
117
|
+
|
|
118
|
+
Inherited props:
|
|
119
|
+
|
|
120
|
+
Inherits all Surface `BadgeProps` except `content`, `size`, `tone`, and
|
|
121
|
+
`variant`. The remaining inherited prop is `testID`.
|
|
122
|
+
|
|
123
|
+
</details>
|
|
124
|
+
|
|
125
|
+
### `Card`
|
|
126
|
+
|
|
127
|
+
Composed content surface with optional header, actions, footer, and ZORA card
|
|
128
|
+
tones.
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
<Card
|
|
132
|
+
actions={<Button>Open</Button>}
|
|
133
|
+
description="A reusable product surface."
|
|
134
|
+
title="Project"
|
|
135
|
+
/>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
<details>
|
|
139
|
+
<summary>Props</summary>
|
|
140
|
+
|
|
141
|
+
ZORA props:
|
|
142
|
+
|
|
143
|
+
| Prop | Type | Default | Notes |
|
|
144
|
+
| --- | --- | --- | --- |
|
|
145
|
+
| `children` | `React.ReactNode` | - | Main card body. |
|
|
146
|
+
| `title` | `React.ReactNode` | - | Header title. |
|
|
147
|
+
| `description` | `React.ReactNode` | - | Header description. |
|
|
148
|
+
| `eyebrow` | `React.ReactNode` | - | Small muted text above the title. |
|
|
149
|
+
| `actions` | `React.ReactNode` | - | Header action area. |
|
|
150
|
+
| `footer` | `React.ReactNode` | - | Footer area below body content. |
|
|
151
|
+
| `tone` | `ZoraCardTone` | `'default'` | Maps to Surface variants: `default -> raised`, `subtle -> subtle`, `outline -> outline`. |
|
|
152
|
+
| `compact` | `boolean` | `false` | Uses tighter padding and heading scale. |
|
|
153
|
+
|
|
154
|
+
Inherited props:
|
|
155
|
+
|
|
156
|
+
Inherits all Surface `CardProps` except `children`, `p`, `radius`, `style`, and
|
|
157
|
+
`variant`. ZORA owns spacing, radius, and variant selection for this wrapper.
|
|
158
|
+
|
|
159
|
+
</details>
|
|
160
|
+
|
|
161
|
+
### `Input`
|
|
162
|
+
|
|
163
|
+
Text input wrapper with ZORA sizing and optional Surface icon specs.
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
<Input
|
|
167
|
+
autoCapitalize="none"
|
|
168
|
+
keyboardType="email-address"
|
|
169
|
+
leadingIcon={{ name: 'mail-outline' }}
|
|
170
|
+
placeholder="you@example.com"
|
|
171
|
+
/>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
<details>
|
|
175
|
+
<summary>Props</summary>
|
|
176
|
+
|
|
177
|
+
ZORA props:
|
|
178
|
+
|
|
179
|
+
| Prop | Type | Default | Notes |
|
|
180
|
+
| --- | --- | --- | --- |
|
|
181
|
+
| `size` | `ZoraControlSize` | `'l'` | Passed to Surface as `size`. |
|
|
182
|
+
| `leadingIcon` | `ButtonIconSpec` | - | Rendered as Surface `leadingAccessory`. |
|
|
183
|
+
| `trailingIcon` | `ButtonIconSpec` | - | Rendered as Surface `trailingAccessory`. |
|
|
184
|
+
|
|
185
|
+
Inherited props:
|
|
186
|
+
|
|
187
|
+
Inherits all Surface `TextInputProps` except `leadingAccessory`, `size`, and
|
|
188
|
+
`trailingAccessory`. Surface `TextInputProps` also inherit React Native
|
|
189
|
+
`TextInputProps` except `defaultValue`, `editable`, `onChangeText`,
|
|
190
|
+
`placeholderTextColor`, `style`, `testID`, and `value`; Surface re-exposes
|
|
191
|
+
`value`, `defaultValue`, `onChangeText`, `placeholder`, `disabled`, `readOnly`,
|
|
192
|
+
`invalid`, `style`, and `testID`.
|
|
193
|
+
|
|
194
|
+
</details>
|
|
195
|
+
|
|
196
|
+
### `Textarea`
|
|
197
|
+
|
|
198
|
+
Multiline text input wrapper with ZORA sizing and optional Surface icon specs.
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
<Textarea leadingIcon={{ name: 'document-text-outline' }} rows={5} />
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
<details>
|
|
205
|
+
<summary>Props</summary>
|
|
206
|
+
|
|
207
|
+
ZORA props:
|
|
208
|
+
|
|
209
|
+
| Prop | Type | Default | Notes |
|
|
210
|
+
| --- | --- | --- | --- |
|
|
211
|
+
| `size` | `ZoraControlSize` | `'l'` | Passed to Surface as `size`. |
|
|
212
|
+
| `leadingIcon` | `ButtonIconSpec` | - | Rendered as Surface `leadingAccessory`. |
|
|
213
|
+
| `trailingIcon` | `ButtonIconSpec` | - | Rendered as Surface `trailingAccessory`. |
|
|
214
|
+
|
|
215
|
+
Inherited props:
|
|
216
|
+
|
|
217
|
+
Inherits all Surface `TextareaProps` except `leadingAccessory`, `size`, and
|
|
218
|
+
`trailingAccessory`. Surface `TextareaProps` extend Surface `TextInputProps`
|
|
219
|
+
except `multiline`, so React Native text input props are available through
|
|
220
|
+
Surface with the same Surface exclusions and re-exposed values listed for
|
|
221
|
+
`Input`.
|
|
222
|
+
|
|
223
|
+
</details>
|
|
224
|
+
|
|
225
|
+
### `Modal`
|
|
226
|
+
|
|
227
|
+
Centered overlay shell with optional header, body, footer, and width preset.
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
<Modal
|
|
231
|
+
footer={<Button>Done</Button>}
|
|
232
|
+
onDismiss={close}
|
|
233
|
+
title="Details"
|
|
234
|
+
visible={visible}
|
|
235
|
+
/>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
<details>
|
|
239
|
+
<summary>Props</summary>
|
|
240
|
+
|
|
241
|
+
ZORA props:
|
|
242
|
+
|
|
243
|
+
| Prop | Type | Default | Notes |
|
|
244
|
+
| --- | --- | --- | --- |
|
|
245
|
+
| `children` | `React.ReactNode` | - | Modal body. |
|
|
246
|
+
| `title` | `React.ReactNode` | - | Header title. |
|
|
247
|
+
| `description` | `React.ReactNode` | - | Header description. |
|
|
248
|
+
| `footer` | `React.ReactNode` | - | Footer area. |
|
|
249
|
+
| `width` | `ZoraContentWidth` | `'default'` | Resolves to `420`, `520`, or `560` pixels. |
|
|
250
|
+
|
|
251
|
+
Inherited props:
|
|
252
|
+
|
|
253
|
+
Picks these Surface `ModalProps`: `closeOnBackdrop`, `onDismiss`, `testID`, and
|
|
254
|
+
`visible`.
|
|
255
|
+
|
|
256
|
+
</details>
|
|
257
|
+
|
|
258
|
+
### `Drawer`
|
|
259
|
+
|
|
260
|
+
Side overlay shell with optional header, body, and footer.
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
<Drawer onDismiss={close} title="Filters" visible={visible}>
|
|
264
|
+
{content}
|
|
265
|
+
</Drawer>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
<details>
|
|
269
|
+
<summary>Props</summary>
|
|
270
|
+
|
|
271
|
+
ZORA props:
|
|
272
|
+
|
|
273
|
+
| Prop | Type | Default | Notes |
|
|
274
|
+
| --- | --- | --- | --- |
|
|
275
|
+
| `children` | `React.ReactNode` | - | Drawer body. |
|
|
276
|
+
| `title` | `React.ReactNode` | - | Header title. |
|
|
277
|
+
| `description` | `React.ReactNode` | - | Header description. |
|
|
278
|
+
| `footer` | `React.ReactNode` | - | Footer area. |
|
|
279
|
+
|
|
280
|
+
Inherited props:
|
|
281
|
+
|
|
282
|
+
Picks these Surface `DrawerProps`: `closeOnBackdrop`, `onDismiss`, `position`,
|
|
283
|
+
`testID`, and `visible`.
|
|
284
|
+
|
|
285
|
+
</details>
|
|
286
|
+
|
|
287
|
+
## Layouts
|
|
288
|
+
|
|
289
|
+
### `Page`
|
|
290
|
+
|
|
291
|
+
Constrained page container with optional header and footer slots.
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
<Page header={<PageHeader title="Projects" />} width="wide">
|
|
295
|
+
{content}
|
|
296
|
+
</Page>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
<details>
|
|
300
|
+
<summary>Props</summary>
|
|
301
|
+
|
|
302
|
+
ZORA props:
|
|
303
|
+
|
|
304
|
+
| Prop | Type | Default | Notes |
|
|
305
|
+
| --- | --- | --- | --- |
|
|
306
|
+
| `children` | `React.ReactNode` | - | Page body. |
|
|
307
|
+
| `header` | `React.ReactNode` | - | Rendered above body content. |
|
|
308
|
+
| `footer` | `React.ReactNode` | - | Rendered below body content. |
|
|
309
|
+
| `width` | `ZoraContentWidth` | `'default'` | Resolves to `760`, `1040`, or `1280` pixels. |
|
|
310
|
+
| `testID` | `string` | - | Forwarded to the root Surface container. |
|
|
311
|
+
|
|
312
|
+
Inherited props:
|
|
313
|
+
|
|
314
|
+
No inherited props. `PageProps` is declared directly by ZORA.
|
|
315
|
+
|
|
316
|
+
</details>
|
|
317
|
+
|
|
318
|
+
### `PageHeader`
|
|
319
|
+
|
|
320
|
+
Top-level page heading with optional eyebrow, metadata, and actions.
|
|
321
|
+
|
|
322
|
+
```tsx
|
|
323
|
+
<PageHeader actions={<Button>New</Button>} title="Projects" />
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
<details>
|
|
327
|
+
<summary>Props</summary>
|
|
328
|
+
|
|
329
|
+
ZORA props:
|
|
330
|
+
|
|
331
|
+
| Prop | Type | Default | Notes |
|
|
332
|
+
| --- | --- | --- | --- |
|
|
333
|
+
| `title` | `React.ReactNode` | - | Required page title. |
|
|
334
|
+
| `description` | `React.ReactNode` | - | Supporting copy below title. |
|
|
335
|
+
| `eyebrow` | `React.ReactNode` | - | Small muted text above title. |
|
|
336
|
+
| `actions` | `React.ReactNode` | - | Action area opposite the heading. |
|
|
337
|
+
| `meta` | `React.ReactNode` | - | Extra content below description. |
|
|
338
|
+
| `testID` | `string` | - | Forwarded to the root Surface stack. |
|
|
339
|
+
|
|
340
|
+
Inherited props:
|
|
341
|
+
|
|
342
|
+
No inherited props. `PageHeaderProps` is declared directly by ZORA.
|
|
343
|
+
|
|
344
|
+
</details>
|
|
345
|
+
|
|
346
|
+
### `PageSection`
|
|
347
|
+
|
|
348
|
+
Section wrapper that optionally renders a `SectionHeader`.
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
<PageSection actions={<Button>Refresh</Button>} title="Recent activity">
|
|
352
|
+
{content}
|
|
353
|
+
</PageSection>
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
<details>
|
|
357
|
+
<summary>Props</summary>
|
|
358
|
+
|
|
359
|
+
ZORA props:
|
|
360
|
+
|
|
361
|
+
| Prop | Type | Default | Notes |
|
|
362
|
+
| --- | --- | --- | --- |
|
|
363
|
+
| `title` | `React.ReactNode` | - | Section title; when absent, no header is rendered. |
|
|
364
|
+
| `description` | `React.ReactNode` | - | Passed to the section header. |
|
|
365
|
+
| `actions` | `React.ReactNode` | - | Passed to the section header. |
|
|
366
|
+
| `children` | `React.ReactNode` | - | Section body. |
|
|
367
|
+
| `testID` | `string` | - | Forwarded to the root Surface stack. |
|
|
368
|
+
|
|
369
|
+
Inherited props:
|
|
370
|
+
|
|
371
|
+
No inherited props. `PageSectionProps` is declared directly by ZORA.
|
|
372
|
+
|
|
373
|
+
</details>
|
|
374
|
+
|
|
375
|
+
### `SidebarLayout`
|
|
376
|
+
|
|
377
|
+
Responsive shell with required sidebar, main content, and optional aside.
|
|
378
|
+
|
|
379
|
+
```tsx
|
|
380
|
+
<SidebarLayout sidebar={navigation} aside={details}>
|
|
381
|
+
{content}
|
|
382
|
+
</SidebarLayout>
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
<details>
|
|
386
|
+
<summary>Props</summary>
|
|
387
|
+
|
|
388
|
+
ZORA props:
|
|
389
|
+
|
|
390
|
+
| Prop | Type | Default | Notes |
|
|
391
|
+
| --- | --- | --- | --- |
|
|
392
|
+
| `sidebar` | `React.ReactNode` | - | Required left column content. |
|
|
393
|
+
| `children` | `React.ReactNode` | - | Main content. |
|
|
394
|
+
| `aside` | `React.ReactNode` | - | Optional right column content. |
|
|
395
|
+
| `sidebarWidth` | `number` | `280` | Desktop sidebar width. |
|
|
396
|
+
| `asideWidth` | `number` | `280` | Desktop aside width. |
|
|
397
|
+
| `testID` | `string` | - | Forwarded to the root Surface stack. |
|
|
398
|
+
|
|
399
|
+
Inherited props:
|
|
400
|
+
|
|
401
|
+
No inherited props. `SidebarLayoutProps` is declared directly by ZORA.
|
|
402
|
+
|
|
403
|
+
</details>
|
|
404
|
+
|
|
405
|
+
### `TopbarLayout`
|
|
406
|
+
|
|
407
|
+
Top navigation shell with optional sidebar composition.
|
|
408
|
+
|
|
409
|
+
```tsx
|
|
410
|
+
<TopbarLayout topbar={topbar} sidebar={sidebar}>
|
|
411
|
+
{content}
|
|
412
|
+
</TopbarLayout>
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
<details>
|
|
416
|
+
<summary>Props</summary>
|
|
417
|
+
|
|
418
|
+
ZORA props:
|
|
419
|
+
|
|
420
|
+
| Prop | Type | Default | Notes |
|
|
421
|
+
| --- | --- | --- | --- |
|
|
422
|
+
| `topbar` | `React.ReactNode` | - | Required topbar content. |
|
|
423
|
+
| `children` | `React.ReactNode` | - | Main content. |
|
|
424
|
+
| `sidebar` | `React.ReactNode` | - | Optional sidebar; when present, content is rendered through `SidebarLayout`. |
|
|
425
|
+
| `testID` | `string` | - | Forwarded to the root Surface stack. |
|
|
426
|
+
|
|
427
|
+
Inherited props:
|
|
428
|
+
|
|
429
|
+
No inherited props. `TopbarLayoutProps` is declared directly by ZORA.
|
|
430
|
+
|
|
431
|
+
</details>
|
|
432
|
+
|
|
433
|
+
### `SettingsLayout`
|
|
434
|
+
|
|
435
|
+
Reusable settings shell with page header, sidebar, and content region.
|
|
436
|
+
|
|
437
|
+
```tsx
|
|
438
|
+
<SettingsLayout actions={<Button>Save</Button>} sidebar={nav} title="Settings">
|
|
439
|
+
{content}
|
|
440
|
+
</SettingsLayout>
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
<details>
|
|
444
|
+
<summary>Props</summary>
|
|
445
|
+
|
|
446
|
+
ZORA props:
|
|
447
|
+
|
|
448
|
+
| Prop | Type | Default | Notes |
|
|
449
|
+
| --- | --- | --- | --- |
|
|
450
|
+
| `title` | `React.ReactNode` | - | Optional page title; when absent, no page header is rendered. |
|
|
451
|
+
| `description` | `React.ReactNode` | - | Header description. |
|
|
452
|
+
| `sidebar` | `React.ReactNode` | - | Required settings navigation or context sidebar. |
|
|
453
|
+
| `children` | `React.ReactNode` | - | Settings content. |
|
|
454
|
+
| `actions` | `React.ReactNode` | - | Header action area. |
|
|
455
|
+
| `testID` | `string` | - | Forwarded to `Page`. |
|
|
456
|
+
|
|
457
|
+
Inherited props:
|
|
458
|
+
|
|
459
|
+
No inherited props. `SettingsLayoutProps` is declared directly by ZORA.
|
|
460
|
+
|
|
461
|
+
</details>
|
|
462
|
+
|
|
463
|
+
### `AuthLayout`
|
|
464
|
+
|
|
465
|
+
Centered authentication-style shell for sign-in, onboarding, and recovery
|
|
466
|
+
screens.
|
|
467
|
+
|
|
468
|
+
```tsx
|
|
469
|
+
<AuthLayout description="Sign in to continue" title="Welcome back">
|
|
470
|
+
{form}
|
|
471
|
+
</AuthLayout>
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
<details>
|
|
475
|
+
<summary>Props</summary>
|
|
476
|
+
|
|
477
|
+
ZORA props:
|
|
478
|
+
|
|
479
|
+
| Prop | Type | Default | Notes |
|
|
480
|
+
| --- | --- | --- | --- |
|
|
481
|
+
| `title` | `React.ReactNode` | - | Card title. |
|
|
482
|
+
| `description` | `React.ReactNode` | - | Card description. |
|
|
483
|
+
| `eyebrow` | `React.ReactNode` | - | Card eyebrow. |
|
|
484
|
+
| `children` | `React.ReactNode` | - | Form or auth content. |
|
|
485
|
+
| `footer` | `React.ReactNode` | - | Card footer. |
|
|
486
|
+
| `testID` | `string` | - | Forwarded to the root Surface center. |
|
|
487
|
+
|
|
488
|
+
Inherited props:
|
|
489
|
+
|
|
490
|
+
No inherited props. `AuthLayoutProps` is declared directly by ZORA.
|
|
491
|
+
|
|
492
|
+
</details>
|
|
493
|
+
|
|
494
|
+
## Patterns
|
|
495
|
+
|
|
496
|
+
### `FormField`
|
|
497
|
+
|
|
498
|
+
Form field wrapper with rich label composition, description, helper text, and
|
|
499
|
+
Surface field state.
|
|
500
|
+
|
|
501
|
+
```tsx
|
|
502
|
+
<FormField helperText="We only use this for sign-in." label="Email">
|
|
503
|
+
<Input keyboardType="email-address" />
|
|
504
|
+
</FormField>
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
<details>
|
|
508
|
+
<summary>Props</summary>
|
|
509
|
+
|
|
510
|
+
ZORA props:
|
|
511
|
+
|
|
512
|
+
| Prop | Type | Default | Notes |
|
|
513
|
+
| --- | --- | --- | --- |
|
|
514
|
+
| `label` | `React.ReactNode` | - | Required field label. |
|
|
515
|
+
| `description` | `React.ReactNode` | - | Rendered under the label. |
|
|
516
|
+
| `helperText` | `React.ReactNode` | - | Passed to Surface `Field` as `helperText`. |
|
|
517
|
+
|
|
518
|
+
Inherited props:
|
|
519
|
+
|
|
520
|
+
Picks these Surface `FieldProps`: `children`, `disabled`, `errorText`,
|
|
521
|
+
`invalid`, `readOnly`, `required`, and `testID`.
|
|
522
|
+
|
|
523
|
+
</details>
|
|
524
|
+
|
|
525
|
+
### `Notice`
|
|
526
|
+
|
|
527
|
+
Semantic notice surface with badge eyebrow, optional body, and actions.
|
|
528
|
+
|
|
529
|
+
```tsx
|
|
530
|
+
<Notice actions={<Button>Review</Button>} title="Publish pipeline ready" tone="success" />
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
<details>
|
|
534
|
+
<summary>Props</summary>
|
|
535
|
+
|
|
536
|
+
ZORA props:
|
|
537
|
+
|
|
538
|
+
| Prop | Type | Default | Notes |
|
|
539
|
+
| --- | --- | --- | --- |
|
|
540
|
+
| `title` | `React.ReactNode` | - | Required notice title. |
|
|
541
|
+
| `description` | `React.ReactNode` | - | Notice description. |
|
|
542
|
+
| `children` | `React.ReactNode` | - | Optional body content. |
|
|
543
|
+
| `actions` | `React.ReactNode` | - | Optional action area. |
|
|
544
|
+
| `tone` | `ZoraTone` | `'primary'` | Drives the badge eyebrow tone. |
|
|
545
|
+
| `testID` | `string` | - | Forwarded to the underlying `Card`. |
|
|
546
|
+
|
|
547
|
+
Inherited props:
|
|
548
|
+
|
|
549
|
+
No inherited props. `NoticeProps` is declared directly by ZORA.
|
|
550
|
+
|
|
551
|
+
</details>
|
|
552
|
+
|
|
553
|
+
### `Panel`
|
|
554
|
+
|
|
555
|
+
Named composition surface that currently forwards to `Card`.
|
|
556
|
+
|
|
557
|
+
```tsx
|
|
558
|
+
<Panel description="Release details" title="Release Candidate">
|
|
559
|
+
{content}
|
|
560
|
+
</Panel>
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
<details>
|
|
564
|
+
<summary>Props</summary>
|
|
565
|
+
|
|
566
|
+
ZORA props:
|
|
567
|
+
|
|
568
|
+
| Prop | Type | Default | Notes |
|
|
569
|
+
| --- | --- | --- | --- |
|
|
570
|
+
| `title` | `React.ReactNode` | - | Header title. |
|
|
571
|
+
| `description` | `React.ReactNode` | - | Header description. |
|
|
572
|
+
| `eyebrow` | `React.ReactNode` | - | Small muted text above the title. |
|
|
573
|
+
| `actions` | `React.ReactNode` | - | Header action area. |
|
|
574
|
+
| `footer` | `React.ReactNode` | - | Footer area below body content. |
|
|
575
|
+
| `children` | `React.ReactNode` | - | Panel body. |
|
|
576
|
+
| `tone` | `ZoraCardTone` | `'default'` | Same tone behavior as `Card`. |
|
|
577
|
+
| `compact` | `boolean` | `false` | Same compact behavior as `Card`. |
|
|
578
|
+
| `testID` | `string` | - | Forwarded through `Card`. |
|
|
579
|
+
|
|
580
|
+
Inherited props:
|
|
581
|
+
|
|
582
|
+
No inherited props. `PanelProps` is declared directly by ZORA.
|
|
583
|
+
|
|
584
|
+
</details>
|
|
585
|
+
|
|
586
|
+
### `SectionHeader`
|
|
587
|
+
|
|
588
|
+
Reusable section heading with optional eyebrow, description, and actions.
|
|
589
|
+
|
|
590
|
+
```tsx
|
|
591
|
+
<SectionHeader actions={<Badge>Live</Badge>} title="Activity" />
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
<details>
|
|
595
|
+
<summary>Props</summary>
|
|
596
|
+
|
|
597
|
+
ZORA props:
|
|
598
|
+
|
|
599
|
+
| Prop | Type | Default | Notes |
|
|
600
|
+
| --- | --- | --- | --- |
|
|
601
|
+
| `title` | `React.ReactNode` | - | Required heading title. |
|
|
602
|
+
| `description` | `React.ReactNode` | - | Supporting copy. |
|
|
603
|
+
| `eyebrow` | `React.ReactNode` | - | Small muted text above the title. |
|
|
604
|
+
| `actions` | `React.ReactNode` | - | Action area opposite the heading. |
|
|
605
|
+
| `testID` | `string` | - | Forwarded to the root Surface stack. |
|
|
606
|
+
|
|
607
|
+
Inherited props:
|
|
608
|
+
|
|
609
|
+
No inherited props. `SectionHeaderProps` is declared directly by ZORA.
|
|
610
|
+
|
|
611
|
+
</details>
|
|
612
|
+
|
|
613
|
+
### `SettingsRow`
|
|
614
|
+
|
|
615
|
+
Compact settings row with optional metadata, control, and press handling.
|
|
616
|
+
|
|
617
|
+
```tsx
|
|
618
|
+
<SettingsRow control={<Switch value={enabled} />} title="Notifications" />
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
<details>
|
|
622
|
+
<summary>Props</summary>
|
|
623
|
+
|
|
624
|
+
ZORA props:
|
|
625
|
+
|
|
626
|
+
| Prop | Type | Default | Notes |
|
|
627
|
+
| --- | --- | --- | --- |
|
|
628
|
+
| `title` | `React.ReactNode` | - | Required row title. |
|
|
629
|
+
| `description` | `React.ReactNode` | - | Row description. |
|
|
630
|
+
| `meta` | `React.ReactNode` | - | Small muted metadata below the row content. |
|
|
631
|
+
| `control` | `React.ReactNode` | - | Trailing control or action content. |
|
|
632
|
+
| `onPress` | `() => void` | - | Makes the underlying card pressable. |
|
|
633
|
+
| `disabled` | `boolean` | `false` | Forwarded to the underlying card. |
|
|
634
|
+
| `testID` | `string` | - | Forwarded to the underlying card. |
|
|
635
|
+
|
|
636
|
+
Inherited props:
|
|
637
|
+
|
|
638
|
+
No inherited props. `SettingsRowProps` is declared directly by ZORA.
|
|
639
|
+
|
|
640
|
+
</details>
|
|
641
|
+
|
|
642
|
+
### `EmptyState`
|
|
643
|
+
|
|
644
|
+
No-data surface with title, optional supporting text, actions, and footer.
|
|
645
|
+
|
|
646
|
+
```tsx
|
|
647
|
+
<EmptyState
|
|
648
|
+
primaryAction={{ label: 'Create project', onPress: createProject }}
|
|
649
|
+
title="Nothing here yet"
|
|
650
|
+
/>
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
<details>
|
|
654
|
+
<summary>Props</summary>
|
|
655
|
+
|
|
656
|
+
ZORA props:
|
|
657
|
+
|
|
658
|
+
| Prop | Type | Default | Notes |
|
|
659
|
+
| --- | --- | --- | --- |
|
|
660
|
+
| `title` | `React.ReactNode` | - | Required empty-state title. |
|
|
661
|
+
| `description` | `React.ReactNode` | - | Supporting copy. |
|
|
662
|
+
| `eyebrow` | `React.ReactNode` | - | Card eyebrow. |
|
|
663
|
+
| `primaryAction` | `EmptyStateAction` | - | Primary action button. |
|
|
664
|
+
| `secondaryAction` | `EmptyStateAction` | - | Secondary action button; defaults to `tone="neutral"` and `emphasis="soft"` when omitted on the action. |
|
|
665
|
+
| `footer` | `React.ReactNode` | - | Footer content below actions. |
|
|
666
|
+
| `testID` | `string` | - | Forwarded to the underlying card. |
|
|
667
|
+
|
|
668
|
+
`EmptyStateAction`:
|
|
669
|
+
|
|
670
|
+
| Prop | Type | Default | Notes |
|
|
671
|
+
| --- | --- | --- | --- |
|
|
672
|
+
| `label` | `React.ReactNode` | - | Button label. |
|
|
673
|
+
| `onPress` | `() => void` | - | Button handler. |
|
|
674
|
+
| `tone` | `ZoraTone` | - | Button tone. |
|
|
675
|
+
| `emphasis` | `ZoraEmphasis` | - | Button emphasis. |
|
|
676
|
+
|
|
677
|
+
Inherited props:
|
|
678
|
+
|
|
679
|
+
No inherited props. `EmptyStateProps` and `EmptyStateAction` are declared
|
|
680
|
+
directly by ZORA.
|
|
681
|
+
|
|
682
|
+
</details>
|
|
683
|
+
|
|
684
|
+
### `ConfirmDialog`
|
|
685
|
+
|
|
686
|
+
Narrow confirmation modal for destructive or high-signal decisions.
|
|
687
|
+
|
|
688
|
+
```tsx
|
|
689
|
+
<ConfirmDialog
|
|
690
|
+
confirmLabel="Archive"
|
|
691
|
+
confirmTone="danger"
|
|
692
|
+
onCancel={close}
|
|
693
|
+
onConfirm={archive}
|
|
694
|
+
title="Archive project?"
|
|
695
|
+
visible={visible}
|
|
696
|
+
/>
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
<details>
|
|
700
|
+
<summary>Props</summary>
|
|
701
|
+
|
|
702
|
+
ZORA props:
|
|
703
|
+
|
|
704
|
+
| Prop | Type | Default | Notes |
|
|
705
|
+
| --- | --- | --- | --- |
|
|
706
|
+
| `visible` | `boolean` | - | Required modal visibility. |
|
|
707
|
+
| `title` | `React.ReactNode` | - | Required dialog title. |
|
|
708
|
+
| `description` | `React.ReactNode` | - | Dialog description. |
|
|
709
|
+
| `children` | `React.ReactNode` | - | Dialog body. |
|
|
710
|
+
| `confirmLabel` | `React.ReactNode` | `'Confirm'` | Confirm button label. |
|
|
711
|
+
| `cancelLabel` | `React.ReactNode` | `'Cancel'` | Cancel button label. |
|
|
712
|
+
| `confirmTone` | `ZoraTone` | `'danger'` | Confirm button tone. |
|
|
713
|
+
| `confirmEmphasis` | `ZoraEmphasis` | `'solid'` | Confirm button emphasis. |
|
|
714
|
+
| `busy` | `boolean` | `false` | Passed to the confirm button as `loading`. |
|
|
715
|
+
| `closeOnBackdrop` | `boolean` | `true` | Passed to the underlying modal. |
|
|
716
|
+
| `onConfirm` | `() => void` | - | Confirm button handler. |
|
|
717
|
+
| `onCancel` | `() => void` | - | Cancel button and modal dismiss handler. |
|
|
718
|
+
| `testID` | `string` | - | Forwarded to the underlying modal. |
|
|
719
|
+
|
|
720
|
+
Confirm dialogs always use `Modal` with `width="narrow"`.
|
|
721
|
+
|
|
722
|
+
Inherited props:
|
|
723
|
+
|
|
724
|
+
No inherited props. `ConfirmDialogProps` is declared directly by ZORA.
|
|
725
|
+
|
|
726
|
+
</details>
|
|
727
|
+
|
|
728
|
+
## Theme
|
|
729
|
+
|
|
730
|
+
### `ZoraProvider`
|
|
731
|
+
|
|
732
|
+
Theme provider that creates the ZORA theme and passes it to Surface
|
|
733
|
+
`ThemeProvider`.
|
|
734
|
+
|
|
735
|
+
```tsx
|
|
736
|
+
<ZoraProvider initialMode="dark">
|
|
737
|
+
<App />
|
|
738
|
+
</ZoraProvider>
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
<details>
|
|
742
|
+
<summary>Props</summary>
|
|
743
|
+
|
|
744
|
+
ZORA props:
|
|
745
|
+
|
|
746
|
+
| Prop | Type | Default | Notes |
|
|
747
|
+
| --- | --- | --- | --- |
|
|
748
|
+
| `children` | `React.ReactNode` | - | Required app content. |
|
|
749
|
+
| `initialConfig` | `ZoraThemeOverride` | - | Partial Surface `ThemeConfig` override merged into `zoraTheme`. |
|
|
750
|
+
| `initialMode` | `'light' \| 'dark'` | `'light'` | Initial theme mode passed to Surface. |
|
|
751
|
+
|
|
752
|
+
Inherited props:
|
|
753
|
+
|
|
754
|
+
No inherited props. `ZoraProviderProps` is declared directly by ZORA.
|
|
755
|
+
|
|
756
|
+
</details>
|
|
757
|
+
|
|
758
|
+
### `createZoraTheme`
|
|
759
|
+
|
|
760
|
+
Creates a Surface `ThemeConfig` by deep-merging overrides into `zoraTheme`.
|
|
761
|
+
|
|
762
|
+
```tsx
|
|
763
|
+
const theme = createZoraTheme({
|
|
764
|
+
light: {
|
|
765
|
+
primaryColor: '#1d4ed8',
|
|
766
|
+
},
|
|
767
|
+
});
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
<details>
|
|
771
|
+
<summary>API</summary>
|
|
772
|
+
|
|
773
|
+
```ts
|
|
774
|
+
type ZoraThemeOverride = Partial<ThemeConfig>;
|
|
775
|
+
|
|
776
|
+
function createZoraTheme(overrides?: ZoraThemeOverride): ThemeConfig;
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
The returned theme keeps `id: 'zora'` unless explicitly changed by the merge
|
|
780
|
+
input.
|
|
781
|
+
|
|
782
|
+
</details>
|
|
783
|
+
|
|
784
|
+
### `zoraTheme`
|
|
785
|
+
|
|
786
|
+
Default ZORA Surface theme preset.
|
|
787
|
+
|
|
788
|
+
<details>
|
|
789
|
+
<summary>Value</summary>
|
|
790
|
+
|
|
791
|
+
```ts
|
|
792
|
+
const zoraTheme: ThemeConfig = {
|
|
793
|
+
id: 'zora',
|
|
794
|
+
name: 'ZORA',
|
|
795
|
+
light: {
|
|
796
|
+
primaryColor: '#0f766e',
|
|
797
|
+
harmony: 'analogous',
|
|
798
|
+
systemTone: 'jewel',
|
|
799
|
+
},
|
|
800
|
+
dark: {
|
|
801
|
+
primaryColor: '#2dd4bf',
|
|
802
|
+
harmony: 'analogous',
|
|
803
|
+
systemTone: 'jewel',
|
|
804
|
+
},
|
|
805
|
+
};
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
</details>
|
|
809
|
+
|
|
810
|
+
## Public Exports
|
|
811
|
+
|
|
812
|
+
```ts
|
|
813
|
+
export {
|
|
814
|
+
AuthLayout,
|
|
815
|
+
Badge,
|
|
816
|
+
Button,
|
|
817
|
+
Card,
|
|
818
|
+
ConfirmDialog,
|
|
819
|
+
createZoraTheme,
|
|
820
|
+
Drawer,
|
|
821
|
+
EmptyState,
|
|
822
|
+
FormField,
|
|
823
|
+
Input,
|
|
824
|
+
Modal,
|
|
825
|
+
Notice,
|
|
826
|
+
Page,
|
|
827
|
+
PageHeader,
|
|
828
|
+
PageSection,
|
|
829
|
+
Panel,
|
|
830
|
+
SectionHeader,
|
|
831
|
+
SettingsLayout,
|
|
832
|
+
SettingsRow,
|
|
833
|
+
SidebarLayout,
|
|
834
|
+
Textarea,
|
|
835
|
+
TopbarLayout,
|
|
836
|
+
ZoraProvider,
|
|
837
|
+
zoraTheme,
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
export type {
|
|
841
|
+
AuthLayoutProps,
|
|
842
|
+
BadgeProps,
|
|
843
|
+
ButtonProps,
|
|
844
|
+
CardProps,
|
|
845
|
+
ConfirmDialogProps,
|
|
846
|
+
DrawerProps,
|
|
847
|
+
EmptyStateAction,
|
|
848
|
+
EmptyStateProps,
|
|
849
|
+
FormFieldProps,
|
|
850
|
+
InputProps,
|
|
851
|
+
ModalProps,
|
|
852
|
+
NoticeProps,
|
|
853
|
+
PageHeaderProps,
|
|
854
|
+
PageProps,
|
|
855
|
+
PageSectionProps,
|
|
856
|
+
PanelProps,
|
|
857
|
+
SectionHeaderProps,
|
|
858
|
+
SettingsLayoutProps,
|
|
859
|
+
SettingsRowProps,
|
|
860
|
+
SidebarLayoutProps,
|
|
861
|
+
TextareaProps,
|
|
862
|
+
TopbarLayoutProps,
|
|
863
|
+
ZoraProviderProps,
|
|
864
|
+
ZoraThemeOverride,
|
|
865
|
+
};
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
## Example App
|
|
869
|
+
|
|
870
|
+
A complete Expo showcase lives in `examples/expo-showcase`. It renders every
|
|
871
|
+
current ZORA component, pattern, layout, and theme entry point on one screen.
|
|
872
|
+
|
|
873
|
+
Run it locally:
|
|
874
|
+
|
|
875
|
+
```bash
|
|
876
|
+
cd examples/expo-showcase
|
|
877
|
+
npm install
|
|
878
|
+
npm run web
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
The example imports `@ankhorage/zora` and demonstrates the package API in
|
|
882
|
+
`examples/expo-showcase/App.tsx`.
|
|
883
|
+
|
|
884
|
+
## Changelog
|
|
885
|
+
|
|
886
|
+
Version history is maintained in [CHANGELOG.md](./CHANGELOG.md).
|
|
887
|
+
|
|
888
|
+
## License
|
|
30
889
|
|
|
31
|
-
|
|
32
|
-
Building UI from scratch is slow. Zora speeds up development with reusable patterns.
|
|
890
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/zora#readme",
|
|
7
7
|
"bugs": {
|