@hero-design/rn 8.135.1 → 8.136.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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @hero-design/rn
2
2
 
3
+ ## 8.136.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#5482](https://github.com/Thinkei/hero-design/pull/5482) [`d72cd39`](https://github.com/Thinkei/hero-design/commit/d72cd3990c6e614cdc1358b5811b4461b317ae29) Thanks [@ttkien](https://github.com/ttkien)! - [Progress.SegmentedBar] Fix muted intent applied to wrong legend text
8
+
9
+ ## 8.136.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#5431](https://github.com/Thinkei/hero-design/pull/5431) [`a921554`](https://github.com/Thinkei/hero-design/commit/a921554bad1514779864fde5740d2b17c059f15e) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - [List] Add List.Group component
14
+
15
+ ### Patch Changes
16
+
17
+ - [#5431](https://github.com/Thinkei/hero-design/pull/5431) [`a921554`](https://github.com/Thinkei/hero-design/commit/a921554bad1514779864fde5740d2b17c059f15e) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - [List] Square off row corners at the top and bottom of List.Group so it reads as one continuous shape
18
+
3
19
  ## 8.135.1
4
20
 
5
21
  ### Patch Changes
package/es/index.js CHANGED
@@ -6468,6 +6468,7 @@ var getListTheme = function getListTheme(theme) {
6468
6468
  var colors = {
6469
6469
  checkedListItemContainerBackground: theme.colors.decorativeSecondarySurface,
6470
6470
  listItemContainerBackground: theme.colors.defaultGlobalSurface,
6471
+ listGroupContainerBackground: theme.colors.defaultGlobalSurface,
6471
6472
  leadingStatus: {
6472
6473
  danger: theme.colors.error,
6473
6474
  info: theme.colors.info,
@@ -6481,12 +6482,19 @@ var getListTheme = function getListTheme(theme) {
6481
6482
  leadingStatusMarginRight: theme.space.small,
6482
6483
  prefixContainerMarginRight: theme.space.small,
6483
6484
  suffixContainerMarginLeft: theme.space.small,
6484
- childrenContainerTopMargin: theme.space.small
6485
+ childrenContainerTopMargin: theme.space.small,
6486
+ listGroupMarginHorizontal: {
6487
+ none: 0,
6488
+ small: theme.space.small,
6489
+ medium: theme.space.medium,
6490
+ large: theme.space.large
6491
+ }
6485
6492
  };
6486
6493
  var radii = {
6487
6494
  item: theme.radii.medium,
6488
6495
  basicItem: theme.radii.base,
6489
- leadingStatus: theme.radii.rounded
6496
+ leadingStatus: theme.radii.rounded,
6497
+ group: theme.radii.xlarge
6490
6498
  };
6491
6499
  var shadows = {
6492
6500
  card: theme.shadows["default"]
@@ -15906,9 +15914,72 @@ var BasicListItem = function BasicListItem(_ref) {
15906
15914
  }) : suffix)));
15907
15915
  };
15908
15916
 
