@hero-design/rn 8.120.2 → 8.121.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/es/index.js +281 -32
  3. package/jest.config.js +1 -1
  4. package/lib/index.js +280 -30
  5. package/package.json +5 -1
  6. package/rollup.config.mjs +2 -0
  7. package/src/components/Icon/AnimatedIcon.tsx +7 -40
  8. package/src/components/Icon/GradientIcon/index.tsx +71 -0
  9. package/src/components/Icon/SpinWrapper.tsx +39 -0
  10. package/src/components/Icon/index.tsx +22 -1
  11. package/src/components/Toolbar/StyledToolbar.tsx +2 -2
  12. package/src/components/Typography/Body/StyledBody.tsx +2 -2
  13. package/src/components/Typography/Body/index.tsx +20 -2
  14. package/src/components/Typography/Caption/StyledCaption.tsx +2 -2
  15. package/src/components/Typography/Caption/index.tsx +20 -2
  16. package/src/components/Typography/GradientText/index.tsx +85 -0
  17. package/src/components/Typography/Label/StyledLabel.tsx +2 -2
  18. package/src/components/Typography/Label/index.tsx +20 -2
  19. package/src/components/Typography/Title/StyledTitle.tsx +2 -2
  20. package/src/components/Typography/Title/index.tsx +32 -13
  21. package/src/components/Typography/types.ts +3 -1
  22. package/src/components/Typography/utils.ts +31 -0
  23. package/src/theme/global/colors/gradients.ts +78 -0
  24. package/src/theme/global/colors/types.ts +22 -0
  25. package/src/theme/global/index.ts +5 -2
  26. package/testUtils/setup.tsx +34 -0
  27. package/types/components/Icon/GradientIcon/index.d.ts +12 -0
  28. package/types/components/Icon/SpinWrapper.d.ts +9 -0
  29. package/types/components/Icon/index.d.ts +1 -1
  30. package/types/components/TextInput/StyledTextInput.d.ts +1 -1
  31. package/types/components/Toolbar/StyledToolbar.d.ts +4 -4
  32. package/types/components/Typography/Body/StyledBody.d.ts +2 -2
  33. package/types/components/Typography/Body/index.d.ts +1 -1
  34. package/types/components/Typography/Caption/StyledCaption.d.ts +2 -2
  35. package/types/components/Typography/Caption/index.d.ts +1 -1
  36. package/types/components/Typography/GradientText/index.d.ts +7 -0
  37. package/types/components/Typography/Label/StyledLabel.d.ts +2 -2
  38. package/types/components/Typography/Label/index.d.ts +1 -1
  39. package/types/components/Typography/Title/StyledTitle.d.ts +2 -2
  40. package/types/components/Typography/Title/index.d.ts +1 -1
  41. package/types/components/Typography/types.d.ts +2 -1
  42. package/types/components/Typography/utils.d.ts +2 -0
  43. package/types/theme/global/colors/gradients.d.ts +3 -0
  44. package/types/theme/global/colors/types.d.ts +21 -0
  45. package/types/theme/global/index.d.ts +3 -2
package/lib/index.js CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  var reactNative = require('react-native');
4
4
  var React = require('react');
5
+ var MaskedView = require('@react-native-masked-view/masked-view');
6
+ var expoLinearGradient = require('expo-linear-gradient');
5
7
  var reactNativeVectorIcons = require('react-native-vector-icons');
6
8
  var reactNativeSafeAreaContext = require('react-native-safe-area-context');
7
9
  var reactNativeMonthYearPicker = require('@hero-design/react-native-month-year-picker');
@@ -37,6 +39,7 @@ function _interopNamespaceCompat(e) {
37
39
 
38
40
  var reactNative__namespace = /*#__PURE__*/_interopNamespaceCompat(reactNative);
39
41
  var React__namespace = /*#__PURE__*/_interopNamespaceCompat(React);
42
+ var MaskedView__default = /*#__PURE__*/_interopDefaultCompat(MaskedView);
40
43
  var Svg__default = /*#__PURE__*/_interopDefaultCompat(Svg);
41
44
  var DateTimePicker__default = /*#__PURE__*/_interopDefaultCompat(DateTimePicker);
42
45
  var RnSlider__default = /*#__PURE__*/_interopDefaultCompat(RnSlider);
@@ -5455,6 +5458,76 @@ var getShadows = function getShadows(palette) {
5455
5458
  }
5456
5459
  };
5457
5460
 
