@telus-uds/components-base 1.89.0 → 1.90.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,12 +1,26 @@
1
1
  # Change Log - @telus-uds/components-base
2
2
 
3
- This log was last generated on Fri, 19 Jul 2024 18:14:09 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 26 Jul 2024 21:17:56 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 1.90.0
8
+
9
+ Fri, 26 Jul 2024 21:17:56 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - `Status`: add component (guillermo.peitzner@telus.com)
14
+ - Bump @telus-uds/system-theme-tokens to v2.60.0
15
+
16
+ ### Patches
17
+
18
+ - Conditionally add iconSpace on mobile if we have an icon to render (jaime.tuyuc@telus.com)
19
+ - `Carousel`: fix accessibility issue, remove unused accessibilityValue (<tony.eng@telus.com>)
20
+
7
21
  ## 1.89.0
8
22
 
9
- Fri, 19 Jul 2024 18:14:09 GMT
23
+ Fri, 19 Jul 2024 18:20:50 GMT
10
24
 
11
25
  ### Minor changes
12
26
 
@@ -306,7 +306,7 @@ const ButtonBase = /*#__PURE__*/_react.default.forwardRef((_ref11, ref) => {
306
306
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.IconText, {
307
307
  icon: IconComponent,
308
308
  iconPosition: iconPosition,
309
- space: iconSpace,
309
+ space: icon ? iconSpace : 0,
310
310
  iconProps: {
311
311
  ...iconProps,
312
312
  tokens: iconTokens
@@ -552,12 +552,7 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
552
552
  const systemProps = selectProps({
553
553
  ...rest,
554
554
  accessibilityRole,
555
- accessibilityLabel,
556
- accessibilityValue: {
557
- min: 1,
558
- max: childrenArray.length,
559
- now: activeIndex + 1
560
- }
555
+ accessibilityLabel
561
556
  });
562
557
 
563
558
  // If container isn't used for focus, give it a label of title if none is passed in,
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
9
+ var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
10
+ var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
11
+ var _propTypes = _interopRequireDefault(require("prop-types"));
12
+ var _ThemeProvider = require("../ThemeProvider");
13
+ var _utils = require("../utils");
14
+ var _Icon = _interopRequireDefault(require("../Icon"));
15
+ var _jsxRuntime = require("react/jsx-runtime");
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
18
+ const selectContainerStyles = _ref => {
19
+ let {
20
+ backgroundColor,
21
+ backgroundGradient,
22
+ borderColor,
23
+ borderRadius,
24
+ borderWidth,
25
+ paddingBottom,
26
+ paddingLeft,
27
+ paddingRight,
28
+ paddingTop
29
+ } = _ref;
30
+ const styles = {
31
+ borderColor,
32
+ borderRadius,
33
+ borderWidth,
34
+ paddingBottom,
35
+ paddingLeft,
36
+ paddingRight,
37
+ paddingTop
38
+ };
39
+ if (backgroundGradient) {
40
+ if (_Platform.default.OS === 'web') {
41
+ styles.background = (0, _utils.transformGradient)(backgroundGradient);
42
+ } else {
43
+ const {
44
+ stops: [stopOne, stopTwo]
45
+ } = backgroundGradient;
46
+ styles.gradient = {};
47
+ styles.gradient.start = {
48
+ x: 0,
49
+ y: 0
50
+ };
51
+ styles.gradient.end = {
52
+ x: 1,
53
+ y: 1
54
+ };
55
+ styles.gradient.colors = [stopOne.color, stopTwo.color];
56
+ }
57
+ } else {
58
+ styles.backgroundColor = backgroundColor;
59
+ }
60
+ return styles;
61
+ };
62
+ const selectIconProps = _ref2 => {
63
+ let {
64
+ icon,
65
+ iconColor
66
+ } = _ref2;
67
+ return {
68
+ icon,
69
+ tokens: {
70
+ color: iconColor
71
+ },
72
+ variant: {
73
+ size: 'small'
74
+ }
75
+ };
76
+ };
77
+ const selectTextStyles = _ref3 => {
78
+ let {
79
+ textColor,
80
+ textLineHeight,
81
+ fontName,
82
+ fontSize,
83
+ fontWeight
84
+ } = _ref3;
85
+ return (0, _ThemeProvider.applyTextStyles)({
86
+ fontColor: textColor,
87
+ fontName,
88
+ fontSize,
89
+ fontWeight,
90
+ lineHeight: _Platform.default.OS === 'web' ? textLineHeight : textLineHeight * 1.2,
91
+ marginLeft: 8
92
+ });
93
+ };
94
+
95
+ /**
96
+ * Status component displays a status indicator with optional custom gradient.
97
+ *
98
+ * @component
99
+ * @param {object} tokens - The tokens for customizing the status component.
100
+ * @param {string} variant - The variant of the status component.
101
+ * @param {ReactNode} children - The content to be displayed inside the status component.
102
+ * @param {function} customGradient - The custom gradient function for the status component.
103
+ * @param {object} rest - The rest of the props to be applied to the status component.
104
+ * @param {React.Ref} ref - The ref to be applied to the status component.
105
+ * @returns {ReactNode} The rendered status component.
106
+ */
107
+ const Status = /*#__PURE__*/_react.default.forwardRef((_ref4, ref) => {
108
+ let {
109
+ tokens,
110
+ variant,
111
+ children,
112
+ customGradient,
113
+ ...rest
114
+ } = _ref4;
115
+ const themeTokens = (0, _ThemeProvider.useThemeTokens)('Status', tokens, variant);
116
+ const containerStyles = {
117
+ ...selectContainerStyles(themeTokens),
118
+ ...staticStyles.container
119
+ };
120
+ let content = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
121
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
122
+ ...selectIconProps(themeTokens)
123
+ }), (0, _utils.wrapStringsInText)(children, {
124
+ style: selectTextStyles(themeTokens)
125
+ })]
126
+ });
127
+ if (typeof customGradient === 'function') {
128
+ content = customGradient(containerStyles.gradient, containerStyles, content);
129
+ }
130
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
131
+ ref: ref,
132
+ style: containerStyles,
133
+ ...selectProps(rest),
134
+ children: content
135
+ });
136
+ });
137
+ Status.displayName = 'Status';
138
+ Status.propTypes = {
139
+ ...selectedSystemPropTypes,
140
+ tokens: (0, _utils.getTokensPropType)('Status'),
141
+ variant: _utils.variantProp.propType,
142
+ /**
143
+ * The content to be displayed inside the status component.
144
+ */
145
+ children: _propTypes.default.node.isRequired,
146
+ /**
147
+ * The custom gradient function for the status component.
148
+ */
149
+ customGradient: _propTypes.default.func
150
+ };
151
+ const staticStyles = _StyleSheet.default.create({
152
+ container: {
153
+ flexDirection: 'row',
154
+ alignItems: 'center',
155
+ ..._Platform.default.select({
156
+ web: {
157
+ display: 'inline-flex',
158
+ width: 'fit-content'
159
+ },
160
+ default: {
161
+ display: 'flex',
162
+ width: 'auto'
163
+ }
164
+ })
165
+ }
166
+ });
167
+ var _default = Status;
168
+ exports.default = _default;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _Status = _interopRequireDefault(require("./Status"));
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+ var _default = _Status.default;
10
+ exports.default = _default;
package/lib/index.js CHANGED
@@ -54,6 +54,7 @@ var _exportNames = {
54
54
  SkipLink: true,
55
55
  Spacer: true,
56
56
  StackView: true,
57
+ Status: true,
57
58
  StepTracker: true,
58
59
  Tabs: true,
59
60
  Tags: true,
@@ -398,6 +399,12 @@ Object.defineProperty(exports, "StackView", {
398
399
  return _StackView.default;
399
400
  }
400
401
  });