15917
+ var StyledListGroupContainer = index$c(View)(function (_ref) {
15918
+ var theme = _ref.theme,
15919
+ themeMarginHorizontal = _ref.themeMarginHorizontal;
15920
+ return {
15921
+ backgroundColor: theme.__hd__.list.colors.listGroupContainerBackground,
15922
+ borderRadius: theme.__hd__.list.radii.group,
15923
+ overflow: 'hidden',
15924
+ marginHorizontal: theme.__hd__.list.space.listGroupMarginHorizontal[themeMarginHorizontal !== null && themeMarginHorizontal !== void 0 ? themeMarginHorizontal : 'medium']
15925
+ };
15926
+ });
15927
+
15928
+ var ERROR_CARD_VARIANT_UNSUPPORTED = 'List.Item with variant="card" is not supported inside List.Group. Use the default full-width variant instead.';
15929
+ // Typed `<T,>` rather than `ReactNode` so flatMap's inferred element type
15930
+ // stays narrow instead of widening to plain ReactNode, which broke type-check.
15931
+ var overrideRowRadius = function overrideRowRadius(row, overrideStyle) {
15932
+ if (! /*#__PURE__*/React__default.isValidElement(row)) {
15933
+ return row;
15934
+ }
15935
+ return /*#__PURE__*/React__default.cloneElement(row, {
15936
+ style: [row.props.style, overrideStyle]
15937
+ });
15938
+ };
15939
+ var ListGroup = function ListGroup(_ref) {
15940
+ var children = _ref.children,
15941
+ style = _ref.style,
15942
+ marginHorizontal = _ref.marginHorizontal,
15943
+ testID = _ref.testID;
15944
+ var rows = React__default.Children.toArray(children);
15945
+ var lastIndex = rows.length - 1;
15946
+ var content = rows.flatMap(function (row, index) {
15947
+ if (/*#__PURE__*/React__default.isValidElement(row) && row.type === ListItem && row.props.variant === 'card') {
15948
+ throw new Error(ERROR_CARD_VARIANT_UNSUPPORTED);
15949
+ }
15950
+ var processedRow = row;
15951
+ if (rows.length > 1 && index === 0) {
15952
+ processedRow = overrideRowRadius(processedRow, {
15953
+ borderBottomLeftRadius: 0,
15954
+ borderBottomRightRadius: 0
15955
+ });
15956
+ }
15957
+ if (rows.length > 1 && index === lastIndex) {
15958
+ processedRow = overrideRowRadius(processedRow, {
15959
+ borderTopLeftRadius: 0,
15960
+ borderTopRightRadius: 0
15961
+ });
15962
+ }
15963
+ if (index === 0) {
15964
+ return [processedRow];
15965
+ }
15966
+ var dividerKey = /*#__PURE__*/React__default.isValidElement(row) ? row.key : index;
15967
+ return [/*#__PURE__*/React__default.createElement(Divider, {
15968
+ key: "list-group-divider-".concat(dividerKey),
15969
+ testID: "list-group-divider"
15970
+ }), processedRow];
15971
+ });
15972
+ return /*#__PURE__*/React__default.createElement(StyledListGroupContainer, {
15973
+ style: style,
15974
+ themeMarginHorizontal: marginHorizontal,
15975
+ testID: testID
15976
+ }, content);
15977
+ };
15978
+
15909
15979
  var List$1 = {
15910
15980
  Item: ListItem,
15911
- BasicItem: BasicListItem
15981
+ BasicItem: BasicListItem,
15982
+ Group: ListGroup
15912
15983
  };
15913
15984
 
15914
15985
  var StyledHeaderContainer = index$c(View)({
@@ -26655,14 +26726,14 @@ var ProgressSegmentedBarLegendItem = function ProgressSegmentedBarLegendItem(_re
26655
26726
  color = _ref.color,
26656
26727
  displayValue = _ref.displayValue,
26657
26728
  testID = _ref.testID;
26658
- var renderedDisplayValue = getTextComponent(displayValue, /*#__PURE__*/React__default.createElement(Typography.Caption, {
26659
- intent: "muted"
26660
- }, displayValue));
26729
+ var renderedDisplayValue = getTextComponent(displayValue, /*#__PURE__*/React__default.createElement(Typography.Caption, null, displayValue));
26661
26730
  return /*#__PURE__*/React__default.createElement(LegendItem, {
26662
26731
  testID: testID
26663
26732
  }, /*#__PURE__*/React__default.createElement(LegendCircle, {
26664
26733
  themeColor: color
26665
- }), /*#__PURE__*/React__default.createElement(Typography.Caption, null, "".concat(title, ":")), renderedDisplayValue ? /*#__PURE__*/React__default.createElement(LegendValue, null, renderedDisplayValue) : null);
26734
+ }), /*#__PURE__*/React__default.createElement(Typography.Caption, {
26735
+ intent: "muted"
26736
+ }, "".concat(title, ":")), renderedDisplayValue ? /*#__PURE__*/React__default.createElement(LegendValue, null, renderedDisplayValue) : null);
26666
26737
  };
26667
26738
 
