@ankhorage/zora 0.3.6 → 0.3.7
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 +0 -90
- package/package.json +5 -1
- package/src/components/badge/Badge.tsx +19 -0
- package/src/components/badge/index.ts +2 -0
- package/src/components/badge/types.ts +14 -0
- package/src/components/button/Button.tsx +13 -0
- package/src/components/button/index.ts +2 -0
- package/src/components/button/types.ts +16 -0
- package/src/components/card/Card.tsx +65 -0
- package/src/components/card/index.ts +2 -0
- package/src/components/card/types.ts +15 -0
- package/src/components/drawer/Drawer.tsx +27 -0
- package/src/components/drawer/index.ts +2 -0
- package/src/components/drawer/types.ts +12 -0
- package/src/components/icon/Icon.tsx +8 -0
- package/src/components/icon/index.ts +2 -0
- package/src/components/icon-button/IconButton.tsx +27 -0
- package/src/components/icon-button/index.ts +2 -0
- package/src/components/icon-button/types.ts +15 -0
- package/src/components/input/Input.tsx +38 -0
- package/src/components/input/index.ts +2 -0
- package/src/components/input/types.ts +12 -0
- package/src/components/modal/Modal.tsx +37 -0
- package/src/components/modal/index.ts +2 -0
- package/src/components/modal/types.ts +15 -0
- package/src/components/select/Select.tsx +49 -0
- package/src/components/select/index.ts +2 -0
- package/src/components/select/types.ts +14 -0
- package/src/components/tabs/Tabs.tsx +103 -0
- package/src/components/tabs/index.ts +2 -0
- package/src/components/tabs/types.ts +25 -0
- package/src/components/textarea/Textarea.tsx +38 -0
- package/src/components/textarea/index.ts +2 -0
- package/src/components/textarea/types.ts +12 -0
- package/src/components/toolbar/Toolbar.tsx +38 -0
- package/src/components/toolbar/ToolbarAction.tsx +15 -0
- package/src/components/toolbar/index.ts +3 -0
- package/src/components/toolbar/types.ts +21 -0
- package/src/index.ts +72 -0
- package/src/internal/deepMerge.ts +23 -0
- package/src/internal/recipes.test.ts +46 -0
- package/src/internal/recipes.ts +92 -0
- package/src/layout/app-shell/AppShell.tsx +15 -0
- package/src/layout/app-shell/index.ts +2 -0
- package/src/layout/app-shell/types.ts +7 -0
- package/src/layout/auth-layout/AuthLayout.tsx +29 -0
- package/src/layout/auth-layout/index.ts +2 -0
- package/src/layout/auth-layout/types.ts +10 -0
- package/src/layout/page/Page.tsx +17 -0
- package/src/layout/page/index.ts +2 -0
- package/src/layout/page/types.ts +11 -0
- package/src/layout/page-header/PageHeader.tsx +41 -0
- package/src/layout/page-header/index.ts +2 -0
- package/src/layout/page-header/types.ts +10 -0
- package/src/layout/page-section/PageSection.tsx +14 -0
- package/src/layout/page-section/index.ts +2 -0
- package/src/layout/page-section/types.ts +9 -0
- package/src/layout/settings-layout/SettingsLayout.tsx +26 -0
- package/src/layout/settings-layout/index.ts +2 -0
- package/src/layout/settings-layout/types.ts +10 -0
- package/src/layout/sidebar-layout/SidebarLayout.tsx +23 -0
- package/src/layout/sidebar-layout/index.ts +2 -0
- package/src/layout/sidebar-layout/types.ts +10 -0
- package/src/layout/topbar-layout/TopbarLayout.tsx +14 -0
- package/src/layout/topbar-layout/index.ts +2 -0
- package/src/layout/topbar-layout/types.ts +8 -0
- package/src/patterns/collection-editor/CollectionEditor.tsx +100 -0
- package/src/patterns/collection-editor/index.ts +2 -0
- package/src/patterns/collection-editor/types.ts +25 -0
- package/src/patterns/confirm-dialog/ConfirmDialog.tsx +46 -0
- package/src/patterns/confirm-dialog/index.ts +2 -0
- package/src/patterns/confirm-dialog/types.ts +19 -0
- package/src/patterns/disclosure-section/DisclosureSection.tsx +61 -0
- package/src/patterns/disclosure-section/index.ts +2 -0
- package/src/patterns/disclosure-section/types.ts +15 -0
- package/src/patterns/empty-state/EmptyState.tsx +53 -0
- package/src/patterns/empty-state/index.ts +2 -0
- package/src/patterns/empty-state/types.ts +20 -0
- package/src/patterns/form-field/FormField.tsx +27 -0
- package/src/patterns/form-field/index.ts +2 -0
- package/src/patterns/form-field/types.ts +11 -0
- package/src/patterns/inspector-field/InspectorField.tsx +16 -0
- package/src/patterns/inspector-field/index.ts +2 -0
- package/src/patterns/inspector-field/types.ts +15 -0
- package/src/patterns/notice/Notice.tsx +30 -0
- package/src/patterns/notice/index.ts +2 -0
- package/src/patterns/notice/types.ts +12 -0
- package/src/patterns/panel/Panel.tsx +8 -0
- package/src/patterns/panel/index.ts +2 -0
- package/src/patterns/panel/types.ts +15 -0
- package/src/patterns/responsive-panel/ResponsivePanel.tsx +70 -0
- package/src/patterns/responsive-panel/index.ts +2 -0
- package/src/patterns/responsive-panel/types.ts +20 -0
- package/src/patterns/section-header/SectionHeader.tsx +39 -0
- package/src/patterns/section-header/index.ts +2 -0
- package/src/patterns/section-header/types.ts +9 -0
- package/src/patterns/settings-row/SettingsRow.tsx +40 -0
- package/src/patterns/settings-row/index.ts +2 -0
- package/src/patterns/settings-row/types.ts +27 -0
- package/src/patterns/switch-field/SwitchField.tsx +24 -0
- package/src/patterns/switch-field/index.ts +2 -0
- package/src/patterns/switch-field/types.ts +10 -0
- package/src/patterns/tile-grid/PaletteItem.tsx +49 -0
- package/src/patterns/tile-grid/TileGrid.tsx +44 -0
- package/src/patterns/tile-grid/index.ts +3 -0
- package/src/patterns/tile-grid/types.ts +20 -0
- package/src/patterns/tree-view/TreeItem.tsx +86 -0
- package/src/patterns/tree-view/TreeView.tsx +50 -0
- package/src/patterns/tree-view/index.ts +3 -0
- package/src/patterns/tree-view/types.ts +31 -0
- package/src/theme/ZoraProvider.tsx +22 -0
- package/src/theme/createZoraTheme.test.ts +25 -0
- package/src/theme/createZoraTheme.ts +10 -0
- package/src/theme/index.ts +6 -0
- package/src/theme/useZoraTheme.ts +5 -0
- package/src/theme/zoraTheme.ts +16 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1158,96 +1158,6 @@ const zoraTheme: ThemeConfig = {
|
|
|
1158
1158
|
|
|
1159
1159
|
</details>
|
|
1160
1160
|
|
|
1161
|
-
## Public Exports
|
|
1162
|
-
|
|
1163
|
-
Add `AppShell` to the public exports:
|
|
1164
|
-
|
|
1165
|
-
```ts
|
|
1166
|
-
export {
|
|
1167
|
-
AppShell,
|
|
1168
|
-
AuthLayout,
|
|
1169
|
-
Badge,
|
|
1170
|
-
Button,
|
|
1171
|
-
Card,
|
|
1172
|
-
CollectionEditor,
|
|
1173
|
-
ConfirmDialog,
|
|
1174
|
-
createZoraTheme,
|
|
1175
|
-
DisclosureSection,
|
|
1176
|
-
Drawer,
|
|
1177
|
-
EmptyState,
|
|
1178
|
-
FormField,
|
|
1179
|
-
IconButton,
|
|
1180
|
-
Input,
|
|
1181
|
-
InspectorField,
|
|
1182
|
-
Modal,
|
|
1183
|
-
Notice,
|
|
1184
|
-
Page,
|
|
1185
|
-
PageHeader,
|
|
1186
|
-
PageSection,
|
|
1187
|
-
PaletteItem,
|
|
1188
|
-
Panel,
|
|
1189
|
-
ResponsivePanel,
|
|
1190
|
-
SectionHeader,
|
|
1191
|
-
Select,
|
|
1192
|
-
SettingsLayout,
|
|
1193
|
-
SettingsRow,
|
|
1194
|
-
SidebarLayout,
|
|
1195
|
-
SwitchField,
|
|
1196
|
-
Tabs,
|
|
1197
|
-
Textarea,
|
|
1198
|
-
TileGrid,
|
|
1199
|
-
Toolbar,
|
|
1200
|
-
ToolbarAction,
|
|
1201
|
-
TopbarLayout,
|
|
1202
|
-
TreeView,
|
|
1203
|
-
ZoraProvider,
|
|
1204
|
-
zoraTheme,
|
|
1205
|
-
};
|
|
1206
|
-
```
|
|
1207
|
-
|
|
1208
|
-
```ts
|
|
1209
|
-
export type {
|
|
1210
|
-
AppShellProps,
|
|
1211
|
-
AuthLayoutProps,
|
|
1212
|
-
BadgeProps,
|
|
1213
|
-
ButtonProps,
|
|
1214
|
-
CardProps,
|
|
1215
|
-
CollectionEditorProps,
|
|
1216
|
-
ConfirmDialogProps,
|
|
1217
|
-
DisclosureSectionProps,
|
|
1218
|
-
DrawerProps,
|
|
1219
|
-
EmptyStateAction,
|
|
1220
|
-
EmptyStateProps,
|
|
1221
|
-
FormFieldProps,
|
|
1222
|
-
IconButtonProps,
|
|
1223
|
-
InputProps,
|
|
1224
|
-
InspectorFieldProps,
|
|
1225
|
-
ModalProps,
|
|
1226
|
-
NoticeProps,
|
|
1227
|
-
PageHeaderProps,
|
|
1228
|
-
PageProps,
|
|
1229
|
-
PageSectionProps,
|
|
1230
|
-
PaletteItemProps,
|
|
1231
|
-
PanelProps,
|
|
1232
|
-
ResponsivePanelProps,
|
|
1233
|
-
SectionHeaderProps,
|
|
1234
|
-
SelectProps,
|
|
1235
|
-
SettingsLayoutProps,
|
|
1236
|
-
SettingsRowProps,
|
|
1237
|
-
SidebarLayoutProps,
|
|
1238
|
-
SwitchFieldProps,
|
|
1239
|
-
TabsProps,
|
|
1240
|
-
TextareaProps,
|
|
1241
|
-
TileGridProps,
|
|
1242
|
-
ToolbarProps,
|
|
1243
|
-
ToolbarActionProps,
|
|
1244
|
-
TopbarLayoutProps,
|
|
1245
|
-
TreeViewProps,
|
|
1246
|
-
ZoraProviderProps,
|
|
1247
|
-
ZoraThemeOverride,
|
|
1248
|
-
};
|
|
1249
|
-
```
|
|
1250
|
-
|
|
1251
1161
|
## Example App
|
|
1252
1162
|
|
|
1253
1163
|
A complete Expo showcase lives in `examples/expo-showcase`. It renders the
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.7",
|
|
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": {
|
|
@@ -47,12 +47,16 @@
|
|
|
47
47
|
},
|
|
48
48
|
"files": [
|
|
49
49
|
"dist",
|
|
50
|
+
"src",
|
|
51
|
+
"package.json",
|
|
50
52
|
"README.md",
|
|
51
53
|
"CHANGELOG.md",
|
|
52
54
|
"LICENSE"
|
|
53
55
|
],
|
|
54
56
|
"exports": {
|
|
55
57
|
".": {
|
|
58
|
+
"react-native": "./src/index.ts",
|
|
59
|
+
"browser": "./src/index.ts",
|
|
56
60
|
"types": "./dist/index.d.ts",
|
|
57
61
|
"import": "./dist/index.js",
|
|
58
62
|
"default": "./dist/index.js"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Badge as SurfaceBadge } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { resolveBadgeRecipe } from '../../internal/recipes';
|
|
5
|
+
import type { BadgeProps } from './types';
|
|
6
|
+
|
|
7
|
+
export function Badge({ children, tone, emphasis, size, ...props }: BadgeProps) {
|
|
8
|
+
const recipe = resolveBadgeRecipe({ tone, emphasis, size });
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<SurfaceBadge
|
|
12
|
+
{...props}
|
|
13
|
+
content={children}
|
|
14
|
+
size={recipe.size}
|
|
15
|
+
tone={recipe.tone}
|
|
16
|
+
variant={recipe.variant}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BadgeProps as SurfaceBadgeProps } from '@ankhorage/surface';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { ZoraBadgeEmphasis, ZoraControlSize, ZoraTone } from '../../internal/recipes';
|
|
5
|
+
|
|
6
|
+
export interface BadgeProps extends Omit<
|
|
7
|
+
SurfaceBadgeProps,
|
|
8
|
+
'content' | 'size' | 'tone' | 'variant'
|
|
9
|
+
> {
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
tone?: ZoraTone;
|
|
12
|
+
emphasis?: ZoraBadgeEmphasis;
|
|
13
|
+
size?: ZoraControlSize;
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Button as SurfaceButton } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { resolveButtonRecipe } from '../../internal/recipes';
|
|
5
|
+
import type { ButtonProps } from './types';
|
|
6
|
+
|
|
7
|
+
export function Button({ tone, emphasis, size, ...props }: ButtonProps) {
|
|
8
|
+
const recipe = resolveButtonRecipe({ tone, emphasis, size });
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<SurfaceButton {...props} size={recipe.size} tone={recipe.tone} variant={recipe.variant} />
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ButtonIconSpec, ButtonProps as SurfaceButtonProps } from '@ankhorage/surface';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { ZoraControlSize, ZoraEmphasis, ZoraTone } from '../../internal/recipes';
|
|
5
|
+
|
|
6
|
+
export interface ButtonProps extends Omit<
|
|
7
|
+
SurfaceButtonProps,
|
|
8
|
+
'children' | 'size' | 'tone' | 'variant'
|
|
9
|
+
> {
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
tone?: ZoraTone;
|
|
12
|
+
emphasis?: ZoraEmphasis;
|
|
13
|
+
size?: ZoraControlSize;
|
|
14
|
+
leadingIcon?: ButtonIconSpec;
|
|
15
|
+
trailingIcon?: ButtonIconSpec;
|
|
16
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Box, Card as SurfaceCard, Heading, Stack, Text } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { resolveCardVariant } from '../../internal/recipes';
|
|
5
|
+
import type { CardProps } from './types';
|
|
6
|
+
|
|
7
|
+
export function Card({
|
|
8
|
+
children,
|
|
9
|
+
title,
|
|
10
|
+
description,
|
|
11
|
+
eyebrow,
|
|
12
|
+
actions,
|
|
13
|
+
footer,
|
|
14
|
+
tone = 'default',
|
|
15
|
+
compact = false,
|
|
16
|
+
onPress,
|
|
17
|
+
...props
|
|
18
|
+
}: CardProps) {
|
|
19
|
+
const hasHeader = [eyebrow, title, description, actions].some((item) => item != null);
|
|
20
|
+
const hasFooter = footer !== undefined;
|
|
21
|
+
const gap = compact ? 's' : 'm';
|
|
22
|
+
const isInteractive = Boolean(onPress) && !actions;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<SurfaceCard
|
|
26
|
+
{...props}
|
|
27
|
+
onPress={isInteractive ? onPress : undefined}
|
|
28
|
+
p={compact ? 'm' : 'l'}
|
|
29
|
+
radius="l"
|
|
30
|
+
variant={resolveCardVariant(tone)}
|
|
31
|
+
>
|
|
32
|
+
<Stack gap={gap}>
|
|
33
|
+
{hasHeader ? (
|
|
34
|
+
<Stack
|
|
35
|
+
align={{ base: 'flex-start', md: 'center' }}
|
|
36
|
+
direction={{ base: 'column', md: 'row' }}
|
|
37
|
+
gap="m"
|
|
38
|
+
justify="space-between"
|
|
39
|
+
>
|
|
40
|
+
<Box flex={1}>
|
|
41
|
+
<Stack gap="xs">
|
|
42
|
+
{eyebrow ? (
|
|
43
|
+
<Text tone="muted" variant="caption" weight="semiBold">
|
|
44
|
+
{eyebrow}
|
|
45
|
+
</Text>
|
|
46
|
+
) : null}
|
|
47
|
+
{title ? <Heading level={compact ? 4 : 3}>{title}</Heading> : null}
|
|
48
|
+
{description ? (
|
|
49
|
+
<Text tone="muted" variant="bodySmall">
|
|
50
|
+
{description}
|
|
51
|
+
</Text>
|
|
52
|
+
) : null}
|
|
53
|
+
</Stack>
|
|
54
|
+
</Box>
|
|
55
|
+
{actions ? <Box>{actions}</Box> : null}
|
|
56
|
+
</Stack>
|
|
57
|
+
) : null}
|
|
58
|
+
|
|
59
|
+
{children ? <Box>{children}</Box> : null}
|
|
60
|
+
|
|
61
|
+
{hasFooter ? <Box pt="xs">{footer}</Box> : null}
|
|
62
|
+
</Stack>
|
|
63
|
+
</SurfaceCard>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CardProps as SurfaceCardProps } from '@ankhorage/surface';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { ZoraCardTone } from '../../internal/recipes';
|
|
5
|
+
|
|
6
|
+
export interface CardProps extends Omit<SurfaceCardProps, 'children' | 'p' | 'radius' | 'variant'> {
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
title?: React.ReactNode;
|
|
9
|
+
description?: React.ReactNode;
|
|
10
|
+
eyebrow?: React.ReactNode;
|
|
11
|
+
actions?: React.ReactNode;
|
|
12
|
+
footer?: React.ReactNode;
|
|
13
|
+
tone?: ZoraCardTone;
|
|
14
|
+
compact?: boolean;
|
|
15
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Box, Drawer as SurfaceDrawer, Heading, Stack, Text } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { DrawerProps } from './types';
|
|
5
|
+
|
|
6
|
+
export function Drawer({ children, title, description, footer, ...props }: DrawerProps) {
|
|
7
|
+
const hasHeader = title != null || description != null;
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<SurfaceDrawer {...props}>
|
|
11
|
+
<Stack gap="m">
|
|
12
|
+
{hasHeader ? (
|
|
13
|
+
<Stack gap="xs">
|
|
14
|
+
{title ? <Heading level={3}>{title}</Heading> : null}
|
|
15
|
+
{description ? (
|
|
16
|
+
<Text tone="muted" variant="bodySmall">
|
|
17
|
+
{description}
|
|
18
|
+
</Text>
|
|
19
|
+
) : null}
|
|
20
|
+
</Stack>
|
|
21
|
+
) : null}
|
|
22
|
+
{children ? <Box flex={1}>{children}</Box> : null}
|
|
23
|
+
{footer ? <Box pt="xs">{footer}</Box> : null}
|
|
24
|
+
</Stack>
|
|
25
|
+
</SurfaceDrawer>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DrawerProps as SurfaceDrawerProps } from '@ankhorage/surface';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
|
|
4
|
+
export interface DrawerProps extends Pick<
|
|
5
|
+
SurfaceDrawerProps,
|
|
6
|
+
'closeOnBackdrop' | 'onDismiss' | 'position' | 'testID' | 'visible'
|
|
7
|
+
> {
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
title?: React.ReactNode;
|
|
10
|
+
description?: React.ReactNode;
|
|
11
|
+
footer?: React.ReactNode;
|
|
12
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { IconButton as SurfaceIconButton } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { resolveButtonRecipe } from '../../internal/recipes';
|
|
5
|
+
import type { IconButtonProps } from './types';
|
|
6
|
+
|
|
7
|
+
export function IconButton({
|
|
8
|
+
icon,
|
|
9
|
+
label,
|
|
10
|
+
emphasis = 'ghost',
|
|
11
|
+
tone = 'neutral',
|
|
12
|
+
size = 'm',
|
|
13
|
+
...props
|
|
14
|
+
}: IconButtonProps) {
|
|
15
|
+
const recipe = resolveButtonRecipe({ emphasis, tone, size });
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<SurfaceIconButton
|
|
19
|
+
{...props}
|
|
20
|
+
icon={icon}
|
|
21
|
+
accessibilityLabel={label}
|
|
22
|
+
size={recipe.size}
|
|
23
|
+
tone={recipe.tone}
|
|
24
|
+
variant={recipe.variant}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ButtonIconSpec } from '@ankhorage/surface';
|
|
2
|
+
|
|
3
|
+
import type { ZoraControlSize, ZoraEmphasis, ZoraTone } from '../../internal/recipes';
|
|
4
|
+
|
|
5
|
+
export interface IconButtonProps {
|
|
6
|
+
icon: ButtonIconSpec;
|
|
7
|
+
label: string;
|
|
8
|
+
emphasis?: ZoraEmphasis;
|
|
9
|
+
tone?: ZoraTone;
|
|
10
|
+
size?: ZoraControlSize;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
loading?: boolean;
|
|
13
|
+
onPress?: () => void;
|
|
14
|
+
testID?: string;
|
|
15
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Icon, TextInput as SurfaceTextInput, useTheme } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { resolveIconSize } from '../../internal/recipes';
|
|
5
|
+
import type { InputProps } from './types';
|
|
6
|
+
|
|
7
|
+
export function Input({ size = 'l', leadingIcon, trailingIcon, ...props }: InputProps) {
|
|
8
|
+
const { theme } = useTheme();
|
|
9
|
+
const iconSize = resolveIconSize(size);
|
|
10
|
+
const iconColor = theme.semantics.content.muted;
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<SurfaceTextInput
|
|
14
|
+
{...props}
|
|
15
|
+
leadingAccessory={
|
|
16
|
+
leadingIcon ? (
|
|
17
|
+
<Icon
|
|
18
|
+
color={iconColor}
|
|
19
|
+
name={leadingIcon.name}
|
|
20
|
+
provider={leadingIcon.provider}
|
|
21
|
+
size={iconSize}
|
|
22
|
+
/>
|
|
23
|
+
) : undefined
|
|
24
|
+
}
|
|
25
|
+
size={size}
|
|
26
|
+
trailingAccessory={
|
|
27
|
+
trailingIcon ? (
|
|
28
|
+
<Icon
|
|
29
|
+
color={iconColor}
|
|
30
|
+
name={trailingIcon.name}
|
|
31
|
+
provider={trailingIcon.provider}
|
|
32
|
+
size={iconSize}
|
|
33
|
+
/>
|
|
34
|
+
) : undefined
|
|
35
|
+
}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ButtonIconSpec, TextInputProps as SurfaceTextInputProps } from '@ankhorage/surface';
|
|
2
|
+
|
|
3
|
+
import type { ZoraControlSize } from '../../internal/recipes';
|
|
4
|
+
|
|
5
|
+
export interface InputProps extends Omit<
|
|
6
|
+
SurfaceTextInputProps,
|
|
7
|
+
'leadingAccessory' | 'size' | 'trailingAccessory'
|
|
8
|
+
> {
|
|
9
|
+
size?: ZoraControlSize;
|
|
10
|
+
leadingIcon?: ButtonIconSpec;
|
|
11
|
+
trailingIcon?: ButtonIconSpec;
|
|
12
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Box, Heading, Modal as SurfaceModal, Stack, Text } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { resolveDialogWidth } from '../../internal/recipes';
|
|
5
|
+
import type { ModalProps } from './types';
|
|
6
|
+
|
|
7
|
+
export function Modal({
|
|
8
|
+
children,
|
|
9
|
+
title,
|
|
10
|
+
description,
|
|
11
|
+
footer,
|
|
12
|
+
width = 'default',
|
|
13
|
+
...props
|
|
14
|
+
}: ModalProps) {
|
|
15
|
+
const hasHeader = title != null || description != null;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<SurfaceModal {...props}>
|
|
19
|
+
<Box maxWidth={resolveDialogWidth(width)} style={{ alignSelf: 'center', width: '100%' }}>
|
|
20
|
+
<Stack gap="m">
|
|
21
|
+
{hasHeader ? (
|
|
22
|
+
<Stack gap="xs">
|
|
23
|
+
{title ? <Heading level={3}>{title}</Heading> : null}
|
|
24
|
+
{description ? (
|
|
25
|
+
<Text tone="muted" variant="bodySmall">
|
|
26
|
+
{description}
|
|
27
|
+
</Text>
|
|
28
|
+
) : null}
|
|
29
|
+
</Stack>
|
|
30
|
+
) : null}
|
|
31
|
+
{children ? <Box>{children}</Box> : null}
|
|
32
|
+
{footer ? <Box pt="xs">{footer}</Box> : null}
|
|
33
|
+
</Stack>
|
|
34
|
+
</Box>
|
|
35
|
+
</SurfaceModal>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ModalProps as SurfaceModalProps } from '@ankhorage/surface';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { ZoraContentWidth } from '../../internal/recipes';
|
|
5
|
+
|
|
6
|
+
export interface ModalProps extends Pick<
|
|
7
|
+
SurfaceModalProps,
|
|
8
|
+
'closeOnBackdrop' | 'onDismiss' | 'testID' | 'visible'
|
|
9
|
+
> {
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
title?: React.ReactNode;
|
|
12
|
+
description?: React.ReactNode;
|
|
13
|
+
footer?: React.ReactNode;
|
|
14
|
+
width?: ZoraContentWidth;
|
|
15
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Box, useTheme } from '@ankhorage/surface';
|
|
2
|
+
import { Picker } from '@react-native-picker/picker';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import type { SelectProps } from './types';
|
|
6
|
+
|
|
7
|
+
export function Select<TValue extends string = string>({
|
|
8
|
+
value,
|
|
9
|
+
options,
|
|
10
|
+
onValueChange,
|
|
11
|
+
disabled,
|
|
12
|
+
invalid,
|
|
13
|
+
testID,
|
|
14
|
+
}: SelectProps<TValue>) {
|
|
15
|
+
const { theme } = useTheme();
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Box
|
|
19
|
+
bg="surface"
|
|
20
|
+
borderColor={invalid ? theme.colors.error : theme.colors.border}
|
|
21
|
+
borderWidth={1}
|
|
22
|
+
opacity={disabled ? 0.5 : 1}
|
|
23
|
+
radius="m"
|
|
24
|
+
testID={testID}
|
|
25
|
+
>
|
|
26
|
+
<Picker
|
|
27
|
+
enabled={!disabled}
|
|
28
|
+
onValueChange={(itemValue) => onValueChange(itemValue)}
|
|
29
|
+
selectedValue={value}
|
|
30
|
+
style={{
|
|
31
|
+
height: 44,
|
|
32
|
+
width: '100%',
|
|
33
|
+
backgroundColor: 'transparent',
|
|
34
|
+
color: theme.colors.text,
|
|
35
|
+
borderWidth: 0,
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
{options.map((option) => (
|
|
39
|
+
<Picker.Item
|
|
40
|
+
key={option.value}
|
|
41
|
+
enabled={!option.disabled}
|
|
42
|
+
label={option.label}
|
|
43
|
+
value={option.value}
|
|
44
|
+
/>
|
|
45
|
+
))}
|
|
46
|
+
</Picker>
|
|
47
|
+
</Box>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface SelectOption<TValue extends string = string> {
|
|
2
|
+
value: TValue;
|
|
3
|
+
label: string;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface SelectProps<TValue extends string = string> {
|
|
8
|
+
value: TValue;
|
|
9
|
+
options: readonly SelectOption<TValue>[];
|
|
10
|
+
onValueChange: (value: TValue) => void;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
invalid?: boolean;
|
|
13
|
+
testID?: string;
|
|
14
|
+
}
|