@ankhorage/zora 13.0.0 → 14.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +182 -6
- package/dist/features/accordion/adapters/inbound/Accordion.js +4 -4
- package/dist/features/accordion/adapters/inbound/Accordion.js.map +1 -1
- package/dist/features/accordion/adapters/inbound/AccordionItem.js +1 -1
- package/dist/features/accordion/adapters/inbound/AccordionItem.js.map +1 -1
- package/dist/features/app-bar/adapters/inbound/AppBar.d.ts +5 -0
- package/dist/features/app-bar/adapters/inbound/AppBar.d.ts.map +1 -0
- package/dist/features/app-bar/adapters/inbound/AppBar.js +91 -0
- package/dist/features/app-bar/adapters/inbound/AppBar.js.map +1 -0
- package/dist/{components/app-bar/meta.d.ts → features/app-bar/appBarMeta.d.ts} +1 -1
- package/dist/features/app-bar/appBarMeta.d.ts.map +1 -0
- package/dist/{components/app-bar/meta.js → features/app-bar/appBarMeta.js} +1 -1
- package/dist/features/app-bar/appBarMeta.js.map +1 -0
- package/dist/features/app-bar/public.d.ts +3 -0
- package/dist/features/app-bar/public.d.ts.map +1 -0
- package/dist/features/app-bar/public.js +2 -0
- package/dist/features/app-bar/public.js.map +1 -0
- package/dist/features/date-picker/adapters/inbound/DatePicker.d.ts +1 -6
- package/dist/features/date-picker/adapters/inbound/DatePicker.d.ts.map +1 -1
- package/dist/features/date-picker/adapters/inbound/DatePicker.js +1 -175
- package/dist/features/date-picker/adapters/inbound/DatePicker.js.map +1 -1
- package/dist/features/date-picker/adapters/inbound/DatePicker.native.d.ts +5 -0
- package/dist/features/date-picker/adapters/inbound/DatePicker.native.d.ts.map +1 -0
- package/dist/features/date-picker/adapters/inbound/DatePicker.native.js +27 -0
- package/dist/features/date-picker/adapters/inbound/DatePicker.native.js.map +1 -0
- package/dist/features/date-picker/adapters/inbound/DatePicker.web.d.ts +5 -0
- package/dist/features/date-picker/adapters/inbound/DatePicker.web.d.ts.map +1 -0
- package/dist/features/date-picker/adapters/inbound/DatePicker.web.js +25 -0
- package/dist/features/date-picker/adapters/inbound/DatePicker.web.js.map +1 -0
- package/dist/features/date-picker/composition/DatePickerContent.d.ts +10 -0
- package/dist/features/date-picker/composition/DatePickerContent.d.ts.map +1 -0
- package/dist/features/date-picker/composition/DatePickerContent.js +129 -0
- package/dist/features/date-picker/composition/DatePickerContent.js.map +1 -0
- package/dist/features/date-picker/composition/DatePickerField.d.ts +9 -0
- package/dist/features/date-picker/composition/DatePickerField.d.ts.map +1 -0
- package/dist/features/date-picker/composition/DatePickerField.js +21 -0
- package/dist/features/date-picker/composition/DatePickerField.js.map +1 -0
- package/dist/features/date-picker/composition/DatePickerTrigger.d.ts +9 -0
- package/dist/features/date-picker/composition/DatePickerTrigger.d.ts.map +1 -0
- package/dist/features/date-picker/composition/DatePickerTrigger.js +18 -0
- package/dist/features/date-picker/composition/DatePickerTrigger.js.map +1 -0
- package/dist/features/time-picker/adapters/inbound/TimePicker.d.ts +1 -6
- package/dist/features/time-picker/adapters/inbound/TimePicker.d.ts.map +1 -1
- package/dist/features/time-picker/adapters/inbound/TimePicker.js +1 -116
- package/dist/features/time-picker/adapters/inbound/TimePicker.js.map +1 -1
- package/dist/features/time-picker/adapters/inbound/TimePicker.native.d.ts +5 -0
- package/dist/features/time-picker/adapters/inbound/TimePicker.native.d.ts.map +1 -0
- package/dist/features/time-picker/adapters/inbound/TimePicker.native.js +26 -0
- package/dist/features/time-picker/adapters/inbound/TimePicker.native.js.map +1 -0
- package/dist/features/time-picker/adapters/inbound/TimePicker.web.d.ts +5 -0
- package/dist/features/time-picker/adapters/inbound/TimePicker.web.d.ts.map +1 -0
- package/dist/features/time-picker/adapters/inbound/TimePicker.web.js +24 -0
- package/dist/features/time-picker/adapters/inbound/TimePicker.web.js.map +1 -0
- package/dist/features/time-picker/composition/TimePickerContent.d.ts +10 -0
- package/dist/features/time-picker/composition/TimePickerContent.d.ts.map +1 -0
- package/dist/features/time-picker/composition/TimePickerContent.js +78 -0
- package/dist/features/time-picker/composition/TimePickerContent.js.map +1 -0
- package/dist/features/time-picker/composition/TimePickerField.d.ts +9 -0
- package/dist/features/time-picker/composition/TimePickerField.d.ts.map +1 -0
- package/dist/features/time-picker/composition/TimePickerField.js +21 -0
- package/dist/features/time-picker/composition/TimePickerField.js.map +1 -0
- package/dist/features/time-picker/composition/TimePickerTrigger.d.ts +8 -0
- package/dist/features/time-picker/composition/TimePickerTrigger.d.ts.map +1 -0
- package/dist/features/time-picker/composition/TimePickerTrigger.js +9 -0
- package/dist/features/time-picker/composition/TimePickerTrigger.js.map +1 -0
- package/dist/features/toast/adapters/inbound/Toast.d.ts +5 -0
- package/dist/features/toast/adapters/inbound/Toast.d.ts.map +1 -0
- package/dist/features/toast/adapters/inbound/Toast.js +10 -0
- package/dist/features/toast/adapters/inbound/Toast.js.map +1 -0
- package/dist/features/toast/adapters/inbound/ToastProvider.d.ts +5 -0
- package/dist/features/toast/adapters/inbound/ToastProvider.d.ts.map +1 -0
- package/dist/features/toast/adapters/inbound/ToastProvider.js +7 -0
- package/dist/features/toast/adapters/inbound/ToastProvider.js.map +1 -0
- package/dist/features/toast/public.d.ts +5 -0
- package/dist/features/toast/public.d.ts.map +1 -0
- package/dist/features/toast/public.js +4 -0
- package/dist/features/toast/public.js.map +1 -0
- package/dist/features/toast/toastMeta.d.ts +9 -0
- package/dist/features/toast/toastMeta.d.ts.map +1 -0
- package/dist/features/toast/toastMeta.js +9 -0
- package/dist/features/toast/toastMeta.js.map +1 -0
- package/dist/features/toast/toastProviderMeta.d.ts +9 -0
- package/dist/features/toast/toastProviderMeta.d.ts.map +1 -0
- package/dist/features/toast/toastProviderMeta.js +9 -0
- package/dist/features/toast/toastProviderMeta.js.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/layout/settings-layout/SettingsLayout.d.ts +0 -2
- package/dist/layout/settings-layout/SettingsLayout.d.ts.map +1 -1
- package/dist/layout/settings-layout/SettingsLayout.js +1 -3
- package/dist/layout/settings-layout/SettingsLayout.js.map +1 -1
- package/dist/metadata/componentMeta.d.ts.map +1 -1
- package/dist/metadata/componentMeta.js +3 -2
- package/dist/metadata/componentMeta.js.map +1 -1
- package/dist/patterns/reader/ReaderSurface.js +1 -1
- package/dist/patterns/reader/ReaderSurface.js.map +1 -1
- package/dist/patterns/selection/SelectionProvider.d.ts +0 -4
- package/dist/patterns/selection/SelectionProvider.d.ts.map +1 -1
- package/dist/patterns/selection/SelectionProvider.js +4 -6
- package/dist/patterns/selection/SelectionProvider.js.map +1 -1
- package/dist/registry.js +2 -2
- package/dist/registry.js.map +1 -1
- package/dist/theme/ZoraProvider.d.ts +4 -10
- package/dist/theme/ZoraProvider.d.ts.map +1 -1
- package/dist/theme/ZoraProvider.js +8 -6
- package/dist/theme/ZoraProvider.js.map +1 -1
- package/dist/theme/ZoraRuntimeCapabilities.d.ts +2 -0
- package/dist/theme/ZoraRuntimeCapabilities.d.ts.map +1 -0
- package/dist/theme/ZoraRuntimeCapabilities.js +2 -0
- package/dist/theme/ZoraRuntimeCapabilities.js.map +1 -0
- package/dist/theme/ZoraRuntimeCapabilities.native.d.ts +4 -0
- package/dist/theme/ZoraRuntimeCapabilities.native.d.ts.map +1 -0
- package/dist/theme/ZoraRuntimeCapabilities.native.js +8 -0
- package/dist/theme/ZoraRuntimeCapabilities.native.js.map +1 -0
- package/dist/theme/ZoraRuntimeCapabilities.web.d.ts +4 -0
- package/dist/theme/ZoraRuntimeCapabilities.web.d.ts.map +1 -0
- package/dist/theme/ZoraRuntimeCapabilities.web.js +8 -0
- package/dist/theme/ZoraRuntimeCapabilities.web.js.map +1 -0
- package/dist/theme/ZoraThemeRuntimeContext.d.ts +1 -0
- package/dist/theme/ZoraThemeRuntimeContext.d.ts.map +1 -1
- package/dist/theme/ZoraThemeRuntimeContext.js +3 -2
- package/dist/theme/ZoraThemeRuntimeContext.js.map +1 -1
- package/dist/theme/ZoraThemeScope.d.ts +1 -0
- package/dist/theme/ZoraThemeScope.d.ts.map +1 -1
- package/dist/theme/ZoraThemeScope.js +12 -10
- package/dist/theme/ZoraThemeScope.js.map +1 -1
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/{components/app-bar/types.d.ts → types/app-bar.d.ts} +2 -2
- package/dist/types/app-bar.d.ts.map +1 -0
- package/dist/types/app-bar.js +2 -0
- package/dist/types/app-bar.js.map +1 -0
- package/dist/types/provider.d.ts +19 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/provider.js +2 -0
- package/dist/types/provider.js.map +1 -0
- package/dist/types/toast.d.ts +9 -0
- package/dist/types/toast.d.ts.map +1 -0
- package/dist/types/toast.js +2 -0
- package/dist/types/toast.js.map +1 -0
- package/package.json +2 -2
- package/src/features/accordion/adapters/inbound/Accordion.tsx +4 -4
- package/src/features/accordion/adapters/inbound/AccordionItem.tsx +1 -1
- package/src/features/app-bar/adapters/inbound/AppBar.tsx +176 -0
- package/src/features/app-bar/public.ts +2 -0
- package/src/features/bottom-sheet/public.test.ts +15 -12
- package/src/features/date-picker/adapters/inbound/DatePicker.native.tsx +46 -0
- package/src/features/date-picker/adapters/inbound/DatePicker.tsx +1 -356
- package/src/features/date-picker/adapters/inbound/DatePicker.web.tsx +48 -0
- package/src/features/date-picker/composition/DatePickerContent.tsx +256 -0
- package/src/features/date-picker/composition/DatePickerField.tsx +53 -0
- package/src/features/date-picker/composition/DatePickerTrigger.tsx +47 -0
- package/src/features/date-picker/public.test.ts +14 -4
- package/src/features/time-picker/adapters/inbound/TimePicker.native.tsx +47 -0
- package/src/features/time-picker/adapters/inbound/TimePicker.tsx +1 -258
- package/src/features/time-picker/adapters/inbound/TimePicker.web.tsx +49 -0
- package/src/features/time-picker/composition/TimePickerContent.tsx +164 -0
- package/src/features/time-picker/composition/TimePickerField.tsx +53 -0
- package/src/features/time-picker/composition/TimePickerTrigger.tsx +35 -0
- package/src/features/time-picker/public.test.ts +14 -3
- package/src/features/toast/adapters/inbound/Toast.tsx +13 -0
- package/src/features/toast/adapters/inbound/ToastProvider.tsx +9 -0
- package/src/features/toast/public.test.ts +19 -0
- package/src/features/toast/public.ts +10 -0
- package/src/features/toast/toastMeta.ts +10 -0
- package/src/features/toast/toastProviderMeta.ts +10 -0
- package/src/index.ts +10 -4
- package/src/interactionPolicy.test.ts +7 -3
- package/src/layout/settings-layout/SettingsLayout.tsx +1 -3
- package/src/metadata/componentMeta.ts +3 -2
- package/src/patterns/reader/ReaderSurface.tsx +1 -1
- package/src/patterns/selection/SelectionProvider.tsx +4 -6
- package/src/registry.ts +2 -2
- package/src/theme/ZoraProvider.tsx +11 -13
- package/src/theme/ZoraRuntimeCapabilities.native.tsx +19 -0
- package/src/theme/ZoraRuntimeCapabilities.tsx +1 -0
- package/src/theme/ZoraRuntimeCapabilities.web.tsx +10 -0
- package/src/theme/ZoraThemeRuntimeContext.tsx +3 -2
- package/src/theme/ZoraThemeScope.tsx +14 -12
- package/src/theme/index.ts +1 -1
- package/src/theme/themeConfigScope.test.ts +4 -1
- package/src/theme/themeScopeStructure.test.ts +26 -18
- package/src/{components/app-bar/types.ts → types/app-bar.ts} +1 -1
- package/src/types/provider.ts +22 -0
- package/src/{components/toast/types.ts → types/toast.ts} +5 -7
- package/dist/components/app-bar/AppBar.d.ts +0 -7
- package/dist/components/app-bar/AppBar.d.ts.map +0 -1
- package/dist/components/app-bar/AppBar.js +0 -67
- package/dist/components/app-bar/AppBar.js.map +0 -1
- package/dist/components/app-bar/index.d.ts +0 -3
- package/dist/components/app-bar/index.d.ts.map +0 -1
- package/dist/components/app-bar/index.js +0 -3
- package/dist/components/app-bar/index.js.map +0 -1
- package/dist/components/app-bar/meta.d.ts.map +0 -1
- package/dist/components/app-bar/meta.js.map +0 -1
- package/dist/components/app-bar/types.d.ts.map +0 -1
- package/dist/components/app-bar/types.js +0 -2
- package/dist/components/app-bar/types.js.map +0 -1
- package/dist/components/toast/Toast.d.ts +0 -9
- package/dist/components/toast/Toast.d.ts.map +0 -1
- package/dist/components/toast/Toast.js +0 -13
- package/dist/components/toast/Toast.js.map +0 -1
- package/dist/components/toast/ToastProvider.d.ts +0 -9
- package/dist/components/toast/ToastProvider.d.ts.map +0 -1
- package/dist/components/toast/ToastProvider.js +0 -14
- package/dist/components/toast/ToastProvider.js.map +0 -1
- package/dist/components/toast/index.d.ts +0 -5
- package/dist/components/toast/index.d.ts.map +0 -1
- package/dist/components/toast/index.js +0 -4
- package/dist/components/toast/index.js.map +0 -1
- package/dist/components/toast/meta.d.ts +0 -17
- package/dist/components/toast/meta.d.ts.map +0 -1
- package/dist/components/toast/meta.js +0 -17
- package/dist/components/toast/meta.js.map +0 -1
- package/dist/components/toast/types.d.ts +0 -12
- package/dist/components/toast/types.d.ts.map +0 -1
- package/dist/components/toast/types.js +0 -2
- package/dist/components/toast/types.js.map +0 -1
- package/src/components/app-bar/AppBar.tsx +0 -140
- package/src/components/app-bar/index.ts +0 -2
- package/src/components/toast/Toast.tsx +0 -16
- package/src/components/toast/ToastProvider.tsx +0 -17
- package/src/components/toast/index.ts +0 -4
- package/src/components/toast/meta.ts +0 -19
- /package/src/{components/app-bar/meta.ts → features/app-bar/appBarMeta.ts} +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Popover } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
5
|
+
import type { TimePickerProps } from '../../../../types/time-picker';
|
|
6
|
+
import { Surface } from '../../../surface/public';
|
|
7
|
+
import { TimePickerContent } from '../../composition/TimePickerContent';
|
|
8
|
+
import { TimePickerField } from '../../composition/TimePickerField';
|
|
9
|
+
import { TimePickerTrigger } from '../../composition/TimePickerTrigger';
|
|
10
|
+
|
|
11
|
+
/*** Renders TimePicker with anchored web Popover presentation. */
|
|
12
|
+
export const TimePicker = withZoraThemeScope(TimePickerInner);
|
|
13
|
+
|
|
14
|
+
/*** Connects the shared TimePicker field and content to the web Popover host. */
|
|
15
|
+
function TimePickerInner({ themeId: _themeId, mode: _mode, ...props }: TimePickerProps) {
|
|
16
|
+
const [open, setOpen] = React.useState(false);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<TimePickerField {...props}>
|
|
20
|
+
<Popover
|
|
21
|
+
anchor={({ toggle }) => <TimePickerTrigger {...props} onPress={toggle} />}
|
|
22
|
+
interactionPolicy={props.interactionPolicy}
|
|
23
|
+
onOpenChange={setOpen}
|
|
24
|
+
open={open}
|
|
25
|
+
placement="bottom-start"
|
|
26
|
+
testID={props.testID ? `${props.testID}-popover` : undefined}
|
|
27
|
+
>
|
|
28
|
+
<Surface variant="raised">
|
|
29
|
+
<TimePickerContent
|
|
30
|
+
description={props.description}
|
|
31
|
+
formatTime={props.formatTime}
|
|
32
|
+
interactionPolicy={props.interactionPolicy}
|
|
33
|
+
label={props.label}
|
|
34
|
+
maxTime={props.maxTime}
|
|
35
|
+
minTime={props.minTime}
|
|
36
|
+
onDismiss={() => setOpen(false)}
|
|
37
|
+
onSelect={(time) => {
|
|
38
|
+
props.onValueChange?.(time);
|
|
39
|
+
setOpen(false);
|
|
40
|
+
}}
|
|
41
|
+
stepMinutes={props.stepMinutes}
|
|
42
|
+
testID={props.testID}
|
|
43
|
+
value={props.value}
|
|
44
|
+
/>
|
|
45
|
+
</Surface>
|
|
46
|
+
</Popover>
|
|
47
|
+
</TimePickerField>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ScrollView, StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { TimePickerProps } from '../../../types/time-picker';
|
|
5
|
+
import { Button } from '../../button/public';
|
|
6
|
+
import { Stack } from '../../layout/public';
|
|
7
|
+
import { Text } from '../../typography/public';
|
|
8
|
+
|
|
9
|
+
const MINUTES_PER_DAY = 24 * 60;
|
|
10
|
+
const DEFAULT_STEP_MINUTES = 30;
|
|
11
|
+
|
|
12
|
+
/*** Renders shared time options for native BottomSheet and web Popover hosts. */
|
|
13
|
+
export function TimePickerContent({
|
|
14
|
+
description,
|
|
15
|
+
formatTime,
|
|
16
|
+
interactionPolicy,
|
|
17
|
+
label,
|
|
18
|
+
maxTime,
|
|
19
|
+
minTime,
|
|
20
|
+
onDismiss,
|
|
21
|
+
onSelect,
|
|
22
|
+
stepMinutes,
|
|
23
|
+
testID,
|
|
24
|
+
value,
|
|
25
|
+
}: TimePickerContentProps) {
|
|
26
|
+
const options = React.useMemo(
|
|
27
|
+
() => generateTimeOptions({ maxTime, minTime, stepMinutes }),
|
|
28
|
+
[maxTime, minTime, stepMinutes],
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Stack gap="m" p="m" testID={testID ? `${testID}-content` : undefined}>
|
|
33
|
+
<PickerHeader description={description} title={label ?? 'Choose time'} />
|
|
34
|
+
<ScrollView style={styles.options}>
|
|
35
|
+
<Stack gap="xxs">
|
|
36
|
+
{options.map((option) => (
|
|
37
|
+
<TimePickerOption
|
|
38
|
+
formatTime={formatTime}
|
|
39
|
+
interactionPolicy={interactionPolicy}
|
|
40
|
+
key={option}
|
|
41
|
+
onSelect={onSelect}
|
|
42
|
+
option={option}
|
|
43
|
+
selected={option === value}
|
|
44
|
+
testID={testID}
|
|
45
|
+
/>
|
|
46
|
+
))}
|
|
47
|
+
</Stack>
|
|
48
|
+
</ScrollView>
|
|
49
|
+
<Button fullWidth interactionPolicy={interactionPolicy} onPress={onDismiss} variant="ghost">
|
|
50
|
+
Cancel
|
|
51
|
+
</Button>
|
|
52
|
+
</Stack>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface TimePickerContentProps extends Pick<
|
|
57
|
+
TimePickerProps,
|
|
58
|
+
| 'description'
|
|
59
|
+
| 'formatTime'
|
|
60
|
+
| 'interactionPolicy'
|
|
61
|
+
| 'label'
|
|
62
|
+
| 'maxTime'
|
|
63
|
+
| 'minTime'
|
|
64
|
+
| 'stepMinutes'
|
|
65
|
+
| 'testID'
|
|
66
|
+
| 'value'
|
|
67
|
+
> {
|
|
68
|
+
onDismiss: () => void;
|
|
69
|
+
onSelect: (value: string) => void;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/*** Renders the shared title block used by picker overlays. */
|
|
73
|
+
function PickerHeader({
|
|
74
|
+
description,
|
|
75
|
+
title,
|
|
76
|
+
}: {
|
|
77
|
+
description: React.ReactNode | undefined;
|
|
78
|
+
title: React.ReactNode;
|
|
79
|
+
}) {
|
|
80
|
+
return (
|
|
81
|
+
<Stack gap="xxs">
|
|
82
|
+
<Text align="center" variant="label" weight="semiBold">
|
|
83
|
+
{title}
|
|
84
|
+
</Text>
|
|
85
|
+
{description ? (
|
|
86
|
+
<Text align="center" emphasis="muted" variant="bodySmall">
|
|
87
|
+
{description}
|
|
88
|
+
</Text>
|
|
89
|
+
) : null}
|
|
90
|
+
</Stack>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/*** Renders one accessible selectable time option. */
|
|
95
|
+
function TimePickerOption({
|
|
96
|
+
formatTime,
|
|
97
|
+
interactionPolicy,
|
|
98
|
+
onSelect,
|
|
99
|
+
option,
|
|
100
|
+
selected,
|
|
101
|
+
testID,
|
|
102
|
+
}: Pick<TimePickerContentProps, 'formatTime' | 'interactionPolicy' | 'testID'> & {
|
|
103
|
+
onSelect: (value: string) => void;
|
|
104
|
+
option: string;
|
|
105
|
+
selected: boolean;
|
|
106
|
+
}) {
|
|
107
|
+
return (
|
|
108
|
+
<Button
|
|
109
|
+
accessibilityState={{ selected }}
|
|
110
|
+
fullWidth
|
|
111
|
+
interactionPolicy={interactionPolicy}
|
|
112
|
+
onPress={() => onSelect(option)}
|
|
113
|
+
testID={testID ? `${testID}-option-${option}` : undefined}
|
|
114
|
+
variant={selected ? 'soft' : 'ghost'}
|
|
115
|
+
>
|
|
116
|
+
{formatTime ? formatTime(option) : option}
|
|
117
|
+
</Button>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/*** Parses one HH:mm value to minutes since midnight. */
|
|
122
|
+
function parseTimeToMinutes(value: string | undefined): number | undefined {
|
|
123
|
+
if (!value) return undefined;
|
|
124
|
+
const match = /^(\d{2}):(\d{2})$/.exec(value);
|
|
125
|
+
if (!match) return undefined;
|
|
126
|
+
|
|
127
|
+
const hours = Number(match[1]);
|
|
128
|
+
const minutes = Number(match[2]);
|
|
129
|
+
if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return undefined;
|
|
130
|
+
return hours * 60 + minutes;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/*** Formats minutes since midnight as HH:mm. */
|
|
134
|
+
function formatMinutes(value: number): string {
|
|
135
|
+
const hours = Math.floor(value / 60);
|
|
136
|
+
const minutes = value % 60;
|
|
137
|
+
return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/*** Normalizes the configured time step to a positive whole minute. */
|
|
141
|
+
function resolveStepMinutes(stepMinutes: number | undefined): number {
|
|
142
|
+
if (stepMinutes === undefined || !Number.isFinite(stepMinutes) || stepMinutes <= 0) {
|
|
143
|
+
return DEFAULT_STEP_MINUTES;
|
|
144
|
+
}
|
|
145
|
+
return Math.max(1, Math.floor(stepMinutes));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/*** Generates selectable HH:mm values within the configured range. */
|
|
149
|
+
function generateTimeOptions({
|
|
150
|
+
minTime,
|
|
151
|
+
maxTime,
|
|
152
|
+
stepMinutes,
|
|
153
|
+
}: Pick<TimePickerProps, 'maxTime' | 'minTime' | 'stepMinutes'>): string[] {
|
|
154
|
+
const step = resolveStepMinutes(stepMinutes);
|
|
155
|
+
const min = parseTimeToMinutes(minTime) ?? 0;
|
|
156
|
+
const max = parseTimeToMinutes(maxTime) ?? MINUTES_PER_DAY - 1;
|
|
157
|
+
return Array.from({ length: Math.ceil(MINUTES_PER_DAY / step) }, (_, index) => index * step)
|
|
158
|
+
.filter((minute) => minute >= min && minute <= max)
|
|
159
|
+
.map(formatMinutes);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const styles = StyleSheet.create({
|
|
163
|
+
options: { maxHeight: 360 },
|
|
164
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Field } from '@ankhorage/surface';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { TimePickerProps } from '../../../types/time-picker';
|
|
5
|
+
import { Stack } from '../../layout/public';
|
|
6
|
+
import { Text } from '../../typography/public';
|
|
7
|
+
|
|
8
|
+
/*** Renders the shared TimePicker field frame around a platform-specific trigger. */
|
|
9
|
+
export function TimePickerField({
|
|
10
|
+
children,
|
|
11
|
+
description,
|
|
12
|
+
disabled,
|
|
13
|
+
error,
|
|
14
|
+
label,
|
|
15
|
+
required,
|
|
16
|
+
testID,
|
|
17
|
+
}: TimePickerFieldProps) {
|
|
18
|
+
return (
|
|
19
|
+
<Field
|
|
20
|
+
disabled={disabled}
|
|
21
|
+
errorText={error}
|
|
22
|
+
invalid={Boolean(error)}
|
|
23
|
+
label={label ? renderLabel(label, description) : undefined}
|
|
24
|
+
required={required}
|
|
25
|
+
testID={testID}
|
|
26
|
+
>
|
|
27
|
+
{children}
|
|
28
|
+
</Field>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface TimePickerFieldProps extends Pick<
|
|
33
|
+
TimePickerProps,
|
|
34
|
+
'description' | 'disabled' | 'error' | 'label' | 'required' | 'testID'
|
|
35
|
+
> {
|
|
36
|
+
children: React.ReactNode;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/*** Renders the picker label and optional supporting description. */
|
|
40
|
+
function renderLabel(label: React.ReactNode, description: React.ReactNode | undefined) {
|
|
41
|
+
return (
|
|
42
|
+
<Stack gap="xs">
|
|
43
|
+
<Text variant="label" weight="semiBold">
|
|
44
|
+
{label}
|
|
45
|
+
</Text>
|
|
46
|
+
{description ? (
|
|
47
|
+
<Text emphasis="muted" variant="bodySmall">
|
|
48
|
+
{description}
|
|
49
|
+
</Text>
|
|
50
|
+
) : null}
|
|
51
|
+
</Stack>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { TimePickerProps } from '../../../types/time-picker';
|
|
2
|
+
import { Button } from '../../button/public';
|
|
3
|
+
|
|
4
|
+
/*** Renders the shared TimePicker trigger button for native and web hosts. */
|
|
5
|
+
export function TimePickerTrigger({
|
|
6
|
+
disabled,
|
|
7
|
+
formatTime,
|
|
8
|
+
interactionPolicy,
|
|
9
|
+
onPress,
|
|
10
|
+
placeholder = 'Choose time',
|
|
11
|
+
testID,
|
|
12
|
+
value,
|
|
13
|
+
}: TimePickerTriggerProps) {
|
|
14
|
+
const displayValue = value ? (formatTime ? formatTime(value) : value) : placeholder;
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Button
|
|
18
|
+
disabled={disabled}
|
|
19
|
+
interactionPolicy={interactionPolicy}
|
|
20
|
+
onPress={onPress}
|
|
21
|
+
testID={testID ? `${testID}-trigger` : undefined}
|
|
22
|
+
trailingIcon={{ name: 'chevron-down-outline' }}
|
|
23
|
+
variant="outline"
|
|
24
|
+
>
|
|
25
|
+
{displayValue}
|
|
26
|
+
</Button>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface TimePickerTriggerProps extends Pick<
|
|
31
|
+
TimePickerProps,
|
|
32
|
+
'disabled' | 'formatTime' | 'interactionPolicy' | 'placeholder' | 'testID' | 'value'
|
|
33
|
+
> {
|
|
34
|
+
onPress: () => void;
|
|
35
|
+
}
|
|
@@ -2,13 +2,24 @@ import { expect, test } from 'bun:test';
|
|
|
2
2
|
|
|
3
3
|
import { ZORA_COMPONENT_META } from '../../metadata/componentMeta';
|
|
4
4
|
|
|
5
|
-
test('TimePicker
|
|
6
|
-
const
|
|
5
|
+
test('TimePicker keeps one manifest contract across native and web presentation hosts', async () => {
|
|
6
|
+
const nativeSource = await Bun.file(
|
|
7
|
+
'src/features/time-picker/adapters/inbound/TimePicker.native.tsx',
|
|
8
|
+
).text();
|
|
9
|
+
const webSource = await Bun.file(
|
|
10
|
+
'src/features/time-picker/adapters/inbound/TimePicker.web.tsx',
|
|
11
|
+
).text();
|
|
12
|
+
const contentSource = await Bun.file(
|
|
13
|
+
'src/features/time-picker/composition/TimePickerContent.tsx',
|
|
14
|
+
).text();
|
|
7
15
|
const meta = ZORA_COMPONENT_META.TimePicker;
|
|
8
16
|
|
|
9
17
|
expect(meta.directManifestNode).toBe(true);
|
|
10
18
|
expect(meta.props.value?.type).toBe('string');
|
|
11
19
|
expect(meta.events?.valueChange?.eventType).toBe('timePicker.valueChange');
|
|
12
20
|
expect(meta.bindings?.props?.value?.value.type).toBe('string');
|
|
13
|
-
expect(
|
|
21
|
+
expect(nativeSource).toContain('useBottomSheet()');
|
|
22
|
+
expect(webSource).toContain('<Popover');
|
|
23
|
+
expect(webSource).not.toContain('useBottomSheet');
|
|
24
|
+
expect(contentSource).toContain('TimePickerOption');
|
|
14
25
|
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Toast as SurfaceToast } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
|
|
5
|
+
import type { ToastProps } from '../../../../types/toast';
|
|
6
|
+
|
|
7
|
+
/*** Renders a toast notification message with ZORA theme scoping. */
|
|
8
|
+
export const Toast = withZoraThemeScope(ToastInner);
|
|
9
|
+
|
|
10
|
+
/*** Applies the ZORA theme scope before delegating toast presentation to Surface. */
|
|
11
|
+
function ToastInner({ mode: _mode, themeId: _themeId, ...props }: ToastProps) {
|
|
12
|
+
return <SurfaceToast {...props} />;
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ToastProvider as SurfaceToastProvider } from '@ankhorage/surface';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import type { ToastProviderProps } from '../../../../types/toast';
|
|
5
|
+
|
|
6
|
+
/*** Provides toast state and rendering context through the Surface runtime host. */
|
|
7
|
+
export function ToastProvider(props: ToastProviderProps) {
|
|
8
|
+
return <SurfaceToastProvider {...props} />;
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { ZORA_COMPONENT_META } from '../../metadata/componentMeta';
|
|
4
|
+
|
|
5
|
+
test('Toast stays imperative and installs its host only when the ZoraProvider capability is enabled', async () => {
|
|
6
|
+
const [publicSource, providerSource, webCapabilities, nativeCapabilities] = await Promise.all([
|
|
7
|
+
Bun.file('src/features/toast/public.ts').text(),
|
|
8
|
+
Bun.file('src/theme/ZoraProvider.tsx').text(),
|
|
9
|
+
Bun.file('src/theme/ZoraRuntimeCapabilities.web.tsx').text(),
|
|
10
|
+
Bun.file('src/theme/ZoraRuntimeCapabilities.native.tsx').text(),
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
expect(ZORA_COMPONENT_META.Toast?.directManifestNode).toBe(false);
|
|
14
|
+
expect(ZORA_COMPONENT_META.ToastProvider?.directManifestNode).toBe(false);
|
|
15
|
+
expect(publicSource).toContain("useToast } from '@ankhorage/surface'");
|
|
16
|
+
expect(providerSource).toContain('toast = false');
|
|
17
|
+
expect(webCapabilities).toContain('if (!toast)');
|
|
18
|
+
expect(nativeCapabilities).toContain('toast ?');
|
|
19
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
ToastController,
|
|
3
|
+
ToastOptions,
|
|
4
|
+
ToastProps,
|
|
5
|
+
ToastProviderProps,
|
|
6
|
+
ToastStatus,
|
|
7
|
+
} from '../../types/toast';
|
|
8
|
+
export { Toast } from './adapters/inbound/Toast';
|
|
9
|
+
export { ToastProvider } from './adapters/inbound/ToastProvider';
|
|
10
|
+
export { useToast } from '@ankhorage/surface';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
|
+
|
|
3
|
+
export const toastMeta = {
|
|
4
|
+
name: 'Toast',
|
|
5
|
+
category: 'component',
|
|
6
|
+
directManifestNode: false,
|
|
7
|
+
allowedChildren: [],
|
|
8
|
+
note: 'Transient feedback component exposed through the imperative toast workflow, not as a manifest node.',
|
|
9
|
+
props: {},
|
|
10
|
+
} as const satisfies ZoraComponentMeta;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
|
+
|
|
3
|
+
export const toastProviderMeta = {
|
|
4
|
+
name: 'ToastProvider',
|
|
5
|
+
category: 'component',
|
|
6
|
+
directManifestNode: false,
|
|
7
|
+
allowedChildren: [],
|
|
8
|
+
note: 'Provider for imperative toast feedback; application roots should normally enable the ZoraProvider toast capability.',
|
|
9
|
+
props: {},
|
|
10
|
+
} as const satisfies ZoraComponentMeta;
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export type { AppBarMode, AppBarOverflowAction, AppBarProps } from './components/app-bar';
|
|
2
|
-
export { AppBar } from './components/app-bar';
|
|
3
1
|
export type { BreadcrumbItem, BreadcrumbsProps } from './components/breadcrumbs';
|
|
4
2
|
export { Breadcrumbs } from './components/breadcrumbs';
|
|
5
3
|
export type { DropdownMenuProps, MenuAction, MenuActionIntent, MenuProps } from './components/menu';
|
|
@@ -16,8 +14,6 @@ export type { SelectOption, SelectProps } from './components/select';
|
|
|
16
14
|
export { Select } from './components/select';
|
|
17
15
|
export type { TabItem, TabsProps, TabsVariant } from './components/tabs';
|
|
18
16
|
export { Tabs } from './components/tabs';
|
|
19
|
-
export type { ToastOptions, ToastProps, ToastProviderProps, ToastStatus } from './components/toast';
|
|
20
|
-
export { Toast, ToastProvider, useToast } from './components/toast';
|
|
21
17
|
export type { ToolbarActionProps, ToolbarPosition, ToolbarProps } from './components/toolbar';
|
|
22
18
|
export { Toolbar, ToolbarAction } from './components/toolbar';
|
|
23
19
|
export { ZORA_CORE_PLUGIN } from './corePlugin';
|
|
@@ -35,6 +31,8 @@ export {
|
|
|
35
31
|
ActivityIndicator,
|
|
36
32
|
type ActivityIndicatorProps,
|
|
37
33
|
} from './features/activity-indicator/public';
|
|
34
|
+
export type { AppBarMode, AppBarOverflowAction, AppBarProps } from './features/app-bar/public';
|
|
35
|
+
export { AppBar } from './features/app-bar/public';
|
|
38
36
|
export type {
|
|
39
37
|
AuthFormBaseProps,
|
|
40
38
|
AuthIdentifierKind,
|
|
@@ -247,6 +245,14 @@ export {
|
|
|
247
245
|
type TimePickerProps,
|
|
248
246
|
type TimePickerValue,
|
|
249
247
|
} from './features/time-picker/public';
|
|
248
|
+
export type {
|
|
249
|
+
ToastController,
|
|
250
|
+
ToastOptions,
|
|
251
|
+
ToastProps,
|
|
252
|
+
ToastProviderProps,
|
|
253
|
+
ToastStatus,
|
|
254
|
+
} from './features/toast/public';
|
|
255
|
+
export { Toast, ToastProvider, useToast } from './features/toast/public';
|
|
250
256
|
export type {
|
|
251
257
|
HeadingAlign,
|
|
252
258
|
HeadingColor,
|
|
@@ -22,6 +22,10 @@ function readComponent(...segments: string[]): string {
|
|
|
22
22
|
return readSource(join('components', ...segments));
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
function readFeature(...segments: string[]): string {
|
|
26
|
+
return readSource(join('features', ...segments));
|
|
27
|
+
}
|
|
28
|
+
|
|
25
29
|
function readPattern(...segments: string[]): string {
|
|
26
30
|
return readSource(join('patterns', ...segments));
|
|
27
31
|
}
|
|
@@ -37,7 +41,7 @@ describe('InteractionPolicy declaration', () => {
|
|
|
37
41
|
test('no duplicate local InteractionPolicy type declarations in ZORA source', () => {
|
|
38
42
|
const files = [
|
|
39
43
|
readSource('theme/ZoraBaseProps.ts'),
|
|
40
|
-
|
|
44
|
+
readSource('types/app-bar.ts'),
|
|
41
45
|
readComponent('breadcrumbs', 'types.ts'),
|
|
42
46
|
readSource('types/empty-state.ts'),
|
|
43
47
|
readSource('types/hero.ts'),
|
|
@@ -75,11 +79,11 @@ describe('Surface wrapper propagation', () => {
|
|
|
75
79
|
|
|
76
80
|
describe('AppBar', () => {
|
|
77
81
|
test('forwards interactionPolicy to internal IconButtons', () => {
|
|
78
|
-
const source =
|
|
82
|
+
const source = readFeature('app-bar', 'adapters', 'inbound', 'AppBar.tsx');
|
|
79
83
|
|
|
80
84
|
expect(source).not.toMatch(/interactionPolicy:\s*_interactionPolicy/);
|
|
81
85
|
expect(source).toMatch(
|
|
82
|
-
/<IconButton[\s\S]*?interactionPolicy=\{interactionPolicy\}[\s\S]*?onPress=\{
|
|
86
|
+
/<IconButton[\s\S]*?interactionPolicy=\{interactionPolicy\}[\s\S]*?onPress=\{mode\.onCancel\}/,
|
|
83
87
|
);
|
|
84
88
|
expect(source).toMatch(
|
|
85
89
|
/<IconButton[\s\S]*?interactionPolicy=\{interactionPolicy\}[\s\S]*?onPress=\{overflow\.onPress\}/,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { AppBar } from '../../
|
|
3
|
+
import { AppBar } from '../../features/app-bar/public';
|
|
4
4
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
5
5
|
import { Screen } from '../screen';
|
|
6
6
|
import { SidebarLayout } from '../sidebar-layout';
|
|
@@ -29,7 +29,5 @@ function SettingsLayoutInner({
|
|
|
29
29
|
|
|
30
30
|
/***
|
|
31
31
|
* Settings page layout with app bar, sidebar, and scrollable content area.
|
|
32
|
-
*
|
|
33
|
-
|
|
34
32
|
*/
|
|
35
33
|
export const SettingsLayout = withZoraThemeScope(SettingsLayoutInner);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { appBarMeta } from '../components/app-bar/meta';
|
|
2
1
|
import { breadcrumbsMeta } from '../components/breadcrumbs/meta';
|
|
3
2
|
import { dropdownMenuMeta, menuMeta } from '../components/menu/meta';
|
|
4
3
|
import { modalMeta } from '../components/modal/meta';
|
|
@@ -7,11 +6,11 @@ import { ratingMeta } from '../components/rating/meta';
|
|
|
7
6
|
import { searchBarMeta } from '../components/search-bar/meta';
|
|
8
7
|
import { selectMeta } from '../components/select/meta';
|
|
9
8
|
import { tabsMeta } from '../components/tabs/meta';
|
|
10
|
-
import { toastMeta, toastProviderMeta } from '../components/toast/meta';
|
|
11
9
|
import { toolbarActionMeta, toolbarMeta } from '../components/toolbar/meta';
|
|
12
10
|
import { accordionItemMeta } from '../features/accordion/accordionItemMeta';
|
|
13
11
|
import { accordionMeta } from '../features/accordion/accordionMeta';
|
|
14
12
|
import { activityIndicatorMeta } from '../features/activity-indicator/activityIndicatorMeta';
|
|
13
|
+
import { appBarMeta } from '../features/app-bar/appBarMeta';
|
|
15
14
|
import { forgotPasswordFormMeta } from '../features/auth/forgotPasswordFormMeta';
|
|
16
15
|
import { oauthProviderButtonMeta } from '../features/auth/oauthProviderButtonMeta';
|
|
17
16
|
import { oauthProviderListMeta } from '../features/auth/oauthProviderListMeta';
|
|
@@ -65,6 +64,8 @@ import {
|
|
|
65
64
|
} from '../features/skeleton/skeletonMeta';
|
|
66
65
|
import { surfaceMeta } from '../features/surface/surfaceMeta';
|
|
67
66
|
import { timePickerMeta } from '../features/time-picker/timePickerMeta';
|
|
67
|
+
import { toastMeta } from '../features/toast/toastMeta';
|
|
68
|
+
import { toastProviderMeta } from '../features/toast/toastProviderMeta';
|
|
68
69
|
import { headingMeta } from '../features/typography/headingMeta';
|
|
69
70
|
import { textMeta } from '../features/typography/textMeta';
|
|
70
71
|
import { uploaderMeta } from '../features/uploader/uploaderMeta';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { AppBar } from '../../
|
|
3
|
+
import { AppBar } from '../../features/app-bar/public';
|
|
4
4
|
import { IconButton } from '../../features/button/public';
|
|
5
5
|
import { Box, Stack } from '../../features/layout/public';
|
|
6
6
|
import { Progress } from '../../features/progress/public';
|
|
@@ -10,21 +10,21 @@ type SelectionContextValue = UseSelectionResult;
|
|
|
10
10
|
|
|
11
11
|
const SelectionContext = React.createContext<SelectionContextValue | null>(null);
|
|
12
12
|
|
|
13
|
+
/*** Resolve the effective selection mode. */
|
|
13
14
|
function resolveMode(mode: SelectionMode | undefined): SelectionMode {
|
|
14
15
|
return mode ?? 'single';
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
/*** Resolve the effective disabled state. */
|
|
17
19
|
function resolveDisabled(disabled: boolean | undefined): boolean {
|
|
18
20
|
return disabled ?? false;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
/***
|
|
22
24
|
* Accesses selection state provided by `SelectionProvider`.
|
|
23
|
-
*
|
|
24
|
-
|
|
25
25
|
*/
|
|
26
26
|
export function useSelection(): UseSelectionResult {
|
|
27
|
-
const value = React.
|
|
27
|
+
const value = React.use(SelectionContext);
|
|
28
28
|
if (!value) {
|
|
29
29
|
throw new Error(MISSING_CONTEXT_MESSAGE);
|
|
30
30
|
}
|
|
@@ -34,8 +34,6 @@ export function useSelection(): UseSelectionResult {
|
|
|
34
34
|
|
|
35
35
|
/***
|
|
36
36
|
* Provides selection state for building selectable lists and grids.
|
|
37
|
-
*
|
|
38
|
-
|
|
39
37
|
*/
|
|
40
38
|
export function SelectionProvider({
|
|
41
39
|
children,
|
|
@@ -110,5 +108,5 @@ export function SelectionProvider({
|
|
|
110
108
|
};
|
|
111
109
|
}, [clear, currentNormalizedIds, resolvedDisabled, resolvedMode, select, selectedIdSet, toggle]);
|
|
112
110
|
|
|
113
|
-
return <SelectionContext
|
|
111
|
+
return <SelectionContext value={value}>{children}</SelectionContext>;
|
|
114
112
|
}
|
package/src/registry.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { InteractionPolicyProps } from '@ankhorage/surface';
|
|
2
2
|
import type React from 'react';
|
|
3
3
|
|
|
4
|
-
import { AppBar } from './components/app-bar';
|
|
5
4
|
import { Breadcrumbs } from './components/breadcrumbs';
|
|
6
5
|
import { DropdownMenu, Menu } from './components/menu';
|
|
7
6
|
import { Modal } from './components/modal';
|
|
@@ -10,10 +9,10 @@ import { Rating } from './components/rating';
|
|
|
10
9
|
import { SearchBar } from './components/search-bar';
|
|
11
10
|
import { Select } from './components/select';
|
|
12
11
|
import { Tabs } from './components/tabs';
|
|
13
|
-
import { Toast } from './components/toast';
|
|
14
12
|
import { Toolbar, ToolbarAction } from './components/toolbar';
|
|
15
13
|
import { Accordion, AccordionItem } from './features/accordion/public';
|
|
16
14
|
import { ActivityIndicator } from './features/activity-indicator/public';
|
|
15
|
+
import { AppBar } from './features/app-bar/public';
|
|
17
16
|
import {
|
|
18
17
|
ForgotPasswordForm,
|
|
19
18
|
OAuthProviderButton,
|
|
@@ -56,6 +55,7 @@ import { Progress, ProgressRing } from './features/progress/public';
|
|
|
56
55
|
import { Skeleton, SkeletonCard, SkeletonList, SkeletonText } from './features/skeleton/public';
|
|
57
56
|
import { Surface } from './features/surface/public';
|
|
58
57
|
import { TimePicker } from './features/time-picker/public';
|
|
58
|
+
import { Toast } from './features/toast/public';
|
|
59
59
|
import { Heading } from './features/typography/public';
|
|
60
60
|
import { Text } from './features/typography/public';
|
|
61
61
|
import { Uploader } from './features/uploader/public';
|
|
@@ -1,26 +1,22 @@
|
|
|
1
|
-
import type { ThemeConfig } from '@ankhorage/contracts';
|
|
2
1
|
import { ThemeProvider } from '@ankhorage/surface';
|
|
3
|
-
import { BottomSheetProvider } from '@ankhorage/surface/bottom-sheet';
|
|
4
2
|
import React from 'react';
|
|
5
3
|
|
|
4
|
+
import type { ZoraProviderProps } from '../types/provider';
|
|
6
5
|
import { createZoraThemeConfig } from './createZoraThemeConfig';
|
|
7
|
-
import type { ZoraTheme, ZoraThemeMode } from './types';
|
|
8
6
|
import { zoraDefaultTheme } from './zoraDefaultTheme';
|
|
7
|
+
import { ZoraRuntimeCapabilities } from './ZoraRuntimeCapabilities';
|
|
9
8
|
import { ZoraThemeRuntimeContext } from './ZoraThemeRuntimeContext';
|
|
10
9
|
|
|
11
|
-
export
|
|
12
|
-
children: React.ReactNode;
|
|
13
|
-
theme?: ZoraTheme;
|
|
14
|
-
themeConfig?: ThemeConfig;
|
|
15
|
-
initialMode?: ZoraThemeMode;
|
|
16
|
-
}
|
|
10
|
+
export type { ZoraProviderProps, ZoraToastCapability } from '../types/provider';
|
|
17
11
|
|
|
18
|
-
|
|
12
|
+
/*** Installs the core ZORA theme runtime and explicitly enabled optional capabilities. */
|
|
19
13
|
export function ZoraProvider({
|
|
14
|
+
bottomSheet = false,
|
|
20
15
|
children,
|
|
21
16
|
theme = zoraDefaultTheme,
|
|
22
17
|
themeConfig,
|
|
23
18
|
initialMode = 'light',
|
|
19
|
+
toast = false,
|
|
24
20
|
}: ZoraProviderProps) {
|
|
25
21
|
const resolvedConfig = React.useMemo(
|
|
26
22
|
() => themeConfig ?? createZoraThemeConfig(theme),
|
|
@@ -29,10 +25,12 @@ export function ZoraProvider({
|
|
|
29
25
|
const runtimeValue = React.useMemo(() => ({ themeId: resolvedConfig.id }), [resolvedConfig.id]);
|
|
30
26
|
|
|
31
27
|
return (
|
|
32
|
-
<ZoraThemeRuntimeContext
|
|
28
|
+
<ZoraThemeRuntimeContext value={runtimeValue}>
|
|
33
29
|
<ThemeProvider initialConfig={resolvedConfig} initialMode={initialMode}>
|
|
34
|
-
<
|
|
30
|
+
<ZoraRuntimeCapabilities bottomSheet={bottomSheet} toast={toast}>
|
|
31
|
+
{children}
|
|
32
|
+
</ZoraRuntimeCapabilities>
|
|
35
33
|
</ThemeProvider>
|
|
36
|
-
</ZoraThemeRuntimeContext
|
|
34
|
+
</ZoraThemeRuntimeContext>
|
|
37
35
|
);
|
|
38
36
|
}
|