@utilitywarehouse/hearth-react-native 0.14.1 → 0.15.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 +1 -1
- package/CHANGELOG.md +55 -0
- package/build/components/BottomSheet/index.d.ts +5 -5
- package/build/components/BottomSheet/index.js +4 -4
- package/build/components/Checkbox/Checkbox.d.ts +1 -1
- package/build/components/Checkbox/Checkbox.js +2 -4
- package/build/components/DescriptionList/DescriptionListItem.js +8 -1
- package/build/components/HTMLElements/ListItem.d.ts +9 -1
- package/build/components/HTMLElements/ListItem.js +1 -2
- package/build/components/HTMLElements/OrderedList.d.ts +3 -2
- package/build/components/HTMLElements/OrderedList.js +29 -4
- package/build/components/HTMLElements/UnorderedList.d.ts +3 -2
- package/build/components/HTMLElements/UnorderedList.js +29 -4
- package/build/components/Helper/Helper.js +1 -1
- package/build/components/Helper/HelperText.js +1 -0
- package/build/components/Input/Input.js +2 -2
- package/build/components/Modal/Modal.d.ts +1 -1
- package/build/components/Modal/Modal.js +49 -4
- package/build/components/Modal/Modal.props.d.ts +1 -0
- package/build/components/PillGroup/PillGroup.props.d.ts +19 -7
- package/package.json +1 -1
- package/src/components/BottomSheet/index.ts +7 -5
- package/src/components/Checkbox/Checkbox.tsx +7 -2
- package/src/components/DescriptionList/DescriptionListItem.tsx +8 -1
- package/src/components/HTMLElements/ListItem.tsx +11 -3
- package/src/components/HTMLElements/Lists.docs.mdx +64 -16
- package/src/components/HTMLElements/OrderedList.stories.tsx +33 -2
- package/src/components/HTMLElements/OrderedList.tsx +54 -6
- package/src/components/HTMLElements/UnorderedList.stories.tsx +63 -5
- package/src/components/HTMLElements/UnorderedList.tsx +50 -6
- package/src/components/Helper/Helper.tsx +1 -1
- package/src/components/Helper/HelperText.tsx +1 -0
- package/src/components/Input/Input.tsx +2 -0
- package/src/components/Modal/Modal.props.ts +1 -0
- package/src/components/Modal/Modal.tsx +86 -23
- package/src/components/PillGroup/PillGroup.props.ts +25 -11
- package/src/components/PillGroup/PillGroup.stories.tsx +5 -6
- package/src/components/PillGroup/PillGroup.tsx +3 -3
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-lint.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @utilitywarehouse/hearth-react-native@0.
|
|
2
|
+
> @utilitywarehouse/hearth-react-native@0.15.1 lint /home/runner/work/hearth/hearth/packages/react-native
|
|
3
3
|
> TIMING=1 eslint --max-warnings 0
|
|
4
4
|
|
|
5
5
|
Rule | Time (ms) | Relative
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,60 @@
|
|
|
1
1
|
# @utilitywarehouse/hearth-react-native
|
|
2
2
|
|
|
3
|
+
## 0.15.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#768](https://github.com/utilitywarehouse/hearth/pull/768) [`570f240`](https://github.com/utilitywarehouse/hearth/commit/570f240a448eae546b893ed3ad69235213ee5fac) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Makes `Modal` footer sticky by default
|
|
8
|
+
|
|
9
|
+
This change updates the `Modal` component to have a sticky footer by default, enhancing user experience by keeping action buttons accessible. The `stickyFooter` prop has been added to allow developers to disable this behavior if needed.
|
|
10
|
+
|
|
11
|
+
## 0.15.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [#766](https://github.com/utilitywarehouse/hearth/pull/766) [`183155a`](https://github.com/utilitywarehouse/hearth/commit/183155a1aaf7713f0ab8a39ab1e5684ef6190d0c) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE] Custom `ListItem` styles for `UL` and `OL` components
|
|
16
|
+
|
|
17
|
+
Added new props to `UL`, `OL`, and `ListItem` components to support custom list markers, including icons, images, and colors. This brings the functionality closer to CSS-like list styling. We also fixed a layout issue where list item text could overflow the container.
|
|
18
|
+
|
|
19
|
+
**Components affected**:
|
|
20
|
+
|
|
21
|
+
- `UL` (UnorderedList)
|
|
22
|
+
- `OL` (OrderedList)
|
|
23
|
+
- `ListItem`
|
|
24
|
+
|
|
25
|
+
**Developer changes**:
|
|
26
|
+
|
|
27
|
+
You can now customise list bullets/markers using the new `listStyle*` props. These can be set on the list container to apply to all items, or overridden on individual list items.
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { UL, LI } from '@utilitywarehouse/hearth-react-native';
|
|
31
|
+
import { TickIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
32
|
+
|
|
33
|
+
<UL listStyleColour="feedbackPositiveSurfaceDefault" listStyleIcon={TickIcon}>
|
|
34
|
+
<LI>Success item 1</LI>
|
|
35
|
+
<LI listStyleColour="feedbackDangerSurfaceDefault">Error item override</LI>
|
|
36
|
+
</UL>;
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Supported props:
|
|
40
|
+
|
|
41
|
+
- `listStyleImage`: React Element (e.g. `<Image />`)
|
|
42
|
+
- `listStyleIcon`: Icon component
|
|
43
|
+
- `listStyleWidth` / `listStyleHeight`: Dimensions for the marker (default: 20)
|
|
44
|
+
- `listStyleColour`: Color token or value for the marker
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- [#762](https://github.com/utilitywarehouse/hearth/pull/762) [`2d2bbd2`](https://github.com/utilitywarehouse/hearth/commit/2d2bbd2ba109b9acb2e0b220766eb02c0ad5710e) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Fixes Android error when passing boolean or number as a `Checkbox` value
|
|
49
|
+
|
|
50
|
+
- [#764](https://github.com/utilitywarehouse/hearth/pull/764) [`46f115d`](https://github.com/utilitywarehouse/hearth/commit/46f115dd4bd9da824496e8ec19e29276523931a1) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Fixes `HelperText` wrapping issue
|
|
51
|
+
|
|
52
|
+
- [#762](https://github.com/utilitywarehouse/hearth/pull/762) [`2d2bbd2`](https://github.com/utilitywarehouse/hearth/commit/2d2bbd2ba109b9acb2e0b220766eb02c0ad5710e) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Fixes `PillGroup` `onChange` prop types
|
|
53
|
+
|
|
54
|
+
- [#764](https://github.com/utilitywarehouse/hearth/pull/764) [`46f115d`](https://github.com/utilitywarehouse/hearth/commit/46f115dd4bd9da824496e8ec19e29276523931a1) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: `DescriptionListItem` description disappearing when direction is `column`
|
|
55
|
+
|
|
56
|
+
- [#762](https://github.com/utilitywarehouse/hearth/pull/762) [`2d2bbd2`](https://github.com/utilitywarehouse/hearth/commit/2d2bbd2ba109b9acb2e0b220766eb02c0ad5710e) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Input styles are now passed to the correct View
|
|
57
|
+
|
|
3
58
|
## 0.14.1
|
|
4
59
|
|
|
5
60
|
### Patch Changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
export { BottomSheetFlashList, BottomSheetFooter, BottomSheetModalProvider, BottomSheetSectionList, BottomSheetVirtualizedList, useBottomSheet, useBottomSheetModal, type BottomSheetBackdropProps, type BottomSheetBackgroundProps, type BottomSheetHandleProps, type BottomSheetModalProps, } from '@gorhom/bottom-sheet';
|
|
1
2
|
export { default as BottomSheet } from './BottomSheet';
|
|
2
|
-
export { default as BottomSheetView } from './BottomSheetView';
|
|
3
|
-
export { default as BottomSheetScrollView } from './BottomSheetScrollView';
|
|
4
|
-
export { default as BottomSheetModal } from './BottomSheetModal';
|
|
5
|
-
export { default as BottomSheetFlatList } from './BottomSheetFlatList';
|
|
6
|
-
export { BottomSheetModalProvider, BottomSheetSectionList, BottomSheetVirtualizedList, useBottomSheet, useBottomSheetModal, type BottomSheetBackdropProps, type BottomSheetBackgroundProps, type BottomSheetHandleProps, type BottomSheetModalProps, } from '@gorhom/bottom-sheet';
|
|
7
3
|
export type { default as BottomSheetProps } from './BottomSheet.props';
|
|
4
|
+
export { default as BottomSheetFlatList } from './BottomSheetFlatList';
|
|
5
|
+
export { default as BottomSheetModal } from './BottomSheetModal';
|
|
6
|
+
export { default as BottomSheetScrollView } from './BottomSheetScrollView';
|
|
7
|
+
export { default as BottomSheetView } from './BottomSheetView';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
export { BottomSheetFlashList, BottomSheetFooter, BottomSheetModalProvider, BottomSheetSectionList, BottomSheetVirtualizedList, useBottomSheet, useBottomSheetModal, } from '@gorhom/bottom-sheet';
|
|
1
2
|
export { default as BottomSheet } from './BottomSheet';
|
|
2
|
-
export { default as BottomSheetView } from './BottomSheetView';
|
|
3
|
-
export { default as BottomSheetScrollView } from './BottomSheetScrollView';
|
|
4
|
-
export { default as BottomSheetModal } from './BottomSheetModal';
|
|
5
3
|
export { default as BottomSheetFlatList } from './BottomSheetFlatList';
|
|
6
|
-
export {
|
|
4
|
+
export { default as BottomSheetModal } from './BottomSheetModal';
|
|
5
|
+
export { default as BottomSheetScrollView } from './BottomSheetScrollView';
|
|
6
|
+
export { default as BottomSheetView } from './BottomSheetView';
|
|
@@ -10,7 +10,7 @@ declare const CheckboxIcon: import("react").ForwardRefExoticComponent<import("re
|
|
|
10
10
|
}>;
|
|
11
11
|
declare const CheckboxLabel: import("react").ForwardRefExoticComponent<import("react").RefAttributes<import("../Label/Label.props").default> & Omit<import("../Label/Label.props").default, "ref">>;
|
|
12
12
|
declare const Checkbox: {
|
|
13
|
-
({ children, label, disabled, checked, helperIcon, helperText, invalidText, validText, validationStatus: validation, showValidationIcon, type, image, ...props }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
({ children, label, disabled, checked, helperIcon, helperText, invalidText, validText, validationStatus: validation, showValidationIcon, type, image, value, ...props }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
|
|
14
14
|
displayName: string;
|
|
15
15
|
};
|
|
16
16
|
declare const CheckboxTile: {
|
|
@@ -25,15 +25,13 @@ CheckboxGroup.displayName = 'CheckboxGroup';
|
|
|
25
25
|
CheckboxIndicator.displayName = 'CheckboxIndicator';
|
|
26
26
|
CheckboxIcon.displayName = 'CheckboxIcon';
|
|
27
27
|
CheckboxLabel.displayName = 'CheckboxLabel';
|
|
28
|
-
const Checkbox = ({ children, label, disabled, checked, helperIcon, helperText, invalidText, validText, validationStatus: validation, showValidationIcon, type = 'default', image, ...props }) => {
|
|
28
|
+
const Checkbox = ({ children, label, disabled, checked, helperIcon, helperText, invalidText, validText, validationStatus: validation, showValidationIcon, type = 'default', image, value, ...props }) => {
|
|
29
29
|
const { validationStatus: fieldValidationStatus } = useFormFieldContext();
|
|
30
30
|
const { validationStatus: groupValidationStatus, type: groupType } = useCheckboxGroupContext();
|
|
31
31
|
const validationStatus = fieldValidationStatus ?? groupValidationStatus ?? validation ?? 'initial';
|
|
32
32
|
const checkboxType = groupType ?? type;
|
|
33
33
|
const checkboxChildren = children ? (children) : (_jsxs(_Fragment, { children: [_jsx(CheckboxIndicator, { children: _jsx(CheckboxIcon, {}) }), image ? image : null, _jsxs(CheckboxTextContent, { children: [!!label && _jsx(CheckboxLabel, { children: label }), !!helperText && _jsx(Helper, { disabled: disabled, icon: helperIcon, text: helperText }), validationStatus === 'invalid' && !!invalidText && (_jsx(Helper, { showIcon: showValidationIcon, disabled: disabled, validationStatus: "invalid", text: invalidText })), validationStatus === 'valid' && !!validText && (_jsx(Helper, { disabled: disabled, showIcon: showValidationIcon, validationStatus: "valid", text: validText }))] })] }));
|
|
34
|
-
return (
|
|
35
|
-
// @ts-expect-error - type
|
|
36
|
-
_jsx(CheckboxComponent, { ...props, isDisabled: disabled, isChecked: checked, children: checkboxType === 'tile' ? (_jsx(CheckboxTileRoot, { children: checkboxChildren })) : (checkboxChildren) }));
|
|
34
|
+
return (_jsx(CheckboxComponent, { ...props, value: (value ?? '').toString(), isDisabled: disabled, isChecked: checked, children: checkboxType === 'tile' ? (_jsx(CheckboxTileRoot, { children: checkboxChildren })) : (checkboxChildren) }));
|
|
37
35
|
};
|
|
38
36
|
const CheckboxTile = ({ type = 'tile', ...props }) => {
|
|
39
37
|
return _jsx(Checkbox, { ...props, type: type });
|
|
@@ -44,7 +44,14 @@ const styles = StyleSheet.create(theme => ({
|
|
|
44
44
|
color: theme.color.text.secondary,
|
|
45
45
|
},
|
|
46
46
|
descriptionWrapper: {
|
|
47
|
-
|
|
47
|
+
variants: {
|
|
48
|
+
direction: {
|
|
49
|
+
row: {
|
|
50
|
+
flex: 1,
|
|
51
|
+
},
|
|
52
|
+
column: {},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
48
55
|
},
|
|
49
56
|
}));
|
|
50
57
|
export default DescriptionListItem;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { ViewProps } from 'react-native';
|
|
2
|
-
|
|
2
|
+
import { ColorValue } from '../../types';
|
|
3
|
+
export interface ListStyleProps {
|
|
4
|
+
listStyleImage?: React.ReactElement;
|
|
5
|
+
listStyleIcon?: React.ComponentType<any>;
|
|
6
|
+
listStyleWidth?: number;
|
|
7
|
+
listStyleHeight?: number;
|
|
8
|
+
listStyleColour?: ColorValue;
|
|
9
|
+
}
|
|
10
|
+
export interface ListItemProps extends ViewProps, ListStyleProps {
|
|
3
11
|
children: ViewProps['children'];
|
|
4
12
|
}
|
|
5
13
|
declare const ListItem: {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ViewProps, ViewStyle } from 'react-native';
|
|
2
2
|
import { SpaceValue } from '../../types';
|
|
3
|
-
|
|
3
|
+
import { ListStyleProps } from './ListItem';
|
|
4
|
+
export interface OrderedListProps extends ViewProps, ListStyleProps {
|
|
4
5
|
children: ViewProps['children'];
|
|
5
6
|
gap?: SpaceValue;
|
|
6
7
|
bulletStyle?: ViewStyle;
|
|
7
8
|
}
|
|
8
9
|
declare const OrderedList: {
|
|
9
|
-
({ children, gap, style, ...rest }: OrderedListProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
({ children, gap, style, listStyleImage, listStyleIcon, listStyleWidth, listStyleHeight, listStyleColour, ...rest }: OrderedListProps): import("react/jsx-runtime").JSX.Element;
|
|
10
11
|
displayName: string;
|
|
11
12
|
};
|
|
12
13
|
export default OrderedList;
|
|
@@ -1,15 +1,40 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { StyleSheet, View } from 'react-native';
|
|
4
|
-
import { useStyleProps } from '../../hooks';
|
|
4
|
+
import { useStyleProps, useTheme } from '../../hooks';
|
|
5
|
+
import { getFlattenedColorValue } from '../../utils';
|
|
5
6
|
import { BodyText } from '../BodyText';
|
|
6
|
-
const OrderedList = ({ children, gap = '100', style, ...rest }) => {
|
|
7
|
+
const OrderedList = ({ children, gap = '100', style, listStyleImage, listStyleIcon, listStyleWidth, listStyleHeight, listStyleColour, ...rest }) => {
|
|
7
8
|
const { computedStyles } = useStyleProps({ gap });
|
|
9
|
+
const theme = useTheme();
|
|
8
10
|
let itemNumber = 0;
|
|
9
11
|
return (_jsx(View, { style: [computedStyles, style], ...rest, children: React.Children.map(children, child => {
|
|
10
12
|
if (React.isValidElement(child)) {
|
|
11
13
|
itemNumber++;
|
|
12
|
-
|
|
14
|
+
const childProps = child.props;
|
|
15
|
+
const image = childProps.listStyleImage ?? listStyleImage;
|
|
16
|
+
const Icon = childProps.listStyleIcon ?? listStyleIcon;
|
|
17
|
+
const width = childProps.listStyleWidth ?? listStyleWidth ?? 20;
|
|
18
|
+
const height = childProps.listStyleHeight ?? listStyleHeight ?? 20;
|
|
19
|
+
const colourRaw = childProps.listStyleColour ?? listStyleColour;
|
|
20
|
+
const colour = colourRaw ? getFlattenedColorValue(colourRaw, theme.color) : undefined;
|
|
21
|
+
let bullet;
|
|
22
|
+
if (image) {
|
|
23
|
+
const imageEl = image;
|
|
24
|
+
bullet = React.cloneElement(imageEl, {
|
|
25
|
+
style: [{ width, height }, imageEl.props.style],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
else if (Icon) {
|
|
29
|
+
bullet = (_jsx(Icon, { width: width, height: height, color: colour ?? theme.color.text.primary }));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
bullet = (_jsx(BodyText, { style: [styles.number, colour && { color: colour }], children: `${itemNumber}.` }));
|
|
33
|
+
}
|
|
34
|
+
const isCustom = !!(image || Icon);
|
|
35
|
+
return (_jsxs(View, { style: styles.listItemContainer, children: [isCustom ? _jsx(View, { style: { marginRight: 8 }, children: bullet }) : bullet, React.cloneElement(child, {
|
|
36
|
+
style: [childProps.style, { flex: 1 }],
|
|
37
|
+
})] }));
|
|
13
38
|
}
|
|
14
39
|
return child;
|
|
15
40
|
}) }));
|
|
@@ -22,7 +47,7 @@ const styles = StyleSheet.create({
|
|
|
22
47
|
},
|
|
23
48
|
number: {
|
|
24
49
|
marginRight: 8,
|
|
25
|
-
lineHeight: undefined,
|
|
50
|
+
lineHeight: undefined,
|
|
26
51
|
},
|
|
27
52
|
});
|
|
28
53
|
export default OrderedList;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ViewProps, ViewStyle } from 'react-native';
|
|
2
2
|
import { SpaceValue } from '../../types';
|
|
3
|
-
|
|
3
|
+
import { ListStyleProps } from './ListItem';
|
|
4
|
+
export interface UnorderedListProps extends ViewProps, ListStyleProps {
|
|
4
5
|
children: ViewProps['children'];
|
|
5
6
|
gap?: SpaceValue;
|
|
6
7
|
bulletStyle?: ViewStyle;
|
|
7
8
|
}
|
|
8
9
|
declare const UnorderedList: {
|
|
9
|
-
({ children, gap, style, ...rest }: UnorderedListProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
({ children, gap, style, listStyleImage, listStyleIcon, listStyleWidth, listStyleHeight, listStyleColour, ...rest }: UnorderedListProps): import("react/jsx-runtime").JSX.Element;
|
|
10
11
|
displayName: string;
|
|
11
12
|
};
|
|
12
13
|
export default UnorderedList;
|
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { StyleSheet, View } from 'react-native';
|
|
4
|
-
import { useStyleProps } from '../../hooks';
|
|
4
|
+
import { useStyleProps, useTheme } from '../../hooks';
|
|
5
|
+
import { getFlattenedColorValue } from '../../utils';
|
|
5
6
|
import { BodyText } from '../BodyText';
|
|
6
|
-
const UnorderedList = ({ children, gap = '100', style, ...rest }) => {
|
|
7
|
+
const UnorderedList = ({ children, gap = '100', style, listStyleImage, listStyleIcon, listStyleWidth, listStyleHeight, listStyleColour, ...rest }) => {
|
|
7
8
|
const { computedStyles } = useStyleProps({ gap });
|
|
9
|
+
const theme = useTheme();
|
|
8
10
|
return (_jsx(View, { style: [computedStyles, style], ...rest, children: React.Children.map(children, child => {
|
|
9
11
|
if (React.isValidElement(child)) {
|
|
10
|
-
|
|
12
|
+
const childProps = child.props;
|
|
13
|
+
const image = childProps.listStyleImage ?? listStyleImage;
|
|
14
|
+
const Icon = childProps.listStyleIcon ?? listStyleIcon;
|
|
15
|
+
const width = childProps.listStyleWidth ?? listStyleWidth ?? 20;
|
|
16
|
+
const height = childProps.listStyleHeight ?? listStyleHeight ?? 20;
|
|
17
|
+
const colourRaw = childProps.listStyleColour ?? listStyleColour;
|
|
18
|
+
const colour = colourRaw ? getFlattenedColorValue(colourRaw, theme.color) : undefined;
|
|
19
|
+
let bullet;
|
|
20
|
+
if (image) {
|
|
21
|
+
const imageEl = image;
|
|
22
|
+
bullet = React.cloneElement(imageEl, {
|
|
23
|
+
style: [{ width, height }, imageEl.props.style],
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else if (Icon) {
|
|
27
|
+
bullet = (_jsx(Icon, { width: width, height: height, color: colour ?? theme.color.text.primary }));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
bullet = _jsx(BodyText, { style: [styles.bullet, colour && { color: colour }], children: "\u2022" });
|
|
31
|
+
}
|
|
32
|
+
const isCustom = !!(image || Icon);
|
|
33
|
+
return (_jsxs(View, { style: styles.listItemContainer, children: [isCustom ? _jsx(View, { style: { marginRight: 8 }, children: bullet }) : bullet, React.cloneElement(child, {
|
|
34
|
+
style: [childProps.style, { flex: 1 }],
|
|
35
|
+
})] }));
|
|
11
36
|
}
|
|
12
37
|
return child;
|
|
13
38
|
}) }));
|
|
@@ -20,7 +45,7 @@ const styles = StyleSheet.create({
|
|
|
20
45
|
},
|
|
21
46
|
bullet: {
|
|
22
47
|
marginRight: 8,
|
|
23
|
-
lineHeight: undefined,
|
|
48
|
+
lineHeight: undefined,
|
|
24
49
|
},
|
|
25
50
|
});
|
|
26
51
|
export default UnorderedList;
|
|
@@ -19,7 +19,7 @@ export const InputComponent = createInput({
|
|
|
19
19
|
export const InputSlot = InputComponent.Slot;
|
|
20
20
|
export const InputField = InputComponent.Input;
|
|
21
21
|
export const InputIcon = InputComponent.Icon;
|
|
22
|
-
const Input = forwardRef(({ validationStatus = 'initial', children, disabled, focused, readonly, leadingIcon, trailingIcon, type, showPasswordToggle = true, onClear, format, loading, clearable = false, required, inBottomSheet = false, ...props }, ref) => {
|
|
22
|
+
const Input = forwardRef(({ validationStatus = 'initial', children, disabled, focused, readonly, leadingIcon, trailingIcon, type, showPasswordToggle = true, onClear, format, loading, clearable = false, required, inBottomSheet = false, style, ...props }, ref) => {
|
|
23
23
|
const formFieldContext = useFormFieldContext();
|
|
24
24
|
const { disabled: formFieldDisabled } = formFieldContext;
|
|
25
25
|
const validationStatusFromContext = formFieldContext?.validationStatus ?? validationStatus;
|
|
@@ -46,7 +46,7 @@ const Input = forwardRef(({ validationStatus = 'initial', children, disabled, fo
|
|
|
46
46
|
}
|
|
47
47
|
return undefined;
|
|
48
48
|
})();
|
|
49
|
-
return (_jsx(InputComponent, { ...(children ? props : {}), validationStatus: validationStatusFromContext, isInvalid: validationStatusFromContext === 'invalid', isReadOnly: readonly, isDisabled: formFieldDisabled ?? disabled, isFocused: focused, type: type, isRequired: isRequired, children: children ? (_jsx(_Fragment, { children: children })) : (_jsxs(_Fragment, { children: [!!leadingIconComponent && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: leadingIconComponent }) })), _jsx(InputField
|
|
49
|
+
return (_jsx(InputComponent, { ...(children ? props : {}), validationStatus: validationStatusFromContext, isInvalid: validationStatusFromContext === 'invalid', isReadOnly: readonly, isDisabled: formFieldDisabled ?? disabled, isFocused: focused, type: type, isRequired: isRequired, style: style, children: children ? (_jsx(_Fragment, { children: children })) : (_jsxs(_Fragment, { children: [!!leadingIconComponent && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: leadingIconComponent }) })), _jsx(InputField
|
|
50
50
|
// @ts-expect-error - ref forwarding issue
|
|
51
51
|
, {
|
|
52
52
|
// @ts-expect-error - ref forwarding issue
|
|
@@ -3,5 +3,5 @@ import ModalProps from './Modal.props';
|
|
|
3
3
|
type Modal<T = any> = BottomSheetModalMethods<T> & {
|
|
4
4
|
triggerCloseAnimation?: () => void;
|
|
5
5
|
};
|
|
6
|
-
declare const Modal: ({ ref, children, heading, description, showCloseButton, primaryButtonText, secondaryButtonText, onPressPrimaryButton, onPressCloseButton, onPressSecondaryButton, closeOnPrimaryButtonPress, closeOnSecondaryButtonPress, loading, fullscreen, image, primaryButtonProps, secondaryButtonProps, closeButtonProps, inNavModal, ...props }: ModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
declare const Modal: ({ ref, children, heading, description, showCloseButton, primaryButtonText, secondaryButtonText, onPressPrimaryButton, onPressCloseButton, onPressSecondaryButton, closeOnPrimaryButtonPress, closeOnSecondaryButtonPress, loading, fullscreen, image, primaryButtonProps, secondaryButtonProps, closeButtonProps, inNavModal, stickyFooter, ...props }: ModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
7
|
export default Modal;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { BottomSheetFooter, } from '@gorhom/bottom-sheet';
|
|
2
3
|
import { CloseMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
3
4
|
import { useCallback, useEffect, useImperativeHandle, useRef } from 'react';
|
|
4
5
|
import { AccessibilityInfo, Platform, View, findNodeHandle } from 'react-native';
|
|
@@ -12,7 +13,7 @@ import { Button } from '../Button';
|
|
|
12
13
|
import { Heading } from '../Heading';
|
|
13
14
|
import { Spinner } from '../Spinner';
|
|
14
15
|
import { UnstyledIconButton } from '../UnstyledIconButton';
|
|
15
|
-
const Modal = ({ ref, children, heading, description, showCloseButton = true, primaryButtonText, secondaryButtonText, onPressPrimaryButton, onPressCloseButton, onPressSecondaryButton, closeOnPrimaryButtonPress = true, closeOnSecondaryButtonPress = true, loading, fullscreen = false, image, primaryButtonProps, secondaryButtonProps, closeButtonProps, inNavModal = false, ...props }) => {
|
|
16
|
+
const Modal = ({ ref, children, heading, description, showCloseButton = true, primaryButtonText, secondaryButtonText, onPressPrimaryButton, onPressCloseButton, onPressSecondaryButton, closeOnPrimaryButtonPress = true, closeOnSecondaryButtonPress = true, loading, fullscreen = false, image, primaryButtonProps, secondaryButtonProps, closeButtonProps, inNavModal = false, stickyFooter = true, ...props }) => {
|
|
16
17
|
const bottomSheetModalRef = useRef(null);
|
|
17
18
|
const viewRef = useRef(null);
|
|
18
19
|
const scrollViewRef = useRef(null);
|
|
@@ -97,9 +98,24 @@ const Modal = ({ ref, children, heading, description, showCloseButton = true, pr
|
|
|
97
98
|
bottomSheetModalRef.current?.dismiss();
|
|
98
99
|
}
|
|
99
100
|
};
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
const noButtons = !onPressPrimaryButton && !onPressSecondaryButton;
|
|
102
|
+
styles.useVariants({
|
|
103
|
+
loading,
|
|
104
|
+
bothButtons: !!(onPressPrimaryButton && onPressSecondaryButton),
|
|
105
|
+
noButtons,
|
|
106
|
+
stickyFooter,
|
|
107
|
+
});
|
|
108
|
+
const footer = (_jsxs(View, { style: styles.footer, children: [onPressPrimaryButton && primaryButtonText ? (_jsx(Button, { onPress: handlePrimaryButtonPress, text: primaryButtonText, ...primaryButtonProps, variant: primaryButtonProps?.variant ?? 'solid', colorScheme: primaryButtonProps?.colorScheme ?? 'highlight' })) : null, onPressSecondaryButton && secondaryButtonText ? (_jsx(Button, { onPress: handleSecondaryButtonPress, text: secondaryButtonText, ...secondaryButtonProps, variant: secondaryButtonProps?.variant ?? 'outline', colorScheme: secondaryButtonProps?.colorScheme ?? 'functional' })) : null] }));
|
|
109
|
+
const content = (_jsx(_Fragment, { children: loading ? (_jsxs(View, { style: styles.loadingContainer, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Loading' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsx(Spinner, { size: "lg" }), _jsx(Heading, { size: "lg", textAlign: "center", children: "Loading..." })] })) : (_jsxs(View, { style: styles.container, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Modal content' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsxs(View, { style: styles.header, children: [_jsxs(View, { style: styles.headerTextContent, children: [heading && !image ? (_jsx(Heading, { size: "lg", accessible: true, children: heading })) : null, description && !image ? _jsx(BodyText, { accessible: true, children: description }) : null] }), showCloseButton ? (_jsx(UnstyledIconButton, { icon: CloseMediumIcon, onPress: handleCloseButtonPress, accessibilityLabel: "Close modal", ...closeButtonProps })) : null] }), image ? (_jsxs(View, { style: styles.imageContainer, children: [image, _jsxs(View, { style: styles.textContent, children: [heading ? (_jsx(Heading, { size: "lg", textAlign: "center", accessible: true, children: heading })) : null, description ? (_jsx(BodyText, { textAlign: "center", accessible: true, children: description })) : null] })] })) : null, children, !stickyFooter && !noButtons ? footer : null] })) }));
|
|
110
|
+
const renderFooter = useCallback((props) => (_jsx(BottomSheetFooter, { ...props, children: _jsx(View, { style: styles.footerWrap, children: footer }) })), [
|
|
111
|
+
onPressPrimaryButton,
|
|
112
|
+
primaryButtonText,
|
|
113
|
+
onPressSecondaryButton,
|
|
114
|
+
secondaryButtonText,
|
|
115
|
+
primaryButtonProps,
|
|
116
|
+
secondaryButtonProps,
|
|
117
|
+
]);
|
|
118
|
+
return inNavModal ? (_jsxs(View, { style: { flex: 1, backgroundColor: theme.color.background.primary }, children: [Platform.OS === 'android' ? (_jsx(Animated.View, { style: [styles.androidContainer, animatedBackgroundStyle], children: _jsx(Animated.View, { style: [styles.pretendContent, animatedPretendContentStyle] }) })) : null, _jsx(Animated.View, { style: [styles.inNavModalContainer, Platform.OS === 'android' && animatedInNavModalStyle], children: _jsx(View, { style: styles.inNavModalContent, children: content }) })] })) : (_jsxs(BottomSheetModal, { ref: bottomSheetModalRef, enableDynamicSizing: true, snapPoints: image || fullscreen ? ['90%'] : props.snapPoints, showHandle: typeof loading !== 'undefined' && loading ? false : props.showHandle, accessible: false, style: styles.modal, footerComponent: stickyFooter && !noButtons ? renderFooter : undefined, ...props, onChange: handleChange, children: [loading ? _jsx(View, { style: styles.loadingTop }) : null, _jsx(BottomSheetScrollView, { contentContainerStyle: styles.scrollView, ref: scrollViewRef, children: content })] }));
|
|
103
119
|
};
|
|
104
120
|
const styles = StyleSheet.create((theme, rt) => ({
|
|
105
121
|
modal: {
|
|
@@ -116,6 +132,30 @@ const styles = StyleSheet.create((theme, rt) => ({
|
|
|
116
132
|
},
|
|
117
133
|
},
|
|
118
134
|
},
|
|
135
|
+
scrollView: {
|
|
136
|
+
flex: 1,
|
|
137
|
+
variants: {
|
|
138
|
+
bothButtons: {
|
|
139
|
+
true: {
|
|
140
|
+
paddingBottom: 166 + rt.insets.bottom - theme.components.modal.padding,
|
|
141
|
+
},
|
|
142
|
+
false: {
|
|
143
|
+
paddingBottom: 102 + rt.insets.bottom - theme.components.modal.padding,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
noButtons: {
|
|
147
|
+
true: {
|
|
148
|
+
paddingBottom: rt.insets.bottom + theme.components.modal.padding,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
stickyFooter: {
|
|
152
|
+
true: {},
|
|
153
|
+
false: {
|
|
154
|
+
paddingBottom: rt.insets.bottom + theme.components.modal.padding,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
119
159
|
header: {
|
|
120
160
|
flexDirection: 'row',
|
|
121
161
|
gap: theme.components.modal.gap,
|
|
@@ -149,6 +189,11 @@ const styles = StyleSheet.create((theme, rt) => ({
|
|
|
149
189
|
footer: {
|
|
150
190
|
gap: theme.components.modal.action.gap,
|
|
151
191
|
},
|
|
192
|
+
footerWrap: {
|
|
193
|
+
backgroundColor: theme.color.surface.neutral.strong,
|
|
194
|
+
paddingHorizontal: theme.components.bottomSheet.padding,
|
|
195
|
+
paddingBottom: theme.components.bottomSheet.padding + rt.insets.bottom,
|
|
196
|
+
},
|
|
152
197
|
inNavModalContainer: {
|
|
153
198
|
flex: 1,
|
|
154
199
|
...(Platform.OS === 'ios' ? { backgroundColor: theme.components.overlay.backgroundColor } : {}),
|
|
@@ -11,6 +11,7 @@ interface ModalProps extends Omit<BottomSheetProps, 'children'> {
|
|
|
11
11
|
description?: string;
|
|
12
12
|
inNavModal?: boolean;
|
|
13
13
|
fullscreen?: boolean;
|
|
14
|
+
stickyFooter?: boolean;
|
|
14
15
|
children?: ViewProps['children'];
|
|
15
16
|
onPressPrimaryButton?: () => void;
|
|
16
17
|
primaryButtonText?: string;
|
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ScrollViewProps, ViewStyle } from 'react-native';
|
|
3
|
-
export interface
|
|
4
|
-
/** Controlled selected value(s) */
|
|
5
|
-
value: string | string[];
|
|
6
|
-
/** Multi-select mode. Default = false */
|
|
7
|
-
multiple?: boolean;
|
|
3
|
+
export interface PillGroupBaseProps extends Omit<ScrollViewProps, 'horizontal' | 'contentContainerStyle' | 'showsHorizontalScrollIndicator'> {
|
|
8
4
|
/** Allow pills to wrap lines. Default = true */
|
|
9
5
|
wrap?: boolean;
|
|
10
|
-
/** Handle selection changes */
|
|
11
|
-
onChange?: (value: string | string[]) => void;
|
|
12
6
|
/** Children must be <Pill> elements */
|
|
13
7
|
children: React.ReactNode;
|
|
14
8
|
style?: ViewStyle | ViewStyle[];
|
|
15
9
|
}
|
|
10
|
+
interface SinglePillGroupProps extends PillGroupBaseProps {
|
|
11
|
+
/** Multi-select mode. Default = false */
|
|
12
|
+
multiple?: false;
|
|
13
|
+
/** Controlled selected value */
|
|
14
|
+
value: string;
|
|
15
|
+
/** Handle selection changes */
|
|
16
|
+
onChange?: (value: string) => void;
|
|
17
|
+
}
|
|
18
|
+
interface MultiPillGroupProps extends PillGroupBaseProps {
|
|
19
|
+
/** Multi-select mode. Default = false */
|
|
20
|
+
multiple: true;
|
|
21
|
+
/** Controlled selected value(s) */
|
|
22
|
+
value: string[];
|
|
23
|
+
/** Handle selection changes */
|
|
24
|
+
onChange?: (value: string[]) => void;
|
|
25
|
+
}
|
|
26
|
+
export type PillGroupProps = SinglePillGroupProps | MultiPillGroupProps;
|
|
27
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
export { default as BottomSheet } from './BottomSheet';
|
|
2
|
-
export { default as BottomSheetView } from './BottomSheetView';
|
|
3
|
-
export { default as BottomSheetScrollView } from './BottomSheetScrollView';
|
|
4
|
-
export { default as BottomSheetModal } from './BottomSheetModal';
|
|
5
|
-
export { default as BottomSheetFlatList } from './BottomSheetFlatList';
|
|
6
1
|
export {
|
|
2
|
+
BottomSheetFlashList,
|
|
3
|
+
BottomSheetFooter,
|
|
7
4
|
BottomSheetModalProvider,
|
|
8
5
|
BottomSheetSectionList,
|
|
9
6
|
BottomSheetVirtualizedList,
|
|
@@ -14,4 +11,9 @@ export {
|
|
|
14
11
|
type BottomSheetHandleProps,
|
|
15
12
|
type BottomSheetModalProps,
|
|
16
13
|
} from '@gorhom/bottom-sheet';
|
|
14
|
+
export { default as BottomSheet } from './BottomSheet';
|
|
17
15
|
export type { default as BottomSheetProps } from './BottomSheet.props';
|
|
16
|
+
export { default as BottomSheetFlatList } from './BottomSheetFlatList';
|
|
17
|
+
export { default as BottomSheetModal } from './BottomSheetModal';
|
|
18
|
+
export { default as BottomSheetScrollView } from './BottomSheetScrollView';
|
|
19
|
+
export { default as BottomSheetView } from './BottomSheetView';
|
|
@@ -42,6 +42,7 @@ const Checkbox = ({
|
|
|
42
42
|
showValidationIcon,
|
|
43
43
|
type = 'default',
|
|
44
44
|
image,
|
|
45
|
+
value,
|
|
45
46
|
...props
|
|
46
47
|
}: CheckboxProps) => {
|
|
47
48
|
const { validationStatus: fieldValidationStatus } = useFormFieldContext();
|
|
@@ -80,8 +81,12 @@ const Checkbox = ({
|
|
|
80
81
|
</>
|
|
81
82
|
);
|
|
82
83
|
return (
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
<CheckboxComponent
|
|
85
|
+
{...props}
|
|
86
|
+
value={(value ?? '').toString()}
|
|
87
|
+
isDisabled={disabled}
|
|
88
|
+
isChecked={checked}
|
|
89
|
+
>
|
|
85
90
|
{checkboxType === 'tile' ? (
|
|
86
91
|
<CheckboxTileRoot>{checkboxChildren}</CheckboxTileRoot>
|
|
87
92
|
) : (
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { StyleSheet, View, ViewProps } from 'react-native';
|
|
2
|
+
import { ColorValue } from '../../types';
|
|
2
3
|
import { BodyText } from '../BodyText';
|
|
3
4
|
|
|
4
|
-
export interface
|
|
5
|
+
export interface ListStyleProps {
|
|
6
|
+
listStyleImage?: React.ReactElement;
|
|
7
|
+
listStyleIcon?: React.ComponentType<any>;
|
|
8
|
+
listStyleWidth?: number;
|
|
9
|
+
listStyleHeight?: number;
|
|
10
|
+
listStyleColour?: ColorValue;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ListItemProps extends ViewProps, ListStyleProps {
|
|
5
14
|
children: ViewProps['children'];
|
|
6
15
|
}
|
|
7
16
|
|
|
@@ -17,8 +26,7 @@ ListItem.displayName = 'ListItem';
|
|
|
17
26
|
|
|
18
27
|
const styles = StyleSheet.create({
|
|
19
28
|
item: {
|
|
20
|
-
|
|
21
|
-
alignItems: 'flex-start',
|
|
29
|
+
flexShrink: 1,
|
|
22
30
|
},
|
|
23
31
|
});
|
|
24
32
|
|