@utilitywarehouse/hearth-react-native 0.2.0 → 0.3.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +1 -1
- package/CHANGELOG.md +22 -0
- package/build/components/Badge/Badge.js +101 -14
- package/build/components/Badge/Badge.props.d.ts +2 -2
- package/build/components/Badge/BadgeIcon.js +5 -79
- package/build/components/Badge/BadgeText.js +7 -81
- 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/Card/Card.props.d.ts +2 -2
- 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/Modal/Modal.js +17 -1
- package/build/components/SectionHeader/SectionHeader.js +1 -0
- 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/index.d.ts +4 -0
- package/build/components/index.js +4 -0
- package/build/core/themes.d.ts +416 -148
- package/build/core/themes.js +57 -1
- package/build/tokens/color.d.ts +76 -68
- package/build/tokens/color.js +38 -34
- 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 +1 -1
- package/build/tokens/components/dark/checkbox.js +1 -1
- package/build/tokens/components/dark/icon-button.d.ts +3 -3
- package/build/tokens/components/dark/icon-button.js +3 -3
- 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/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 +3 -3
- package/build/tokens/components/light/checkbox.js +3 -3
- package/build/tokens/components/light/icon-button.d.ts +1 -1
- package/build/tokens/components/light/icon-button.js +1 -1
- 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/layout.d.ts +48 -30
- package/build/tokens/layout.js +24 -15
- package/build/tokens/semantic-dark.d.ts +21 -19
- package/build/tokens/semantic-dark.js +21 -19
- package/build/tokens/semantic-light.d.ts +17 -15
- package/build/tokens/semantic-light.js +17 -15
- 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/components/AllComponents.web.tsx +97 -8
- package/docs/components/NextPrevPage.tsx +11 -3
- package/docs/components/UsageWrap.tsx +2 -2
- package/docs/heplers/addReactNativePrefix.ts +8 -0
- package/docs/heplers/index.ts +1 -0
- package/docs/theme-tokens.mdx +42 -0
- package/package.json +2 -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 +5 -79
- package/src/components/Badge/BadgeText.tsx +7 -81
- package/src/components/Button/ButtonGroupRoot.tsx +12 -2
- package/src/components/Card/Card.docs.mdx +1 -1
- package/src/components/Card/Card.props.ts +2 -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/Modal/Modal.tsx +18 -0
- package/src/components/SectionHeader/SectionHeader.tsx +1 -0
- 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/index.ts +4 -0
- package/src/core/themes.ts +57 -1
- package/src/tokens/color.ts +38 -34
- package/src/tokens/components/dark/button.ts +1 -0
- package/src/tokens/components/dark/checkbox.ts +1 -1
- package/src/tokens/components/dark/icon-button.ts +3 -3
- package/src/tokens/components/dark/radio.ts +1 -1
- package/src/tokens/components/dark/tabs.ts +2 -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 +3 -3
- package/src/tokens/components/light/icon-button.ts +1 -1
- package/src/tokens/components/light/radio.ts +3 -3
- package/src/tokens/components/light/tabs.ts +2 -0
- package/src/tokens/layout.ts +24 -15
- package/src/tokens/semantic-dark.ts +21 -19
- package/src/tokens/semantic-light.ts +17 -15
- package/src/types/values.ts +3 -1
- package/src/utils/formatThousands.ts +14 -0
- package/src/utils/index.ts +1 -0
|
@@ -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;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as DescriptionList } from './DescriptionList';
|
|
2
|
+
export type { default as DescriptionListProps } from './DescriptionList.props';
|
|
3
|
+
export { default as DescriptionListItem } from './DescriptionListItem';
|
|
4
|
+
export type { default as DescriptionListItemProps } from './DescriptionListItem.props';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { DimensionValue, ViewProps } from 'react-native';
|
|
2
|
-
import type { ColorValue } from '../../types';
|
|
2
|
+
import type { ColorValue, SpacingValues } from '../../types';
|
|
3
3
|
|
|
4
4
|
interface DividerProps extends Omit<ViewProps, 'children'> {
|
|
5
5
|
color?: ColorValue;
|
|
6
|
-
space?:
|
|
6
|
+
space?: SpacingValues;
|
|
7
7
|
orientation?: 'horizontal' | 'vertical';
|
|
8
8
|
height?: DimensionValue;
|
|
9
9
|
width?: DimensionValue;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Divider } from '.';
|
|
2
1
|
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
-
import {
|
|
2
|
+
import { Divider } from '.';
|
|
4
3
|
import { coloursAsArray } from '../../utils';
|
|
4
|
+
import { Box } from '../Box';
|
|
5
5
|
|
|
6
6
|
const meta = {
|
|
7
7
|
title: 'Stories / Divider',
|
|
@@ -21,7 +21,7 @@ const meta = {
|
|
|
21
21
|
description: 'Color of the divider',
|
|
22
22
|
},
|
|
23
23
|
space: {
|
|
24
|
-
options: ['none', 'xs', 'sm', 'md', 'lg', 'xl'],
|
|
24
|
+
options: ['none', '2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl'],
|
|
25
25
|
control: 'select',
|
|
26
26
|
description: 'Space between the divider',
|
|
27
27
|
},
|
|
@@ -44,11 +44,13 @@ const styles = StyleSheet.create(theme => ({
|
|
|
44
44
|
},
|
|
45
45
|
space: {
|
|
46
46
|
none: {},
|
|
47
|
+
'2xs': {},
|
|
47
48
|
xs: {},
|
|
48
49
|
sm: {},
|
|
49
50
|
md: {},
|
|
50
51
|
lg: {},
|
|
51
52
|
xl: {},
|
|
53
|
+
'2xl': {},
|
|
52
54
|
},
|
|
53
55
|
flexItem: {
|
|
54
56
|
true: {
|
|
@@ -64,6 +66,17 @@ const styles = StyleSheet.create(theme => ({
|
|
|
64
66
|
marginVertical: 0,
|
|
65
67
|
},
|
|
66
68
|
},
|
|
69
|
+
{
|
|
70
|
+
orientation: 'horizontal',
|
|
71
|
+
space: '2xs',
|
|
72
|
+
styles: {
|
|
73
|
+
marginVertical: {
|
|
74
|
+
base: theme.layout.mobile.spacing['2xs'],
|
|
75
|
+
md: theme.layout.tablet.spacing['2xs'],
|
|
76
|
+
lg: theme.layout.desktop.spacing['2xs'],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
67
80
|
{
|
|
68
81
|
orientation: 'horizontal',
|
|
69
82
|
space: 'xs',
|
|
@@ -119,6 +132,17 @@ const styles = StyleSheet.create(theme => ({
|
|
|
119
132
|
},
|
|
120
133
|
},
|
|
121
134
|
},
|
|
135
|
+
{
|
|
136
|
+
orientation: 'horizontal',
|
|
137
|
+
space: '2xl',
|
|
138
|
+
styles: {
|
|
139
|
+
marginVertical: {
|
|
140
|
+
base: theme.layout.mobile.spacing['2xl'],
|
|
141
|
+
md: theme.layout.tablet.spacing['2xl'],
|
|
142
|
+
lg: theme.layout.desktop.spacing['2xl'],
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
122
146
|
{
|
|
123
147
|
orientation: 'vertical',
|
|
124
148
|
space: 'none',
|
|
@@ -126,6 +150,17 @@ const styles = StyleSheet.create(theme => ({
|
|
|
126
150
|
marginHorizontal: 0,
|
|
127
151
|
},
|
|
128
152
|
},
|
|
153
|
+
{
|
|
154
|
+
orientation: 'vertical',
|
|
155
|
+
space: '2xs',
|
|
156
|
+
styles: {
|
|
157
|
+
marginHorizontal: {
|
|
158
|
+
base: theme.layout.mobile.spacing['2xs'],
|
|
159
|
+
md: theme.layout.tablet.spacing['2xs'],
|
|
160
|
+
lg: theme.layout.desktop.spacing['2xs'],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
129
164
|
{
|
|
130
165
|
orientation: 'vertical',
|
|
131
166
|
space: 'xs',
|
|
@@ -181,6 +216,17 @@ const styles = StyleSheet.create(theme => ({
|
|
|
181
216
|
},
|
|
182
217
|
},
|
|
183
218
|
},
|
|
219
|
+
{
|
|
220
|
+
orientation: 'vertical',
|
|
221
|
+
space: '2xl',
|
|
222
|
+
styles: {
|
|
223
|
+
marginHorizontal: {
|
|
224
|
+
base: theme.layout.mobile.spacing['2xl'],
|
|
225
|
+
md: theme.layout.tablet.spacing['2xl'],
|
|
226
|
+
lg: theme.layout.desktop.spacing['2xl'],
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
},
|
|
184
230
|
],
|
|
185
231
|
},
|
|
186
232
|
extraStyles: (color, width, height) => ({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Canvas, Controls, Meta, Primary, Story } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import { BodyText, Center, Flex, Pressable } from '../..';
|
|
3
|
+
import { BackToTopButton, UsageWrap, ViewFigmaButton } from '../../../docs/components';
|
|
2
4
|
import * as Stories from './Flex.stories';
|
|
3
|
-
import { Center, Pressable, Flex, BodyText } from '../..';
|
|
4
|
-
import { UsageWrap, BackToTopButton, ViewFigmaButton } from '../../../docs/components';
|
|
5
5
|
|
|
6
6
|
<Meta title="Primitives / Flex" />
|
|
7
7
|
|
|
@@ -57,4 +57,4 @@ const MyComponent = () => (
|
|
|
57
57
|
| `wrap` | `'wrap' \| 'nowrap' \| 'wrap-reverse'` | `nowrap` | The wrap of the flex container. |
|
|
58
58
|
| `justify` | `'flex-start' \| 'flex-end' \| 'center' \| `<br />`'space-between' \| 'space-around' \| 'space-evenly'` | `flex-start` | The justify content of the flex container. |
|
|
59
59
|
| `align` | `'flex-start' \| 'flex-end' \| 'center' \| 'stretch' \| 'baseline'` | `flex-start` | The align items of the flex container. |
|
|
60
|
-
| `space` | `'none' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'`
|
|
60
|
+
| `space` | `'none' \| '2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | `md` | The space between the content. |
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type { ViewProps, ViewStyle
|
|
1
|
+
import type { FlexAlignType, ViewProps, ViewStyle } from 'react-native';
|
|
2
|
+
import { SpacingValues } from '../../types';
|
|
2
3
|
|
|
3
4
|
interface FlexProps extends ViewProps {
|
|
4
5
|
direction?: ViewStyle['flexDirection'];
|
|
5
6
|
align?: FlexAlignType;
|
|
6
7
|
justify?: ViewStyle['justifyContent'];
|
|
7
8
|
wrap?: ViewStyle['flexWrap'];
|
|
8
|
-
space?:
|
|
9
|
+
space?: SpacingValues;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export default FlexProps;
|
|
@@ -40,7 +40,7 @@ const meta = {
|
|
|
40
40
|
description: 'The justify of the flex container.',
|
|
41
41
|
},
|
|
42
42
|
space: {
|
|
43
|
-
options: ['none', 'xs', 'sm', 'md', 'lg', 'xl'],
|
|
43
|
+
options: ['none', '2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl'],
|
|
44
44
|
control: 'radio',
|
|
45
45
|
description: 'The space of the flex container.',
|
|
46
46
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Canvas, Controls, Meta, Primary, Story } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import { BodyText, Box, Center, Grid } from '../..';
|
|
3
|
+
import { BackToTopButton, UsageWrap, ViewFigmaButton } from '../../../docs/components';
|
|
2
4
|
import * as Stories from './Grid.stories';
|
|
3
|
-
import { Center, Grid, Box, BodyText } from '../..';
|
|
4
|
-
import { UsageWrap, BackToTopButton, ViewFigmaButton } from '../../../docs/components';
|
|
5
5
|
|
|
6
6
|
<Meta title="Primitives / Grid" />
|
|
7
7
|
|
|
@@ -173,15 +173,15 @@ const MyComponent = () => (
|
|
|
173
173
|
|
|
174
174
|
The Grid component extends all the props from the [View component](https://reactnative.dev/docs/view), and adds the following:
|
|
175
175
|
|
|
176
|
-
| Name | Type
|
|
177
|
-
| ---------------- |
|
|
178
|
-
| `columns` | `number` or `GridColumns`
|
|
179
|
-
| `space` | `'none' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | - | Spacing between grid items (both rows and columns) |
|
|
180
|
-
| `columnGap` | `number`
|
|
181
|
-
| `rowGap` | `number`
|
|
182
|
-
| `containerStyle` | `StyleProp\<ViewStyle\>`
|
|
183
|
-
| `itemStyle` | `StyleProp\<ViewStyle\>`
|
|
184
|
-
| `rowStyle` | `StyleProp\<ViewStyle\>`
|
|
176
|
+
| Name | Type | Default | Description |
|
|
177
|
+
| ---------------- | ------------------------------------------------------------------ | ------- | ------------------------------------------------------------- |
|
|
178
|
+
| `columns` | `number` or `GridColumns` | 2 | Number of columns or responsive object with breakpoint values |
|
|
179
|
+
| `space` | `'none' \| '2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | - | Spacing between grid items (both rows and columns) |
|
|
180
|
+
| `columnGap` | `number` | - | Gap between columns (overrides spacing if provided) |
|
|
181
|
+
| `rowGap` | `number` | - | Gap between rows (overrides spacing if provided) |
|
|
182
|
+
| `containerStyle` | `StyleProp\<ViewStyle\>` | - | Style for the grid container |
|
|
183
|
+
| `itemStyle` | `StyleProp\<ViewStyle\>` | - | Style applied to each grid item |
|
|
184
|
+
| `rowStyle` | `StyleProp\<ViewStyle\>` | - | Style applied to each row |
|
|
185
185
|
|
|
186
186
|
Where `GridColumns` is defined as:
|
|
187
187
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StyleProp, ViewProps, ViewStyle } from 'react-native';
|
|
2
2
|
import { UnistylesBreakpoints } from 'react-native-unistyles';
|
|
3
|
-
import { SpaceValue } from '../../types';
|
|
3
|
+
import { SpaceValue, SpacingValues } from '../../types';
|
|
4
4
|
|
|
5
5
|
// Create a type that uses the keys from our breakpoints object
|
|
6
6
|
export type GridColumns = {
|
|
@@ -17,7 +17,7 @@ export interface GridProps extends ViewProps {
|
|
|
17
17
|
/**
|
|
18
18
|
* Spacing between grid items (applies to both rows and columns)
|
|
19
19
|
*/
|
|
20
|
-
space?:
|
|
20
|
+
space?: SpacingValues;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Gap between items (overrides spacing if provided)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import {
|
|
2
|
+
import { Text, View } from 'react-native';
|
|
3
3
|
import { Grid } from '.';
|
|
4
4
|
|
|
5
5
|
const meta = {
|
|
@@ -14,7 +14,7 @@ const meta = {
|
|
|
14
14
|
description: 'Number of columns or responsive object with breakpoints',
|
|
15
15
|
},
|
|
16
16
|
space: {
|
|
17
|
-
options: ['none', 'xs', 'sm', 'md', 'lg', 'xl'],
|
|
17
|
+
options: ['none', '2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl'],
|
|
18
18
|
control: 'radio',
|
|
19
19
|
description: 'Responsive spacing between grid items (applied to both rows and columns).',
|
|
20
20
|
},
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Canvas, Controls, Meta, Story } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import {
|
|
3
|
+
BroadbandMediumIcon,
|
|
4
|
+
CashbackCardMediumIcon,
|
|
5
|
+
ConfettiMediumIcon,
|
|
6
|
+
ElectricityMediumIcon,
|
|
7
|
+
InsuranceMediumIcon,
|
|
8
|
+
MobileMediumIcon,
|
|
9
|
+
} from '@utilitywarehouse/hearth-react-native-icons';
|
|
10
|
+
import { Center, Flex, IconContainer } from '../../';
|
|
11
|
+
import { BackToTopButton, UsageWrap } from '../../../docs/components';
|
|
12
|
+
import * as Stories from './IconContainer.stories';
|
|
13
|
+
|
|
14
|
+
<BackToTopButton />
|
|
15
|
+
|
|
16
|
+
<Meta title="Components / Icon Container" />
|
|
17
|
+
|
|
18
|
+
# Icon Container
|
|
19
|
+
|
|
20
|
+
The `IconContainer` component provides a consistent background and sizing (via component tokens) for any standalone icon, with semantic colour families and subtle/emphasis variants.
|
|
21
|
+
|
|
22
|
+
- [Playground](#playground)
|
|
23
|
+
- [Usage](#usage)
|
|
24
|
+
- [Props](#props)
|
|
25
|
+
- [Variants](#variants)
|
|
26
|
+
|
|
27
|
+
## Playground
|
|
28
|
+
|
|
29
|
+
<Canvas of={Stories.Playground} />
|
|
30
|
+
|
|
31
|
+
<Controls of={Stories.Playground} />
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
Wrap an icon with the `IconContainer` to apply sizing + background styles without repeating layout code.
|
|
36
|
+
|
|
37
|
+
<UsageWrap>
|
|
38
|
+
<Center>
|
|
39
|
+
<Flex direction="row" space="lg" alignItems="center">
|
|
40
|
+
<IconContainer icon={ElectricityMediumIcon} size="md" variant="emphasis" color="energy" />
|
|
41
|
+
<IconContainer icon={BroadbandMediumIcon} size="md" variant="emphasis" color="broadband" />
|
|
42
|
+
<IconContainer icon={MobileMediumIcon} size="md" variant="emphasis" color="mobile" />
|
|
43
|
+
<IconContainer icon={InsuranceMediumIcon} size="md" variant="emphasis" color="insurance" />
|
|
44
|
+
<IconContainer icon={CashbackCardMediumIcon} size="md" variant="emphasis" color="cashback" />
|
|
45
|
+
<IconContainer icon={ConfettiMediumIcon} size="md" variant="emphasis" color="pig" />
|
|
46
|
+
</Flex>
|
|
47
|
+
</Center>
|
|
48
|
+
</UsageWrap>
|
|
49
|
+
|
|
50
|
+
```jsx
|
|
51
|
+
import { IconContainer } from '@utilitywarehouse/hearth-react-native';
|
|
52
|
+
import {
|
|
53
|
+
ElectricityMediumIcon,
|
|
54
|
+
BroadbandMediumIcon,
|
|
55
|
+
MobileMediumIcon,
|
|
56
|
+
InsuranceMediumIcon,
|
|
57
|
+
CashbackCardMediumIcon,
|
|
58
|
+
ConfettiMediumIcon,
|
|
59
|
+
} from '@utilitywarehouse/hearth-react-native-icons';
|
|
60
|
+
|
|
61
|
+
const MyComponent = () => (
|
|
62
|
+
<>
|
|
63
|
+
<IconContainer icon={ElectricityMediumIcon} size="md" variant="emphasis" color="energy" />
|
|
64
|
+
<IconContainer icon={BroadbandMediumIcon} size="md" variant="emphasis" color="broadband" />
|
|
65
|
+
<IconContainer icon={MobileMediumIcon} size="md" variant="emphasis" color="mobile" />
|
|
66
|
+
<IconContainer icon={InsuranceMediumIcon} size="md" variant="emphasis" color="insurance" />
|
|
67
|
+
<IconContainer icon={CashbackCardMediumIcon} size="md" variant="emphasis" color="cashback" />
|
|
68
|
+
<IconContainer icon={ConfettiMediumIcon} size="md" variant="emphasis" color="pig" />
|
|
69
|
+
</>
|
|
70
|
+
);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Props
|
|
74
|
+
|
|
75
|
+
| Name | Type | Description | Default |
|
|
76
|
+
| ------------ | -------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ---------- |
|
|
77
|
+
| `icon` | `React.ComponentType` | Icon component rendered inside the container | (required) |
|
|
78
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | Size variant (token-based width/height/padding) | `md` |
|
|
79
|
+
| `radiusNone` | `boolean` | Remove border radius (square container) | `false` |
|
|
80
|
+
| `variant` | `'subtle' \| 'emphasis'` | Background emphasis level | `subtle` |
|
|
81
|
+
| `color` | `'pig' \| 'energy' \| 'broadband' \| 'mobile' \|` <br />`'insurance' \| 'cashback' \| 'highlight'` | Semantic colour family for surface tokens | `pig` |
|
|
82
|
+
| `...View` | React Native `ViewProps` | Any additional View props | - |
|
|
83
|
+
|
|
84
|
+
> Colours resolve to `theme.color.surface.<family>.{subtle|default}` depending on variant.
|
|
85
|
+
|
|
86
|
+
## Variants
|
|
87
|
+
|
|
88
|
+
Use the matrix below to compare every combination of size, variant, and color.
|
|
89
|
+
|
|
90
|
+
<Canvas of={Stories.KitchenSink} />
|