@hero-design/rn 8.123.0 → 8.124.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @hero-design/rn
2
2
 
3
+ ## 8.124.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#5023](https://github.com/Thinkei/hero-design/pull/5023) [`7d35f92916acd42649e79f2f276dff3cf94a5a03`](https://github.com/Thinkei/hero-design/commit/7d35f92916acd42649e79f2f276dff3cf94a5a03) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - [Tag] Support icon and rightIcon props
8
+
3
9
  ## 8.123.0
4
10
 
5
11
  ### Minor Changes
package/CLAUDE.md ADDED
@@ -0,0 +1,35 @@
1
+ # @hero-design/rn
2
+
3
+ React Native component library for Hero Design. Built with TypeScript and emotion (`@emotion/native`).
4
+
5
+ ## File Organization
6
+
7
+ - Entry: `ComponentName/index.tsx` (exports main component, often compound)
8
+ - Component: `ComponentName/ComponentName.tsx` (main implementation)
9
+ - Styled: `ComponentName/StyledComponentName.tsx`
10
+ - Sub-components: `ComponentName/SubComponentName/index.tsx`
11
+ - Types: `ComponentName/types.ts` (if needed)
12
+ - Tests: `ComponentName/__tests__/ComponentName.spec.tsx`
13
+
14
+ ## Conventions
15
+
16
+ - Import `styled` from `@emotion/native`; use `useTheme()` hook (no prop drilling)
17
+ - Styled props: `themeButtonVariant`, `themeIsPressed`, `themeIsCompact` pattern
18
+ - Use `theme.__hd__.componentName.*` tokens (component-specific) over global tokens
19
+ - JSDoc on each prop; include `testID?: string` for testing
20
+ - Functional components; React Native primitives (`Text`, `View`, not HTML); strict TypeScript
21
+
22
+ ## Testing
23
+
24
+ - Use `renderWithTheme()` from `'../../../testHelpers/renderWithTheme'` for theme context
25
+ - Use `@testing-library/react-native` + `jest` + `@testing-library/jest-native`
26
+ - Handle nested styles with `StyleSheet.flatten()` when needed
27
+
28
+ ## Commands
29
+
30
+ ```bash
31
+ yarn turbo run test --filter=@hero-design/rn -- -- ComponentName [--watch|--updateSnapshot]
32
+ yarn workspace @hero-design/rn lint
33
+ yarn workspace @hero-design/rn type-check
34
+ yarn build:watch:rn
35
+ ```
package/es/index.js CHANGED
@@ -7187,7 +7187,8 @@ var getTagTheme = function getTagTheme(theme) {
7187
7187
  };
7188
7188
  var space = {
7189
7189
  horizontalPadding: theme.space.small,
7190
- verticalPadding: theme.space.xsmall
7190
+ verticalPadding: theme.space.xsmall,
7191
+ iconGap: theme.space.xsmall
7191
7192
  };
7192
7193
  var radii = {
7193
7194
  "default": theme.radii.large
@@ -28546,7 +28547,10 @@ var StyledView = index$c(View)(function (_ref) {
28546
28547
  backgroundColor: theme.__hd__.tag.colors["".concat(themeIntent, "Background")],
28547
28548
  borderRadius: theme.__hd__.tag.radii["default"],
28548
28549
  paddingVertical: theme.__hd__.tag.space.verticalPadding,
28549
- paddingHorizontal: theme.__hd__.tag.space.horizontalPadding
28550
+ paddingHorizontal: theme.__hd__.tag.space.horizontalPadding,
28551
+ flexDirection: 'row',
28552
+ alignItems: 'center',
28553
+ alignSelf: 'flex-start'
28550
28554
  };
28551
28555
  });