26668
26739
  var StyledHeader = index$c(Box)(function (_ref) {
package/eslint.config.js CHANGED
@@ -1,24 +1,16 @@
1
1
  const heroDesign = require('@hero-design/eslint-plugin');
2
- const _import = require('eslint-plugin-import');
3
- const { FlatCompat } = require('@eslint/eslintrc');
4
2
  const { includeIgnoreFile } = require('@eslint/compat');
5
3
  const path = require('path');
6
-
7
- const compat = new FlatCompat({
8
- baseDirectory: __dirname,
9
- });
4
+ const hdConfig = require('eslint-config-hd');
10
5
 
11
6
  const gitignorePath = path.resolve(__dirname, '../../.gitignore');
12
7
 
13
8
  module.exports = [
14
- ...compat.extends('hd', 'plugin:@hero-design/recommendedRn'),
9
+ ...hdConfig,
10
+ ...heroDesign.configs.recommendedRn,
15
11
  includeIgnoreFile(gitignorePath),
16
12
  {
17
13
  files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'],
18
- plugins: {
19
- '@hero-design': heroDesign,
20
- import: _import,
21
- },
22
14
  languageOptions: {
23
15
  parserOptions: {
24
16
  tsconfigRootDir: __dirname,
package/lib/index.js CHANGED
@@ -6497,6 +6497,7 @@ var getListTheme = function getListTheme(theme) {
6497
6497
  var colors = {
6498
6498
  checkedListItemContainerBackground: theme.colors.decorativeSecondarySurface,
6499
6499
  listItemContainerBackground: theme.colors.defaultGlobalSurface,
6500
+ listGroupContainerBackground: theme.colors.defaultGlobalSurface,
6500
6501
  leadingStatus: {
6501
6502
  danger: theme.colors.error,
6502
6503
  info: theme.colors.info,
@@ -6510,12 +6511,19 @@ var getListTheme = function getListTheme(theme) {
6510
6511
  leadingStatusMarginRight: theme.space.small,
6511
6512
  prefixContainerMarginRight: theme.space.small,
6512
6513
  suffixContainerMarginLeft: theme.space.small,
6513
- childrenContainerTopMargin: theme.space.small
6514
+ childrenContainerTopMargin: theme.space.small,
6515
+ listGroupMarginHorizontal: {
6516
+ none: 0,
6517
+ small: theme.space.small,
6518
+ medium: theme.space.medium,
6519
+ large: theme.space.large
6520
+ }
6514
6521
  };
6515
6522
  var radii = {
6516
6523
  item: theme.radii.medium,
6517
6524
  basicItem: theme.radii.base,
6518
- leadingStatus: theme.radii.rounded
6525
+ leadingStatus: theme.radii.rounded,
6526
+ group: theme.radii.xlarge
6519
6527
  };
6520
6528
  var shadows = {
6521
6529
  card: theme.shadows["default"]
@@ -15935,9 +15943,72 @@ var BasicListItem = function BasicListItem(_ref) {
15935
15943
  }) : suffix)));
15936
15944
  };
15937
15945
 
15946
+ var StyledListGroupContainer = index$c(reactNative.View)(function (_ref) {
15947
+ var theme = _ref.theme,
15948
+ themeMarginHorizontal = _ref.themeMarginHorizontal;
15949
+ return {
15950
+ backgroundColor: theme.__hd__.list.colors.listGroupContainerBackground,
15951
+ borderRadius: theme.__hd__.list.radii.group,
15952
+ overflow: 'hidden',
15953
+ marginHorizontal: theme.__hd__.list.space.listGroupMarginHorizontal[themeMarginHorizontal !== null && themeMarginHorizontal !== void 0 ? themeMarginHorizontal : 'medium']
15954
+ };
15955
+ });
15956
+
15957
+ var ERROR_CARD_VARIANT_UNSUPPORTED = 'List.Item with variant="card" is not supported inside List.Group. Use the default full-width variant instead.';
15958
+ // Typed `<T,>` rather than `ReactNode` so flatMap's inferred element type
15959
+ // stays narrow instead of widening to plain ReactNode, which broke type-check.
15960
+ var overrideRowRadius = function overrideRowRadius(row, overrideStyle) {
15961
+ if (! /*#__PURE__*/React__namespace.default.isValidElement(row)) {
15962
+ return row;
15963
+ }
15964
+ return /*#__PURE__*/React__namespace.default.cloneElement(row, {
15965
+ style: [row.props.style, overrideStyle]
15966
+ });
15967
+ };
15968
+ var ListGroup = function ListGroup(_ref) {
15969
+ var children = _ref.children,
15970
+ style = _ref.style,
15971
+ marginHorizontal = _ref.marginHorizontal,
15972
+ testID = _ref.testID;
15973
+ var rows = React__namespace.default.Children.toArray(children);
15974
+ var lastIndex = rows.length - 1;
15975
+ var content = rows.flatMap(function (row, index) {
15976
+ if (/*#__PURE__*/React__namespace.default.isValidElement(row) && row.type === ListItem && row.props.variant === 'card') {
15977
+ throw new Error(ERROR_CARD_VARIANT_UNSUPPORTED);
15978
+ }
15979
+ var processedRow = row;
15980
+ if (rows.length > 1 && index === 0) {
15981
+ processedRow = overrideRowRadius(processedRow, {
15982
+ borderBottomLeftRadius: 0,
15983
+ borderBottomRightRadius: 0
15984
+ });
15985
+ }
15986
+ if (rows.length > 1 && index === lastIndex) {
15987
+ processedRow = overrideRowRadius(processedRow, {
15988
+ borderTopLeftRadius: 0,
15989
+ borderTopRightRadius: 0
15990
+ });
15991
+ }
15992
+ if (index === 0) {
15993
+ return [processedRow];
15994
+ }
15995
+ var dividerKey = /*#__PURE__*/React__namespace.default.isValidElement(row) ? row.key : index;
15996
+ return [/*#__PURE__*/React__namespace.default.createElement(Divider, {
15997
+ key: "list-group-divider-".concat(dividerKey),
15998
+ testID: "list-group-divider"
15999
+ }), processedRow];
16000
+ });
16001
+ return /*#__PURE__*/React__namespace.default.createElement(StyledListGroupContainer, {
16002
+ style: style,
16003
+ themeMarginHorizontal: marginHorizontal,
16004
+ testID: testID
16005
+ }, content);
16006
+ };
16007
+
15938
16008
  var List$1 = {
15939
16009
  Item: ListItem,
15940
- BasicItem: BasicListItem
16010
+ BasicItem: BasicListItem,
16011
+ Group: ListGroup
15941
16012
  };
15942
16013
 
15943
16014
  var StyledHeaderContainer = index$c(reactNative.View)({
@@ -26684,14 +26755,14 @@ var ProgressSegmentedBarLegendItem = function ProgressSegmentedBarLegendItem(_re
26684
26755
  color = _ref.color,
26685
26756
  displayValue = _ref.displayValue,
26686
26757
  testID = _ref.testID;
26687
- var renderedDisplayValue = getTextComponent(displayValue, /*#__PURE__*/React__namespace.default.createElement(Typography.Caption, {
26688
- intent: "muted"
26689
- }, displayValue));
26758
+ var renderedDisplayValue = getTextComponent(displayValue, /*#__PURE__*/React__namespace.default.createElement(Typography.Caption, null, displayValue));
26690
26759
  return /*#__PURE__*/React__namespace.default.createElement(LegendItem, {
26691
26760
  testID: testID
26692
26761
  }, /*#__PURE__*/React__namespace.default.createElement(LegendCircle, {
26693
26762
  themeColor: color
26694
- }), /*#__PURE__*/React__namespace.default.createElement(Typography.Caption, null, "".concat(title, ":")), renderedDisplayValue ? /*#__PURE__*/React__namespace.default.createElement(LegendValue, null, renderedDisplayValue) : null);
26763
+ }), /*#__PURE__*/React__namespace.default.createElement(Typography.Caption, {
26764
+ intent: "muted"
26765
+ }, "".concat(title, ":")), renderedDisplayValue ? /*#__PURE__*/React__namespace.default.createElement(LegendValue, null, renderedDisplayValue) : null);
26695
26766
  };
26696
26767
 
26697
26768
  var StyledHeader = index$c(Box)(function (_ref) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hero-design/rn",
3
- "version": "8.135.1",
3
+ "version": "8.136.1",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -62,9 +62,8 @@
62
62
  "@babel/runtime": "^7.29.7",
63
63
  "@emotion/jest": "^11.11.0",
64
64
  "@eslint/compat": "^1.1.1",
65
- "@eslint/eslintrc": "^3.1.0",
66
65
  "@eslint/js": "^9.8.0",
67
- "@hero-design/eslint-plugin": "9.2.4",
66
+ "@hero-design/eslint-plugin": "10.0.0",
68
67
  "@hero-design/react-native-month-year-picker": "^8.46.1",
69
68
  "@ptomasroos/react-native-multi-slider": "^2.2.2",
70
69
  "@react-native-community/datetimepicker": "8.4.4",
@@ -88,7 +87,7 @@
88
87
  "@typescript-eslint/eslint-plugin": "^8.57.0",
89
88
  "babel-plugin-inline-import": "^3.0.0",
90
89
  "core-js": "^3.33.0",
91
- "eslint": "^8.57.0",
90
+ "eslint": "^9.0.0",
92
91
  "eslint-config-hd": "8.42.7",
93
92
  "expo-linear-gradient": "55.0.9",
94
93
  "jest": "^29.7.0",
@@ -0,0 +1,106 @@
1
+ import type { ReactElement, ReactNode } from 'react';
2
+ import React from 'react';
3
+ import type { StyleProp, ViewStyle } from 'react-native';
4
+ import Divider from '../Divider';
5
+ import ListItem from './ListItem';
6
+ import type { ListItemProps } from './ListItem';
7
+ import { StyledListGroupContainer } from './StyledListGroup';
8
+ import type { MarginHorizontal } from './StyledListGroup';
9
+
10
+ export const ERROR_CARD_VARIANT_UNSUPPORTED =
11
+ 'List.Item with variant="card" is not supported inside List.Group. Use the default full-width variant instead.';
12
+
13
+ // Typed `<T,>` rather than `ReactNode` so flatMap's inferred element type
14
+ // stays narrow instead of widening to plain ReactNode, which broke type-check.
15
+ const overrideRowRadius = <T,>(row: T, overrideStyle: ViewStyle): T => {
16
+ if (!React.isValidElement<{ style?: StyleProp<ViewStyle> }>(row)) {
17
+ return row;
18
+ }
19
+
20
+ return React.cloneElement(row, {
21
+ style: [row.props.style, overrideStyle],
22
+ }) as unknown as T;
23
+ };
24
+
25
+ export interface ListGroupProps {
26
+ /**
27
+ * List.Item and/or List.BasicItem rows to render as one bounded, divided group.
28
+ */
29
+ children: ReactNode;
30
+ /**
31
+ * Additional wrapper style.
32
+ */
33
+ style?: StyleProp<ViewStyle>;
34
+ /**
35
+ * Horizontal margin applied so the group never renders flush against a screen edge.
36
+ * Default is 'medium'. Pass 'none' for screens that already apply their own side
37
+ * gutter, to avoid doubled spacing.
38
+ */
39
+ marginHorizontal?: MarginHorizontal;
40
+ /**
41
+ * Testing id of the component.
42
+ */
43
+ testID?: string;
44
+ }
45
+
46
+ const ListGroup = ({
47
+ children,
48
+ style,
49
+ marginHorizontal,
50
+ testID,
51
+ }: ListGroupProps): ReactElement => {
52
+ const rows = React.Children.toArray(children);
53
+ const lastIndex = rows.length - 1;
54
+
55
+ const content: ReactNode[] = rows.flatMap((row, index) => {
56
+ if (
57
+ React.isValidElement<ListItemProps>(row) &&
58
+ row.type === ListItem &&
59
+ row.props.variant === 'card'
60
+ ) {
61
+ throw new Error(ERROR_CARD_VARIANT_UNSUPPORTED);
62
+ }
63
+
64
+ let processedRow = row;
65
+
66
+ if (rows.length > 1 && index === 0) {
67
+ processedRow = overrideRowRadius(processedRow, {
68
+ borderBottomLeftRadius: 0,
69
+ borderBottomRightRadius: 0,
70
+ });
71
+ }
72
+
73
+ if (rows.length > 1 && index === lastIndex) {
74
+ processedRow = overrideRowRadius(processedRow, {
75
+ borderTopLeftRadius: 0,
76
+ borderTopRightRadius: 0,
77
+ });
78
+ }
79
+
80
+ if (index === 0) {
81
+ return [processedRow];
82
+ }
83
+
84
+ const dividerKey = React.isValidElement(row) ? row.key : index;
85
+
86
+ return [
87
+ <Divider
88
+ key={`list-group-divider-${dividerKey}`}
89
+ testID="list-group-divider"
90
+ />,
91
+ processedRow,
92
+ ];
93
+ });
94
+
95
+ return (
96
+ <StyledListGroupContainer
97
+ style={style}
98
+ themeMarginHorizontal={marginHorizontal}
99
+ testID={testID}
100
+ >
101
+ {content}
102
+ </StyledListGroupContainer>
103
+ );
104
+ };
105
+
106
+ export default ListGroup;
@@ -0,0 +1,19 @@
1
+ import { View } from 'react-native';
2
+ import styled from '@emotion/native';
3
+
4
+ type MarginHorizontal = 'none' | 'small' | 'medium' | 'large';
5
+
6
+ const StyledListGroupContainer = styled(View)<{
7
+ themeMarginHorizontal?: MarginHorizontal;
8
+ }>(({ theme, themeMarginHorizontal }) => ({
9
+ backgroundColor: theme.__hd__.list.colors.listGroupContainerBackground,
10
+ borderRadius: theme.__hd__.list.radii.group,
11
+ overflow: 'hidden',
12
+ marginHorizontal:
13
+ theme.__hd__.list.space.listGroupMarginHorizontal[
14
+ themeMarginHorizontal ?? 'medium'
15
+ ],
16
+ }));
17
+
18
+ export { StyledListGroupContainer };
19
+ export type { MarginHorizontal };
@@ -1,5 +1,6 @@
1
1
  import ListItem from './ListItem';
2
2
  import BasicListItem from './BasicListItem';
3
+ import ListGroup from './ListGroup';
3
4
 
4
5
  export type { ListItemProps } from './ListItem';
5
6
  export type { BasicListItemProps } from './BasicListItem';
@@ -7,11 +8,13 @@ export type { BasicListItemProps } from './BasicListItem';
7
8
  interface ListType {
8
9
  Item: typeof ListItem;
9
10
  BasicItem: typeof BasicListItem;
11
+ Group: typeof ListGroup;
10
12
  }
11
13
 
12
14
  const List: ListType = {
13
15
  Item: ListItem,
14
16
  BasicItem: BasicListItem,
17
+ Group: ListGroup,
15
18
  };
16
19
 
17
20
  export default List;
@@ -22,13 +22,13 @@ const ProgressSegmentedBarLegendItem = ({
22
22
  }: ProgressSegmentedBarLegendItemProps): ReactNode => {
23
23
  const renderedDisplayValue = getTextComponent(
24
24
  displayValue,
25
- <Typography.Caption intent="muted">{displayValue}</Typography.Caption>
25
+ <Typography.Caption>{displayValue}</Typography.Caption>
26
26
  );
27
27
 
28
28
  return (
29
29
  <LegendItem testID={testID}>
30
30
  <LegendCircle themeColor={color} />
31
- <Typography.Caption>{`${title}:`}</Typography.Caption>
31
+ <Typography.Caption intent="muted">{`${title}:`}</Typography.Caption>
32
32
  {renderedDisplayValue ? (
33
33
  <LegendValue>{renderedDisplayValue}</LegendValue>
34
34
  ) : null}
@@ -4,6 +4,7 @@ const getListTheme = (theme: GlobalTheme) => {
4
4
  const colors = {
5
5
  checkedListItemContainerBackground: theme.colors.decorativeSecondarySurface,
6
6
  listItemContainerBackground: theme.colors.defaultGlobalSurface,
7
+ listGroupContainerBackground: theme.colors.defaultGlobalSurface,
7
8
  leadingStatus: {
8
9
  danger: theme.colors.error,
9
10
  info: theme.colors.info,
@@ -19,12 +20,19 @@ const getListTheme = (theme: GlobalTheme) => {
19
20
  prefixContainerMarginRight: theme.space.small,
20
21
  suffixContainerMarginLeft: theme.space.small,
21
22
  childrenContainerTopMargin: theme.space.small,
23
+ listGroupMarginHorizontal: {
24
+ none: 0,
25
+ small: theme.space.small,
26
+ medium: theme.space.medium,
27
+ large: theme.space.large,
28
+ },
22
29
  };
23
30
 
24
31
  const radii = {
25
32
  item: theme.radii.medium,
26
33
  basicItem: theme.radii.base,
27
34
  leadingStatus: theme.radii.rounded,
35
+ group: theme.radii.xlarge,
28
36
  };
29
37
 
30
38
  const shadows = {
@@ -0,0 +1,26 @@
1
+ import type { ReactElement, ReactNode } from 'react';
2
+ import type { StyleProp, ViewStyle } from 'react-native';
3
+ import type { MarginHorizontal } from './StyledListGroup';
4
+ export declare const ERROR_CARD_VARIANT_UNSUPPORTED = "List.Item with variant=\"card\" is not supported inside List.Group. Use the default full-width variant instead.";
5
+ export interface ListGroupProps {
6
+ /**
7
+ * List.Item and/or List.BasicItem rows to render as one bounded, divided group.
8
+ */
9
+ children: ReactNode;
10
+ /**
11
+ * Additional wrapper style.
12
+ */
13
+ style?: StyleProp<ViewStyle>;
14
+ /**
15
+ * Horizontal margin applied so the group never renders flush against a screen edge.
16
+ * Default is 'medium'. Pass 'none' for screens that already apply their own side
17
+ * gutter, to avoid doubled spacing.
18
+ */
19
+ marginHorizontal?: MarginHorizontal;
20
+ /**
21
+ * Testing id of the component.
22
+ */
23
+ testID?: string;
24
+ }
25
+ declare const ListGroup: ({ children, style, marginHorizontal, testID, }: ListGroupProps) => ReactElement;
26
+ export default ListGroup;
@@ -0,0 +1,12 @@
1
+ import { View } from 'react-native';
2
+ type MarginHorizontal = 'none' | 'small' | 'medium' | 'large';
3
+ declare const StyledListGroupContainer: import("@emotion/native").StyledComponent<import("react-native").ViewProps & {
4
+ theme?: import("@emotion/react").Theme;
5
+ as?: React.ElementType;
6
+ } & {
7
+ themeMarginHorizontal?: MarginHorizontal;
8
+ }, {}, {
9
+ ref?: import("react").Ref<View> | undefined;
10
+ }>;
11
+ export { StyledListGroupContainer };
12
+ export type { MarginHorizontal };
@@ -1,10 +1,12 @@
1
1
  import ListItem from './ListItem';
2
2
  import BasicListItem from './BasicListItem';
3
+ import ListGroup from './ListGroup';
3
4
  export type { ListItemProps } from './ListItem';
4
5
  export type { BasicListItemProps } from './BasicListItem';
5
6
  interface ListType {
6
7
  Item: typeof ListItem;
7
8
  BasicItem: typeof BasicListItem;
9
+ Group: typeof ListGroup;
8
10
  }
9
11
  declare const List: ListType;
10
12
  export default List;
@@ -3,6 +3,7 @@ declare const getListTheme: (theme: GlobalTheme) => {
3
3
  colors: {
4
4
  checkedListItemContainerBackground: string | undefined;
5
5
  listItemContainerBackground: string;
6
+ listGroupContainerBackground: string;
6
7
  leadingStatus: {
7
8
  danger: string;
8
9
  info: string;
@@ -17,11 +18,18 @@ declare const getListTheme: (theme: GlobalTheme) => {
17
18
  prefixContainerMarginRight: number;
18
19
  suffixContainerMarginLeft: number;
19
20
  childrenContainerTopMargin: number;
21
+ listGroupMarginHorizontal: {
22
+ none: number;
23
+ small: number;
24
+ medium: number;
25
+ large: number;
26
+ };
20
27
  };
21
28
  radii: {
22
29
  item: number;
23
30
  basicItem: number;
24
31
  leadingStatus: number;
32
+ group: number;
25
33
  };
26
34
  widths: {
27
35
  leadingStatus: number;