@ankhorage/zora 12.1.0 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +11 -5
- package/dist/features/accordion/accordionItemMeta.d.ts +53 -0
- package/dist/features/accordion/accordionItemMeta.d.ts.map +1 -0
- package/dist/features/accordion/accordionItemMeta.js +45 -0
- package/dist/features/accordion/accordionItemMeta.js.map +1 -0
- package/dist/features/accordion/accordionMeta.d.ts +36 -0
- package/dist/features/accordion/accordionMeta.d.ts.map +1 -0
- package/dist/features/accordion/accordionMeta.js +33 -0
- package/dist/features/accordion/accordionMeta.js.map +1 -0
- package/dist/features/accordion/adapters/inbound/Accordion.d.ts +5 -0
- package/dist/features/accordion/adapters/inbound/Accordion.d.ts.map +1 -0
- package/dist/features/accordion/adapters/inbound/Accordion.js +41 -0
- package/dist/features/accordion/adapters/inbound/Accordion.js.map +1 -0
- package/dist/features/accordion/adapters/inbound/AccordionItem.d.ts +5 -0
- package/dist/features/accordion/adapters/inbound/AccordionItem.d.ts.map +1 -0
- package/dist/features/accordion/adapters/inbound/AccordionItem.js +52 -0
- package/dist/features/accordion/adapters/inbound/AccordionItem.js.map +1 -0
- package/dist/features/accordion/composition/AccordionPresentationContext.d.ts +4 -0
- package/dist/features/accordion/composition/AccordionPresentationContext.d.ts.map +1 -0
- package/dist/features/accordion/composition/AccordionPresentationContext.js +3 -0
- package/dist/features/accordion/composition/AccordionPresentationContext.js.map +1 -0
- package/dist/features/accordion/public.d.ts +4 -0
- package/dist/features/accordion/public.d.ts.map +1 -0
- package/dist/features/accordion/public.js +3 -0
- package/dist/features/accordion/public.js.map +1 -0
- package/dist/features/bottom-sheet/bottomSheetMeta.d.ts +1 -1
- package/dist/features/card/cardMeta.d.ts +1 -1
- package/dist/features/card/mediaCardMeta.d.ts +1 -1
- package/dist/features/card/postCardMeta.d.ts +1 -1
- 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/gradient/gradientMeta.d.ts +1 -1
- package/dist/features/keyboard-avoiding-view/keyboardAvoidingViewMeta.d.ts +1 -1
- package/dist/features/layout/boxMeta.d.ts +1 -1
- package/dist/features/layout/containerMeta.d.ts +1 -1
- package/dist/features/layout/gridMeta.d.ts +1 -1
- package/dist/features/layout/stackMeta.d.ts +1 -1
- package/dist/features/list/flatListMeta.d.ts +1 -1
- package/dist/features/list/sectionListMeta.d.ts +1 -1
- package/dist/features/surface/surfaceMeta.d.ts +1 -1
- 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 +3 -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/screen/meta.d.ts +1 -1
- package/dist/layout/screen-section/meta.d.ts +1 -1
- package/dist/metadata/allowedChildren.d.ts +3 -3
- package/dist/metadata/allowedChildren.d.ts.map +1 -1
- package/dist/metadata/allowedChildren.js +1 -0
- package/dist/metadata/allowedChildren.js.map +1 -1
- package/dist/metadata/bindableComponentMeta.d.ts +2 -2
- package/dist/metadata/componentMeta.d.ts.map +1 -1
- package/dist/metadata/componentMeta.js +6 -3
- package/dist/metadata/componentMeta.js.map +1 -1
- package/dist/patterns/message-bubble/meta.d.ts +1 -1
- package/dist/patterns/notice/meta.d.ts +1 -1
- package/dist/patterns/panel/meta.d.ts +1 -1
- package/dist/patterns/reader/meta.d.ts +2 -2
- package/dist/patterns/scanner/meta.d.ts +2 -2
- 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.d.ts.map +1 -1
- package/dist/registry.js +4 -3
- 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/types/accordion.d.ts +23 -0
- package/dist/types/accordion.d.ts.map +1 -0
- package/dist/types/accordion.js +2 -0
- package/dist/types/accordion.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/accordionItemMeta.ts +46 -0
- package/src/features/accordion/accordionMeta.ts +34 -0
- package/src/features/accordion/adapters/inbound/Accordion.tsx +94 -0
- package/src/features/accordion/adapters/inbound/AccordionItem.tsx +86 -0
- package/src/features/accordion/composition/AccordionPresentationContext.ts +6 -0
- package/src/features/accordion/public.ts +9 -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 +17 -4
- package/src/metadata/allowedChildren.ts +1 -0
- package/src/metadata/componentMeta.test.ts +9 -0
- package/src/metadata/componentMeta.ts +6 -3
- package/src/patterns/selection/SelectionProvider.tsx +4 -6
- package/src/registry.ts +4 -3
- package/src/showcaseCoverage.test.ts +2 -1
- 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 +27 -18
- package/src/types/accordion.ts +38 -0
- package/src/types/provider.ts +22 -0
- package/src/{components/toast/types.ts → types/toast.ts} +5 -7
- 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/dist/patterns/disclosure-section/DisclosureSection.d.ts +0 -9
- package/dist/patterns/disclosure-section/DisclosureSection.d.ts.map +0 -1
- package/dist/patterns/disclosure-section/DisclosureSection.js +0 -86
- package/dist/patterns/disclosure-section/DisclosureSection.js.map +0 -1
- package/dist/patterns/disclosure-section/index.d.ts +0 -3
- package/dist/patterns/disclosure-section/index.d.ts.map +0 -1
- package/dist/patterns/disclosure-section/index.js +0 -3
- package/dist/patterns/disclosure-section/index.js.map +0 -1
- package/dist/patterns/disclosure-section/meta.d.ts +0 -9
- package/dist/patterns/disclosure-section/meta.d.ts.map +0 -1
- package/dist/patterns/disclosure-section/meta.js +0 -9
- package/dist/patterns/disclosure-section/meta.js.map +0 -1
- package/dist/patterns/disclosure-section/types.d.ts +0 -15
- package/dist/patterns/disclosure-section/types.d.ts.map +0 -1
- package/dist/patterns/disclosure-section/types.js +0 -2
- package/dist/patterns/disclosure-section/types.js.map +0 -1
- 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/patterns/disclosure-section/DisclosureSection.tsx +0 -130
- package/src/patterns/disclosure-section/index.ts +0 -2
- package/src/patterns/disclosure-section/meta.ts +0 -10
- package/src/patterns/disclosure-section/types.ts +0 -16
|
@@ -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
|
@@ -16,12 +16,19 @@ export type { SelectOption, SelectProps } from './components/select';
|
|
|
16
16
|
export { Select } from './components/select';
|
|
17
17
|
export type { TabItem, TabsProps, TabsVariant } from './components/tabs';
|
|
18
18
|
export { Tabs } from './components/tabs';
|
|
19
|
-
export type { ToastOptions, ToastProps, ToastProviderProps, ToastStatus } from './components/toast';
|
|
20
|
-
export { Toast, ToastProvider, useToast } from './components/toast';
|
|
21
19
|
export type { ToolbarActionProps, ToolbarPosition, ToolbarProps } from './components/toolbar';
|
|
22
20
|
export { Toolbar, ToolbarAction } from './components/toolbar';
|
|
23
21
|
export { ZORA_CORE_PLUGIN } from './corePlugin';
|
|
24
22
|
export { ZORA_CORE_PLUGIN_METADATA } from './corePluginMetadata';
|
|
23
|
+
export {
|
|
24
|
+
Accordion,
|
|
25
|
+
AccordionItem,
|
|
26
|
+
type AccordionItemProps,
|
|
27
|
+
type AccordionMode,
|
|
28
|
+
type AccordionMultipleProps,
|
|
29
|
+
type AccordionProps,
|
|
30
|
+
type AccordionSingleProps,
|
|
31
|
+
} from './features/accordion/public';
|
|
25
32
|
export {
|
|
26
33
|
ActivityIndicator,
|
|
27
34
|
type ActivityIndicatorProps,
|
|
@@ -238,6 +245,14 @@ export {
|
|
|
238
245
|
type TimePickerProps,
|
|
239
246
|
type TimePickerValue,
|
|
240
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';
|
|
241
256
|
export type {
|
|
242
257
|
HeadingAlign,
|
|
243
258
|
HeadingColor,
|
|
@@ -334,8 +349,6 @@ export type {
|
|
|
334
349
|
export { CollectionEditor } from './patterns/collection-editor';
|
|
335
350
|
export type { ConfirmDialogProps } from './patterns/confirm-dialog';
|
|
336
351
|
export { ConfirmDialog } from './patterns/confirm-dialog';
|
|
337
|
-
export type { DisclosureSectionProps } from './patterns/disclosure-section';
|
|
338
|
-
export { DisclosureSection } from './patterns/disclosure-section';
|
|
339
352
|
export type { FilterBarProps } from './patterns/filter-bar';
|
|
340
353
|
export { FilterBar } from './patterns/filter-bar';
|
|
341
354
|
export type { InspectorFieldProps } from './patterns/inspector-field';
|
|
@@ -186,6 +186,8 @@ describe('ZORA_COMPONENT_META invariants', () => {
|
|
|
186
186
|
]);
|
|
187
187
|
|
|
188
188
|
const expectedContainerNodes = new Set([
|
|
189
|
+
'Accordion',
|
|
190
|
+
'AccordionItem',
|
|
189
191
|
'Form',
|
|
190
192
|
'Gradient',
|
|
191
193
|
'Surface',
|
|
@@ -234,6 +236,13 @@ describe('ZORA_COMPONENT_META invariants', () => {
|
|
|
234
236
|
}
|
|
235
237
|
});
|
|
236
238
|
|
|
239
|
+
test('Accordion constrains authored items to its canonical hierarchy', () => {
|
|
240
|
+
expect(ZORA_COMPONENT_META.Accordion.directManifestNode).toBe(true);
|
|
241
|
+
expect(ZORA_COMPONENT_META.Accordion.allowedChildren).toEqual(['AccordionItem']);
|
|
242
|
+
expect(ZORA_COMPONENT_META.AccordionItem.directManifestNode).toBe(true);
|
|
243
|
+
expect(ZORA_COMPONENT_META.AccordionItem.allowedChildren).not.toContain('AccordionItem');
|
|
244
|
+
});
|
|
245
|
+
|
|
237
246
|
test('Image is a direct manifest leaf with canonical media authoring metadata', () => {
|
|
238
247
|
expect(ZORA_COMPONENT_META.Image.directManifestNode).toBe(true);
|
|
239
248
|
expect(ZORA_COMPONENT_META.Image.allowedChildren).toEqual([]);
|
|
@@ -7,8 +7,9 @@ import { ratingMeta } from '../components/rating/meta';
|
|
|
7
7
|
import { searchBarMeta } from '../components/search-bar/meta';
|
|
8
8
|
import { selectMeta } from '../components/select/meta';
|
|
9
9
|
import { tabsMeta } from '../components/tabs/meta';
|
|
10
|
-
import { toastMeta, toastProviderMeta } from '../components/toast/meta';
|
|
11
10
|
import { toolbarActionMeta, toolbarMeta } from '../components/toolbar/meta';
|
|
11
|
+
import { accordionItemMeta } from '../features/accordion/accordionItemMeta';
|
|
12
|
+
import { accordionMeta } from '../features/accordion/accordionMeta';
|
|
12
13
|
import { activityIndicatorMeta } from '../features/activity-indicator/activityIndicatorMeta';
|
|
13
14
|
import { forgotPasswordFormMeta } from '../features/auth/forgotPasswordFormMeta';
|
|
14
15
|
import { oauthProviderButtonMeta } from '../features/auth/oauthProviderButtonMeta';
|
|
@@ -63,6 +64,8 @@ import {
|
|
|
63
64
|
} from '../features/skeleton/skeletonMeta';
|
|
64
65
|
import { surfaceMeta } from '../features/surface/surfaceMeta';
|
|
65
66
|
import { timePickerMeta } from '../features/time-picker/timePickerMeta';
|
|
67
|
+
import { toastMeta } from '../features/toast/toastMeta';
|
|
68
|
+
import { toastProviderMeta } from '../features/toast/toastProviderMeta';
|
|
66
69
|
import { headingMeta } from '../features/typography/headingMeta';
|
|
67
70
|
import { textMeta } from '../features/typography/textMeta';
|
|
68
71
|
import { uploaderMeta } from '../features/uploader/uploaderMeta';
|
|
@@ -76,7 +79,6 @@ import { topbarLayoutMeta } from '../layout/topbar-layout/meta';
|
|
|
76
79
|
import { chatListItemMeta } from '../patterns/chat-list-item/meta';
|
|
77
80
|
import { collectionEditorMeta } from '../patterns/collection-editor/meta';
|
|
78
81
|
import { confirmDialogMeta } from '../patterns/confirm-dialog/meta';
|
|
79
|
-
import { disclosureSectionMeta } from '../patterns/disclosure-section/meta';
|
|
80
82
|
import { filterBarMeta } from '../patterns/filter-bar/meta';
|
|
81
83
|
import { inspectorFieldMeta } from '../patterns/inspector-field/meta';
|
|
82
84
|
import { listMeta, listRowMeta, listSectionMeta } from '../patterns/list/meta';
|
|
@@ -103,6 +105,8 @@ import type { ZoraComponentMetaRegistry } from './types';
|
|
|
103
105
|
|
|
104
106
|
export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = finalizeFeatureMetadata({
|
|
105
107
|
...foundationMetas,
|
|
108
|
+
Accordion: accordionMeta,
|
|
109
|
+
AccordionItem: accordionItemMeta,
|
|
106
110
|
ActivityIndicator: activityIndicatorMeta,
|
|
107
111
|
Box: boxMeta,
|
|
108
112
|
Container: containerMeta,
|
|
@@ -180,7 +184,6 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = finalizeFeatureMet
|
|
|
180
184
|
CollectionEditor: collectionEditorMeta,
|
|
181
185
|
ConfirmDialog: confirmDialogMeta,
|
|
182
186
|
ContentRail: contentRailMeta,
|
|
183
|
-
DisclosureSection: disclosureSectionMeta,
|
|
184
187
|
EmptyState: emptyStateMeta,
|
|
185
188
|
FilterBar: filterBarMeta,
|
|
186
189
|
Hero: heroMeta,
|
|
@@ -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
|
@@ -10,8 +10,8 @@ import { Rating } from './components/rating';
|
|
|
10
10
|
import { SearchBar } from './components/search-bar';
|
|
11
11
|
import { Select } from './components/select';
|
|
12
12
|
import { Tabs } from './components/tabs';
|
|
13
|
-
import { Toast } from './components/toast';
|
|
14
13
|
import { Toolbar, ToolbarAction } from './components/toolbar';
|
|
14
|
+
import { Accordion, AccordionItem } from './features/accordion/public';
|
|
15
15
|
import { ActivityIndicator } from './features/activity-indicator/public';
|
|
16
16
|
import {
|
|
17
17
|
ForgotPasswordForm,
|
|
@@ -55,6 +55,7 @@ import { Progress, ProgressRing } from './features/progress/public';
|
|
|
55
55
|
import { Skeleton, SkeletonCard, SkeletonList, SkeletonText } from './features/skeleton/public';
|
|
56
56
|
import { Surface } from './features/surface/public';
|
|
57
57
|
import { TimePicker } from './features/time-picker/public';
|
|
58
|
+
import { Toast } from './features/toast/public';
|
|
58
59
|
import { Heading } from './features/typography/public';
|
|
59
60
|
import { Text } from './features/typography/public';
|
|
60
61
|
import { Uploader } from './features/uploader/public';
|
|
@@ -68,7 +69,6 @@ import { TopbarLayout } from './layout/topbar-layout';
|
|
|
68
69
|
import { ChatListItem } from './patterns/chat-list-item';
|
|
69
70
|
import { CollectionEditor } from './patterns/collection-editor';
|
|
70
71
|
import { ConfirmDialog } from './patterns/confirm-dialog';
|
|
71
|
-
import { DisclosureSection } from './patterns/disclosure-section';
|
|
72
72
|
import { FilterBar } from './patterns/filter-bar';
|
|
73
73
|
import { InspectorField } from './patterns/inspector-field';
|
|
74
74
|
import { List, ListRow, ListSection } from './patterns/list';
|
|
@@ -113,6 +113,8 @@ type _RegistryInteractionPolicyCheck = _AssertTrue<
|
|
|
113
113
|
>;
|
|
114
114
|
|
|
115
115
|
const _ZORA_COMPONENT_REGISTRY = {
|
|
116
|
+
Accordion,
|
|
117
|
+
AccordionItem,
|
|
116
118
|
ActivityIndicator,
|
|
117
119
|
AppBar,
|
|
118
120
|
Avatar,
|
|
@@ -193,7 +195,6 @@ const _ZORA_COMPONENT_REGISTRY = {
|
|
|
193
195
|
CollectionEditor,
|
|
194
196
|
ConfirmDialog,
|
|
195
197
|
ContentRail,
|
|
196
|
-
DisclosureSection,
|
|
197
198
|
EmptyState,
|
|
198
199
|
FilterBar,
|
|
199
200
|
Hero,
|
|
@@ -17,6 +17,8 @@ const IGNORED_DIRECTORY_NAMES = new Set([
|
|
|
17
17
|
|
|
18
18
|
const REQUIRED_SHOWCASE_COVERAGE = {
|
|
19
19
|
components: [
|
|
20
|
+
'Accordion',
|
|
21
|
+
'AccordionItem',
|
|
20
22
|
'AppBar',
|
|
21
23
|
'Avatar',
|
|
22
24
|
'AvatarGroup',
|
|
@@ -81,7 +83,6 @@ const REQUIRED_SHOWCASE_COVERAGE = {
|
|
|
81
83
|
'SignUpForm',
|
|
82
84
|
'CollectionEditor',
|
|
83
85
|
'ConfirmDialog',
|
|
84
|
-
'DisclosureSection',
|
|
85
86
|
'EmptyState',
|
|
86
87
|
'FilterBar',
|
|
87
88
|
'SelectableItem',
|
|
@@ -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
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ToastProvider as SurfaceToastProvider } from '@ankhorage/surface';
|
|
2
|
+
import { BottomSheetProvider } from '@ankhorage/surface/bottom-sheet';
|
|
3
|
+
|
|
4
|
+
import type { ZoraRuntimeCapabilitiesProps } from '../types/provider';
|
|
5
|
+
|
|
6
|
+
/*** Installs optional native runtime capabilities without forcing unused hosts. */
|
|
7
|
+
export function ZoraRuntimeCapabilities({
|
|
8
|
+
bottomSheet,
|
|
9
|
+
children,
|
|
10
|
+
toast,
|
|
11
|
+
}: ZoraRuntimeCapabilitiesProps) {
|
|
12
|
+
const toastContent = toast ? (
|
|
13
|
+
<SurfaceToastProvider {...(toast === true ? {} : toast)}>{children}</SurfaceToastProvider>
|
|
14
|
+
) : (
|
|
15
|
+
children
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
return bottomSheet ? <BottomSheetProvider>{toastContent}</BottomSheetProvider> : toastContent;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ZoraRuntimeCapabilities } from './ZoraRuntimeCapabilities.web';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ToastProvider as SurfaceToastProvider } from '@ankhorage/surface';
|
|
2
|
+
|
|
3
|
+
import type { ZoraRuntimeCapabilitiesProps } from '../types/provider';
|
|
4
|
+
|
|
5
|
+
/*** Installs only web-relevant optional runtime capabilities. */
|
|
6
|
+
export function ZoraRuntimeCapabilities({ children, toast }: ZoraRuntimeCapabilitiesProps) {
|
|
7
|
+
if (!toast) return children;
|
|
8
|
+
|
|
9
|
+
return <SurfaceToastProvider {...(toast === true ? {} : toast)}>{children}</SurfaceToastProvider>;
|
|
10
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext,
|
|
1
|
+
import { createContext, use } from 'react';
|
|
2
2
|
|
|
3
3
|
import type { ZoraThemeId } from './types';
|
|
4
4
|
import { zoraDefaultTheme } from './zoraDefaultTheme';
|
|
@@ -11,6 +11,7 @@ export const ZoraThemeRuntimeContext = createContext<ZoraThemeRuntime>({
|
|
|
11
11
|
themeId: zoraDefaultTheme.id,
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
+
/*** Returns the active ZORA theme runtime. */
|
|
14
15
|
export function useZoraThemeRuntime(): ZoraThemeRuntime {
|
|
15
|
-
return
|
|
16
|
+
return use(ZoraThemeRuntimeContext);
|
|
16
17
|
}
|
|
@@ -11,6 +11,17 @@ export interface ZoraThemeScopeProps {
|
|
|
11
11
|
mode?: ZoraThemeMode;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/*** Applies nested ZORA theme overrides without installing another Surface theme runtime. */
|
|
15
|
+
export function ZoraThemeScope({ children, themeId, mode }: ZoraThemeScopeProps) {
|
|
16
|
+
if (mode === undefined && themeId === undefined) return children;
|
|
17
|
+
return (
|
|
18
|
+
<ZoraThemeScopeInner mode={mode} themeId={themeId}>
|
|
19
|
+
{children}
|
|
20
|
+
</ZoraThemeScopeInner>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/*** Resolves and provides the scoped Surface and ZORA theme runtime values. */
|
|
14
25
|
function ZoraThemeScopeInner({ children, themeId, mode }: ZoraThemeScopeProps) {
|
|
15
26
|
const parentSurface = useTheme();
|
|
16
27
|
const parentRuntime = useZoraThemeRuntime();
|
|
@@ -38,17 +49,8 @@ function ZoraThemeScopeInner({ children, themeId, mode }: ZoraThemeScopeProps) {
|
|
|
38
49
|
const scopedRuntimeValue = useMemo(() => ({ themeId: scopedThemeId }), [scopedThemeId]);
|
|
39
50
|
|
|
40
51
|
return (
|
|
41
|
-
<ZoraThemeRuntimeContext
|
|
42
|
-
<ThemeContext
|
|
43
|
-
</ZoraThemeRuntimeContext
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function ZoraThemeScope({ children, themeId, mode }: ZoraThemeScopeProps) {
|
|
48
|
-
if (mode === undefined && themeId === undefined) return children;
|
|
49
|
-
return (
|
|
50
|
-
<ZoraThemeScopeInner mode={mode} themeId={themeId}>
|
|
51
|
-
{children}
|
|
52
|
-
</ZoraThemeScopeInner>
|
|
52
|
+
<ZoraThemeRuntimeContext value={scopedRuntimeValue}>
|
|
53
|
+
<ThemeContext value={scopedSurfaceValue}>{children}</ThemeContext>
|
|
54
|
+
</ZoraThemeRuntimeContext>
|
|
53
55
|
);
|
|
54
56
|
}
|
package/src/theme/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ export type { ThemeModeToggleProps } from './ThemeModeToggleProps';
|
|
|
4
4
|
export { useZoraTheme } from './useZoraTheme';
|
|
5
5
|
export { withZoraThemeScope } from './withZoraThemeScope';
|
|
6
6
|
export type { ZoraBaseProps } from './ZoraBaseProps';
|
|
7
|
-
export type { ZoraProviderProps } from './ZoraProvider';
|
|
7
|
+
export type { ZoraProviderProps, ZoraToastCapability } from './ZoraProvider';
|
|
8
8
|
export { ZoraProvider } from './ZoraProvider';
|
|
9
9
|
export type { ZoraThemeScopeProps } from './ZoraThemeScope';
|
|
10
10
|
export { ZoraThemeScope } from './ZoraThemeScope';
|
|
@@ -4,12 +4,15 @@ import { join } from 'node:path';
|
|
|
4
4
|
import { describe, expect, test } from 'bun:test';
|
|
5
5
|
|
|
6
6
|
const themeDir = import.meta.dir;
|
|
7
|
+
const srcDir = join(themeDir, '..');
|
|
7
8
|
|
|
8
9
|
describe('canonical ThemeConfig scope propagation', () => {
|
|
9
10
|
test('provider accepts the canonical ThemeConfig without duplicating live config state', () => {
|
|
10
11
|
const provider = readFileSync(join(themeDir, 'ZoraProvider.tsx'), 'utf8');
|
|
12
|
+
const providerTypes = readFileSync(join(srcDir, 'types', 'provider.ts'), 'utf8');
|
|
11
13
|
const context = readFileSync(join(themeDir, 'ZoraThemeRuntimeContext.tsx'), 'utf8');
|
|
12
|
-
|
|
14
|
+
|
|
15
|
+
expect(providerTypes).toContain('themeConfig?: ThemeConfig');
|
|
13
16
|
expect(provider).toContain('themeConfig ?? createZoraThemeConfig(theme)');
|
|
14
17
|
expect(context).not.toContain('ThemeConfig');
|
|
15
18
|
expect(context).not.toContain('sourceTheme');
|