28552
28556
  var StyledText$1 = index$c(Typography.Caption)(function (_ref2) {
@@ -28559,14 +28563,26 @@ var StyledText$1 = index$c(Typography.Caption)(function (_ref2) {
28559
28563
  textAlign: 'center'
28560
28564
  };
28561
28565
  });
28566
+ var StyledTagIcon = index$c(Icon)(function (_ref3) {
28567
+ var themeIntent = _ref3.themeIntent,
28568
+ themePosition = _ref3.themePosition,
28569
+ theme = _ref3.theme;
28570
+ return {
28571
+ color: theme.__hd__.tag.colors[themeIntent],
28572
+ marginRight: themePosition === 'left' ? theme.__hd__.tag.space.iconGap : undefined,
28573
+ marginLeft: themePosition === 'right' ? theme.__hd__.tag.space.iconGap : undefined
28574
+ };
28575
+ });
28562
28576
 
28563
- var _excluded$9 = ["content", "variant", "intent", "style", "testID"];
28577
+ var _excluded$9 = ["content", "icon", "variant", "intent", "rightIcon", "style", "testID"];
28564
28578
  var Tag = function Tag(_ref) {
28565
28579
  var content = _ref.content,
28580
+ icon = _ref.icon,
28566
28581
  _ref$variant = _ref.variant,
28567
28582
  variant = _ref$variant === void 0 ? 'outlined' : _ref$variant,
28568
28583
  _ref$intent = _ref.intent,
28569
28584
  intent = _ref$intent === void 0 ? 'primary' : _ref$intent,
28585
+ rightIcon = _ref.rightIcon,
28570
28586
  style = _ref.style,
28571
28587
  testID = _ref.testID,
28572
28588
  nativeProps = _objectWithoutProperties(_ref, _excluded$9);
@@ -28575,10 +28591,22 @@ var Tag = function Tag(_ref) {
28575
28591
  themeIntent: intent,
28576
28592
  style: style,
28577
28593
  testID: testID
28594
+ }), icon !== undefined && /*#__PURE__*/React__default.createElement(StyledTagIcon, {
28595
+ icon: icon,
28596
+ size: "xsmall",
28597
+ themeIntent: intent,
28598
+ themePosition: "left",
28599
+ testID: testID !== undefined ? "".concat(testID, "-left-icon") : undefined
28578
28600
  }), typeof content === 'string' ? /*#__PURE__*/React__default.createElement(StyledText$1, {
28579
28601
  themeIntent: intent,
28580
28602
  fontWeight: "semi-bold"
28581
- }, content) : content);
28603
+ }, content) : content, rightIcon !== undefined && /*#__PURE__*/React__default.createElement(StyledTagIcon, {
28604
+ icon: rightIcon,
28605
+ size: "xsmall",
28606
+ themeIntent: intent,
28607
+ themePosition: "right",
28608
+ testID: testID !== undefined ? "".concat(testID, "-right-icon") : undefined
28609
+ }));
28582
28610
  };
28583
28611
 
28584
28612
  var StyledPickerWrapper = index$c(View)(function (_ref) {
package/lib/index.js CHANGED
@@ -7217,7 +7217,8 @@ var getTagTheme = function getTagTheme(theme) {
7217
7217
  };
7218
7218
  var space = {
7219
7219
  horizontalPadding: theme.space.small,
7220
- verticalPadding: theme.space.xsmall
7220
+ verticalPadding: theme.space.xsmall,
7221
+ iconGap: theme.space.xsmall
7221
7222
  };
7222
7223
  var radii = {
7223
7224
  "default": theme.radii.large
@@ -28576,7 +28577,10 @@ var StyledView = index$c(reactNative.View)(function (_ref) {
28576
28577
  backgroundColor: theme.__hd__.tag.colors["".concat(themeIntent, "Background")],
28577
28578
  borderRadius: theme.__hd__.tag.radii["default"],
28578
28579
  paddingVertical: theme.__hd__.tag.space.verticalPadding,
28579
- paddingHorizontal: theme.__hd__.tag.space.horizontalPadding
28580
+ paddingHorizontal: theme.__hd__.tag.space.horizontalPadding,
28581
+ flexDirection: 'row',
28582
+ alignItems: 'center',
28583
+ alignSelf: 'flex-start'
28580
28584
  };
28581
28585
  });
28582
28586
  var StyledText$1 = index$c(Typography.Caption)(function (_ref2) {
@@ -28589,14 +28593,26 @@ var StyledText$1 = index$c(Typography.Caption)(function (_ref2) {
28589
28593
  textAlign: 'center'
28590
28594
  };
28591
28595
  });
28596
+ var StyledTagIcon = index$c(Icon)(function (_ref3) {
28597
+ var themeIntent = _ref3.themeIntent,
28598
+ themePosition = _ref3.themePosition,
28599
+ theme = _ref3.theme;
28600
+ return {
28601
+ color: theme.__hd__.tag.colors[themeIntent],
28602
+ marginRight: themePosition === 'left' ? theme.__hd__.tag.space.iconGap : undefined,
28603
+ marginLeft: themePosition === 'right' ? theme.__hd__.tag.space.iconGap : undefined
28604
+ };
28605
+ });
28592
28606
 
28593
- var _excluded$9 = ["content", "variant", "intent", "style", "testID"];
28607
+ var _excluded$9 = ["content", "icon", "variant", "intent", "rightIcon", "style", "testID"];
28594
28608
  var Tag = function Tag(_ref) {
28595
28609
  var content = _ref.content,
28610
+ icon = _ref.icon,
28596
28611
  _ref$variant = _ref.variant,
28597
28612
  variant = _ref$variant === void 0 ? 'outlined' : _ref$variant,
28598
28613
  _ref$intent = _ref.intent,
28599
28614
  intent = _ref$intent === void 0 ? 'primary' : _ref$intent,
28615
+ rightIcon = _ref.rightIcon,
28600
28616
  style = _ref.style,
28601
28617
  testID = _ref.testID,
28602
28618
  nativeProps = _objectWithoutProperties(_ref, _excluded$9);
@@ -28605,10 +28621,22 @@ var Tag = function Tag(_ref) {
28605
28621
  themeIntent: intent,
28606
28622
  style: style,
28607
28623
  testID: testID
28624
+ }), icon !== undefined && /*#__PURE__*/React__namespace.default.createElement(StyledTagIcon, {
28625
+ icon: icon,
28626
+ size: "xsmall",
28627
+ themeIntent: intent,
28628
+ themePosition: "left",
28629
+ testID: testID !== undefined ? "".concat(testID, "-left-icon") : undefined
28608
28630
  }), typeof content === 'string' ? /*#__PURE__*/React__namespace.default.createElement(StyledText$1, {
28609
28631
  themeIntent: intent,
28610
28632
  fontWeight: "semi-bold"
28611
- }, content) : content);
28633
+ }, content) : content, rightIcon !== undefined && /*#__PURE__*/React__namespace.default.createElement(StyledTagIcon, {
28634
+ icon: rightIcon,
28635
+ size: "xsmall",
28636
+ themeIntent: intent,
28637
+ themePosition: "right",
28638
+ testID: testID !== undefined ? "".concat(testID, "-right-icon") : undefined
28639
+ }));
28612
28640
  };
