@ankhorage/surface 6.0.0 → 8.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 +12 -0
- package/README.md +1 -1
- package/dist/features/button/adapters/inbound/Button.d.ts.map +1 -1
- package/dist/features/button/adapters/inbound/Button.js +5 -5
- package/dist/features/button/adapters/inbound/Button.js.map +1 -1
- package/dist/features/button/adapters/inbound/IconButton.d.ts.map +1 -1
- package/dist/features/button/adapters/inbound/IconButton.js +3 -3
- package/dist/features/button/adapters/inbound/IconButton.js.map +1 -1
- package/dist/features/card/adapters/inbound/Card.d.ts.map +1 -1
- package/dist/features/card/adapters/inbound/Card.js +3 -3
- package/dist/features/card/adapters/inbound/Card.js.map +1 -1
- package/dist/features/form/checkbox/adapters/inbound/Checkbox.d.ts.map +1 -1
- package/dist/features/form/checkbox/adapters/inbound/Checkbox.js +3 -3
- package/dist/features/form/checkbox/adapters/inbound/Checkbox.js.map +1 -1
- package/dist/{components/field → features/form/field/adapters/inbound}/Field.d.ts +2 -2
- package/dist/features/form/field/adapters/inbound/Field.d.ts.map +1 -0
- package/dist/features/form/field/adapters/inbound/Field.js +40 -0
- package/dist/features/form/field/adapters/inbound/Field.js.map +1 -0
- package/dist/features/form/field/public.d.ts +3 -0
- package/dist/features/form/field/public.d.ts.map +1 -0
- package/dist/features/form/field/public.js +2 -0
- package/dist/features/form/field/public.js.map +1 -0
- package/dist/features/form/radio/adapters/inbound/Radio.d.ts.map +1 -1
- package/dist/features/form/radio/adapters/inbound/Radio.js +3 -3
- package/dist/features/form/radio/adapters/inbound/Radio.js.map +1 -1
- package/dist/{components/switch → features/form/switch/adapters/inbound}/Switch.d.ts +1 -1
- package/dist/features/form/switch/adapters/inbound/Switch.d.ts.map +1 -0
- package/dist/features/form/switch/adapters/inbound/Switch.js +52 -0
- package/dist/features/form/switch/adapters/inbound/Switch.js.map +1 -0
- package/dist/features/form/switch/public.d.ts +3 -0
- package/dist/features/form/switch/public.d.ts.map +1 -0
- package/dist/features/form/switch/public.js +2 -0
- package/dist/features/form/switch/public.js.map +1 -0
- package/dist/features/form/text-input/adapters/inbound/TextInput.d.ts.map +1 -1
- package/dist/features/form/text-input/adapters/inbound/TextInput.js +8 -4
- package/dist/features/form/text-input/adapters/inbound/TextInput.js.map +1 -1
- package/dist/features/list/adapters/inbound/List.d.ts +5 -0
- package/dist/features/list/adapters/inbound/List.d.ts.map +1 -0
- package/dist/features/list/adapters/inbound/List.js +7 -0
- package/dist/features/list/adapters/inbound/List.js.map +1 -0
- package/dist/features/list/adapters/inbound/ListItem.d.ts +5 -0
- package/dist/features/list/adapters/inbound/ListItem.d.ts.map +1 -0
- package/dist/features/list/adapters/inbound/ListItem.js +59 -0
- package/dist/features/list/adapters/inbound/ListItem.js.map +1 -0
- package/dist/features/list/public.d.ts +4 -0
- package/dist/features/list/public.d.ts.map +1 -0
- package/dist/features/list/public.js +3 -0
- package/dist/features/list/public.js.map +1 -0
- package/dist/features/pressable/adapters/inbound/Pressable.d.ts +5 -0
- package/dist/features/pressable/adapters/inbound/Pressable.d.ts.map +1 -0
- package/dist/features/pressable/adapters/inbound/Pressable.js +48 -0
- package/dist/features/pressable/adapters/inbound/Pressable.js.map +1 -0
- package/dist/features/pressable/public.d.ts +3 -0
- package/dist/features/pressable/public.d.ts.map +1 -0
- package/dist/features/pressable/public.js +2 -0
- package/dist/features/pressable/public.js.map +1 -0
- package/dist/index.d.ts +8 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -7
- package/dist/index.js.map +1 -1
- package/dist/types/button.d.ts +3 -3
- package/dist/types/button.d.ts.map +1 -1
- package/dist/types/button.js.map +1 -1
- package/dist/types/checkbox.d.ts +2 -2
- package/dist/types/checkbox.d.ts.map +1 -1
- package/dist/types/checkbox.js.map +1 -1
- package/dist/{components/field/types.d.ts → types/field.d.ts} +1 -1
- package/dist/types/field.d.ts.map +1 -0
- package/dist/types/field.js +2 -0
- package/dist/types/field.js.map +1 -0
- package/dist/types/list.d.ts +20 -0
- package/dist/types/list.d.ts.map +1 -0
- package/dist/types/list.js +2 -0
- package/dist/types/list.js.map +1 -0
- package/dist/{primitives/button-base/types.d.ts → types/pressable.d.ts} +5 -5
- package/dist/types/pressable.d.ts.map +1 -0
- package/dist/types/pressable.js +2 -0
- package/dist/types/pressable.js.map +1 -0
- package/dist/types/radio.d.ts +2 -2
- package/dist/types/radio.d.ts.map +1 -1
- package/dist/types/radio.js.map +1 -1
- package/dist/types/switch.d.ts +15 -0
- package/dist/types/switch.d.ts.map +1 -0
- package/dist/types/switch.js +2 -0
- package/dist/types/switch.js.map +1 -0
- package/package.json +1 -1
- package/src/features/button/adapters/inbound/Button.tsx +6 -6
- package/src/features/button/adapters/inbound/IconButton.tsx +3 -3
- package/src/features/card/adapters/inbound/Card.tsx +3 -3
- package/src/features/form/checkbox/adapters/inbound/Checkbox.tsx +5 -5
- package/src/features/form/field/adapters/inbound/Field.tsx +82 -0
- package/src/features/form/field/public.ts +2 -0
- package/src/features/form/radio/adapters/inbound/Radio.tsx +5 -5
- package/src/features/form/switch/adapters/inbound/Switch.tsx +123 -0
- package/src/features/form/switch/public.ts +2 -0
- package/src/features/form/text-input/adapters/inbound/TextInput.tsx +21 -5
- package/src/features/list/adapters/inbound/List.tsx +9 -0
- package/src/features/list/adapters/inbound/ListItem.tsx +128 -0
- package/src/features/list/public.test.ts +13 -0
- package/src/features/list/public.ts +3 -0
- package/src/{primitives/button-base/ButtonBase.tsx → features/pressable/adapters/inbound/Pressable.tsx} +45 -31
- package/src/features/pressable/public.ts +2 -0
- package/src/index.test.ts +17 -11
- package/src/index.ts +8 -14
- package/src/interactionPolicy.test.ts +4 -4
- package/src/types/button.ts +3 -3
- package/src/types/checkbox.ts +2 -2
- package/src/types/list.ts +22 -0
- package/src/{primitives/button-base/types.ts → types/pressable.ts} +4 -4
- package/src/types/radio.ts +2 -2
- package/src/{components/switch/types.ts → types/switch.ts} +4 -4
- package/dist/components/field/Field.d.ts.map +0 -1
- package/dist/components/field/Field.js +0 -27
- package/dist/components/field/Field.js.map +0 -1
- package/dist/components/field/index.d.ts +0 -3
- package/dist/components/field/index.d.ts.map +0 -1
- package/dist/components/field/index.js +0 -2
- package/dist/components/field/index.js.map +0 -1
- package/dist/components/field/types.d.ts.map +0 -1
- package/dist/components/field/types.js +0 -2
- package/dist/components/field/types.js.map +0 -1
- package/dist/components/helper-text/HelperText.d.ts +0 -4
- package/dist/components/helper-text/HelperText.d.ts.map +0 -1
- package/dist/components/helper-text/HelperText.js +0 -8
- package/dist/components/helper-text/HelperText.js.map +0 -1
- package/dist/components/helper-text/index.d.ts +0 -3
- package/dist/components/helper-text/index.d.ts.map +0 -1
- package/dist/components/helper-text/index.js +0 -2
- package/dist/components/helper-text/index.js.map +0 -1
- package/dist/components/helper-text/types.d.ts +0 -9
- package/dist/components/helper-text/types.d.ts.map +0 -1
- package/dist/components/helper-text/types.js +0 -2
- package/dist/components/helper-text/types.js.map +0 -1
- package/dist/components/label/Label.d.ts +0 -4
- package/dist/components/label/Label.d.ts.map +0 -1
- package/dist/components/label/Label.js +0 -11
- package/dist/components/label/Label.js.map +0 -1
- package/dist/components/label/index.d.ts +0 -3
- package/dist/components/label/index.d.ts.map +0 -1
- package/dist/components/label/index.js +0 -2
- package/dist/components/label/index.js.map +0 -1
- package/dist/components/label/types.d.ts +0 -10
- package/dist/components/label/types.d.ts.map +0 -1
- package/dist/components/label/types.js +0 -2
- package/dist/components/label/types.js.map +0 -1
- package/dist/components/list-item/ListItem.d.ts +0 -5
- package/dist/components/list-item/ListItem.d.ts.map +0 -1
- package/dist/components/list-item/ListItem.js +0 -44
- package/dist/components/list-item/ListItem.js.map +0 -1
- package/dist/components/list-item/index.d.ts +0 -3
- package/dist/components/list-item/index.d.ts.map +0 -1
- package/dist/components/list-item/index.js +0 -2
- package/dist/components/list-item/index.js.map +0 -1
- package/dist/components/list-item/types.d.ts +0 -11
- package/dist/components/list-item/types.d.ts.map +0 -1
- package/dist/components/list-item/types.js +0 -2
- package/dist/components/list-item/types.js.map +0 -1
- package/dist/components/switch/Switch.d.ts.map +0 -1
- package/dist/components/switch/Switch.js +0 -68
- package/dist/components/switch/Switch.js.map +0 -1
- package/dist/components/switch/index.d.ts +0 -3
- package/dist/components/switch/index.d.ts.map +0 -1
- package/dist/components/switch/index.js +0 -2
- package/dist/components/switch/index.js.map +0 -1
- package/dist/components/switch/types.d.ts +0 -15
- package/dist/components/switch/types.d.ts.map +0 -1
- package/dist/components/switch/types.js +0 -2
- package/dist/components/switch/types.js.map +0 -1
- package/dist/components/textarea/Textarea.d.ts +0 -4
- package/dist/components/textarea/Textarea.d.ts.map +0 -1
- package/dist/components/textarea/Textarea.js +0 -6
- package/dist/components/textarea/Textarea.js.map +0 -1
- package/dist/components/textarea/index.d.ts +0 -3
- package/dist/components/textarea/index.d.ts.map +0 -1
- package/dist/components/textarea/index.js +0 -2
- package/dist/components/textarea/index.js.map +0 -1
- package/dist/components/textarea/types.d.ts +0 -5
- package/dist/components/textarea/types.d.ts.map +0 -1
- package/dist/components/textarea/types.js +0 -2
- package/dist/components/textarea/types.js.map +0 -1
- package/dist/primitives/button-base/ButtonBase.d.ts +0 -5
- package/dist/primitives/button-base/ButtonBase.d.ts.map +0 -1
- package/dist/primitives/button-base/ButtonBase.js +0 -42
- package/dist/primitives/button-base/ButtonBase.js.map +0 -1
- package/dist/primitives/button-base/index.d.ts +0 -3
- package/dist/primitives/button-base/index.d.ts.map +0 -1
- package/dist/primitives/button-base/index.js +0 -2
- package/dist/primitives/button-base/index.js.map +0 -1
- package/dist/primitives/button-base/types.d.ts.map +0 -1
- package/dist/primitives/button-base/types.js +0 -2
- package/dist/primitives/button-base/types.js.map +0 -1
- package/src/components/field/Field.tsx +0 -52
- package/src/components/field/index.ts +0 -2
- package/src/components/helper-text/HelperText.tsx +0 -12
- package/src/components/helper-text/index.ts +0 -2
- package/src/components/helper-text/types.ts +0 -10
- package/src/components/label/Label.tsx +0 -23
- package/src/components/label/index.ts +0 -2
- package/src/components/label/types.ts +0 -11
- package/src/components/list-item/ListItem.tsx +0 -76
- package/src/components/list-item/index.ts +0 -2
- package/src/components/list-item/types.ts +0 -11
- package/src/components/switch/Switch.tsx +0 -113
- package/src/components/switch/index.ts +0 -2
- package/src/components/textarea/Textarea.tsx +0 -15
- package/src/components/textarea/index.ts +0 -2
- package/src/components/textarea/types.ts +0 -5
- package/src/primitives/button-base/index.ts +0 -2
- /package/src/{components/field/types.ts → types/field.ts} +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { useTheme } from '../../../../theme/ThemeContext';
|
|
4
|
+
import type { SurfaceTheme } from '../../../../theme/types';
|
|
5
|
+
import type { ListItemProps } from '../../../../types/list';
|
|
6
|
+
import { View } from '../../../layout/public';
|
|
7
|
+
import { Pressable } from '../../../pressable/public';
|
|
8
|
+
import { Text } from '../../../typography/public';
|
|
9
|
+
|
|
10
|
+
/*** Renders a static or interactive list item with shared row geometry and interaction states. */
|
|
11
|
+
export function ListItem(props: ListItemProps) {
|
|
12
|
+
const { theme } = useTheme();
|
|
13
|
+
if (!props.onPress) return renderStaticListItem(props, theme);
|
|
14
|
+
return renderInteractiveListItem({ ...props, onPress: props.onPress }, theme);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/*** Renders a non-pressable list item. */
|
|
18
|
+
function renderStaticListItem(props: ListItemProps, theme: SurfaceTheme) {
|
|
19
|
+
return (
|
|
20
|
+
<ListItemContent
|
|
21
|
+
{...props}
|
|
22
|
+
backgroundColor={props.selected ? theme.semantics.selection.background : 'transparent'}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/*** Renders a pressable list item with shared interaction-state presentation. */
|
|
28
|
+
function renderInteractiveListItem(
|
|
29
|
+
props: ListItemProps & { onPress: NonNullable<ListItemProps['onPress']> },
|
|
30
|
+
theme: SurfaceTheme,
|
|
31
|
+
) {
|
|
32
|
+
return (
|
|
33
|
+
<Pressable
|
|
34
|
+
accessibilityLabel={props.accessibilityLabel}
|
|
35
|
+
accessibilityRole="button"
|
|
36
|
+
accessibilityState={{ disabled: props.disabled ?? false, selected: props.selected ?? false }}
|
|
37
|
+
disabled={props.disabled ?? false}
|
|
38
|
+
interactionPolicy={props.interactionPolicy}
|
|
39
|
+
onPress={props.onPress}
|
|
40
|
+
testID={props.testID}
|
|
41
|
+
>
|
|
42
|
+
{(state) => (
|
|
43
|
+
<ListItemContent
|
|
44
|
+
{...props}
|
|
45
|
+
backgroundColor={resolveListItemBackground(theme, {
|
|
46
|
+
hovered: state.hovered,
|
|
47
|
+
pressed: state.pressed,
|
|
48
|
+
selected: props.selected ?? false,
|
|
49
|
+
})}
|
|
50
|
+
disabled={state.disabled}
|
|
51
|
+
testID={undefined}
|
|
52
|
+
/>
|
|
53
|
+
)}
|
|
54
|
+
</Pressable>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface ListItemBackgroundState {
|
|
59
|
+
hovered: boolean;
|
|
60
|
+
pressed: boolean;
|
|
61
|
+
selected: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
type ListItemContentProps = Omit<
|
|
65
|
+
ListItemProps,
|
|
66
|
+
'accessibilityLabel' | 'interactionPolicy' | 'onPress' | 'selected'
|
|
67
|
+
> & {
|
|
68
|
+
backgroundColor: string;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/*** Resolves the neutral list-item background for one interaction state. */
|
|
72
|
+
function resolveListItemBackground(theme: SurfaceTheme, state: ListItemBackgroundState) {
|
|
73
|
+
if (state.pressed) return theme.semantics.neutral.surfaceActive;
|
|
74
|
+
if (state.hovered) return theme.semantics.neutral.surfaceHover;
|
|
75
|
+
if (state.selected) return theme.semantics.selection.background;
|
|
76
|
+
return 'transparent';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/*** Renders the shared visual row content for static and interactive list items. */
|
|
80
|
+
function ListItemContent({
|
|
81
|
+
backgroundColor,
|
|
82
|
+
children,
|
|
83
|
+
compact = false,
|
|
84
|
+
description,
|
|
85
|
+
disabled = false,
|
|
86
|
+
leading,
|
|
87
|
+
testID,
|
|
88
|
+
title,
|
|
89
|
+
trailing,
|
|
90
|
+
}: ListItemContentProps) {
|
|
91
|
+
const content = children ?? renderDefaultContent(title, description);
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<View
|
|
95
|
+
align="center"
|
|
96
|
+
bg={backgroundColor}
|
|
97
|
+
direction="row"
|
|
98
|
+
gap="m"
|
|
99
|
+
opacity={disabled ? 0.72 : 1}
|
|
100
|
+
px="m"
|
|
101
|
+
py={compact ? 's' : 'm'}
|
|
102
|
+
testID={testID}
|
|
103
|
+
>
|
|
104
|
+
{leading !== undefined ? <View>{leading}</View> : null}
|
|
105
|
+
<View flex={1}>{content}</View>
|
|
106
|
+
{trailing !== undefined ? <View>{trailing}</View> : null}
|
|
107
|
+
</View>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/*** Renders the default title and description content when custom children are absent. */
|
|
112
|
+
function renderDefaultContent(title: React.ReactNode, description: React.ReactNode) {
|
|
113
|
+
if (title === undefined && description === undefined) return null;
|
|
114
|
+
return (
|
|
115
|
+
<View flex={1} gap="xs">
|
|
116
|
+
{title !== undefined ? (
|
|
117
|
+
<Text numberOfLines={1} variant="body" weight="medium">
|
|
118
|
+
{title}
|
|
119
|
+
</Text>
|
|
120
|
+
) : null}
|
|
121
|
+
{description !== undefined ? (
|
|
122
|
+
<Text emphasis="muted" numberOfLines={2} variant="bodySmall">
|
|
123
|
+
{description}
|
|
124
|
+
</Text>
|
|
125
|
+
) : null}
|
|
126
|
+
</View>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
test('list capability owns List and ListItem under one feature boundary', async () => {
|
|
4
|
+
const listSource = await Bun.file('src/features/list/adapters/inbound/List.tsx').text();
|
|
5
|
+
const listItemSource = await Bun.file('src/features/list/adapters/inbound/ListItem.tsx').text();
|
|
6
|
+
|
|
7
|
+
expect(listSource).toContain('export function List');
|
|
8
|
+
expect(listItemSource).toContain('export function ListItem');
|
|
9
|
+
expect(listItemSource).toContain('interactionPolicy={props.interactionPolicy}');
|
|
10
|
+
expect(listItemSource).toContain('selected');
|
|
11
|
+
expect(listItemSource).toContain('compact');
|
|
12
|
+
expect(listItemSource).not.toContain('components/list-item');
|
|
13
|
+
});
|
|
@@ -1,33 +1,22 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Platform,
|
|
4
|
+
Pressable as ReactNativePressable,
|
|
5
|
+
type PressableStateCallbackType,
|
|
6
|
+
} from 'react-native';
|
|
3
7
|
|
|
4
|
-
import { useResponsiveRuntime } from '
|
|
8
|
+
import { useResponsiveRuntime } from '../../../../core/responsive';
|
|
5
9
|
import {
|
|
6
10
|
type InteractionState,
|
|
7
11
|
resolveFocusRingStyles,
|
|
8
12
|
resolveInteractiveState,
|
|
9
|
-
} from '
|
|
10
|
-
import { useTheme } from '
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
+
} from '../../../../internal/resolvers';
|
|
14
|
+
import { useTheme } from '../../../../theme/ThemeContext';
|
|
15
|
+
import type { PressableProps } from '../../../../types/pressable';
|
|
16
|
+
import { resolveViewStyles } from '../../../../utils/resolveViewStyles';
|
|
13
17
|
|
|
14
|
-
/***
|
|
15
|
-
function
|
|
16
|
-
pressableState: PressableStateCallbackType,
|
|
17
|
-
hovered: boolean,
|
|
18
|
-
focused: boolean,
|
|
19
|
-
disabled: boolean,
|
|
20
|
-
): InteractionState {
|
|
21
|
-
return resolveInteractiveState({
|
|
22
|
-
pressed: pressableState.pressed,
|
|
23
|
-
hovered,
|
|
24
|
-
focused,
|
|
25
|
-
disabled,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/*** Renders the low-level token-aware Pressable boundary shared by Surface controls. */
|
|
30
|
-
export function ButtonBase({
|
|
18
|
+
/*** Renders the token-aware Surface adapter for React Native Pressable. */
|
|
19
|
+
export function Pressable({
|
|
31
20
|
children,
|
|
32
21
|
disabled = false,
|
|
33
22
|
interactionPolicy = 'enabled',
|
|
@@ -39,17 +28,18 @@ export function ButtonBase({
|
|
|
39
28
|
style,
|
|
40
29
|
testID,
|
|
41
30
|
...props
|
|
42
|
-
}:
|
|
31
|
+
}: PressableProps) {
|
|
43
32
|
const { theme } = useTheme();
|
|
44
33
|
const { breakpoint } = useResponsiveRuntime();
|
|
45
34
|
const [hovered, setHovered] = React.useState(false);
|
|
46
35
|
const [focused, setFocused] = React.useState(false);
|
|
47
36
|
const isWeb = Platform.OS === 'web';
|
|
48
37
|
const resolvedViewStyles = resolveViewStyles(theme, breakpoint, props);
|
|
49
|
-
const
|
|
38
|
+
const pressHandlers = resolvePressHandlers(interactionPolicy, onPress, onLongPress);
|
|
50
39
|
|
|
51
40
|
return (
|
|
52
|
-
<
|
|
41
|
+
<ReactNativePressable
|
|
42
|
+
{...pressHandlers}
|
|
53
43
|
accessibilityLabel={accessibilityLabel}
|
|
54
44
|
accessibilityRole={accessibilityRole}
|
|
55
45
|
accessibilityState={{ ...accessibilityState, disabled }}
|
|
@@ -60,10 +50,8 @@ export function ButtonBase({
|
|
|
60
50
|
}}
|
|
61
51
|
onHoverIn={isWeb ? () => setHovered(true) : undefined}
|
|
62
52
|
onHoverOut={isWeb ? () => setHovered(false) : undefined}
|
|
63
|
-
onLongPress={passive ? undefined : onLongPress}
|
|
64
|
-
onPress={passive ? undefined : onPress}
|
|
65
53
|
style={(pressableState) => {
|
|
66
|
-
const state =
|
|
54
|
+
const state = resolveInteractionState(pressableState, hovered, focused, disabled);
|
|
67
55
|
return [
|
|
68
56
|
resolvedViewStyles,
|
|
69
57
|
resolveFocusRingStyles(theme.semantics.border.focus, state.focused, isWeb),
|
|
@@ -73,9 +61,35 @@ export function ButtonBase({
|
|
|
73
61
|
testID={testID}
|
|
74
62
|
>
|
|
75
63
|
{(pressableState) => {
|
|
76
|
-
const state =
|
|
64
|
+
const state = resolveInteractionState(pressableState, hovered, focused, disabled);
|
|
77
65
|
return typeof children === 'function' ? children(state) : children;
|
|
78
66
|
}}
|
|
79
|
-
</
|
|
67
|
+
</ReactNativePressable>
|
|
80
68
|
);
|
|
81
69
|
}
|
|
70
|
+
|
|
71
|
+
/*** Resolves press handlers according to the shared interaction policy. */
|
|
72
|
+
function resolvePressHandlers(
|
|
73
|
+
interactionPolicy: PressableProps['interactionPolicy'],
|
|
74
|
+
onPress: PressableProps['onPress'],
|
|
75
|
+
onLongPress: PressableProps['onLongPress'],
|
|
76
|
+
) {
|
|
77
|
+
return interactionPolicy === 'passive'
|
|
78
|
+
? { onLongPress: undefined, onPress: undefined }
|
|
79
|
+
: { onLongPress, onPress };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/*** Resolves one native Pressable state into the canonical Surface interaction state. */
|
|
83
|
+
function resolveInteractionState(
|
|
84
|
+
pressableState: PressableStateCallbackType,
|
|
85
|
+
hovered: boolean,
|
|
86
|
+
focused: boolean,
|
|
87
|
+
disabled: boolean,
|
|
88
|
+
): InteractionState {
|
|
89
|
+
return resolveInteractiveState({
|
|
90
|
+
pressed: pressableState.pressed,
|
|
91
|
+
hovered,
|
|
92
|
+
focused,
|
|
93
|
+
disabled,
|
|
94
|
+
});
|
|
95
|
+
}
|
package/src/index.test.ts
CHANGED
|
@@ -22,15 +22,19 @@ const expectedFeatureRootExports = [
|
|
|
22
22
|
"export { Button, IconButton } from './features/button/public';",
|
|
23
23
|
"export { Card } from './features/card/public';",
|
|
24
24
|
"export { Checkbox } from './features/form/checkbox/public';",
|
|
25
|
+
"export { Field } from './features/form/field/public';",
|
|
25
26
|
"export { Radio } from './features/form/radio/public';",
|
|
27
|
+
"export { Switch } from './features/form/switch/public';",
|
|
26
28
|
"export { TextInput } from './features/form/text-input/public';",
|
|
27
29
|
"export { Icon, SUPPORTED_ICON_PROVIDERS } from './features/icon/public';",
|
|
28
30
|
"export { Image } from './features/image/public';",
|
|
29
31
|
"export { KeyboardAvoidingView } from './features/keyboard-avoiding-view/public';",
|
|
30
32
|
"export { Divider, Grid, ScrollView, View } from './features/layout/public';",
|
|
33
|
+
"export { List, ListItem } from './features/list/public';",
|
|
31
34
|
"export { Modal } from './features/modal/public';",
|
|
32
35
|
"export { PopoverMenu } from './features/popover-menu/public';",
|
|
33
36
|
"export { Popover } from './features/popover/public';",
|
|
37
|
+
"export { Pressable } from './features/pressable/public';",
|
|
34
38
|
"export { Surface } from './features/surface/public';",
|
|
35
39
|
"export { Tab, TabList, TabPanel, Tabs } from './features/tabs/public';",
|
|
36
40
|
"export { Tooltip } from './features/tooltip/public';",
|
|
@@ -38,38 +42,40 @@ const expectedFeatureRootExports = [
|
|
|
38
42
|
"export { Heading, Text } from './features/typography/public';",
|
|
39
43
|
] as const;
|
|
40
44
|
|
|
41
|
-
const
|
|
42
|
-
"export { Field } from './components/field';",
|
|
43
|
-
"export { HelperText } from './components/helper-text';",
|
|
44
|
-
"export { Label } from './components/label';",
|
|
45
|
-
"export { ListItem } from './components/list-item';",
|
|
46
|
-
"export { Switch } from './components/switch';",
|
|
47
|
-
"export { Textarea } from './components/textarea';",
|
|
45
|
+
const expectedCrossCuttingRootExports = [
|
|
48
46
|
"export type { InteractionPolicy, InteractionPolicyProps } from './interactionPolicy';",
|
|
49
47
|
"export * from './core/responsive';",
|
|
50
48
|
] as const;
|
|
51
49
|
|
|
52
50
|
describe('feature-owned root barrel contract', () => {
|
|
53
|
-
it('routes
|
|
51
|
+
it('routes UI through feature-owned public facades', () => {
|
|
54
52
|
expectedFeatureRootExports.forEach((line) => expect(indexSource).toContain(line));
|
|
55
53
|
});
|
|
56
54
|
|
|
57
|
-
it('does not retain removed
|
|
55
|
+
it('does not retain removed component or layout facades and aliases', () => {
|
|
56
|
+
expect(indexSource).not.toContain("'./components/");
|
|
58
57
|
expect(indexSource).not.toContain("'./layout");
|
|
58
|
+
expect(indexSource).not.toContain("'./primitives/");
|
|
59
59
|
expect(indexSource).not.toMatch(/\bBoxProps\b/u);
|
|
60
60
|
expect(indexSource).not.toMatch(/\bContainerProps\b/u);
|
|
61
61
|
expect(indexSource).not.toMatch(/\bStackProps\b/u);
|
|
62
62
|
expect(indexSource).not.toMatch(/\bScrollAreaProps\b/u);
|
|
63
|
+
expect(indexSource).not.toMatch(/\bTextareaProps\b/u);
|
|
64
|
+
expect(indexSource).not.toMatch(/\bHelperTextProps\b/u);
|
|
65
|
+
expect(indexSource).not.toMatch(/\bLabelProps\b/u);
|
|
63
66
|
expect(indexSource).not.toMatch(/export\s*\{[^}]*\bBox\b/u);
|
|
64
67
|
expect(indexSource).not.toMatch(/export\s*\{[^}]*\bContainer\b/u);
|
|
65
68
|
expect(indexSource).not.toMatch(/export\s*\{[^}]*\bStack\b/u);
|
|
66
69
|
expect(indexSource).not.toMatch(/export\s*\{[^}]*\bScrollArea\b/u);
|
|
70
|
+
expect(indexSource).not.toMatch(/export\s*\{[^}]*\bTextarea\b/u);
|
|
71
|
+
expect(indexSource).not.toMatch(/export\s*\{[^}]*\bHelperText\b/u);
|
|
72
|
+
expect(indexSource).not.toMatch(/export\s*\{[^}]*\bLabel\b/u);
|
|
67
73
|
});
|
|
68
74
|
});
|
|
69
75
|
|
|
70
76
|
describe('remaining root barrel contract', () => {
|
|
71
|
-
it('keeps
|
|
72
|
-
|
|
77
|
+
it('keeps deliberate cross-cutting public APIs', () => {
|
|
78
|
+
expectedCrossCuttingRootExports.forEach((line) => expect(indexSource).toContain(line));
|
|
73
79
|
});
|
|
74
80
|
|
|
75
81
|
it('does not retain obsolete action-sheet, drawer, menu aliases, or navigation chrome', () => {
|
package/src/index.ts
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
export type { FieldProps } from './components/field';
|
|
2
|
-
export { Field } from './components/field';
|
|
3
|
-
export type { HelperTextProps } from './components/helper-text';
|
|
4
|
-
export { HelperText } from './components/helper-text';
|
|
5
|
-
export type { LabelProps } from './components/label';
|
|
6
|
-
export { Label } from './components/label';
|
|
7
|
-
export type { ListItemProps } from './components/list-item';
|
|
8
|
-
export { ListItem } from './components/list-item';
|
|
9
|
-
export type { SwitchProps } from './components/switch';
|
|
10
|
-
export { Switch } from './components/switch';
|
|
11
|
-
export type { TextareaProps } from './components/textarea';
|
|
12
|
-
export { Textarea } from './components/textarea';
|
|
13
1
|
export type { FontRuntime } from './context/FontContext';
|
|
14
2
|
export { FontProvider, useFontContext } from './context/FontContext';
|
|
15
3
|
export type { I18nInstance, TranslationRuntime, Translator } from './context/TranslationContext';
|
|
@@ -40,8 +28,12 @@ export type { CardProps } from './features/card/public';
|
|
|
40
28
|
export { Card } from './features/card/public';
|
|
41
29
|
export type { CheckboxProps } from './features/form/checkbox/public';
|
|
42
30
|
export { Checkbox } from './features/form/checkbox/public';
|
|
31
|
+
export type { FieldProps } from './features/form/field/public';
|
|
32
|
+
export { Field } from './features/form/field/public';
|
|
43
33
|
export type { RadioProps } from './features/form/radio/public';
|
|
44
34
|
export { Radio } from './features/form/radio/public';
|
|
35
|
+
export type { SwitchProps } from './features/form/switch/public';
|
|
36
|
+
export { Switch } from './features/form/switch/public';
|
|
45
37
|
export type { TextInputProps } from './features/form/text-input/public';
|
|
46
38
|
export { TextInput } from './features/form/text-input/public';
|
|
47
39
|
export type {
|
|
@@ -62,6 +54,8 @@ export type {
|
|
|
62
54
|
export { KeyboardAvoidingView } from './features/keyboard-avoiding-view/public';
|
|
63
55
|
export type { DividerProps, GridProps, ScrollViewProps, ViewProps } from './features/layout/public';
|
|
64
56
|
export { Divider, Grid, ScrollView, View } from './features/layout/public';
|
|
57
|
+
export type { ListItemProps, ListProps } from './features/list/public';
|
|
58
|
+
export { List, ListItem } from './features/list/public';
|
|
65
59
|
export type { ModalProps } from './features/modal/public';
|
|
66
60
|
export { Modal } from './features/modal/public';
|
|
67
61
|
export type {
|
|
@@ -76,6 +70,8 @@ export type {
|
|
|
76
70
|
PopoverMenuProps,
|
|
77
71
|
} from './features/popover-menu/public';
|
|
78
72
|
export { PopoverMenu } from './features/popover-menu/public';
|
|
73
|
+
export type { PressableProps } from './features/pressable/public';
|
|
74
|
+
export { Pressable } from './features/pressable/public';
|
|
79
75
|
export type { SurfaceProps, SurfaceVariant } from './features/surface/public';
|
|
80
76
|
export { Surface } from './features/surface/public';
|
|
81
77
|
export type { TabListProps, TabPanelProps, TabProps, TabsProps } from './features/tabs/public';
|
|
@@ -93,8 +89,6 @@ export { Tooltip } from './features/tooltip/public';
|
|
|
93
89
|
export type { HeadingLevel, HeadingProps, TextProps } from './features/typography/public';
|
|
94
90
|
export { Heading, Text } from './features/typography/public';
|
|
95
91
|
export type { InteractionPolicy, InteractionPolicyProps } from './interactionPolicy';
|
|
96
|
-
export type { ButtonBaseProps } from './primitives/button-base';
|
|
97
|
-
export { ButtonBase } from './primitives/button-base';
|
|
98
92
|
export type {
|
|
99
93
|
SurfaceColor,
|
|
100
94
|
SurfaceEmphasis,
|
|
@@ -19,7 +19,7 @@ describe('InteractionPolicy public export', () => {
|
|
|
19
19
|
|
|
20
20
|
it('does not export InteractionPolicy from button-base', () => {
|
|
21
21
|
expect(indexSource).not.toContain(
|
|
22
|
-
"export type { InteractionPolicy, InteractionPolicyProps } from './
|
|
22
|
+
"export type { InteractionPolicy, InteractionPolicyProps } from './features/pressable/public';",
|
|
23
23
|
);
|
|
24
24
|
});
|
|
25
25
|
});
|
|
@@ -57,10 +57,10 @@ describe('InteractionPolicyProps', () => {
|
|
|
57
57
|
});
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
describe('
|
|
61
|
-
it('has interactionPolicy in
|
|
60
|
+
describe('PressableProps includes interactionPolicy', () => {
|
|
61
|
+
it('has interactionPolicy in PressableProps', () => {
|
|
62
62
|
expect(indexSource).toContain(
|
|
63
|
-
"export type {
|
|
63
|
+
"export type { PressableProps } from './features/pressable/public';",
|
|
64
64
|
);
|
|
65
65
|
});
|
|
66
66
|
});
|
package/src/types/button.ts
CHANGED
|
@@ -2,14 +2,14 @@ import type React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import type { ControlSize } from '../internal/resolvers/resolveControlSize';
|
|
4
4
|
import type { ButtonVariant } from '../internal/resolvers/resolveInteractiveColors';
|
|
5
|
-
import type { ButtonBaseProps } from '../primitives/button-base';
|
|
6
5
|
import type { SurfaceColor } from '../surfaceColor';
|
|
7
6
|
import type { IconSource } from './icon';
|
|
7
|
+
import type { PressableProps } from './pressable';
|
|
8
8
|
|
|
9
9
|
export type ButtonIconSpec = IconSource;
|
|
10
10
|
|
|
11
11
|
export interface ButtonProps extends Omit<
|
|
12
|
-
|
|
12
|
+
PressableProps,
|
|
13
13
|
'accessibilityLabel' | 'children' | 'style'
|
|
14
14
|
> {
|
|
15
15
|
children?: React.ReactNode;
|
|
@@ -23,7 +23,7 @@ export interface ButtonProps extends Omit<
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export interface IconButtonProps extends Omit<
|
|
26
|
-
|
|
26
|
+
PressableProps,
|
|
27
27
|
'children' | 'style' | 'accessibilityLabel'
|
|
28
28
|
> {
|
|
29
29
|
icon: IconSource;
|
package/src/types/checkbox.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
|
|
3
3
|
import type { ControlSize } from '../internal/resolvers/resolveControlSize';
|
|
4
|
-
import type { ButtonBaseProps } from '../primitives/button-base';
|
|
5
4
|
import type { SurfaceColor } from '../surfaceColor';
|
|
5
|
+
import type { PressableProps } from './pressable';
|
|
6
6
|
|
|
7
7
|
export interface CheckboxProps extends Omit<
|
|
8
|
-
|
|
8
|
+
PressableProps,
|
|
9
9
|
'accessibilityRole' | 'accessibilityState' | 'children' | 'onPress' | 'style'
|
|
10
10
|
> {
|
|
11
11
|
children?: React.ReactNode;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { InteractionPolicyProps } from '../interactionPolicy';
|
|
4
|
+
|
|
5
|
+
export interface ListProps {
|
|
6
|
+
children?: React.ReactNode;
|
|
7
|
+
testID?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ListItemProps extends InteractionPolicyProps {
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
title?: React.ReactNode;
|
|
13
|
+
description?: React.ReactNode;
|
|
14
|
+
leading?: React.ReactNode;
|
|
15
|
+
trailing?: React.ReactNode;
|
|
16
|
+
onPress?: (() => void) | undefined;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
selected?: boolean;
|
|
19
|
+
compact?: boolean;
|
|
20
|
+
accessibilityLabel?: string;
|
|
21
|
+
testID?: string;
|
|
22
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import type { AccessibilityRole, AccessibilityState, GestureResponderEvent } from 'react-native';
|
|
3
3
|
|
|
4
|
-
import type { InteractionPolicyProps } from '
|
|
5
|
-
import type { InteractionState } from '
|
|
6
|
-
import type { ViewProps } from '
|
|
4
|
+
import type { InteractionPolicyProps } from '../interactionPolicy';
|
|
5
|
+
import type { InteractionState } from '../internal/resolvers/resolveInteractiveState';
|
|
6
|
+
import type { ViewProps } from './layout';
|
|
7
7
|
|
|
8
|
-
export interface
|
|
8
|
+
export interface PressableProps
|
|
9
9
|
extends Omit<ViewProps, 'children' | 'pointerEvents'>, InteractionPolicyProps {
|
|
10
10
|
children?: React.ReactNode | ((state: InteractionState) => React.ReactNode);
|
|
11
11
|
disabled?: boolean;
|
package/src/types/radio.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
|
|
3
3
|
import type { ControlSize } from '../internal/resolvers/resolveControlSize';
|
|
4
|
-
import type { ButtonBaseProps } from '../primitives/button-base';
|
|
5
4
|
import type { SurfaceColor } from '../surfaceColor';
|
|
5
|
+
import type { PressableProps } from './pressable';
|
|
6
6
|
|
|
7
7
|
export interface RadioProps extends Omit<
|
|
8
|
-
|
|
8
|
+
PressableProps,
|
|
9
9
|
'accessibilityRole' | 'accessibilityState' | 'children' | 'onPress' | 'style'
|
|
10
10
|
> {
|
|
11
11
|
children?: React.ReactNode;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
|
|
3
|
-
import type { ControlSize } from '
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
3
|
+
import type { ControlSize } from '../internal/resolvers/resolveControlSize';
|
|
4
|
+
import type { SurfaceColor } from '../surfaceColor';
|
|
5
|
+
import type { PressableProps } from './pressable';
|
|
6
6
|
|
|
7
7
|
export interface SwitchProps extends Omit<
|
|
8
|
-
|
|
8
|
+
PressableProps,
|
|
9
9
|
'accessibilityRole' | 'accessibilityState' | 'children' | 'onPress' | 'style'
|
|
10
10
|
> {
|
|
11
11
|
children?: React.ReactNode;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../../src/components/field/Field.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,8EAA8E;AAC9E,wBAAgB,KAAK,CAAC,EACpB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,SAAS,EACT,QAAgB,EAChB,QAAgB,EAChB,OAAe,EACf,QAAgB,EAChB,MAAM,GACP,EAAE,UAAU,qBAgCZ"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { View } from '../../features/layout/public';
|
|
3
|
-
import { resolveFieldPresentation, resolveFieldState } from '../../internal/resolvers';
|
|
4
|
-
import { HelperText } from '../helper-text';
|
|
5
|
-
import { Label } from '../label';
|
|
6
|
-
/*** Composes a label, control, and helper or error message into one field. */
|
|
7
|
-
export function Field({ children, label, helperText, errorText, required = false, disabled = false, invalid = false, readOnly = false, testID, }) {
|
|
8
|
-
const hasErrorText = Boolean(errorText);
|
|
9
|
-
const fieldState = resolveFieldState({
|
|
10
|
-
disabled,
|
|
11
|
-
invalid: invalid || hasErrorText,
|
|
12
|
-
readOnly,
|
|
13
|
-
});
|
|
14
|
-
const presentation = resolveFieldPresentation(fieldState);
|
|
15
|
-
return (<View gap="xs" testID={testID}>
|
|
16
|
-
{label ? (<Label color={presentation.labelColor} emphasis={presentation.labelEmphasis} required={required}>
|
|
17
|
-
{label}
|
|
18
|
-
</Label>) : null}
|
|
19
|
-
<View>{children}</View>
|
|
20
|
-
{hasErrorText ? (<HelperText color={presentation.helperColor} emphasis={presentation.helperEmphasis}>
|
|
21
|
-
{errorText}
|
|
22
|
-
</HelperText>) : helperText ? (<HelperText color={presentation.helperColor} emphasis={presentation.helperEmphasis}>
|
|
23
|
-
{helperText}
|
|
24
|
-
</HelperText>) : null}
|
|
25
|
-
</View>);
|
|
26
|
-
}
|
|
27
|
-
//# sourceMappingURL=Field.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Field.js","sourceRoot":"","sources":["../../../src/components/field/Field.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGjC,8EAA8E;AAC9E,MAAM,UAAU,KAAK,CAAC,EACpB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,SAAS,EACT,QAAQ,GAAG,KAAK,EAChB,QAAQ,GAAG,KAAK,EAChB,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,MAAM,GACK;IACX,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,iBAAiB,CAAC;QACnC,QAAQ;QACR,OAAO,EAAE,OAAO,IAAI,YAAY;QAChC,QAAQ;KACT,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAE1D,OAAO,CACL,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAC5B;MAAA,CAAC,KAAK,CAAC,CAAC,CAAC,CACP,CAAC,KAAK,CACJ,KAAK,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CAC/B,QAAQ,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,CACrC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAEnB;UAAA,CAAC,KAAK,CACR;QAAA,EAAE,KAAK,CAAC,CACT,CAAC,CAAC,CAAC,IAAI,CACR;MAAA,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,CACtB;MAAA,CAAC,YAAY,CAAC,CAAC,CAAC,CACd,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,CACjF;UAAA,CAAC,SAAS,CACZ;QAAA,EAAE,UAAU,CAAC,CACd,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CACf,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,CACjF;UAAA,CAAC,UAAU,CACb;QAAA,EAAE,UAAU,CAAC,CACd,CAAC,CAAC,CAAC,IAAI,CACV;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC","sourcesContent":["import React from 'react';\n\nimport { View } from '../../features/layout/public';\nimport { resolveFieldPresentation, resolveFieldState } from '../../internal/resolvers';\nimport { HelperText } from '../helper-text';\nimport { Label } from '../label';\nimport type { FieldProps } from './types';\n\n/*** Composes a label, control, and helper or error message into one field. */\nexport function Field({\n children,\n label,\n helperText,\n errorText,\n required = false,\n disabled = false,\n invalid = false,\n readOnly = false,\n testID,\n}: FieldProps) {\n const hasErrorText = Boolean(errorText);\n const fieldState = resolveFieldState({\n disabled,\n invalid: invalid || hasErrorText,\n readOnly,\n });\n const presentation = resolveFieldPresentation(fieldState);\n\n return (\n <View gap=\"xs\" testID={testID}>\n {label ? (\n <Label\n color={presentation.labelColor}\n emphasis={presentation.labelEmphasis}\n required={required}\n >\n {label}\n </Label>\n ) : null}\n <View>{children}</View>\n {hasErrorText ? (\n <HelperText color={presentation.helperColor} emphasis={presentation.helperEmphasis}>\n {errorText}\n </HelperText>\n ) : helperText ? (\n <HelperText color={presentation.helperColor} emphasis={presentation.helperEmphasis}>\n {helperText}\n </HelperText>\n ) : null}\n </View>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/field/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/field/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC","sourcesContent":["export { Field } from './Field';\nexport type { FieldProps } from './types';\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/field/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/field/types.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\n\nexport interface FieldProps {\n children?: React.ReactNode;\n label?: React.ReactNode;\n helperText?: React.ReactNode;\n errorText?: React.ReactNode;\n required?: boolean;\n disabled?: boolean;\n invalid?: boolean;\n readOnly?: boolean;\n testID?: string;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HelperText.d.ts","sourceRoot":"","sources":["../../../src/components/helper-text/HelperText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,eAAe,qBAM1F"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Text } from '../../features/typography/public';
|
|
3
|
-
export function HelperText({ children, emphasis = 'muted', color, testID }) {
|
|
4
|
-
return (<Text color={color} emphasis={emphasis} testID={testID} variant="caption">
|
|
5
|
-
{children}
|
|
6
|
-
</Text>);
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=HelperText.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HelperText.js","sourceRoot":"","sources":["../../../src/components/helper-text/HelperText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,IAAI,EAAE,MAAM,kCAAkC,CAAC;AAGxD,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAmB;IACzF,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,CACvE;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC","sourcesContent":["import React from 'react';\n\nimport { Text } from '../../features/typography/public';\nimport type { HelperTextProps } from './types';\n\nexport function HelperText({ children, emphasis = 'muted', color, testID }: HelperTextProps) {\n return (\n <Text color={color} emphasis={emphasis} testID={testID} variant=\"caption\">\n {children}\n </Text>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/helper-text/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC"}
|