@utilitywarehouse/hearth-react-native 0.9.0 → 0.10.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 +8 -0
- package/build/components/PillGroup/Pill.d.ts +16 -0
- package/build/components/PillGroup/Pill.js +94 -0
- package/build/components/PillGroup/Pill.props.d.ts +10 -0
- package/build/components/PillGroup/Pill.props.js +1 -0
- package/build/components/PillGroup/PillGroup.context.d.ts +6 -0
- package/build/components/PillGroup/PillGroup.context.js +5 -0
- package/build/components/PillGroup/PillGroup.d.ts +5 -0
- package/build/components/PillGroup/PillGroup.js +34 -0
- package/build/components/PillGroup/PillGroup.props.d.ts +15 -0
- package/build/components/PillGroup/PillGroup.props.js +1 -0
- package/build/components/PillGroup/index.d.ts +4 -0
- package/build/components/PillGroup/index.js +2 -0
- package/build/components/Select/Select.js +2 -1
- package/build/components/Toast/Toast.context.d.ts +9 -0
- package/build/components/Toast/Toast.context.js +90 -0
- package/build/components/Toast/Toast.props.d.ts +29 -0
- package/build/components/Toast/Toast.props.js +1 -0
- package/build/components/Toast/ToastItem.d.ts +10 -0
- package/build/components/Toast/ToastItem.js +129 -0
- package/build/components/Toast/index.d.ts +3 -0
- package/build/components/Toast/index.js +2 -0
- package/build/components/index.d.ts +2 -0
- package/build/components/index.js +2 -0
- package/build/tokens/components/dark/checkbox.d.ts +3 -0
- package/build/tokens/components/dark/checkbox.js +3 -0
- package/build/tokens/components/dark/input.d.ts +6 -0
- package/build/tokens/components/dark/input.js +6 -0
- package/build/tokens/components/dark/radio.d.ts +3 -0
- package/build/tokens/components/dark/radio.js +3 -0
- package/build/tokens/components/dark/table.d.ts +2 -0
- package/build/tokens/components/dark/table.js +2 -0
- package/build/tokens/components/dark/toast.d.ts +6 -2
- package/build/tokens/components/dark/toast.js +6 -2
- package/build/tokens/components/light/checkbox.d.ts +3 -0
- package/build/tokens/components/light/checkbox.js +3 -0
- package/build/tokens/components/light/input.d.ts +6 -0
- package/build/tokens/components/light/input.js +6 -0
- package/build/tokens/components/light/radio.d.ts +3 -0
- package/build/tokens/components/light/radio.js +3 -0
- package/build/tokens/components/light/table.d.ts +2 -0
- package/build/tokens/components/light/table.js +2 -0
- package/build/tokens/components/light/toast.d.ts +6 -2
- package/build/tokens/components/light/toast.js +6 -2
- package/docs/assets/toast-ios.MP4 +0 -0
- package/docs/components/AllComponents.web.tsx +26 -0
- package/package.json +3 -3
- package/src/components/PillGroup/Pill.props.ts +13 -0
- package/src/components/PillGroup/Pill.tsx +120 -0
- package/src/components/PillGroup/PillGroup.context.tsx +12 -0
- package/src/components/PillGroup/PillGroup.docs.mdx +96 -0
- package/src/components/PillGroup/PillGroup.props.ts +22 -0
- package/src/components/PillGroup/PillGroup.stories.tsx +159 -0
- package/src/components/PillGroup/PillGroup.tsx +66 -0
- package/src/components/PillGroup/index.ts +4 -0
- package/src/components/Select/Select.tsx +2 -0
- package/src/components/Toast/Toast.context.tsx +118 -0
- package/src/components/Toast/Toast.docs.mdx +164 -0
- package/src/components/Toast/Toast.props.ts +33 -0
- package/src/components/Toast/Toast.stories.tsx +356 -0
- package/src/components/Toast/ToastItem.tsx +200 -0
- package/src/components/Toast/index.ts +3 -0
- package/src/components/index.ts +2 -0
- package/src/tokens/components/dark/checkbox.ts +3 -0
- package/src/tokens/components/dark/input.ts +6 -0
- package/src/tokens/components/dark/radio.ts +3 -0
- package/src/tokens/components/dark/table.ts +2 -0
- package/src/tokens/components/dark/toast.ts +6 -2
- package/src/tokens/components/light/checkbox.ts +3 -0
- package/src/tokens/components/light/input.ts +6 -0
- package/src/tokens/components/light/radio.ts +3 -0
- package/src/tokens/components/light/table.ts +2 -0
- package/src/tokens/components/light/toast.ts +6 -2
|
@@ -5,6 +5,7 @@ declare const _default: {
|
|
|
5
5
|
readonly borderRadius: 16;
|
|
6
6
|
readonly cell: {
|
|
7
7
|
readonly borderWidth: 1;
|
|
8
|
+
readonly minHeight: 48;
|
|
8
9
|
readonly padding: 12;
|
|
9
10
|
};
|
|
10
11
|
readonly emphasis: {
|
|
@@ -13,6 +14,7 @@ declare const _default: {
|
|
|
13
14
|
readonly headerCell: {
|
|
14
15
|
readonly borderWidth: 2;
|
|
15
16
|
readonly gap: 8;
|
|
17
|
+
readonly height: 56;
|
|
16
18
|
readonly paddingHorizontal: 12;
|
|
17
19
|
readonly paddingVertical: 16;
|
|
18
20
|
};
|
|
@@ -5,6 +5,7 @@ export default {
|
|
|
5
5
|
borderRadius: 16,
|
|
6
6
|
cell: {
|
|
7
7
|
borderWidth: 1,
|
|
8
|
+
minHeight: 48,
|
|
8
9
|
padding: 12,
|
|
9
10
|
},
|
|
10
11
|
emphasis: {
|
|
@@ -13,6 +14,7 @@ export default {
|
|
|
13
14
|
headerCell: {
|
|
14
15
|
borderWidth: 2,
|
|
15
16
|
gap: 8,
|
|
17
|
+
height: 56,
|
|
16
18
|
paddingHorizontal: 12,
|
|
17
19
|
paddingVertical: 16,
|
|
18
20
|
},
|
|
@@ -4,10 +4,14 @@
|
|
|
4
4
|
declare const _default: {
|
|
5
5
|
readonly backgroundColor: "#3f3f3f";
|
|
6
6
|
readonly borderRadius: 8;
|
|
7
|
-
readonly
|
|
7
|
+
readonly bottomPosition: 32;
|
|
8
|
+
readonly gap: 16;
|
|
8
9
|
readonly padding: 14;
|
|
9
10
|
readonly stack: {
|
|
10
|
-
readonly
|
|
11
|
+
readonly gap: 12;
|
|
12
|
+
};
|
|
13
|
+
readonly text: {
|
|
14
|
+
readonly gap: 8;
|
|
11
15
|
};
|
|
12
16
|
};
|
|
13
17
|
export default _default;
|
|
@@ -5,6 +5,7 @@ declare const _default: {
|
|
|
5
5
|
readonly borderRadius: 16;
|
|
6
6
|
readonly cell: {
|
|
7
7
|
readonly borderWidth: 1;
|
|
8
|
+
readonly minHeight: 48;
|
|
8
9
|
readonly padding: 12;
|
|
9
10
|
};
|
|
10
11
|
readonly emphasis: {
|
|
@@ -13,6 +14,7 @@ declare const _default: {
|
|
|
13
14
|
readonly headerCell: {
|
|
14
15
|
readonly borderWidth: 2;
|
|
15
16
|
readonly gap: 8;
|
|
17
|
+
readonly height: 56;
|
|
16
18
|
readonly paddingHorizontal: 12;
|
|
17
19
|
readonly paddingVertical: 16;
|
|
18
20
|
};
|
|
@@ -5,6 +5,7 @@ export default {
|
|
|
5
5
|
borderRadius: 16,
|
|
6
6
|
cell: {
|
|
7
7
|
borderWidth: 1,
|
|
8
|
+
minHeight: 48,
|
|
8
9
|
padding: 12,
|
|
9
10
|
},
|
|
10
11
|
emphasis: {
|
|
@@ -13,6 +14,7 @@ export default {
|
|
|
13
14
|
headerCell: {
|
|
14
15
|
borderWidth: 2,
|
|
15
16
|
gap: 8,
|
|
17
|
+
height: 56,
|
|
16
18
|
paddingHorizontal: 12,
|
|
17
19
|
paddingVertical: 16,
|
|
18
20
|
},
|
|
@@ -4,10 +4,14 @@
|
|
|
4
4
|
declare const _default: {
|
|
5
5
|
readonly backgroundColor: "#101010";
|
|
6
6
|
readonly borderRadius: 8;
|
|
7
|
-
readonly
|
|
7
|
+
readonly bottomPosition: 32;
|
|
8
|
+
readonly gap: 16;
|
|
8
9
|
readonly padding: 14;
|
|
9
10
|
readonly stack: {
|
|
10
|
-
readonly
|
|
11
|
+
readonly gap: 12;
|
|
12
|
+
};
|
|
13
|
+
readonly text: {
|
|
14
|
+
readonly gap: 8;
|
|
11
15
|
};
|
|
12
16
|
};
|
|
13
17
|
export default _default;
|
|
Binary file
|
|
@@ -68,6 +68,8 @@ import {
|
|
|
68
68
|
MenuTrigger,
|
|
69
69
|
Modal,
|
|
70
70
|
OL,
|
|
71
|
+
Pill,
|
|
72
|
+
PillGroup,
|
|
71
73
|
ProgressStep,
|
|
72
74
|
ProgressStepper,
|
|
73
75
|
Radio,
|
|
@@ -85,6 +87,7 @@ import {
|
|
|
85
87
|
TabsList,
|
|
86
88
|
Textarea,
|
|
87
89
|
ThemedImage,
|
|
90
|
+
ToastItem,
|
|
88
91
|
ToggleButtonCard,
|
|
89
92
|
ToggleButtonCardGroup,
|
|
90
93
|
UL,
|
|
@@ -627,6 +630,21 @@ const AllComponents: React.FC = () => {
|
|
|
627
630
|
</OL>
|
|
628
631
|
</Center>
|
|
629
632
|
</ComponentWrapper>
|
|
633
|
+
<ComponentWrapper name="Pill Group" link="/?path=/docs/components-pill-group--docs">
|
|
634
|
+
<Center flex={1} p="200">
|
|
635
|
+
{(() => {
|
|
636
|
+
const [pillValue, setPillValue] = React.useState<string[]>(['energy', 'mobile']);
|
|
637
|
+
return (
|
|
638
|
+
<PillGroup value={pillValue} onChange={v => setPillValue(v as string[])} wrap={false} multiple>
|
|
639
|
+
<Pill value="all" label="All" />
|
|
640
|
+
<Pill value="energy" label="Energy" icon={ElectricityMediumIcon} />
|
|
641
|
+
<Pill value="broadband" label="Broadband" icon={BroadbandMediumIcon} />
|
|
642
|
+
<Pill value="mobile" label="Mobile" icon={MobileMediumIcon} />
|
|
643
|
+
</PillGroup>
|
|
644
|
+
);
|
|
645
|
+
})()}
|
|
646
|
+
</Center>
|
|
647
|
+
</ComponentWrapper>
|
|
630
648
|
<ComponentWrapper
|
|
631
649
|
name="Progress Stepper"
|
|
632
650
|
link="/?path=/docs/components-progress-stepper--docs"
|
|
@@ -745,6 +763,14 @@ const AllComponents: React.FC = () => {
|
|
|
745
763
|
/>
|
|
746
764
|
</Center>
|
|
747
765
|
</ComponentWrapper>
|
|
766
|
+
<ComponentWrapper name="Toast" link="/?path=/docs/components-toast--docs">
|
|
767
|
+
<Center flex={1} p="200">
|
|
768
|
+
<ToastItem
|
|
769
|
+
onClose={() => {}}
|
|
770
|
+
toast={{ id: 'tst', text: "I'm a toast", duration: 0 }}
|
|
771
|
+
/>
|
|
772
|
+
</Center>
|
|
773
|
+
</ComponentWrapper>
|
|
748
774
|
<ComponentWrapper
|
|
749
775
|
name="Toggle Button Card"
|
|
750
776
|
link="/?path=/docs/components-toggle-button-card--docs"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utilitywarehouse/hearth-react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Utility Warehouse React Native UI library",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"vite-plugin-svgr": "^4.5.0",
|
|
58
58
|
"vitest": "^3.2.4",
|
|
59
59
|
"@utilitywarehouse/hearth-fonts": "^0.0.4",
|
|
60
|
-
"@utilitywarehouse/hearth-react-icons": "^0.7.
|
|
61
|
-
"@utilitywarehouse/hearth-react-native-icons": "^0.7.
|
|
60
|
+
"@utilitywarehouse/hearth-react-icons": "^0.7.4",
|
|
61
|
+
"@utilitywarehouse/hearth-react-native-icons": "^0.7.4",
|
|
62
62
|
"@utilitywarehouse/hearth-svg-assets": "^0.2.0",
|
|
63
63
|
"@utilitywarehouse/hearth-tokens": "^0.2.0"
|
|
64
64
|
},
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PressableProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface PillProps extends Omit<PressableProps, 'children'> {
|
|
5
|
+
/** Value returned when selected */
|
|
6
|
+
value: string;
|
|
7
|
+
|
|
8
|
+
/** Text label shown inside the pill */
|
|
9
|
+
label: string;
|
|
10
|
+
|
|
11
|
+
/** Left icon */
|
|
12
|
+
icon?: React.ComponentType<any>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { createPressable } from '@gluestack-ui/pressable';
|
|
2
|
+
import { Pressable } from 'react-native';
|
|
3
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
4
|
+
import { Icon } from '../Icon';
|
|
5
|
+
import { BodyText } from '../BodyText';
|
|
6
|
+
import { usePillGroupContext } from './PillGroup.context';
|
|
7
|
+
import type { PillProps } from './Pill.props';
|
|
8
|
+
|
|
9
|
+
const PillRoot = ({
|
|
10
|
+
value,
|
|
11
|
+
label,
|
|
12
|
+
icon,
|
|
13
|
+
states = {},
|
|
14
|
+
...props
|
|
15
|
+
}: PillProps & { states?: { active?: boolean } }) => {
|
|
16
|
+
const { active } = states;
|
|
17
|
+
const context = usePillGroupContext();
|
|
18
|
+
const isSelected = context?.value.includes(value) ?? false;
|
|
19
|
+
|
|
20
|
+
styles.useVariants({ selected: isSelected, active });
|
|
21
|
+
|
|
22
|
+
const handlePress = () => {
|
|
23
|
+
context?.onChange(value);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<Pressable
|
|
28
|
+
{...props}
|
|
29
|
+
style={styles.pill}
|
|
30
|
+
accessibilityRole="button"
|
|
31
|
+
accessibilityState={{ selected: isSelected }}
|
|
32
|
+
onPress={handlePress}
|
|
33
|
+
>
|
|
34
|
+
{icon && <Icon as={icon} size="sm" style={styles.icon} />}
|
|
35
|
+
<BodyText weight="semibold" style={styles.text}>
|
|
36
|
+
{label}
|
|
37
|
+
</BodyText>
|
|
38
|
+
</Pressable>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const Pill = createPressable({ Root: PillRoot });
|
|
43
|
+
|
|
44
|
+
Pill.displayName = 'Pill';
|
|
45
|
+
|
|
46
|
+
const styles = StyleSheet.create(theme => ({
|
|
47
|
+
pill: {
|
|
48
|
+
flexDirection: 'row',
|
|
49
|
+
alignItems: 'center',
|
|
50
|
+
justifyContent: 'center',
|
|
51
|
+
height: theme.components.pill.height,
|
|
52
|
+
minWidth: theme.components.pill.minWidth,
|
|
53
|
+
gap: theme.components.pill.gap,
|
|
54
|
+
paddingHorizontal: theme.components.pill.paddingHorizontal,
|
|
55
|
+
paddingVertical: theme.components.pill.paddingVertical,
|
|
56
|
+
borderRadius: theme.components.pill.borderRadius,
|
|
57
|
+
borderWidth: theme.components.pill.borderWidth,
|
|
58
|
+
borderColor: theme.color.interactive.neutral.border.subtle,
|
|
59
|
+
backgroundColor: 'transparent',
|
|
60
|
+
_web: {
|
|
61
|
+
_hover: {
|
|
62
|
+
backgroundColor: theme.color.interactive.neutral.surface.subtle.hover,
|
|
63
|
+
},
|
|
64
|
+
'_focus-visible': theme.helpers.focusVisible,
|
|
65
|
+
},
|
|
66
|
+
variants: {
|
|
67
|
+
active: {
|
|
68
|
+
true: {
|
|
69
|
+
backgroundColor: theme.color.interactive.neutral.surface.subtle.active,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
selected: {
|
|
73
|
+
true: {
|
|
74
|
+
backgroundColor: theme.color.interactive.brand.surface.strong.default,
|
|
75
|
+
borderColor: theme.color.interactive.brand.surface.strong.default,
|
|
76
|
+
_web: {
|
|
77
|
+
_hover: {
|
|
78
|
+
backgroundColor: theme.color.interactive.brand.surface.strong.hover,
|
|
79
|
+
borderColor: theme.color.interactive.brand.surface.strong.hover,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
compoundVariants: [
|
|
86
|
+
{
|
|
87
|
+
selected: true,
|
|
88
|
+
active: true,
|
|
89
|
+
styles: {
|
|
90
|
+
backgroundColor: theme.color.interactive.brand.surface.strong.active,
|
|
91
|
+
borderColor: theme.color.interactive.brand.surface.strong.active,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
text: {
|
|
97
|
+
variants: {
|
|
98
|
+
selected: {
|
|
99
|
+
true: {
|
|
100
|
+
color: theme.color.text.inverted,
|
|
101
|
+
},
|
|
102
|
+
false: {
|
|
103
|
+
color: theme.color.text.primary,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
icon: {
|
|
109
|
+
variants: {
|
|
110
|
+
selected: {
|
|
111
|
+
true: {
|
|
112
|
+
color: theme.color.icon.inverted,
|
|
113
|
+
},
|
|
114
|
+
false: {
|
|
115
|
+
color: theme.color.icon.primary,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface PillGroupContextValue {
|
|
4
|
+
value: string[];
|
|
5
|
+
onChange: (value: string) => void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const PillGroupContext = createContext<PillGroupContextValue | null>(null);
|
|
9
|
+
|
|
10
|
+
export const usePillGroupContext = () => {
|
|
11
|
+
return useContext(PillGroupContext);
|
|
12
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Canvas, Controls, Meta } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import { BackToTopButton, ViewFigmaButton } from '../../../docs/components';
|
|
3
|
+
import * as PillGroupStories from './PillGroup.stories';
|
|
4
|
+
|
|
5
|
+
<Meta title="Components / Pill Group" />
|
|
6
|
+
|
|
7
|
+
<ViewFigmaButton url="https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR/Hearth-Components---Tokens" />
|
|
8
|
+
|
|
9
|
+
<BackToTopButton />
|
|
10
|
+
|
|
11
|
+
# Pill Group
|
|
12
|
+
|
|
13
|
+
A container component that groups multiple `Pill` components together for filtering and categorization. It provides layout control with optional wrapping behavior and manages selection state.
|
|
14
|
+
|
|
15
|
+
- [Playground](#playground)
|
|
16
|
+
- [Usage](#usage)
|
|
17
|
+
- [Props](#props)
|
|
18
|
+
- [Examples](#examples)
|
|
19
|
+
|
|
20
|
+
## Playground
|
|
21
|
+
|
|
22
|
+
<Canvas of={PillGroupStories.Playground} />
|
|
23
|
+
|
|
24
|
+
<Controls of={PillGroupStories.Playground} />
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
The `PillGroup` component is a controlled component that manages the selection state of multiple `Pill` components. It supports both single and multi-select modes.
|
|
29
|
+
|
|
30
|
+
### Basic Usage
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { Pill, PillGroup } from '@hearth/react-native';
|
|
34
|
+
import { useState } from 'react';
|
|
35
|
+
|
|
36
|
+
const [selectedTags, setSelectedTags] = useState(['ui']);
|
|
37
|
+
|
|
38
|
+
<PillGroup value={selectedTags} onChange={setSelectedTags}>
|
|
39
|
+
<Pill value="ui" label="UI" />
|
|
40
|
+
<Pill value="backend" label="Backend" icon={ServerMediumIcon} />
|
|
41
|
+
<Pill value="devops" label="DevOps" />
|
|
42
|
+
</PillGroup>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Props
|
|
46
|
+
|
|
47
|
+
### PillGroup Props
|
|
48
|
+
|
|
49
|
+
| Prop | Type | Default | Description |
|
|
50
|
+
|------|------|---------|-------------|
|
|
51
|
+
| `value` | `string \| string[]` | Required | Controlled selected value(s). Single string for single-select, array for multi-select |
|
|
52
|
+
| `multiple` | `boolean` | `false` | Enable multi-select mode |
|
|
53
|
+
| `wrap` | `boolean` | `true` | Whether pills should wrap to multiple lines when they overflow |
|
|
54
|
+
| `onChange` | `(value: string \| string[]) => void` | - | Handle selection changes. Returns single string in single-select mode, array in multi-select mode |
|
|
55
|
+
| `children` | `ReactNode` | Required | `Pill` components to group together |
|
|
56
|
+
| ...rest | `ViewProps` | - | All standard View props are supported |
|
|
57
|
+
|
|
58
|
+
### Pill Props
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default | Description |
|
|
61
|
+
|------|------|---------|-------------|
|
|
62
|
+
| `value` | `string` | Required | Value returned when selected |
|
|
63
|
+
| `label` | `string` | Required | The text content of the pill |
|
|
64
|
+
| `icon` | `ComponentType<any>` | - | Optional icon component to display before the label |
|
|
65
|
+
| ...rest | `PressableProps` | - | All standard Pressable props are supported |
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Multi-Select Mode
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
const [tags, setTags] = useState(['ui', 'backend']);
|
|
72
|
+
|
|
73
|
+
<PillGroup multiple value={tags} onChange={setTags}>
|
|
74
|
+
<Pill value="ui" label="UI" />
|
|
75
|
+
<Pill value="backend" label="Backend" icon={ServerMediumIcon} />
|
|
76
|
+
<Pill value="devops" label="DevOps" />
|
|
77
|
+
</PillGroup>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Examples
|
|
81
|
+
|
|
82
|
+
### Wrap Behavior
|
|
83
|
+
|
|
84
|
+
Compare how pills behave with and without wrapping enabled.
|
|
85
|
+
|
|
86
|
+
<Canvas of={PillGroupStories.WrapBehavior} />
|
|
87
|
+
|
|
88
|
+
### Multi-Select Example
|
|
89
|
+
|
|
90
|
+
Select multiple options
|
|
91
|
+
|
|
92
|
+
<Canvas of={PillGroupStories.Multiple} />
|
|
93
|
+
|
|
94
|
+
### All States of Pill
|
|
95
|
+
|
|
96
|
+
<Canvas of={PillGroupStories.PillStates} />
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ScrollViewProps, ViewStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface PillGroupProps
|
|
5
|
+
extends Omit<ScrollViewProps, 'horizontal' | 'contentContainerStyle' | 'showsHorizontalScrollIndicator'> {
|
|
6
|
+
/** Controlled selected value(s) */
|
|
7
|
+
value: string | string[];
|
|
8
|
+
|
|
9
|
+
/** Multi-select mode. Default = false */
|
|
10
|
+
multiple?: boolean;
|
|
11
|
+
|
|
12
|
+
/** Allow pills to wrap lines. Default = true */
|
|
13
|
+
wrap?: boolean;
|
|
14
|
+
|
|
15
|
+
/** Handle selection changes */
|
|
16
|
+
onChange?: (value: string | string[]) => void;
|
|
17
|
+
|
|
18
|
+
/** Children must be <Pill> elements */
|
|
19
|
+
children: React.ReactNode;
|
|
20
|
+
|
|
21
|
+
style?: ViewStyle | ViewStyle[];
|
|
22
|
+
}
|