28613
28641
 
28614
28642
  var StyledPickerWrapper = index$c(reactNative.View)(function (_ref) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hero-design/rn",
3
- "version": "8.123.0",
3
+ "version": "8.124.0",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -1,6 +1,7 @@
1
1
  import styled from '@emotion/native';
2
2
  import { View } from 'react-native';
3
3
  import Typography from '../Typography';
4
+ import Icon from '../Icon';
4
5
 
5
6
  type ThemeIntent =
6
7
  | 'primary'
@@ -18,6 +19,9 @@ const StyledView = styled(View)<{
18
19
  borderRadius: theme.__hd__.tag.radii.default,
19
20
  paddingVertical: theme.__hd__.tag.space.verticalPadding,
20
21
  paddingHorizontal: theme.__hd__.tag.space.horizontalPadding,
22
+ flexDirection: 'row',
23
+ alignItems: 'center',
24
+ alignSelf: 'flex-start',
21
25
  };
22
26
  });
23
27
 
@@ -32,4 +36,15 @@ const StyledText = styled(Typography.Caption)<{
32
36
  };
33
37
  });
34
38
 
35
- export { StyledText, StyledView };
39
+ const StyledTagIcon = styled(Icon)<{
40
+ themeIntent: ThemeIntent;
41
+ themePosition: 'left' | 'right';
42
+ }>(({ themeIntent, themePosition, theme }) => ({
43
+ color: theme.__hd__.tag.colors[themeIntent],
44
+ marginRight:
45
+ themePosition === 'left' ? theme.__hd__.tag.space.iconGap : undefined,
46
+ marginLeft:
47
+ themePosition === 'right' ? theme.__hd__.tag.space.iconGap : undefined,
48
+ }));
49
+
50
+ export { StyledText, StyledView, StyledTagIcon };
@@ -1,18 +1,27 @@
1
1
  import type { ReactElement } from 'react';
2
2
  import React from 'react';
3
3
  import type { StyleProp, ViewProps, ViewStyle } from 'react-native';
4
- import { StyledText, StyledView } from './StyledTag';
4
+ import { StyledText, StyledView, StyledTagIcon } from './StyledTag';
5
5
  import { useDeprecation } from '../../utils/hooks';
6
+ import type { IconName } from '../Icon';
6
7
 
