@utilitywarehouse/hearth-react-native 0.2.0 → 0.3.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +3 -1
- package/CHANGELOG.md +34 -0
- package/build/components/Alert/AlertCloseButton.js +25 -3
- package/build/components/Alert/AlertIcon.js +17 -1
- package/build/components/Alert/AlertIconButton.js +27 -1
- package/build/components/Alert/AlertLink.js +47 -1
- package/build/components/Alert/AlertText.d.ts +1 -1
- package/build/components/Alert/AlertText.js +26 -2
- package/build/components/Alert/AlertTitle.d.ts +1 -1
- package/build/components/Alert/AlertTitle.js +26 -2
- package/build/components/Badge/Badge.js +101 -14
- package/build/components/Badge/Badge.props.d.ts +2 -2
- package/build/components/Badge/BadgeIcon.js +27 -29
- package/build/components/Badge/BadgeText.js +29 -31
- package/build/components/Button/Button.d.ts +2 -2
- package/build/components/Button/ButtonGroupRoot.d.ts +3 -2
- package/build/components/Button/ButtonGroupRoot.js +9 -0
- package/build/components/Button/ButtonRoot.js +1 -0
- package/build/components/Card/Card.props.d.ts +2 -2
- package/build/components/Checkbox/Checkbox.d.ts +2 -2
- package/build/components/Checkbox/Checkbox.js +11 -10
- package/build/components/Checkbox/Checkbox.props.d.ts +3 -1
- package/build/components/Checkbox/CheckboxIcon.js +1 -1
- package/build/components/Checkbox/CheckboxImage.d.ts +6 -0
- package/build/components/Checkbox/CheckboxImage.js +5 -0
- package/build/components/Checkbox/CheckboxTileRoot.js +1 -1
- package/build/components/Checkbox/index.d.ts +3 -2
- package/build/components/Checkbox/index.js +2 -1
- package/build/components/CurrencyInput/CurrencyInput.d.ts +6 -0
- package/build/components/CurrencyInput/CurrencyInput.js +47 -0
- package/build/components/CurrencyInput/CurrencyInput.props.d.ts +14 -0
- package/build/components/CurrencyInput/CurrencyInput.props.js +1 -0
- package/build/components/CurrencyInput/index.d.ts +1 -0
- package/build/components/CurrencyInput/index.js +1 -0
- package/build/components/DescriptionList/DescriptionList.context.d.ts +6 -0
- package/build/components/DescriptionList/DescriptionList.context.js +9 -0
- package/build/components/DescriptionList/DescriptionList.d.ts +6 -0
- package/build/components/DescriptionList/DescriptionList.js +25 -0
- package/build/components/DescriptionList/DescriptionList.props.d.ts +18 -0
- package/build/components/DescriptionList/DescriptionList.props.js +1 -0
- package/build/components/DescriptionList/DescriptionListItem.d.ts +6 -0
- package/build/components/DescriptionList/DescriptionListItem.js +49 -0
- package/build/components/DescriptionList/DescriptionListItem.props.d.ts +17 -0
- package/build/components/DescriptionList/DescriptionListItem.props.js +1 -0
- package/build/components/DescriptionList/index.d.ts +4 -0
- package/build/components/DescriptionList/index.js +2 -0
- package/build/components/Divider/Divider.js +46 -0
- package/build/components/Divider/Divider.props.d.ts +2 -2
- package/build/components/Flex/Flex.props.d.ts +3 -2
- package/build/components/Grid/Grid.props.d.ts +2 -2
- package/build/components/IconContainer/IconContainer.d.ts +5 -0
- package/build/components/IconContainer/IconContainer.js +161 -0
- package/build/components/IconContainer/IconContainer.props.d.ts +15 -0
- package/build/components/IconContainer/IconContainer.props.js +1 -0
- package/build/components/IconContainer/index.d.ts +2 -0
- package/build/components/IconContainer/index.js +1 -0
- package/build/components/Icons/CircleIcon.js +3 -3
- package/build/components/Input/Input.js +2 -34
- package/build/components/Input/Input.props.d.ts +1 -17
- package/build/components/Input/InputField.js +0 -7
- package/build/components/Link/Link.d.ts +1 -1
- package/build/components/Link/Link.js +4 -4
- package/build/components/Link/Link.props.d.ts +3 -0
- package/build/components/Modal/Modal.js +17 -1
- package/build/components/Radio/Radio.d.ts +2 -2
- package/build/components/Radio/Radio.js +9 -8
- package/build/components/Radio/Radio.props.d.ts +3 -1
- package/build/components/Radio/RadioImage.d.ts +6 -0
- package/build/components/Radio/RadioImage.js +5 -0
- package/build/components/Radio/RadioTileRoot.js +1 -1
- package/build/components/Radio/index.d.ts +3 -2
- package/build/components/Radio/index.js +2 -1
- package/build/components/SectionHeader/SectionHeader.js +1 -0
- package/build/components/Select/SelectOption.js +1 -7
- package/build/components/Tabs/Tab.d.ts +18 -0
- package/build/components/Tabs/Tab.js +74 -0
- package/build/components/Tabs/Tab.props.d.ts +14 -0
- package/build/components/Tabs/Tab.props.js +1 -0
- package/build/components/Tabs/TabPanel.d.ts +3 -0
- package/build/components/Tabs/TabPanel.js +34 -0
- package/build/components/Tabs/TabPanel.props.d.ts +8 -0
- package/build/components/Tabs/TabPanel.props.js +1 -0
- package/build/components/Tabs/Tabs.context.d.ts +23 -0
- package/build/components/Tabs/Tabs.context.js +8 -0
- package/build/components/Tabs/Tabs.d.ts +6 -0
- package/build/components/Tabs/Tabs.js +114 -0
- package/build/components/Tabs/Tabs.props.d.ts +19 -0
- package/build/components/Tabs/Tabs.props.js +1 -0
- package/build/components/Tabs/TabsList.d.ts +6 -0
- package/build/components/Tabs/TabsList.js +112 -0
- package/build/components/Tabs/TabsList.props.d.ts +6 -0
- package/build/components/Tabs/TabsList.props.js +1 -0
- package/build/components/Tabs/index.d.ts +8 -0
- package/build/components/Tabs/index.js +4 -0
- package/build/components/UnstyledIconButton/UnstyledIconButton.d.ts +1 -1
- package/build/components/UnstyledIconButton/UnstyledIconButton.js +4 -4
- package/build/components/UnstyledIconButton/UnstyledIconButton.props.d.ts +2 -1
- package/build/components/index.d.ts +4 -0
- package/build/components/index.js +4 -0
- package/build/core/themes.d.ts +428 -160
- package/build/core/themes.js +57 -1
- package/build/tokens/color.d.ts +88 -80
- package/build/tokens/color.js +44 -40
- package/build/tokens/components/dark/alert.d.ts +13 -0
- package/build/tokens/components/dark/alert.js +13 -0
- package/build/tokens/components/dark/button.d.ts +1 -0
- package/build/tokens/components/dark/button.js +1 -0
- package/build/tokens/components/dark/checkbox.d.ts +4 -1
- package/build/tokens/components/dark/checkbox.js +4 -1
- package/build/tokens/components/dark/icon-button.d.ts +10 -3
- package/build/tokens/components/dark/icon-button.js +10 -3
- package/build/tokens/components/dark/index.d.ts +1 -0
- package/build/tokens/components/dark/index.js +1 -0
- package/build/tokens/components/dark/link.d.ts +5 -0
- package/build/tokens/components/dark/link.js +5 -0
- package/build/tokens/components/dark/progress-bar.d.ts +41 -0
- package/build/tokens/components/dark/progress-bar.js +40 -0
- package/build/tokens/components/dark/radio.d.ts +1 -1
- package/build/tokens/components/dark/radio.js +1 -1
- package/build/tokens/components/dark/tabs.d.ts +2 -0
- package/build/tokens/components/dark/tabs.js +2 -0
- package/build/tokens/components/light/alert.d.ts +13 -0
- package/build/tokens/components/light/alert.js +13 -0
- package/build/tokens/components/light/badge.d.ts +1 -1
- package/build/tokens/components/light/badge.js +1 -1
- package/build/tokens/components/light/button.d.ts +1 -0
- package/build/tokens/components/light/button.js +1 -0
- package/build/tokens/components/light/checkbox.d.ts +6 -3
- package/build/tokens/components/light/checkbox.js +6 -3
- package/build/tokens/components/light/icon-button.d.ts +8 -1
- package/build/tokens/components/light/icon-button.js +8 -1
- package/build/tokens/components/light/index.d.ts +1 -0
- package/build/tokens/components/light/index.js +1 -0
- package/build/tokens/components/light/link.d.ts +5 -0
- package/build/tokens/components/light/link.js +5 -0
- package/build/tokens/components/light/progress-bar.d.ts +41 -0
- package/build/tokens/components/light/progress-bar.js +40 -0
- package/build/tokens/components/light/radio.d.ts +3 -3
- package/build/tokens/components/light/radio.js +3 -3
- package/build/tokens/components/light/tabs.d.ts +2 -0
- package/build/tokens/components/light/tabs.js +2 -0
- package/build/tokens/index.d.ts +1 -0
- package/build/tokens/index.js +1 -0
- package/build/tokens/layout.d.ts +48 -30
- package/build/tokens/layout.js +24 -15
- package/build/tokens/motion.d.ts +23 -0
- package/build/tokens/motion.js +22 -0
- package/build/tokens/primitive.d.ts +19 -0
- package/build/tokens/primitive.js +19 -0
- package/build/tokens/semantic-dark.d.ts +26 -24
- package/build/tokens/semantic-dark.js +26 -24
- package/build/tokens/semantic-light.d.ts +18 -16
- package/build/tokens/semantic-light.js +18 -16
- package/build/types/values.d.ts +2 -1
- package/build/utils/formatThousands.d.ts +2 -0
- package/build/utils/formatThousands.js +16 -0
- package/build/utils/index.d.ts +1 -0
- package/build/utils/index.js +1 -0
- package/docs/assets/bank-logo.png +0 -0
- package/docs/assets/bank-logo1.png +0 -0
- package/docs/components/AllComponents.web.tsx +97 -8
- package/docs/components/NextPrevPage.tsx +11 -3
- package/docs/components/UsageWrap.tsx +2 -2
- package/docs/components/index.ts +6 -7
- package/docs/heplers/addReactNativePrefix.ts +8 -0
- package/docs/heplers/index.ts +1 -0
- package/docs/introduction.mdx +3 -3
- package/docs/theme-tokens.mdx +42 -0
- package/package.json +13 -13
- package/src/components/Alert/AlertCloseButton.tsx +33 -5
- package/src/components/Alert/AlertIcon.tsx +17 -1
- package/src/components/Alert/AlertIconButton.tsx +37 -4
- package/src/components/Alert/AlertLink.tsx +52 -1
- package/src/components/Alert/AlertText.tsx +28 -3
- package/src/components/Alert/AlertTitle.tsx +28 -3
- package/src/components/Badge/Badge.docs.mdx +7 -7
- package/src/components/Badge/Badge.props.ts +3 -2
- package/src/components/Badge/Badge.stories.tsx +81 -92
- package/src/components/Badge/Badge.tsx +101 -14
- package/src/components/Badge/BadgeIcon.tsx +27 -29
- package/src/components/Badge/BadgeText.tsx +29 -31
- package/src/components/Button/ButtonGroupRoot.tsx +12 -2
- package/src/components/Button/ButtonRoot.tsx +1 -0
- package/src/components/Card/Card.docs.mdx +1 -1
- package/src/components/Card/Card.props.ts +2 -2
- package/src/components/Checkbox/Checkbox.docs.mdx +45 -7
- package/src/components/Checkbox/Checkbox.props.ts +3 -1
- package/src/components/Checkbox/Checkbox.stories.tsx +37 -1
- package/src/components/Checkbox/Checkbox.tsx +12 -9
- package/src/components/Checkbox/CheckboxIcon.tsx +1 -1
- package/src/components/Checkbox/CheckboxImage.tsx +9 -0
- package/src/components/Checkbox/CheckboxTileRoot.tsx +1 -1
- package/src/components/Checkbox/index.ts +3 -2
- package/src/components/CurrencyInput/CurrencyInput.docs.mdx +120 -0
- package/src/components/CurrencyInput/CurrencyInput.props.ts +19 -0
- package/src/components/CurrencyInput/CurrencyInput.stories.tsx +116 -0
- package/src/components/CurrencyInput/CurrencyInput.tsx +91 -0
- package/src/components/CurrencyInput/index.ts +1 -0
- package/src/components/DescriptionList/DescriptionList.context.ts +18 -0
- package/src/components/DescriptionList/DescriptionList.docs.mdx +98 -0
- package/src/components/DescriptionList/DescriptionList.props.ts +20 -0
- package/src/components/DescriptionList/DescriptionList.stories.tsx +154 -0
- package/src/components/DescriptionList/DescriptionList.tsx +64 -0
- package/src/components/DescriptionList/DescriptionListItem.props.ts +19 -0
- package/src/components/DescriptionList/DescriptionListItem.tsx +101 -0
- package/src/components/DescriptionList/index.ts +4 -0
- package/src/components/Divider/Divider.props.ts +2 -2
- package/src/components/Divider/Divider.stories.tsx +3 -3
- package/src/components/Divider/Divider.tsx +46 -0
- package/src/components/Flex/Flex.docs.mdx +4 -4
- package/src/components/Flex/Flex.props.ts +3 -2
- package/src/components/Flex/Flex.stories.tsx +1 -1
- package/src/components/Grid/Grid.docs.mdx +12 -12
- package/src/components/Grid/Grid.props.ts +2 -2
- package/src/components/Grid/Grid.stories.tsx +2 -2
- package/src/components/IconContainer/IconContainer.docs.mdx +90 -0
- package/src/components/IconContainer/IconContainer.props.ts +17 -0
- package/src/components/IconContainer/IconContainer.stories.tsx +130 -0
- package/src/components/IconContainer/IconContainer.tsx +180 -0
- package/src/components/IconContainer/index.tsx +2 -0
- package/src/components/Icons/CircleIcon.tsx +9 -11
- package/src/components/Input/Input.docs.mdx +3 -3
- package/src/components/Input/Input.props.ts +0 -20
- package/src/components/Input/Input.stories.tsx +0 -6
- package/src/components/Input/Input.tsx +2 -49
- package/src/components/Input/InputField.tsx +0 -7
- package/src/components/Link/Link.props.ts +3 -0
- package/src/components/Link/Link.tsx +12 -6
- package/src/components/List/List.docs.mdx +24 -23
- package/src/components/Modal/Modal.tsx +18 -0
- package/src/components/Radio/Radio.docs.mdx +96 -124
- package/src/components/Radio/Radio.props.ts +3 -1
- package/src/components/Radio/Radio.stories.tsx +47 -0
- package/src/components/Radio/Radio.tsx +10 -7
- package/src/components/Radio/RadioImage.tsx +9 -0
- package/src/components/Radio/RadioTileRoot.tsx +1 -1
- package/src/components/Radio/index.ts +3 -2
- package/src/components/SectionHeader/SectionHeader.tsx +1 -0
- package/src/components/Select/Select.docs.mdx +6 -6
- package/src/components/Select/Select.stories.tsx +7 -7
- package/src/components/Select/SelectOption.tsx +4 -10
- package/src/components/Tabs/Tab.props.ts +16 -0
- package/src/components/Tabs/Tab.tsx +113 -0
- package/src/components/Tabs/TabPanel.props.ts +10 -0
- package/src/components/Tabs/TabPanel.tsx +46 -0
- package/src/components/Tabs/Tabs.context.ts +26 -0
- package/src/components/Tabs/Tabs.docs.mdx +214 -0
- package/src/components/Tabs/Tabs.props.ts +21 -0
- package/src/components/Tabs/Tabs.stories.tsx +270 -0
- package/src/components/Tabs/Tabs.tsx +139 -0
- package/src/components/Tabs/TabsList.props.ts +8 -0
- package/src/components/Tabs/TabsList.tsx +194 -0
- package/src/components/Tabs/index.ts +8 -0
- package/src/components/UnstyledIconButton/UnstyledIconButton.props.ts +2 -1
- package/src/components/UnstyledIconButton/UnstyledIconButton.tsx +9 -3
- package/src/components/index.ts +4 -0
- package/src/core/themes.ts +57 -1
- package/src/tokens/color.ts +44 -40
- package/src/tokens/components/dark/alert.ts +13 -0
- package/src/tokens/components/dark/button.ts +1 -0
- package/src/tokens/components/dark/checkbox.ts +4 -1
- package/src/tokens/components/dark/icon-button.ts +10 -3
- package/src/tokens/components/dark/index.ts +1 -0
- package/src/tokens/components/dark/link.ts +5 -0
- package/src/tokens/components/dark/progress-bar.ts +41 -0
- package/src/tokens/components/dark/radio.ts +1 -1
- package/src/tokens/components/dark/tabs.ts +2 -0
- package/src/tokens/components/light/alert.ts +13 -0
- package/src/tokens/components/light/badge.ts +1 -1
- package/src/tokens/components/light/button.ts +1 -0
- package/src/tokens/components/light/checkbox.ts +6 -3
- package/src/tokens/components/light/icon-button.ts +8 -1
- package/src/tokens/components/light/index.ts +1 -0
- package/src/tokens/components/light/link.ts +5 -0
- package/src/tokens/components/light/progress-bar.ts +41 -0
- package/src/tokens/components/light/radio.ts +3 -3
- package/src/tokens/components/light/tabs.ts +2 -0
- package/src/tokens/index.ts +1 -0
- package/src/tokens/layout.ts +24 -15
- package/src/tokens/motion.ts +23 -0
- package/src/tokens/primitive.ts +19 -0
- package/src/tokens/semantic-dark.ts +26 -24
- package/src/tokens/semantic-light.ts +18 -16
- package/src/types/values.ts +3 -1
- package/src/utils/formatThousands.ts +14 -0
- package/src/utils/index.ts +1 -0
- package/docs/assets/react-native-pig.png +0 -0
- package/docs/components/AdvancedRadioExample.tsx +0 -126
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { CurrencyInput } from '..';
|
|
4
|
+
import { VariantTitle } from '../../../docs/components';
|
|
5
|
+
import { Flex } from '../Flex';
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'Stories / CurrencyInput',
|
|
9
|
+
component: CurrencyInput,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'centered',
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
placeholder: {
|
|
15
|
+
control: 'text',
|
|
16
|
+
description: 'The CurrencyInput field placeholder',
|
|
17
|
+
defaultValue: '0.00',
|
|
18
|
+
},
|
|
19
|
+
validationStatus: {
|
|
20
|
+
control: 'select',
|
|
21
|
+
options: ['initial', 'valid', 'invalid'],
|
|
22
|
+
description: 'The validation status',
|
|
23
|
+
defaultValue: 'initial',
|
|
24
|
+
},
|
|
25
|
+
disabled: {
|
|
26
|
+
control: 'boolean',
|
|
27
|
+
description: 'Disable the input',
|
|
28
|
+
defaultValue: false,
|
|
29
|
+
},
|
|
30
|
+
readonly: {
|
|
31
|
+
control: 'boolean',
|
|
32
|
+
description: 'Read only',
|
|
33
|
+
defaultValue: false,
|
|
34
|
+
},
|
|
35
|
+
focused: {
|
|
36
|
+
control: 'boolean',
|
|
37
|
+
description: 'Focused',
|
|
38
|
+
defaultValue: false,
|
|
39
|
+
},
|
|
40
|
+
autoFormatThousands: {
|
|
41
|
+
control: 'boolean',
|
|
42
|
+
description:
|
|
43
|
+
'Automatically add thousand separators while typing _(Only works with controlled components via onTextChange)_',
|
|
44
|
+
defaultValue: false,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
args: {
|
|
48
|
+
placeholder: '0.00',
|
|
49
|
+
validationStatus: 'initial',
|
|
50
|
+
disabled: false,
|
|
51
|
+
readonly: false,
|
|
52
|
+
focused: false,
|
|
53
|
+
autoFormatThousands: false,
|
|
54
|
+
},
|
|
55
|
+
} satisfies Meta<typeof CurrencyInput>;
|
|
56
|
+
|
|
57
|
+
export default meta;
|
|
58
|
+
type Story = StoryObj<typeof meta>;
|
|
59
|
+
|
|
60
|
+
export const Playground: Story = {};
|
|
61
|
+
|
|
62
|
+
export const AutoFormatThousands: Story = {
|
|
63
|
+
parameters: {
|
|
64
|
+
controls: { include: ['autoFormatThousands'] },
|
|
65
|
+
},
|
|
66
|
+
args: { autoFormatThousands: true },
|
|
67
|
+
render: args => {
|
|
68
|
+
const [value, setValue] = useState('1234.56');
|
|
69
|
+
const handleChange = (val: string) => {
|
|
70
|
+
setValue(val);
|
|
71
|
+
};
|
|
72
|
+
return <CurrencyInput {...args} value={value} onChangeText={handleChange} />;
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const States: Story = {
|
|
77
|
+
parameters: {
|
|
78
|
+
controls: { include: [] },
|
|
79
|
+
},
|
|
80
|
+
render: () => {
|
|
81
|
+
return (
|
|
82
|
+
<Flex direction="column" space="lg">
|
|
83
|
+
<VariantTitle title="Default">
|
|
84
|
+
<CurrencyInput />
|
|
85
|
+
</VariantTitle>
|
|
86
|
+
<VariantTitle title="With placeholder">
|
|
87
|
+
<CurrencyInput placeholder="0.00" />
|
|
88
|
+
</VariantTitle>
|
|
89
|
+
<VariantTitle title="Focused">
|
|
90
|
+
<CurrencyInput focused value="12.34" />
|
|
91
|
+
</VariantTitle>
|
|
92
|
+
<VariantTitle title="Valid">
|
|
93
|
+
<CurrencyInput validationStatus="valid" />
|
|
94
|
+
</VariantTitle>
|
|
95
|
+
<VariantTitle title="Invalid">
|
|
96
|
+
<CurrencyInput validationStatus="invalid" />
|
|
97
|
+
</VariantTitle>
|
|
98
|
+
<VariantTitle title="Valid - Focused">
|
|
99
|
+
<CurrencyInput validationStatus="valid" focused />
|
|
100
|
+
</VariantTitle>
|
|
101
|
+
<VariantTitle title="Invalid - Focused">
|
|
102
|
+
<CurrencyInput validationStatus="invalid" focused />
|
|
103
|
+
</VariantTitle>
|
|
104
|
+
<VariantTitle title="Disabled">
|
|
105
|
+
<CurrencyInput disabled />
|
|
106
|
+
</VariantTitle>
|
|
107
|
+
<VariantTitle title="Readonly">
|
|
108
|
+
<CurrencyInput readonly />
|
|
109
|
+
</VariantTitle>
|
|
110
|
+
<VariantTitle title="Auto format thousands">
|
|
111
|
+
<CurrencyInput autoFormatThousands value="1234.56" />
|
|
112
|
+
</VariantTitle>
|
|
113
|
+
</Flex>
|
|
114
|
+
);
|
|
115
|
+
},
|
|
116
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
3
|
+
import { formatThousands } from '../../utils';
|
|
4
|
+
import { DetailText } from '../DetailText';
|
|
5
|
+
import { useFormFieldContext } from '../FormField';
|
|
6
|
+
import { Input, InputField, InputSlot } from '../Input';
|
|
7
|
+
import type CurrencyInputProps from './CurrencyInput.props';
|
|
8
|
+
|
|
9
|
+
const CurrencyInput = ({
|
|
10
|
+
validationStatus = 'initial',
|
|
11
|
+
disabled,
|
|
12
|
+
focused,
|
|
13
|
+
readonly,
|
|
14
|
+
placeholder,
|
|
15
|
+
inBottomSheet = false,
|
|
16
|
+
required,
|
|
17
|
+
autoFormatThousands = false,
|
|
18
|
+
value,
|
|
19
|
+
onChangeText,
|
|
20
|
+
...rest
|
|
21
|
+
}: CurrencyInputProps) => {
|
|
22
|
+
const formFieldContext = useFormFieldContext();
|
|
23
|
+
const { disabled: formFieldDisabled } = formFieldContext;
|
|
24
|
+
const validationStatusFromContext = formFieldContext?.validationStatus ?? validationStatus;
|
|
25
|
+
|
|
26
|
+
const defaultFormat = '0.00';
|
|
27
|
+
const getPlaceholder = placeholder ?? defaultFormat;
|
|
28
|
+
|
|
29
|
+
const handleChangeText = (text: string) => {
|
|
30
|
+
if (autoFormatThousands) {
|
|
31
|
+
const formatted = formatThousands(text);
|
|
32
|
+
onChangeText?.(formatted);
|
|
33
|
+
} else {
|
|
34
|
+
onChangeText?.(text);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const displayValue =
|
|
39
|
+
autoFormatThousands && typeof value === 'string' ? formatThousands(value) : value;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Input
|
|
43
|
+
validationStatus={validationStatusFromContext}
|
|
44
|
+
disabled={formFieldDisabled ?? disabled}
|
|
45
|
+
readonly={readonly}
|
|
46
|
+
focused={focused}
|
|
47
|
+
style={styles.wrap}
|
|
48
|
+
>
|
|
49
|
+
<InputSlot>
|
|
50
|
+
<DetailText size="4xl" style={styles.text}>
|
|
51
|
+
£
|
|
52
|
+
</DetailText>
|
|
53
|
+
</InputSlot>
|
|
54
|
+
<InputField
|
|
55
|
+
inputMode="decimal"
|
|
56
|
+
inBottomSheet={inBottomSheet}
|
|
57
|
+
{...rest}
|
|
58
|
+
placeholder={getPlaceholder}
|
|
59
|
+
keyboardType="decimal-pad"
|
|
60
|
+
style={styles.input}
|
|
61
|
+
value={displayValue as any}
|
|
62
|
+
onChangeText={handleChangeText}
|
|
63
|
+
/>
|
|
64
|
+
</Input>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
CurrencyInput.displayName = 'CurrencyInput';
|
|
69
|
+
|
|
70
|
+
const styles = StyleSheet.create(theme => ({
|
|
71
|
+
wrap: {
|
|
72
|
+
height: theme.components.input.currency.height,
|
|
73
|
+
gap: theme.components.input.currency.gap,
|
|
74
|
+
},
|
|
75
|
+
text: {
|
|
76
|
+
...(Platform.OS === 'ios' && { lineHeight: 46 }),
|
|
77
|
+
_web: {
|
|
78
|
+
marginTop: 1,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
input: {
|
|
82
|
+
fontSize: theme.typography.mobile.detailText['4xl'].fontSize,
|
|
83
|
+
fontFamily: theme.typography.mobile.detailText.fontFamily,
|
|
84
|
+
fontWeight: theme.typography.mobile.detailText.fontWeight,
|
|
85
|
+
paddingTop: 0,
|
|
86
|
+
paddingBottom: 0,
|
|
87
|
+
paddingLeft: 0,
|
|
88
|
+
},
|
|
89
|
+
}));
|
|
90
|
+
|
|
91
|
+
export default CurrencyInput;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as CurrencyInput } from './CurrencyInput';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface DescriptionListContextValue {
|
|
4
|
+
direction: 'row' | 'column';
|
|
5
|
+
itemHeadingWidth?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const DescriptionListContext = createContext<DescriptionListContextValue | undefined>(
|
|
9
|
+
undefined
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export const useDescriptionListContext = () => {
|
|
13
|
+
const ctx = useContext(DescriptionListContext);
|
|
14
|
+
if (!ctx) {
|
|
15
|
+
throw new Error('DescriptionListItem must be used within a DescriptionList');
|
|
16
|
+
}
|
|
17
|
+
return ctx;
|
|
18
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Canvas, Controls, Meta } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import { DescriptionList, DescriptionListItem } from '../../';
|
|
3
|
+
import { BackToTopButton, UsageWrap } from '../../../docs/components';
|
|
4
|
+
import * as Stories from './DescriptionList.stories';
|
|
5
|
+
|
|
6
|
+
<BackToTopButton />
|
|
7
|
+
|
|
8
|
+
<Meta title="Components / Description List" />
|
|
9
|
+
|
|
10
|
+
# Description List
|
|
11
|
+
|
|
12
|
+
Display pairs of related metadata (heading + description). Supports column (stacked) and row (two-column) layouts, optional SectionHeader (heading + helper text), and per-item action links.
|
|
13
|
+
|
|
14
|
+
- [Playground](#playground)
|
|
15
|
+
- [Usage](#usage)
|
|
16
|
+
- [Props](#props)
|
|
17
|
+
- [Variants](#variants)
|
|
18
|
+
- [Accessibility](#accessibility)
|
|
19
|
+
|
|
20
|
+
## Playground
|
|
21
|
+
|
|
22
|
+
<Canvas of={Stories.Playground} />
|
|
23
|
+
<Controls of={Stories.Playground} />
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
<UsageWrap>
|
|
28
|
+
<DescriptionList
|
|
29
|
+
direction="column"
|
|
30
|
+
heading="Account details"
|
|
31
|
+
helperText="Static account metadata"
|
|
32
|
+
>
|
|
33
|
+
<DescriptionListItem heading="Account Number" description="123456789" />
|
|
34
|
+
<DescriptionListItem heading="Sort Code" description="12-34-56" />
|
|
35
|
+
<DescriptionListItem heading="Status" description="Active" />
|
|
36
|
+
</DescriptionList>
|
|
37
|
+
</UsageWrap>
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { DescriptionList, DescriptionListItem } from '@utilitywarehouse/hearth-react-native';
|
|
41
|
+
|
|
42
|
+
<DescriptionList direction="column" heading="Account details" helperText="Static account metadata">
|
|
43
|
+
<DescriptionListItem heading="Account Number" description="123456789" />
|
|
44
|
+
<DescriptionListItem heading="Sort Code" description="12-34-56" />
|
|
45
|
+
<DescriptionListItem heading="Status" description="Active" />
|
|
46
|
+
</DescriptionList>;
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Props
|
|
50
|
+
|
|
51
|
+
### DescriptionList
|
|
52
|
+
|
|
53
|
+
| Prop | Type | Description | Default |
|
|
54
|
+
| ------------------ | -------------------------------------------- | ------------------------------------------------ | ----------- |
|
|
55
|
+
| `direction` | `'row' \| 'column'` | Layout orientation | `column` |
|
|
56
|
+
| `itemHeadingWidth` | `number` | Override heading column width in row layout | token value |
|
|
57
|
+
| `heading` | `string` | Optional overall heading (renders SectionHeader) | - |
|
|
58
|
+
| `helperText` | `string` | Supporting text under heading | - |
|
|
59
|
+
| `linkText` | `string` | Section header link text | - |
|
|
60
|
+
| `linkHref` | `string` | Header link URL (web) | - |
|
|
61
|
+
| `linkIcon` | `ComponentType` | Header link icon | - |
|
|
62
|
+
| `linkIconPosition` | `'left' \| 'right'` | Header link icon position | `right` |
|
|
63
|
+
| `linkOnPress` | `() => void` | Header link press handler | - |
|
|
64
|
+
| `linkTarget` | `'_blank' \| '_self' \| '_parent' \| '_top'` | Header link target | `_self` |
|
|
65
|
+
| `linkShowIcon` | `boolean` | Whether header link icon is shown | `false` |
|
|
66
|
+
|
|
67
|
+
### DescriptionListItem
|
|
68
|
+
|
|
69
|
+
| Prop | Type | Description | Default |
|
|
70
|
+
| ------------------ | -------------------------------------------- | -------------------------------------------- | ---------- |
|
|
71
|
+
| `heading` | `ReactNode` | Heading (label) content | (required) |
|
|
72
|
+
| `description` | `ReactNode` | Description (value) content | (required) |
|
|
73
|
+
| `headingWidth` | `number` | Per-item heading width override (row layout) | inherits |
|
|
74
|
+
| `linkText` | `string` | Inline action link text | - |
|
|
75
|
+
| `linkHref` | `string` | Inline action link URL (web) | - |
|
|
76
|
+
| `linkIcon` | `ComponentType` | Inline action link icon | - |
|
|
77
|
+
| `linkIconPosition` | `'left' \| 'right'` | Inline link icon position | `right` |
|
|
78
|
+
| `linkOnPress` | `() => void` | Inline link press handler | - |
|
|
79
|
+
| `linkTarget` | `'_blank' \| '_self' \| '_parent' \| '_top'` | Inline link target | `_self` |
|
|
80
|
+
| `linkShowIcon` | `boolean` | Show inline link icon | `false` |
|
|
81
|
+
|
|
82
|
+
> Uses `theme.components.descriptionList` tokens for spacing & column width.
|
|
83
|
+
|
|
84
|
+
## Variants
|
|
85
|
+
|
|
86
|
+
<Canvas of={Stories.KitchenSink} />
|
|
87
|
+
<Canvas of={Stories.WithLinks} />
|
|
88
|
+
|
|
89
|
+
## Accessibility
|
|
90
|
+
|
|
91
|
+
The component applies the following roles:
|
|
92
|
+
|
|
93
|
+
| Element | Role |
|
|
94
|
+
| ----------------------------- | ------------------------------------- |
|
|
95
|
+
| `DescriptionList` root | `list` |
|
|
96
|
+
| `DescriptionListItem` wrapper | `text` (combined label when possible) |
|
|
97
|
+
|
|
98
|
+
When both heading and description are plain text they are merged into one accessibility node (e.g. “Account Number: 123456789”) and the child elements are hidden from the a11y tree to avoid duplicate reading (TalkBack / VoiceOver). If either part is non‑text the children remain individually exposed.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import type { ViewProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface DescriptionListProps extends ViewProps {
|
|
5
|
+
/** Direction orientation for items */
|
|
6
|
+
direction?: 'row' | 'column';
|
|
7
|
+
/** Override heading/term column width when layout is row (defaults to token) */
|
|
8
|
+
itemHeadingWidth?: number;
|
|
9
|
+
heading?: string;
|
|
10
|
+
helperText?: string;
|
|
11
|
+
linkText?: string;
|
|
12
|
+
linkHref?: string;
|
|
13
|
+
linkIcon?: ComponentType;
|
|
14
|
+
linkIconPosition?: 'left' | 'right';
|
|
15
|
+
linkOnPress?: () => void;
|
|
16
|
+
linkTarget?: '_blank' | '_self' | '_parent' | '_top';
|
|
17
|
+
linkShowIcon?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default DescriptionListProps;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { DescriptionList, DescriptionListItem } from '.';
|
|
3
|
+
import { VariantTitle } from '../../../docs/components';
|
|
4
|
+
import { Flex } from '../Flex';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof DescriptionList> = {
|
|
7
|
+
title: 'Stories / DescriptionList',
|
|
8
|
+
component: DescriptionList,
|
|
9
|
+
parameters: { layout: 'centered' },
|
|
10
|
+
argTypes: {
|
|
11
|
+
direction: {
|
|
12
|
+
control: 'select',
|
|
13
|
+
options: ['row', 'column'],
|
|
14
|
+
description: 'Orientation of heading & description pairs',
|
|
15
|
+
},
|
|
16
|
+
itemHeadingWidth: {
|
|
17
|
+
control: 'number',
|
|
18
|
+
description: 'Override width (px) for heading column when direction is row',
|
|
19
|
+
},
|
|
20
|
+
heading: {
|
|
21
|
+
control: 'text',
|
|
22
|
+
description:
|
|
23
|
+
'Optional overall heading (renders a SectionHeader). Playground only – prefer SectionHeader directly when composing.',
|
|
24
|
+
},
|
|
25
|
+
helperText: {
|
|
26
|
+
control: 'text',
|
|
27
|
+
description: 'Supporting text shown under heading (Playground only).',
|
|
28
|
+
},
|
|
29
|
+
linkText: { control: 'text', description: 'Header link text (Playground only).' },
|
|
30
|
+
linkHref: { control: 'text', description: 'Header link href (web).' },
|
|
31
|
+
linkIconPosition: {
|
|
32
|
+
control: 'select',
|
|
33
|
+
options: ['left', 'right'],
|
|
34
|
+
description: 'Header link icon position.',
|
|
35
|
+
},
|
|
36
|
+
linkShowIcon: { control: 'boolean', description: 'Show header link icon.' },
|
|
37
|
+
linkTarget: {
|
|
38
|
+
control: 'select',
|
|
39
|
+
options: ['_blank', '_self', '_parent', '_top'],
|
|
40
|
+
description: 'Header link target (web).',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
args: {
|
|
44
|
+
direction: 'column',
|
|
45
|
+
heading: 'Account details',
|
|
46
|
+
helperText: 'Static account metadata',
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default meta;
|
|
51
|
+
type Story = StoryObj<typeof meta>;
|
|
52
|
+
|
|
53
|
+
const sampleData = [
|
|
54
|
+
{ heading: 'Account Number', description: '123456789' },
|
|
55
|
+
{ heading: 'Sort Code', description: '12-34-56' },
|
|
56
|
+
{ heading: 'Status', description: 'Active' },
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
export const Playground: Story = {
|
|
60
|
+
render: args => (
|
|
61
|
+
<DescriptionList {...args}>
|
|
62
|
+
{sampleData.map(item => (
|
|
63
|
+
<DescriptionListItem
|
|
64
|
+
key={item.heading}
|
|
65
|
+
heading={item.heading}
|
|
66
|
+
description={item.description}
|
|
67
|
+
/>
|
|
68
|
+
))}
|
|
69
|
+
</DescriptionList>
|
|
70
|
+
),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const Row: Story = {
|
|
74
|
+
args: { direction: 'row' },
|
|
75
|
+
render: args => (
|
|
76
|
+
<DescriptionList {...args}>
|
|
77
|
+
{sampleData.map(item => (
|
|
78
|
+
<DescriptionListItem
|
|
79
|
+
key={item.heading}
|
|
80
|
+
heading={item.heading}
|
|
81
|
+
description={item.description}
|
|
82
|
+
/>
|
|
83
|
+
))}
|
|
84
|
+
</DescriptionList>
|
|
85
|
+
),
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const Column: Story = {
|
|
89
|
+
args: { direction: 'column' },
|
|
90
|
+
render: args => (
|
|
91
|
+
<DescriptionList {...args}>
|
|
92
|
+
{sampleData.map(item => (
|
|
93
|
+
<DescriptionListItem
|
|
94
|
+
key={item.heading}
|
|
95
|
+
heading={item.heading}
|
|
96
|
+
description={item.description}
|
|
97
|
+
/>
|
|
98
|
+
))}
|
|
99
|
+
</DescriptionList>
|
|
100
|
+
),
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const KitchenSink: Story = {
|
|
104
|
+
parameters: { controls: { include: [] } },
|
|
105
|
+
render: () => (
|
|
106
|
+
<Flex direction="column" space="lg" style={{ width: '100%' }}>
|
|
107
|
+
<VariantTitle title="Row direction">
|
|
108
|
+
<DescriptionList direction="row">
|
|
109
|
+
{sampleData.map(item => (
|
|
110
|
+
<DescriptionListItem
|
|
111
|
+
key={item.heading}
|
|
112
|
+
heading={item.heading}
|
|
113
|
+
description={item.description}
|
|
114
|
+
/>
|
|
115
|
+
))}
|
|
116
|
+
</DescriptionList>
|
|
117
|
+
</VariantTitle>
|
|
118
|
+
<VariantTitle title="Column direction">
|
|
119
|
+
<DescriptionList direction="column">
|
|
120
|
+
{sampleData.map(item => (
|
|
121
|
+
<DescriptionListItem
|
|
122
|
+
key={item.heading}
|
|
123
|
+
heading={item.heading}
|
|
124
|
+
description={item.description}
|
|
125
|
+
/>
|
|
126
|
+
))}
|
|
127
|
+
</DescriptionList>
|
|
128
|
+
</VariantTitle>
|
|
129
|
+
</Flex>
|
|
130
|
+
),
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export const WithLinks: Story = {
|
|
134
|
+
parameters: { controls: { include: ['direction', 'itemHeadingWidth'] } },
|
|
135
|
+
args: { direction: 'row' },
|
|
136
|
+
render: args => (
|
|
137
|
+
<DescriptionList {...args}>
|
|
138
|
+
<DescriptionListItem
|
|
139
|
+
heading="Account Number"
|
|
140
|
+
description="123456789"
|
|
141
|
+
linkText="Manage"
|
|
142
|
+
linkHref="https://example.com/account"
|
|
143
|
+
linkShowIcon
|
|
144
|
+
/>
|
|
145
|
+
<DescriptionListItem
|
|
146
|
+
heading="Status"
|
|
147
|
+
description="Active"
|
|
148
|
+
linkText="Change"
|
|
149
|
+
linkHref="https://example.com/status"
|
|
150
|
+
/>
|
|
151
|
+
<DescriptionListItem heading="Region" description="United Kingdom" />
|
|
152
|
+
</DescriptionList>
|
|
153
|
+
),
|
|
154
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
4
|
+
import { SectionHeader } from '../SectionHeader';
|
|
5
|
+
import { DescriptionListContext } from './DescriptionList.context';
|
|
6
|
+
import type DescriptionListProps from './DescriptionList.props';
|
|
7
|
+
|
|
8
|
+
const DescriptionList = ({
|
|
9
|
+
direction = 'column',
|
|
10
|
+
itemHeadingWidth,
|
|
11
|
+
heading,
|
|
12
|
+
helperText,
|
|
13
|
+
linkText,
|
|
14
|
+
linkHref,
|
|
15
|
+
linkIcon,
|
|
16
|
+
linkIconPosition,
|
|
17
|
+
linkOnPress,
|
|
18
|
+
linkTarget,
|
|
19
|
+
linkShowIcon,
|
|
20
|
+
children,
|
|
21
|
+
style,
|
|
22
|
+
...props
|
|
23
|
+
}: DescriptionListProps) => {
|
|
24
|
+
styles.useVariants({ direction });
|
|
25
|
+
const value = useMemo(() => ({ direction, itemHeadingWidth }), [direction, itemHeadingWidth]);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<DescriptionListContext.Provider value={value}>
|
|
29
|
+
<View accessibilityRole="list" {...props} style={[styles.container, style]}>
|
|
30
|
+
{heading ? (
|
|
31
|
+
<SectionHeader
|
|
32
|
+
heading={heading}
|
|
33
|
+
helperText={helperText}
|
|
34
|
+
linkText={linkText}
|
|
35
|
+
linkHref={linkHref}
|
|
36
|
+
linkIcon={linkIcon}
|
|
37
|
+
linkIconPosition={linkIconPosition}
|
|
38
|
+
linkOnPress={linkOnPress}
|
|
39
|
+
linkTarget={linkTarget}
|
|
40
|
+
linkShowIcon={linkShowIcon}
|
|
41
|
+
/>
|
|
42
|
+
) : null}
|
|
43
|
+
{children}
|
|
44
|
+
</View>
|
|
45
|
+
</DescriptionListContext.Provider>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
DescriptionList.displayName = 'DescriptionList';
|
|
50
|
+
|
|
51
|
+
const styles = StyleSheet.create(theme => ({
|
|
52
|
+
container: {
|
|
53
|
+
width: theme.space.full,
|
|
54
|
+
gap: theme.components.descriptionList.gap,
|
|
55
|
+
variants: {
|
|
56
|
+
direction: {
|
|
57
|
+
row: {},
|
|
58
|
+
column: {},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
}));
|
|
63
|
+
|
|
64
|
+
export default DescriptionList;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
2
|
+
import type { ViewProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface DescriptionListItemProps extends ViewProps {
|
|
5
|
+
/** Heading / label part */
|
|
6
|
+
heading: ReactNode;
|
|
7
|
+
/** Description / value part */
|
|
8
|
+
description: ReactNode;
|
|
9
|
+
headingWidth?: number;
|
|
10
|
+
linkText?: string;
|
|
11
|
+
linkHref?: string;
|
|
12
|
+
linkIcon?: ComponentType;
|
|
13
|
+
linkIconPosition?: 'left' | 'right';
|
|
14
|
+
linkOnPress?: () => void;
|
|
15
|
+
linkTarget?: '_blank' | '_self' | '_parent' | '_top';
|
|
16
|
+
linkShowIcon?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default DescriptionListItemProps;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
3
|
+
import { useTheme } from '../../hooks';
|
|
4
|
+
import { BodyText } from '../BodyText';
|
|
5
|
+
import { Link } from '../Link';
|
|
6
|
+
import { useDescriptionListContext } from './DescriptionList.context';
|
|
7
|
+
import type DescriptionListItemProps from './DescriptionListItem.props';
|
|
8
|
+
|
|
9
|
+
const DescriptionListItem = ({
|
|
10
|
+
heading,
|
|
11
|
+
description,
|
|
12
|
+
headingWidth,
|
|
13
|
+
linkText,
|
|
14
|
+
linkHref,
|
|
15
|
+
linkIcon,
|
|
16
|
+
linkIconPosition,
|
|
17
|
+
linkOnPress,
|
|
18
|
+
linkTarget,
|
|
19
|
+
linkShowIcon,
|
|
20
|
+
style,
|
|
21
|
+
...props
|
|
22
|
+
}: DescriptionListItemProps) => {
|
|
23
|
+
const { components } = useTheme();
|
|
24
|
+
const { direction, itemHeadingWidth = components.descriptionList.item.row.headingWidth } =
|
|
25
|
+
useDescriptionListContext();
|
|
26
|
+
styles.useVariants({ direction });
|
|
27
|
+
const headingIsText = typeof heading === 'string' || typeof heading === 'number';
|
|
28
|
+
const descIsText = typeof description === 'string' || typeof description === 'number';
|
|
29
|
+
const combinedLabel = headingIsText && descIsText ? `${heading}: ${description}` : undefined;
|
|
30
|
+
const hideDescendants = !!combinedLabel;
|
|
31
|
+
return (
|
|
32
|
+
<View
|
|
33
|
+
accessibilityRole="text"
|
|
34
|
+
accessible={!!combinedLabel}
|
|
35
|
+
accessibilityLabel={combinedLabel}
|
|
36
|
+
{...props}
|
|
37
|
+
style={[styles.item, style]}
|
|
38
|
+
>
|
|
39
|
+
<View
|
|
40
|
+
style={styles.textWrap}
|
|
41
|
+
importantForAccessibility={hideDescendants ? 'no-hide-descendants' : undefined}
|
|
42
|
+
accessibilityElementsHidden={hideDescendants || undefined}
|
|
43
|
+
>
|
|
44
|
+
<View style={[direction === 'row' && { width: headingWidth || itemHeadingWidth }]}>
|
|
45
|
+
{headingIsText ? <BodyText style={styles.headingText}>{heading}</BodyText> : heading}
|
|
46
|
+
</View>
|
|
47
|
+
<View style={styles.descriptionWrapper}>
|
|
48
|
+
{descIsText ? <BodyText>{description}</BodyText> : description}
|
|
49
|
+
</View>
|
|
50
|
+
</View>
|
|
51
|
+
{linkText ? (
|
|
52
|
+
<Link
|
|
53
|
+
href={linkHref}
|
|
54
|
+
onPress={linkOnPress}
|
|
55
|
+
target={linkTarget}
|
|
56
|
+
showIcon={linkShowIcon}
|
|
57
|
+
icon={linkIcon}
|
|
58
|
+
iconPosition={linkIconPosition}
|
|
59
|
+
accessibilityRole="link"
|
|
60
|
+
>
|
|
61
|
+
{linkText}
|
|
62
|
+
</Link>
|
|
63
|
+
) : null}
|
|
64
|
+
</View>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
DescriptionListItem.displayName = 'DescriptionListItem';
|
|
69
|
+
|
|
70
|
+
const styles = StyleSheet.create(theme => ({
|
|
71
|
+
item: {
|
|
72
|
+
width: theme.space.full,
|
|
73
|
+
flexDirection: 'row',
|
|
74
|
+
alignItems: 'flex-start',
|
|
75
|
+
gap: theme.components.descriptionList.item.gap,
|
|
76
|
+
},
|
|
77
|
+
textWrap: {
|
|
78
|
+
flex: 1,
|
|
79
|
+
variants: {
|
|
80
|
+
direction: {
|
|
81
|
+
row: {
|
|
82
|
+
flexDirection: 'row',
|
|
83
|
+
alignItems: 'flex-start',
|
|
84
|
+
gap: theme.components.descriptionList.item.row.gap,
|
|
85
|
+
},
|
|
86
|
+
column: {
|
|
87
|
+
flexDirection: 'column',
|
|
88
|
+
gap: theme.components.descriptionList.item.column.gap,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
headingText: {
|
|
94
|
+
color: theme.color.text.secondary,
|
|
95
|
+
},
|
|
96
|
+
descriptionWrapper: {
|
|
97
|
+
flex: 1,
|
|
98
|
+
},
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
export default DescriptionListItem;
|