5461
+ var DIAGONAL_ANGLE = 282;
5462
+ var HORIZONTAL_ANGLE = 90;
5463
+ var DIAGONAL_LOCATIONS = [0, 0.2931, 0.993];
5464
+ var HORIZONTAL_LOCATIONS = [0, 0.25, 0.75];
5465
+ // Convert CSS gradient angle (degrees) to expo-linear-gradient start/end points.
5466
+ // Follows CSS convention: 0° = bottom→top, 90° = left→right,
5467
+ // 180° = top→bottom, 270° = right→left.
5468
+ var angleToPoints = function angleToPoints(angleDeg) {
5469
+ var rad = (angleDeg - 90) * Math.PI / 180;
5470
+ var x = Math.cos(rad);
5471
+ var y = Math.sin(rad);
5472
+ // Normalize so both components are in [0, 1]
5473
+ var start = {
5474
+ x: Math.round((1 - x) / 2 * 100) / 100,
5475
+ y: Math.round((1 - y) / 2 * 100) / 100
5476
+ };
5477
+ var end = {
5478
+ x: Math.round((1 + x) / 2 * 100) / 100,
5479
+ y: Math.round((1 + y) / 2 * 100) / 100
5480
+ };
5481
+ return {
5482
+ start: start,
5483
+ end: end
5484
+ };
5485
+ };
5486
+ var getGradients = function getGradients(systemPalette) {
5487
+ var blueMedium = palette$9.blueMedium;
5488
+ var pinkMedium = palette$9.pinkMedium;
5489
+ var brandPrimary = systemPalette.primary;
5490
+ var backgroundFallback = systemPalette.defaultGlobalSurface;
5491
+ return {
5492
+ aiDiagonal: _objectSpread2(_objectSpread2({
5493
+ angle: DIAGONAL_ANGLE
5494
+ }, angleToPoints(DIAGONAL_ANGLE)), {}, {
5495
+ colors: [blueMedium, brandPrimary, pinkMedium],
5496
+ locations: DIAGONAL_LOCATIONS
5497
+ }),
5498
+ aiDiagonal8: _objectSpread2(_objectSpread2({
5499
+ angle: DIAGONAL_ANGLE
5500
+ }, angleToPoints(DIAGONAL_ANGLE)), {}, {
5501
+ colors: [blueMedium, brandPrimary, pinkMedium],
5502
+ locations: DIAGONAL_LOCATIONS,
5503
+ opacity: 0.08,
5504
+ backgroundFallback: backgroundFallback
5505
+ }),
5506
+ aiDiagonal16: _objectSpread2(_objectSpread2({
5507
+ angle: DIAGONAL_ANGLE
5508
+ }, angleToPoints(DIAGONAL_ANGLE)), {}, {
5509
+ colors: [blueMedium, brandPrimary, pinkMedium],
5510
+ locations: DIAGONAL_LOCATIONS,
5511
+ opacity: 0.16,
5512
+ backgroundFallback: backgroundFallback
5513
+ }),
5514
+ aiDiagonal24: _objectSpread2(_objectSpread2({
5515
+ angle: DIAGONAL_ANGLE
5516
+ }, angleToPoints(DIAGONAL_ANGLE)), {}, {
5517
+ colors: [blueMedium, brandPrimary, pinkMedium],
5518
+ locations: DIAGONAL_LOCATIONS,
5519
+ opacity: 0.24,
5520
+ backgroundFallback: backgroundFallback
5521
+ }),
5522
+ aiHorizontal: _objectSpread2(_objectSpread2({
5523
+ angle: HORIZONTAL_ANGLE
5524
+ }, angleToPoints(HORIZONTAL_ANGLE)), {}, {
5525
+ colors: [brandPrimary, pinkMedium, brandPrimary],
5526
+ locations: HORIZONTAL_LOCATIONS
5527
+ })
5528
+ };
5529
+ };
5530
+
5458
5531
  var getGlobalTheme = function getGlobalTheme(scale, systemPalette) {
5459
5532
  var fonts = getFonts(scale.font);
5460
5533
  var fontSizes = getFontSizes(scale.fontSize);
@@ -5464,8 +5537,11 @@ var getGlobalTheme = function getGlobalTheme(scale, systemPalette) {
5464
5537
  var sizes = getSizes(scale.size);
5465
5538
  var radii = getRadii(scale.radius);
5466
5539
  var shadows = getShadows(systemPalette);
5540
+ var gradients = getGradients(systemPalette);
5467
5541
  return {
5468
- colors: _objectSpread2({}, systemPalette),
5542
+ colors: _objectSpread2(_objectSpread2({}, systemPalette), {}, {
5543
+ gradients: gradients
5544
+ }),
5469
5545
  fonts: fonts,
5470
5546
  fontSizes: fontSizes,
5471
5547
  lineHeights: lineHeights,
@@ -8095,7 +8171,7 @@ var StyledText$4 = index$c(reactNative.Text)(function (_ref) {
8095
8171
  });
8096
8172
  });
8097
8173
 
8098
- var _excluded$O = ["children", "fontSize", "fontWeight", "intent", "typeface", "allowFontScaling"];
8174
+ var _excluded$Q = ["children", "fontSize", "fontWeight", "intent", "typeface", "allowFontScaling"];
8099
8175
  /**
8100
8176
  * @deprecated Typography.Text is deprecated and will be removed in the next major release, please refer to https://design.employmenthero.com/mobile/Components/typography for the appropriate alternatives.
8101
8177
  */
@@ -8111,7 +8187,7 @@ var Text = function Text(_ref) {
8111
8187
  typeface = _ref$typeface === void 0 ? 'neutral' : _ref$typeface,
8112
8188
  _ref$allowFontScaling = _ref.allowFontScaling,
8113
8189
  allowFontScaling = _ref$allowFontScaling === void 0 ? false : _ref$allowFontScaling,
8114
- nativeProps = _objectWithoutProperties(_ref, _excluded$O);
8190
+ nativeProps = _objectWithoutProperties(_ref, _excluded$Q);
8115
8191
  useDeprecation('Typography.Text is deprecated and will be removed in the next major release, please refer to https://design.employmenthero.com/mobile/Components/typography for the appropriate alternatives.');
8116
8192
  return /*#__PURE__*/React__namespace.default.createElement(StyledText$4, _extends$1({}, nativeProps, {
8117
8193
  themeFontSize: fontSize,
@@ -8144,7 +8220,79 @@ var StyledCaption = index$c(reactNative.Text)(function (_ref) {
8144
8220
  };
8145
8221
  });
8146
8222
 
8147
- var _excluded$N = ["children", "fontWeight", "intent", "allowFontScaling", "fontStyle"];
8223
+ var ACCESSIBILITY_KEYS = ['accessible', 'accessibilityActions', 'accessibilityLabel', 'accessibilityRole', 'accessibilityState', 'accessibilityHint', 'accessibilityValue', 'onAccessibilityAction',
8224
+ // Android
8225
+ 'accessibilityLabelledBy', 'accessibilityLiveRegion', 'importantForAccessibility',
8226
+ // iOS
8227
+ 'accessibilityElementsHidden', 'accessibilityLanguage', 'accessibilityIgnoresInvertColors', 'accessibilityViewIsModal', 'onAccessibilityEscape', 'onAccessibilityTap', 'onMagicTap', 'accessibilityIgnoresInvertColors'];
8228
+ var pickAccessibilityProps = function pickAccessibilityProps(props) {
8229
+ return ACCESSIBILITY_KEYS.filter(function (key) {
8230
+ return key in props;
8231
+ }).reduce(function (acc, key) {
8232
+ return Object.assign(acc, _defineProperty({}, key, props[key]));
8233
+ }, {});
8234
+ };
8235
+
8236
+ var _excluded$P = ["children"];
8237
+ var GradientText = function GradientText(_ref) {
8238
+ var children = _ref.children,
8239
+ accessibilityProps = _objectWithoutProperties(_ref, _excluded$P);
8240
+ var theme = useTheme();
8241
+ var gradient = theme.colors.gradients.aiDiagonal;
8242
+ var _useState = React.useState(null),
8243
+ _useState2 = _slicedToArray(_useState, 2),
8244
+ size = _useState2[0],
8245
+ setSize = _useState2[1];
8246
+ var onLayout = React.useCallback(function (event) {
8247
+ var _event$nativeEvent$la = event.nativeEvent.layout,
8248
+ width = _event$nativeEvent$la.width,
8249
+ height = _event$nativeEvent$la.height;
8250
+ setSize(function (prevSize) {
8251
+ if (prevSize && prevSize.width === width && prevSize.height === height) {
8252
+ return prevSize;
8253
+ }
8254
+ return {
8255
+ width: width,
8256
+ height: height
8257
+ };
8258
+ });
8259
+ }, []);
8260
+ return /*#__PURE__*/React__namespace.default.createElement(reactNative.View, accessibilityProps, /*#__PURE__*/React__namespace.default.createElement(MaskedView__default.default, {
8261
+ style: {
8262
+ alignSelf: 'stretch'
8263
+ },
8264
+ accessibilityElementsHidden: true,
8265
+ importantForAccessibility: "no-hide-descendants",
8266
+ maskElement: /*#__PURE__*/React__namespace.default.createElement(reactNative.View, {
8267
+ onLayout: onLayout,
8268
+ style: {
8269
+ backgroundColor: 'transparent'
8270
+ },
8271
+ testID: "gradient-text-mask"
8272
+ }, children)
8273
+ }, size ? /*#__PURE__*/React__namespace.default.createElement(expoLinearGradient.LinearGradient, {
8274
+ start: gradient.start,
8275
+ end: gradient.end,
8276
+ colors: gradient.colors,
8277
+ locations: gradient.locations,
8278
+ style: {
8279
+ width: size.width,
8280
+ height: size.height
8281
+ }
8282
+ }) :
8283
+ // Render children as fallback until layout is measured, so text
8284
+ // is visible immediately rather than blank on the first frame.
8285
+ children), /*#__PURE__*/React__namespace.default.createElement(reactNative.View, {
8286
+ style: {
8287
+ position: 'absolute',
8288
+ opacity: 0
8289
+ },
8290
+ importantForAccessibility: "yes",
8291
+ accessibilityElementsHidden: false
8292
+ }, children));
8293
+ };
8294
+
8295
+ var _excluded$O = ["children", "fontWeight", "intent", "allowFontScaling", "fontStyle", "style", "testID"];
8148
8296
  var Caption = function Caption(_ref) {
8149
8297
  var children = _ref.children,
8150
8298
  _ref$fontWeight = _ref.fontWeight,
@@ -8155,13 +8303,22 @@ var Caption = function Caption(_ref) {
8155
8303
  allowFontScaling = _ref$allowFontScaling === void 0 ? false : _ref$allowFontScaling,
8156
8304
  _ref$fontStyle = _ref.fontStyle,
8157
8305
  fontStyle = _ref$fontStyle === void 0 ? 'normal' : _ref$fontStyle,
8158
- nativeProps = _objectWithoutProperties(_ref, _excluded$N);
8159
- return /*#__PURE__*/React__namespace.default.createElement(StyledCaption, _extends$1({}, nativeProps, {
8306
+ style = _ref.style,
8307
+ testID = _ref.testID,
8308
+ nativeProps = _objectWithoutProperties(_ref, _excluded$O);
8309
+ var isAi = intent === 'ai';
8310
+ var styledText = /*#__PURE__*/React__namespace.default.createElement(StyledCaption, _extends$1({}, nativeProps, {
8160
8311
  themeFontWeight: fontWeight,
8161
- themeIntent: intent,
8312
+ themeIntent: isAi ? 'body' : intent,
8162
8313
  themeIsItalic: fontStyle === 'italic',
8163
- allowFontScaling: allowFontScaling
8314
+ allowFontScaling: allowFontScaling,
8315
+ style: style,
8316
+ testID: testID
8164
8317
  }), children);
8318
+ if (isAi) {
8319
+ return /*#__PURE__*/React__namespace.default.createElement(GradientText, pickAccessibilityProps(nativeProps), styledText);
8320
+ }
8321
+ return styledText;
8165
8322
  };
8166
8323
 
8167
8324
  var StyledLabel$1 = index$c(reactNative.Text)(function (_ref) {
@@ -8180,7 +8337,7 @@ var StyledLabel$1 = index$c(reactNative.Text)(function (_ref) {
8180
8337
  };
8181
8338
  });
8182
8339
 
8183
- var _excluded$M = ["children", "intent", "allowFontScaling", "fontStyle"];
8340
+ var _excluded$N = ["children", "intent", "allowFontScaling", "fontStyle", "style", "testID"];
8184
8341
  var Label = function Label(_ref) {
8185
8342
  var children = _ref.children,
8186
8343
  _ref$intent = _ref.intent,
@@ -8189,12 +8346,21 @@ var Label = function Label(_ref) {
8189
8346
  allowFontScaling = _ref$allowFontScaling === void 0 ? false : _ref$allowFontScaling,
8190
8347
  _ref$fontStyle = _ref.fontStyle,
8191
8348
  fontStyle = _ref$fontStyle === void 0 ? 'normal' : _ref$fontStyle,
8192
- nativeProps = _objectWithoutProperties(_ref, _excluded$M);
8193
- return /*#__PURE__*/React__namespace.default.createElement(StyledLabel$1, _extends$1({}, nativeProps, {
8194
- themeIntent: intent,
8349
+ style = _ref.style,
8350
+ testID = _ref.testID,
8351
+ nativeProps = _objectWithoutProperties(_ref, _excluded$N);
8352
+ var isAi = intent === 'ai';
8353
+ var styledText = /*#__PURE__*/React__namespace.default.createElement(StyledLabel$1, _extends$1({}, nativeProps, {
8354
+ themeIntent: isAi ? 'body' : intent,
8195
8355
  themeIsItalic: fontStyle === 'italic',
8196
- allowFontScaling: allowFontScaling
8356
+ allowFontScaling: allowFontScaling,
8357
+ style: style,
8358
+ testID: testID
8197
8359
  }), children);
8360
+ if (isAi) {
8361
+ return /*#__PURE__*/React__namespace.default.createElement(GradientText, pickAccessibilityProps(nativeProps), styledText);
8362
+ }
8363
+ return styledText;
8198
8364
  };
8199
8365
 
8200
8366
  var StyledTitle$1 = index$c(reactNative.Text)(function (_ref) {
@@ -8212,7 +8378,7 @@ var StyledTitle$1 = index$c(reactNative.Text)(function (_ref) {
8212
8378
  };
8213
8379
  });
8214
8380
 
8215
- var _excluded$L = ["children", "intent", "allowFontScaling", "level", "typeface", "fontStyle"];
8381
+ var _excluded$M = ["children", "intent", "allowFontScaling", "level", "typeface", "fontStyle", "style", "testID"];
8216
8382
  var Title = function Title(_ref) {
8217
8383
  var children = _ref.children,
8218
8384
  _ref$intent = _ref.intent,
@@ -8225,14 +8391,23 @@ var Title = function Title(_ref) {
8225
8391
  typeface = _ref$typeface === void 0 ? 'neutral' : _ref$typeface,
8226
8392
  _ref$fontStyle = _ref.fontStyle,
8227
8393
  fontStyle = _ref$fontStyle === void 0 ? 'normal' : _ref$fontStyle,
8228
- nativeProps = _objectWithoutProperties(_ref, _excluded$L);
8229
- return /*#__PURE__*/React__namespace.default.createElement(StyledTitle$1, _extends$1({}, nativeProps, {
8394
+ style = _ref.style,
8395
+ testID = _ref.testID,
8396
+ nativeProps = _objectWithoutProperties(_ref, _excluded$M);
8397
+ var isAi = intent === 'ai';
8398
+ var styledText = /*#__PURE__*/React__namespace.default.createElement(StyledTitle$1, _extends$1({}, nativeProps, {
8230
8399
  themeLevel: level,
8231
8400
  themeTypeface: typeface,
8232
- themeIntent: intent,
8401
+ themeIntent: isAi ? 'body' : intent,
8233
8402
  themeIsItalic: fontStyle === 'italic',
8234
- allowFontScaling: allowFontScaling
8403
+ allowFontScaling: allowFontScaling,
8404
+ style: style,
8405
+ testID: testID
8235
8406
  }), children);
8407
+ if (isAi) {
8408
+ return /*#__PURE__*/React__namespace.default.createElement(GradientText, pickAccessibilityProps(nativeProps), styledText);
8409
+ }
8410
+ return styledText;
8236
8411
  };
8237
8412
 
8238
8413
  var FONTWEIGHT_MAP = {
@@ -8264,7 +8439,7 @@ var StyledBody$2 = index$c(reactNative.Text)(function (_ref) {
8264
8439
  };
8265
8440
  });
8266
8441
 
8267
- var _excluded$K = ["children", "intent", "allowFontScaling", "typeface", "variant", "fontStyle"];
8442
+ var _excluded$L = ["children", "intent", "allowFontScaling", "typeface", "variant", "fontStyle", "style", "testID"];
8268
8443
  var Body = function Body(_ref) {
8269
8444
  var children = _ref.children,
8270
8445
  _ref$intent = _ref.intent,
@@ -8277,14 +8452,23 @@ var Body = function Body(_ref) {
8277
8452
  variant = _ref$variant === void 0 ? 'regular' : _ref$variant,
8278
8453
  _ref$fontStyle = _ref.fontStyle,
8279
8454
  fontStyle = _ref$fontStyle === void 0 ? 'normal' : _ref$fontStyle,
8280
- nativeProps = _objectWithoutProperties(_ref, _excluded$K);
8281
- return /*#__PURE__*/React__namespace.default.createElement(StyledBody$2, _extends$1({}, nativeProps, {
8455
+ style = _ref.style,
8456
+ testID = _ref.testID,
8457
+ nativeProps = _objectWithoutProperties(_ref, _excluded$L);
8458
+ var isAi = intent === 'ai';
8459
+ var styledText = /*#__PURE__*/React__namespace.default.createElement(StyledBody$2, _extends$1({}, nativeProps, {
8282
8460
  themeTypeface: typeface,
8283
- themeIntent: intent,
8461
+ themeIntent: isAi ? 'body' : intent,
8284
8462
  themeVariant: variant,
8285
8463
  themeIsItalic: fontStyle === 'italic',
8286
- allowFontScaling: allowFontScaling
8464
+ allowFontScaling: allowFontScaling,
8465
+ style: style,
8466
+ testID: testID
8287
8467
  }), children);
8468
+ if (isAi) {
8469
+ return /*#__PURE__*/React__namespace.default.createElement(GradientText, pickAccessibilityProps(nativeProps), styledText);
8470
+ }
8471
+ return styledText;
8288
8472
  };
8289
8473
 
8290
8474
  var Typography = {
@@ -8894,10 +9078,10 @@ var StyledHeroIcon = index$c(HeroIcon)(function (_ref) {
8894
9078
  };
8895
9079
  });
8896
9080
 
8897
- var _excluded$J = ["style"];
8898
- var AnimatedIcon = function AnimatedIcon(_ref) {
8899
- var style = _ref.style,
8900
- otherProps = _objectWithoutProperties(_ref, _excluded$J);
9081
+ var SpinWrapper = function SpinWrapper(_ref) {
9082
+ var children = _ref.children,
9083
+ style = _ref.style,
9084
+ testID = _ref.testID;
8901
9085
  var rotateAnimation = React.useRef(new reactNative.Animated.Value(0));
8902
9086
  React.useEffect(function () {
8903
9087
  var animation = reactNative.Animated.loop(reactNative.Animated.timing(rotateAnimation.current, {
@@ -8908,22 +9092,74 @@ var AnimatedIcon = function AnimatedIcon(_ref) {
8908
9092
  }));
8909
9093
  animation.start();
8910
9094
  return function () {
8911
- animation.stop();
9095
+ return animation.stop();
8912
9096
  };
8913
9097
  }, []);
8914
- var interpolatedRotateAnimation = rotateAnimation.current.interpolate({
9098
+ var rotate = rotateAnimation.current.interpolate({
8915
9099
  inputRange: [0, 1],
8916
9100
  outputRange: ['0deg', '360deg']
8917
9101
  });
8918
9102
  return /*#__PURE__*/React__namespace.default.createElement(reactNative.Animated.View, {
9103
+ testID: testID,
8919
9104
  style: [{
8920
9105
  transform: [{
8921
- rotate: interpolatedRotateAnimation
9106
+ rotate: rotate
8922
9107
  }]
8923
9108
  }, style]
9109
+ }, children);
9110
+ };
9111
+
9112
+ var _excluded$K = ["style"];
9113
+ var AnimatedIcon = function AnimatedIcon(_ref) {
9114
+ var style = _ref.style,
9115
+ otherProps = _objectWithoutProperties(_ref, _excluded$K);
9116
+ return /*#__PURE__*/React__namespace.default.createElement(SpinWrapper, {
9117
+ style: style
8924
9118
  }, /*#__PURE__*/React__namespace.default.createElement(StyledHeroIcon, otherProps));
8925
9119
  };
8926
9120
 
9121
+ var _excluded$J = ["name", "themeSize", "testID", "style"];
9122
+ var GradientIcon = function GradientIcon(_ref) {
9123
+ var name = _ref.name,
9124
+ themeSize = _ref.themeSize,
9125
+ testID = _ref.testID,
9126
+ style = _ref.style,
9127
+ accessibilityProps = _objectWithoutProperties(_ref, _excluded$J);
9128
+ var theme = useTheme();
9129
+ var gradient = theme.colors.gradients.aiDiagonal;
9130
+ var size = theme.__hd__.icon.sizes[themeSize];
9131
+ return /*#__PURE__*/React__namespace.default.createElement(MaskedView__default.default, _extends$1({
9132
+ testID: testID,
9133
+ style: [{
9134
+ width: size,
9135
+ height: size
9136
+ }, style]
9137
+ }, accessibilityProps, {
9138
+ maskElement: /*#__PURE__*/React__namespace.default.createElement(reactNative.View, {
9139
+ style: {
9140
+ backgroundColor: 'transparent',
9141
+ width: size,
9142
+ height: size,
9143
+ alignItems: 'center',
9144
+ justifyContent: 'center'
9145
+ }
9146
+ }, /*#__PURE__*/React__namespace.default.createElement(StyledHeroIcon, {
9147
+ name: name,
9148
+ themeIntent: "text",
9149
+ themeSize: themeSize
9150
+ }))
9151
+ }), /*#__PURE__*/React__namespace.default.createElement(expoLinearGradient.LinearGradient, {
9152
+ start: gradient.start,
9153
+ end: gradient.end,
9154
+ colors: gradient.colors,
9155
+ locations: gradient.locations,
9156
+ style: {
9157
+ width: size,
9158
+ height: size
9159
+ }
9160
+ }));
9161
+ };
9162
+
8927
9163
  var Icon = function Icon(_ref) {
8928
9164
  var icon = _ref.icon,
8929
9165
  style = _ref.style,
@@ -8959,6 +9195,20 @@ var Icon = function Icon(_ref) {
8959
9195
  accessibilityViewIsModal: accessibilityViewIsModal,
8960
9196
  accessibilityActions: accessibilityActions
8961
9197
  };
9198
+ if (intent === 'ai') {
9199
+ var gradientIcon = /*#__PURE__*/React__namespace.default.createElement(GradientIcon, _extends$1({
9200
+ name: icon,
9201
+ themeSize: size,
9202
+ testID: testID,
9203
+ style: spin ? undefined : style
9204
+ }, accessibilityProps));
9205
+ if (spin) {
9206
+ return /*#__PURE__*/React__namespace.default.createElement(SpinWrapper, {
9207
+ style: style
9208
+ }, gradientIcon);
9209
+ }
9210
+ return gradientIcon;
9211
+ }
8962
9212
  return spin ? /*#__PURE__*/React__namespace.default.createElement(AnimatedIcon, _extends$1({
8963
9213
  name: icon,
8964
9214
  themeIntent: intent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hero-design/rn",
3
- "version": "8.120.2",
3
+ "version": "8.121.0",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -33,6 +33,8 @@
33
33
  "@ptomasroos/react-native-multi-slider": "^2.2.2",
34
34
  "@react-native-community/datetimepicker": "^8.4.4",
35
35
  "@react-native-community/slider": "^5.0.1",
36
+ "@react-native-masked-view/masked-view": "^0.3.2",
37
+ "expo-linear-gradient": ">=14.0.0",
36
38
  "react": "19.1.0",
37
39
  "react-native": "0.81.5",
38
40
  "react-native-gesture-handler": "~2.28.0",
@@ -61,6 +63,7 @@
61
63
  "@ptomasroos/react-native-multi-slider": "^2.2.2",
62
64
  "@react-native-community/datetimepicker": "8.4.4",
63
65
  "@react-native-community/slider": "^5.0.1",
66
+ "@react-native-masked-view/masked-view": "0.3.2",
64
67
  "@react-native/babel-preset": "0.81.5",
65
68
  "@rollup/plugin-babel": "^6.0.4",
66
69
  "@rollup/plugin-commonjs": "^28.0.1",
@@ -81,6 +84,7 @@
81
84
  "core-js": "^3.33.0",
82
85
  "eslint": "^8.56.0",
83
86
  "eslint-config-hd": "8.42.5",
87
+ "expo-linear-gradient": "55.0.9",
84
88
  "jest": "^29.2.1",
85
89
  "jest-environment-jsdom": "^29.2.1",
86
90
  "jest-junit": "^16.0.0",
package/rollup.config.mjs CHANGED
@@ -33,6 +33,8 @@ export default [
33
33
  },
34
34
  ],
35
35
  external: [
36
+ '@react-native-masked-view/masked-view',
37
+ 'expo-linear-gradient',
36
38
  'react',
37
39
  'react-native',
38
40
  'react-native-safe-area-context',
@@ -1,47 +1,14 @@
1
- import React, { useEffect, useRef } from 'react';
2
- import { Animated, Easing } from 'react-native';
1
+ import React from 'react';
3
2
  import type { ComponentProps } from 'react';
4
3
  import StyledHeroIcon from './HeroIcon';
4
+ import SpinWrapper from './SpinWrapper';
5
5
 
6
6
  type AnimatedIconProps = ComponentProps<typeof StyledHeroIcon>;
7
7
 
8
- const AnimatedIcon = ({ style, ...otherProps }: AnimatedIconProps) => {
9
- const rotateAnimation = useRef<Animated.Value>(new Animated.Value(0));
10
-
11
- useEffect(() => {
12
- const animation = Animated.loop(
13
- Animated.timing(rotateAnimation.current, {
14
- toValue: 1,
15
- duration: 1000,
16
- easing: Easing.linear,
17
- useNativeDriver: true,
18
- })
19
- );
20
-
21
- animation.start();
22
-
23
- return () => {
24
- animation.stop();
25
- };
26
- }, []);
27
-
28
- const interpolatedRotateAnimation = rotateAnimation.current.interpolate({
29
- inputRange: [0, 1],
30
- outputRange: ['0deg', '360deg'],
31
- });
32
-
33
- return (
34
- <Animated.View
35
- style={[
36
- {
37
- transform: [{ rotate: interpolatedRotateAnimation }],
38
- },
39
- style,
40
- ]}
41
- >
42
- <StyledHeroIcon {...otherProps} />
43
- </Animated.View>
44
- );
45
- };
8
+ const AnimatedIcon = ({ style, ...otherProps }: AnimatedIconProps) => (
9
+ <SpinWrapper style={style}>
10
+ <StyledHeroIcon {...otherProps} />
11
+ </SpinWrapper>
12
+ );
46
13
 
47
14
  export default AnimatedIcon;
@@ -0,0 +1,71 @@
1
+ import MaskedView from '@react-native-masked-view/masked-view';
2
+ import { LinearGradient } from 'expo-linear-gradient';
3
+ import React from 'react';
4
+ import type { AccessibilityProps, StyleProp, ViewStyle } from 'react-native';
5
+ import { View } from 'react-native';
6
+
7
+ import { useTheme } from '../../../theme';
8
+ import StyledHeroIcon from '../HeroIcon';
9
+ import type { IconName } from '..';
10
+
11
+ type GradientIconSize =
12
+ | 'xxxsmall'
13
+ | 'xsmall'
14
+ | 'small'
15
+ | 'medium'
16
+ | 'large'
17
+ | 'xlarge';
18
+
19
+ interface GradientIconProps extends AccessibilityProps {
20
+ name: IconName;
21
+ themeSize: GradientIconSize;
22
+ testID?: string;
23
+ style?: StyleProp<ViewStyle>;
24
+ }
25
+
26
+ const GradientIcon = ({
27
+ name,
28
+ themeSize,
29
+ testID,
30
+ style,
31
+ ...accessibilityProps
32
+ }: GradientIconProps) => {
33
+ const theme = useTheme();
34
+ const gradient = theme.colors.gradients.aiDiagonal;
35
+ const size = theme.__hd__.icon.sizes[themeSize];
36
+
37
+ return (
38
+ <MaskedView
39
+ testID={testID}
40
+ style={[{ width: size, height: size }, style]}
41
+ {...accessibilityProps}
42
+ maskElement={
43
+ <View
44
+ style={{
45
+ backgroundColor: 'transparent',
46
+ width: size,
47
+ height: size,
48
+ alignItems: 'center',
49
+ justifyContent: 'center',
50
+ }}
51
+ >
52
+ <StyledHeroIcon
53
+ name={name}
54
+ themeIntent="text"
55
+ themeSize={themeSize}
56
+ />
57
+ </View>
58
+ }
59
+ >
60
+ <LinearGradient
61
+ start={gradient.start}
62
+ end={gradient.end}
63
+ colors={gradient.colors}
64
+ locations={gradient.locations}
65
+ style={{ width: size, height: size }}
66
+ />
67
+ </MaskedView>
68
+ );
69
+ };
70
+
71
+ export default GradientIcon;
@@ -0,0 +1,39 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+ import type { StyleProp, ViewStyle } from 'react-native';
3
+ import { Animated, Easing } from 'react-native';
4
+
5
+ export interface SpinWrapperProps {
6
+ children: React.ReactNode;
7
+ style?: StyleProp<ViewStyle>;
8
+ testID?: string;
9
+ }
10
+
11
+ const SpinWrapper = ({ children, style, testID }: SpinWrapperProps) => {
12
+ const rotateAnimation = useRef(new Animated.Value(0));
13
+
14
+ useEffect(() => {
15
+ const animation = Animated.loop(
16
+ Animated.timing(rotateAnimation.current, {
17
+ toValue: 1,
18
+ duration: 1000,
19
+ easing: Easing.linear,
20
+ useNativeDriver: true,
21
+ })
22
+ );
23
+ animation.start();
24
+ return () => animation.stop();
25
+ }, []);
26
+
27
+ const rotate = rotateAnimation.current.interpolate({
28
+ inputRange: [0, 1],
29
+ outputRange: ['0deg', '360deg'],
30
+ });
31
+
32
+ return (
33
+ <Animated.View testID={testID} style={[{ transform: [{ rotate }] }, style]}>
34
+ {children}
35
+ </Animated.View>
36
+ );
37
+ };
38
+
39
+ export default SpinWrapper;