7
8
  interface TagProps extends ViewProps {
8
9
  /**
9
10
  * Content of the Tag.
10
11
  */
11
12
  content: string | ReactElement;
13
+ /**
14
+ * Places an icon within the tag, before the content.
15
+ */
16
+ icon?: IconName;
12
17
  /**
13
18
  * Visual intent color to apply to Tag.
14
19
  */
15
20
  intent?: 'primary' | 'info' | 'success' | 'warning' | 'danger' | 'archived';
21
+ /**
22
+ * Places an icon within the tag, after the content.
23
+ */
24
+ rightIcon?: IconName;
16
25
  /**
17
26
  * @deprecated Tag variant prop is deprecated and will be removed in the next major release. Please remove it.
18
27
  *
@@ -31,8 +40,10 @@ interface TagProps extends ViewProps {
31
40
 
32
41
  const Tag = ({
33
42
  content,
43
+ icon,
34
44
  variant = 'outlined',
35
45
  intent = 'primary',
46
+ rightIcon,
36
47
  style,
37
48
  testID,
38
49
  ...nativeProps
@@ -49,6 +60,15 @@ const Tag = ({
49
60
  style={style}
50
61
  testID={testID}
51
62
  >
63
+ {icon !== undefined && (
64
+ <StyledTagIcon
65
+ icon={icon}
66
+ size="xsmall"
67
+ themeIntent={intent}
68
+ themePosition="left"
69
+ testID={testID !== undefined ? `${testID}-left-icon` : undefined}
70
+ />
71
+ )}
52
72
  {typeof content === 'string' ? (
53
73
  <StyledText themeIntent={intent} fontWeight="semi-bold">
54
74
  {content}
@@ -56,6 +76,15 @@ const Tag = ({
56
76
  ) : (
57
77
  content
58
78
  )}
79
+ {rightIcon !== undefined && (
80
+ <StyledTagIcon
81
+ icon={rightIcon}
82
+ size="xsmall"
83
+ themeIntent={intent}
84
+ themePosition="right"
85
+ testID={testID !== undefined ? `${testID}-right-icon` : undefined}
86
+ />
87
+ )}
59
88
  </StyledView>
60
89
  );
61
90
  };
@@ -35,6 +35,7 @@ const getTagTheme = (theme: GlobalTheme) => {
35
35
  const space = {
36
36
  horizontalPadding: theme.space.small,
37
37
  verticalPadding: theme.space.xsmall,
38
+ iconGap: theme.space.xsmall,
38
39
  };
39
40
 
40
41
  const radii = {
@@ -14,4 +14,11 @@ declare const StyledText: import("@emotion/native").StyledComponent<import("../.
14
14
  } & {
15
15
  themeIntent: ThemeIntent;
16
16
  }, {}, {}>;
17
- export { StyledText, StyledView };
17
+ declare const StyledTagIcon: import("@emotion/native").StyledComponent<import("../Icon").IconProps & {
18
+ theme?: import("@emotion/react").Theme;
19
+ as?: React.ElementType;
20
+ } & {
21
+ themeIntent: ThemeIntent;
22
+ themePosition: "left" | "right";
23
+ }, {}, {}>;
24
+ export { StyledText, StyledView, StyledTagIcon };
@@ -1,14 +1,23 @@
1
1
  import type { ReactElement } from 'react';
2
2
  import type { StyleProp, ViewProps, ViewStyle } from 'react-native';
3
+ import type { IconName } from '../Icon';
3
4
  interface TagProps extends ViewProps {
4
5
  /**
5
6
  * Content of the Tag.
6
7
  */
7
8
  content: string | ReactElement;
9
+ /**
10
+ * Places an icon within the tag, before the content.
11
+ */
12
+ icon?: IconName;
8
13
  /**
9
14
  * Visual intent color to apply to Tag.
10
15
  */
11
16
  intent?: 'primary' | 'info' | 'success' | 'warning' | 'danger' | 'archived';
17
+ /**
18
+ * Places an icon within the tag, after the content.
19
+ */
20
+ rightIcon?: IconName;
12
21
  /**
13
22
  * @deprecated Tag variant prop is deprecated and will be removed in the next major release. Please remove it.
14
23
  *
@@ -24,5 +33,5 @@ interface TagProps extends ViewProps {
24
33
  */
25
34
  testID?: string;
26
35
  }
27
- declare const Tag: ({ content, variant, intent, style, testID, ...nativeProps }: TagProps) => ReactElement;
36
+ declare const Tag: ({ content, icon, variant, intent, rightIcon, style, testID, ...nativeProps }: TagProps) => ReactElement;
28
37
  export default Tag;
@@ -27,6 +27,7 @@ declare const getTagTheme: (theme: GlobalTheme) => {
27
27
  space: {
28
28
  horizontalPadding: number;
29
29
  verticalPadding: number;
30
+ iconGap: number;
30
31
  };
31
32
  radii: {
32
33
  default: number;