402
+ Object.defineProperty(exports, "Status", {
403
+ enumerable: true,
404
+ get: function () {
405
+ return _Status.default;
406
+ }
407
+ });
401
408
  Object.defineProperty(exports, "StepTracker", {
402
409
  enumerable: true,
403
410
  get: function () {
@@ -678,6 +685,7 @@ Object.keys(_StackView).forEach(function (key) {
678
685
  }
679
686
  });
680
687
  });
688
+ var _Status = _interopRequireDefault(require("./Status"));
681
689
  var _StepTracker = _interopRequireDefault(require("./StepTracker"));
682
690
  var _Tabs = _interopRequireDefault(require("./Tabs"));
683
691
  var _Tags = _interopRequireDefault(require("./Tags"));
@@ -16,7 +16,8 @@ var _exportNames = {
16
16
  withLinkRouter: true,
17
17
  containUniqueFields: true,
18
18
  BaseView: true,
19
- htmlAttrs: true
19
+ htmlAttrs: true,
20
+ transformGradient: true
20
21
  };
21
22
  Object.defineProperty(exports, "BaseView", {
22
23
  enumerable: true,
@@ -42,6 +43,12 @@ Object.defineProperty(exports, "info", {
42
43
  return _info.default;
43
44
  }
44
45
  });
46
+ Object.defineProperty(exports, "transformGradient", {
47
+ enumerable: true,
48
+ get: function () {
49
+ return _transformGradient.transformGradient;
50
+ }
51
+ });
45
52
  Object.defineProperty(exports, "useCopy", {
46
53
  enumerable: true,
47
54
  get: function () {
@@ -216,6 +223,7 @@ Object.keys(_ssr).forEach(function (key) {
216
223
  var _containUniqueFields = _interopRequireDefault(require("./containUniqueFields"));
217
224
  var _BaseView = _interopRequireDefault(require("./BaseView"));
218
225
  var _htmlAttrs = _interopRequireDefault(require("./htmlAttrs"));
226
+ var _transformGradient = require("./transformGradient");
219
227
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
220
228
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
221
229
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.transformGradient = exports.default = void 0;
7
+ /**
8
+ * Transforms a gradient object into a CSS gradient string.
9
+ *
10
+ * @param {Object} gradient - The gradient object to transform.
11
+ * @param {string} gradient.type - The type of gradient (linear or radial).
12
+ * @param {number} gradient.angle - The angle of the linear gradient in degrees.
13
+ * @param {Array} gradient.stops - An array of gradient stops.
14
+ * @param {string} gradient.stops[].color - The color of the gradient stop.
15
+ * @param {number} gradient.stops[].stop - The position of the gradient stop as a percentage.
16
+ * @returns {string} The CSS gradient string.
17
+ */
18
+ const transformGradient = gradient => `${gradient.type}-gradient(${gradient.angle}deg, ${gradient.stops[0].color} ${gradient.stops[0].stop * 100}%, ${gradient.stops[1].color} ${gradient.stops[1].stop * 100}%)`;
19
+ exports.transformGradient = transformGradient;
20
+ var _default = {
21
+ transformGradient
22
+ };
23
+ exports.default = _default;
@@ -299,7 +299,7 @@ const ButtonBase = /*#__PURE__*/React.forwardRef((_ref11, ref) => {
299
299
  children: /*#__PURE__*/_jsx(IconText, {
300
300
  icon: IconComponent,
301
301
  iconPosition: iconPosition,
302
- space: iconSpace,
302
+ space: icon ? iconSpace : 0,
303
303
  iconProps: {
304
304
  ...iconProps,
305
305
  tokens: iconTokens
@@ -546,12 +546,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
546
546
  const systemProps = selectProps({
547
547
  ...rest,
548
548
  accessibilityRole,
549
- accessibilityLabel,
550
- accessibilityValue: {
551
- min: 1,
552
- max: childrenArray.length,
553
- now: activeIndex + 1
554
- }
549
+ accessibilityLabel
555
550
  });
556
551
 
557
552
  // If container isn't used for focus, give it a label of title if none is passed in,
@@ -0,0 +1,162 @@
1
+ import React from 'react';
2
+ import Platform from "react-native-web/dist/exports/Platform";
3
+ import StyleSheet from "react-native-web/dist/exports/StyleSheet";
4
+ import View from "react-native-web/dist/exports/View";
5
+ import PropTypes from 'prop-types';
6
+ import { useThemeTokens, applyTextStyles } from '../ThemeProvider';
7
+ import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps, wrapStringsInText, transformGradient } from '../utils';
8
+ import Icon from '../Icon';
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ import { Fragment as _Fragment } from "react/jsx-runtime";
11
+ import { jsxs as _jsxs } from "react/jsx-runtime";
12
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
13
+ const selectContainerStyles = _ref => {
14
+ let {
15
+ backgroundColor,
16
+ backgroundGradient,
17
+ borderColor,
18
+ borderRadius,
19
+ borderWidth,
20
+ paddingBottom,
21
+ paddingLeft,
22
+ paddingRight,
23
+ paddingTop
24
+ } = _ref;
25
+ const styles = {
26
+ borderColor,
27
+ borderRadius,
28
+ borderWidth,
29
+ paddingBottom,
30
+ paddingLeft,
31
+ paddingRight,
32
+ paddingTop
33
+ };
34
+ if (backgroundGradient) {
35
+ if (Platform.OS === 'web') {
36
+ styles.background = transformGradient(backgroundGradient);
37
+ } else {
38
+ const {
39
+ stops: [stopOne, stopTwo]
40
+ } = backgroundGradient;
41
+ styles.gradient = {};
42
+ styles.gradient.start = {
43
+ x: 0,
44
+ y: 0
45
+ };
46
+ styles.gradient.end = {
47
+ x: 1,
48
+ y: 1
49
+ };
50
+ styles.gradient.colors = [stopOne.color, stopTwo.color];
51
+ }
52
+ } else {
53
+ styles.backgroundColor = backgroundColor;
54
+ }
55
+ return styles;
56
+ };
57
+ const selectIconProps = _ref2 => {
58
+ let {
59
+ icon,
60
+ iconColor
61
+ } = _ref2;
62
+ return {
63
+ icon,
64
+ tokens: {
65
+ color: iconColor
66
+ },
67
+ variant: {
68
+ size: 'small'
69
+ }
70
+ };
71
+ };
72
+ const selectTextStyles = _ref3 => {
73
+ let {
74
+ textColor,
75
+ textLineHeight,
76
+ fontName,
77
+ fontSize,
78
+ fontWeight
79
+ } = _ref3;
80
+ return applyTextStyles({
81
+ fontColor: textColor,
82
+ fontName,
83
+ fontSize,
84
+ fontWeight,
85
+ lineHeight: Platform.OS === 'web' ? textLineHeight : textLineHeight * 1.2,
86
+ marginLeft: 8
87
+ });
88
+ };
89
+
90
+ /**
91
+ * Status component displays a status indicator with optional custom gradient.
92
+ *
93
+ * @component
94
+ * @param {object} tokens - The tokens for customizing the status component.
95
+ * @param {string} variant - The variant of the status component.
96
+ * @param {ReactNode} children - The content to be displayed inside the status component.
97
+ * @param {function} customGradient - The custom gradient function for the status component.
98
+ * @param {object} rest - The rest of the props to be applied to the status component.
99
+ * @param {React.Ref} ref - The ref to be applied to the status component.
100
+ * @returns {ReactNode} The rendered status component.
101
+ */
102
+ const Status = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
103
+ let {
104
+ tokens,
105
+ variant,
106
+ children,
107
+ customGradient,
108
+ ...rest
109
+ } = _ref4;
110
+ const themeTokens = useThemeTokens('Status', tokens, variant);
111
+ const containerStyles = {
112
+ ...selectContainerStyles(themeTokens),
113
+ ...staticStyles.container
114
+ };
115
+ let content = /*#__PURE__*/_jsxs(_Fragment, {
116
+ children: [/*#__PURE__*/_jsx(Icon, {
117
+ ...selectIconProps(themeTokens)
118
+ }), wrapStringsInText(children, {
119
+ style: selectTextStyles(themeTokens)
120
+ })]
121
+ });
122
+ if (typeof customGradient === 'function') {
123
+ content = customGradient(containerStyles.gradient, containerStyles, content);
124
+ }
125
+ return /*#__PURE__*/_jsx(View, {
126
+ ref: ref,
127
+ style: containerStyles,
128
+ ...selectProps(rest),
129
+ children: content
130
+ });
131
+ });
132
+ Status.displayName = 'Status';
133
+ Status.propTypes = {
134
+ ...selectedSystemPropTypes,
135
+ tokens: getTokensPropType('Status'),
136
+ variant: variantProp.propType,
137
+ /**
138
+ * The content to be displayed inside the status component.
139
+ */
140
+ children: PropTypes.node.isRequired,
141
+ /**
142
+ * The custom gradient function for the status component.
143
+ */
144
+ customGradient: PropTypes.func
145
+ };
146
+ const staticStyles = StyleSheet.create({
147
+ container: {
148
+ flexDirection: 'row',
149
+ alignItems: 'center',
150
+ ...Platform.select({
151
+ web: {
152
+ display: 'inline-flex',
153
+ width: 'fit-content'
154
+ },
155
+ default: {
156
+ display: 'flex',
157
+ width: 'auto'
158
+ }
159
+ })
160
+ }
161
+ });
162
+ export default Status;
@@ -0,0 +1,2 @@
1
+ import Status from './Status';
2
+ export default Status;
@@ -53,6 +53,7 @@ export { default as SkipLink } from './SkipLink';
53
53
  export { default as Spacer } from './Spacer';
54
54
  export { default as StackView } from './StackView';
55
55
  export * from './StackView';
56
+ export { default as Status } from './Status';
56
57
  export { default as StepTracker } from './StepTracker';
57
58
  export { default as Tabs } from './Tabs';
58
59
  export { default as Tags } from './Tags';
@@ -19,4 +19,5 @@ export { default as withLinkRouter } from './withLinkRouter';
19
19
  export * from './ssr';
20
20
  export { default as containUniqueFields } from './containUniqueFields';
21
21
  export { default as BaseView } from './BaseView';
22
- export { default as htmlAttrs } from './htmlAttrs';
22
+ export { default as htmlAttrs } from './htmlAttrs';
23
+ export { transformGradient } from './transformGradient';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Transforms a gradient object into a CSS gradient string.
3
+ *
4
+ * @param {Object} gradient - The gradient object to transform.
5
+ * @param {string} gradient.type - The type of gradient (linear or radial).
6
+ * @param {number} gradient.angle - The angle of the linear gradient in degrees.
7
+ * @param {Array} gradient.stops - An array of gradient stops.
8
+ * @param {string} gradient.stops[].color - The color of the gradient stop.
9
+ * @param {number} gradient.stops[].stop - The position of the gradient stop as a percentage.
10
+ * @returns {string} The CSS gradient string.
11
+ */
12
+ export const transformGradient = gradient => `${gradient.type}-gradient(${gradient.angle}deg, ${gradient.stops[0].color} ${gradient.stops[0].stop * 100}%, ${gradient.stops[1].color} ${gradient.stops[1].stop * 100}%)`;
13
+ export default {
14
+ transformGradient
15
+ };
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "@floating-ui/react-native": "^0.8.1",
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@telus-uds/system-constants": "^1.3.0",
14
- "@telus-uds/system-theme-tokens": "^2.59.0",
14
+ "@telus-uds/system-theme-tokens": "^2.60.0",
15
15
  "airbnb-prop-types": "^2.16.0",
16
16
  "css-mediaquery": "^0.1.2",
17
17
  "expo-linear-gradient": "^12.5.0",
@@ -85,6 +85,6 @@
85
85
  "standard-engine": {
86
86
  "skip": true
87
87
  },
88
- "version": "1.89.0",
88
+ "version": "1.90.0",
89
89
  "types": "types/index.d.ts"
90
90
  }
@@ -276,7 +276,7 @@ const ButtonBase = React.forwardRef(
276
276
  <IconText
277
277
  icon={IconComponent}
278
278
  iconPosition={iconPosition}
279
- space={iconSpace}
279
+ space={icon ? iconSpace : 0}
280
280
  iconProps={{ ...iconProps, tokens: iconTokens }}
281
281
  >
282
282
  {wrapStringsInText(
@@ -616,12 +616,7 @@ const Carousel = React.forwardRef(
616
616
  const systemProps = selectProps({
617
617
  ...rest,
618
618
  accessibilityRole,
619
- accessibilityLabel,
620
- accessibilityValue: {
621
- min: 1,
622
- max: childrenArray.length,
623
- now: activeIndex + 1
624
- }
619
+ accessibilityLabel
625
620
  })
626
621
 
627
622
  // If container isn't used for focus, give it a label of title if none is passed in,
@@ -0,0 +1,142 @@
1
+ import React from 'react'
2
+ import { Platform, StyleSheet, View } from 'react-native'
3
+ import PropTypes from 'prop-types'
4
+
5
+ import { useThemeTokens, applyTextStyles } from '../ThemeProvider'
6
+ import {
7
+ a11yProps,
8
+ getTokensPropType,
9
+ selectSystemProps,
10
+ variantProp,
11
+ viewProps,
12
+ wrapStringsInText,
13
+ transformGradient
14
+ } from '../utils'
15
+
16
+ import Icon from '../Icon'
17
+
18
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
19
+
20
+ const selectContainerStyles = ({
21
+ backgroundColor,
22
+ backgroundGradient,
23
+ borderColor,
24
+ borderRadius,
25
+ borderWidth,
26
+ paddingBottom,
27
+ paddingLeft,
28
+ paddingRight,
29
+ paddingTop
30
+ }) => {
31
+ const styles = {
32
+ borderColor,
33
+ borderRadius,
34
+ borderWidth,
35
+ paddingBottom,
36
+ paddingLeft,
37
+ paddingRight,
38
+ paddingTop
39
+ }
40
+
41
+ if (backgroundGradient) {
42
+ if (Platform.OS === 'web') {
43
+ styles.background = transformGradient(backgroundGradient)
44
+ } else {
45
+ const {
46
+ stops: [stopOne, stopTwo]
47
+ } = backgroundGradient
48
+ styles.gradient = {}
49
+ styles.gradient.start = { x: 0, y: 0 }
50
+ styles.gradient.end = { x: 1, y: 1 }
51
+ styles.gradient.colors = [stopOne.color, stopTwo.color]
52
+ }
53
+ } else {
54
+ styles.backgroundColor = backgroundColor
55
+ }
56
+
57
+ return styles
58
+ }
59
+
60
+ const selectIconProps = ({ icon, iconColor }) => ({
61
+ icon,
62
+ tokens: { color: iconColor },
63
+ variant: { size: 'small' }
64
+ })
65
+
66
+ const selectTextStyles = ({ textColor, textLineHeight, fontName, fontSize, fontWeight }) =>
67
+ applyTextStyles({
68
+ fontColor: textColor,
69
+ fontName,
70
+ fontSize,
71
+ fontWeight,
72
+ lineHeight: Platform.OS === 'web' ? textLineHeight : textLineHeight * 1.2,
73
+ marginLeft: 8
74
+ })
75
+
76
+ /**
77
+ * Status component displays a status indicator with optional custom gradient.
78
+ *
79
+ * @component
80
+ * @param {object} tokens - The tokens for customizing the status component.
81
+ * @param {string} variant - The variant of the status component.
82
+ * @param {ReactNode} children - The content to be displayed inside the status component.
83
+ * @param {function} customGradient - The custom gradient function for the status component.
84
+ * @param {object} rest - The rest of the props to be applied to the status component.
85
+ * @param {React.Ref} ref - The ref to be applied to the status component.
86
+ * @returns {ReactNode} The rendered status component.
87
+ */
88
+ const Status = React.forwardRef(({ tokens, variant, children, customGradient, ...rest }, ref) => {
89
+ const themeTokens = useThemeTokens('Status', tokens, variant)
90
+ const containerStyles = { ...selectContainerStyles(themeTokens), ...staticStyles.container }
91
+
92
+ let content = (
93
+ <>
94
+ <Icon {...selectIconProps(themeTokens)} />
95
+ {wrapStringsInText(children, { style: selectTextStyles(themeTokens) })}
96
+ </>
97
+ )
98
+ if (typeof customGradient === 'function') {
99
+ content = customGradient(containerStyles.gradient, containerStyles, content)
100
+ }
101
+
102
+ return (
103
+ <View ref={ref} style={containerStyles} {...selectProps(rest)}>
104
+ {content}
105
+ </View>
106
+ )
107
+ })
108
+
109
+ Status.displayName = 'Status'
110
+
111
+ Status.propTypes = {
112
+ ...selectedSystemPropTypes,
113
+ tokens: getTokensPropType('Status'),
114
+ variant: variantProp.propType,
115
+ /**
116
+ * The content to be displayed inside the status component.
117
+ */
118
+ children: PropTypes.node.isRequired,
119
+ /**
120
+ * The custom gradient function for the status component.
121
+ */
122
+ customGradient: PropTypes.func
123
+ }
124
+
125
+ const staticStyles = StyleSheet.create({
126
+ container: {
127
+ flexDirection: 'row',
128
+ alignItems: 'center',
129
+ ...Platform.select({
130
+ web: {
131
+ display: 'inline-flex',
132
+ width: 'fit-content'
133
+ },
134
+ default: {
135
+ display: 'flex',
136
+ width: 'auto'
137
+ }
138
+ })
139
+ }
140
+ })
141
+
142
+ export default Status
@@ -0,0 +1,3 @@
1
+ import Status from './Status'
2
+
3
+ export default Status
package/src/index.js CHANGED
@@ -53,6 +53,7 @@ export { default as SkipLink } from './SkipLink'
53
53
  export { default as Spacer } from './Spacer'
54
54
  export { default as StackView } from './StackView'
55
55
  export * from './StackView'
56
+ export { default as Status } from './Status'
56
57
  export { default as StepTracker } from './StepTracker'
57
58
  export { default as Tabs } from './Tabs'
58
59
  export { default as Tags } from './Tags'
@@ -20,3 +20,4 @@ export * from './ssr'
20
20
  export { default as containUniqueFields } from './containUniqueFields'
21
21
  export { default as BaseView } from './BaseView'
22
22
  export { default as htmlAttrs } from './htmlAttrs'
23
+ export { transformGradient } from './transformGradient'
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Transforms a gradient object into a CSS gradient string.
3
+ *
4
+ * @param {Object} gradient - The gradient object to transform.
5
+ * @param {string} gradient.type - The type of gradient (linear or radial).
6
+ * @param {number} gradient.angle - The angle of the linear gradient in degrees.
7
+ * @param {Array} gradient.stops - An array of gradient stops.
8
+ * @param {string} gradient.stops[].color - The color of the gradient stop.
9
+ * @param {number} gradient.stops[].stop - The position of the gradient stop as a percentage.
10
+ * @returns {string} The CSS gradient string.
11
+ */
12
+ export const transformGradient = (gradient) =>
13
+ `${gradient.type}-gradient(${gradient.angle}deg, ${gradient.stops[0].color} ${
14
+ gradient.stops[0].stop * 100
15
+ }%, ${gradient.stops[1].color} ${gradient.stops[1].stop * 100}%)`
16
+
17
+ export default { transformGradient }