@telus-uds/components-base 1.80.0 → 1.81.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 (49) hide show
  1. package/CHANGELOG.md +25 -2
  2. package/lib/Autocomplete/Autocomplete.js +1 -1
  3. package/lib/Badge/Badge.js +1 -10
  4. package/lib/Fieldset/Fieldset.js +3 -1
  5. package/lib/Fieldset/FieldsetContainer.js +9 -2
  6. package/lib/Fieldset/FieldsetContainer.native.js +7 -1
  7. package/lib/FlexGrid/FlexGrid.js +6 -3
  8. package/lib/Listbox/ListboxOverlay.js +2 -2
  9. package/lib/Portal/Portal.js +57 -0
  10. package/lib/Portal/Portal.native.js +9 -0
  11. package/lib/Portal/index.js +10 -0
  12. package/lib/TextInput/TextInput.js +1 -0
  13. package/lib/TextInput/TextInputBase.js +5 -2
  14. package/lib/index.js +2 -2
  15. package/lib/utils/ssr-media-query/create-stylesheet/index.js +2 -1
  16. package/lib/utils/ssr-media-query/utils/common.js +21 -2
  17. package/lib-module/Autocomplete/Autocomplete.js +1 -1
  18. package/lib-module/Badge/Badge.js +1 -10
  19. package/lib-module/Fieldset/Fieldset.js +3 -1
  20. package/lib-module/Fieldset/FieldsetContainer.js +7 -2
  21. package/lib-module/Fieldset/FieldsetContainer.native.js +10 -3
  22. package/lib-module/FlexGrid/FlexGrid.js +6 -3
  23. package/lib-module/Listbox/ListboxOverlay.js +1 -1
  24. package/lib-module/Portal/Portal.js +50 -0
  25. package/lib-module/Portal/Portal.native.js +2 -0
  26. package/lib-module/Portal/index.js +2 -0
  27. package/lib-module/TextInput/TextInput.js +1 -0
  28. package/lib-module/TextInput/TextInputBase.js +5 -2
  29. package/lib-module/index.js +1 -1
  30. package/lib-module/utils/ssr-media-query/create-stylesheet/index.js +3 -2
  31. package/lib-module/utils/ssr-media-query/utils/common.js +19 -1
  32. package/package.json +1 -1
  33. package/src/Autocomplete/Autocomplete.jsx +1 -1
  34. package/src/Badge/Badge.jsx +7 -10
  35. package/src/Fieldset/Fieldset.jsx +3 -1
  36. package/src/Fieldset/FieldsetContainer.jsx +8 -1
  37. package/src/Fieldset/FieldsetContainer.native.jsx +7 -2
  38. package/src/FlexGrid/FlexGrid.jsx +4 -6
  39. package/src/Listbox/ListboxOverlay.jsx +1 -1
  40. package/src/Portal/Portal.jsx +52 -0
  41. package/src/Portal/Portal.native.jsx +3 -0
  42. package/src/Portal/index.js +3 -0
  43. package/src/TextInput/TextInput.jsx +1 -0
  44. package/src/TextInput/TextInputBase.jsx +5 -2
  45. package/src/index.js +1 -1
  46. package/src/utils/ssr-media-query/create-stylesheet/index.js +3 -2
  47. package/src/utils/ssr-media-query/utils/common.js +19 -1
  48. package/types/Portal.d.ts +5 -0
  49. package/types/index.d.ts +3 -0
package/CHANGELOG.md CHANGED
@@ -1,12 +1,35 @@
1
1
  # Change Log - @telus-uds/components-base
2
2
 
3
- This log was last generated on Tue, 12 Mar 2024 22:22:38 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 27 Mar 2024 21:09:55 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 1.81.0
8
+
9
+ Wed, 27 Mar 2024 21:09:55 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - add test-id prop to radio-group component (guillermo.peitzner@telus.com)
14
+
15
+ ### Patches
16
+
17
+ - SSR: sanitize function values in CSS styles (guillermo.peitzner@telus.com)
18
+ - validation added to the datepicker input and input cleaned after the content is deleted (35577399+JoshHC@users.noreply.github.com)
19
+
20
+ ## 1.80.1
21
+
22
+ Tue, 19 Mar 2024 18:39:50 GMT
23
+
24
+ ### Patches
25
+
26
+ - prevent flexgrid dataset property to be overruled (guillermo.peitzner@telus.com)
27
+ - `Autocomplete`: Component breaks on Android because of type-casting (shahzaibkhalidmalik@outlook.com)
28
+ - `Autocomplete`: Overlay does not render next to `TextInput` (shahzaibkhalidmalik@outlook.com)
29
+
7
30
  ## 1.80.0
8
31
 
9
- Tue, 12 Mar 2024 22:22:38 GMT
32
+ Tue, 12 Mar 2024 22:26:51 GMT
10
33
 
11
34
  ### Minor changes
12
35
 
@@ -193,7 +193,7 @@ const Autocomplete = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
193
193
  const throttledUpdateInputWidth = (0, _lodash.default)(updateInputWidth, 100, {
194
194
  leading: false
195
195
  });
196
- updateInputWidth();
196
+ throttledUpdateInputWidth();
197
197
  _Dimensions.default.addEventListener('change', throttledUpdateInputWidth);
198
198
  return () => {
199
199
  _Dimensions.default.removeEventListener('change', throttledUpdateInputWidth);
@@ -7,7 +7,6 @@ exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
9
9
  var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
10
- var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
11
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
12
11
  var _ThemeProvider = require("../ThemeProvider");
13
12
  var _Typography = _interopRequireDefault(require("../Typography"));
@@ -86,15 +85,7 @@ const Badge = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
86
85
  const themeTokens = (0, _ThemeProvider.useThemeTokens)('Badge', tokens, variant);
87
86
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
88
87
  ref: ref,
89
- style: _Platform.default.select({
90
- native: {
91
- ...staticStyles.container,
92
- ...selectContainerBackground(themeTokens),
93
- ...selectContainerBorder(themeTokens),
94
- ...selectContainerPadding(themeTokens)
95
- },
96
- web: {}
97
- }),
88
+ style: [staticStyles.container, selectContainerBackground(themeTokens), selectContainerBorder(themeTokens), selectContainerPadding(themeTokens)],
98
89
  ...selectProps(rest),
99
90
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
100
91
  tokens: getTypographyTokens(themeTokens),
@@ -40,7 +40,8 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
40
40
  name: fieldsetName,
41
41
  children,
42
42
  variant = {},
43
- tokens = {}
43
+ tokens = {},
44
+ ...rest
44
45
  } = _ref;
45
46
  /* Fieldset tokenization:
46
47
  - error variant can only be activated by passing showErrorBorder and also having validaton as 'error'
@@ -126,6 +127,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
126
127
  name: fieldsetName,
127
128
  borderStyle: borderStyles(themeTokens),
128
129
  showBorderStyle: showErrorBorder,
130
+ ...rest,
129
131
  children: stackedContent
130
132
  });
131
133
  });
@@ -7,20 +7,25 @@ exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _cssReset = _interopRequireDefault(require("./cssReset"));
10
+ var _utils = require("../utils");
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
13
  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); }
13
14
  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; }
15
+ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.htmlAttrs]);
16
+
14
17
  /**
15
18
  * On Web, wraps children with a HTML `<fieldset>` and sets its attributes as necessary.
16
- */const FieldsetContainer = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
19
+ */
20
+ const FieldsetContainer = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
17
21
  let {
18
22
  children,
19
23
  inactive,
20
24
  accessibilityRole,
21
25
  name: fieldsetName,
22
26
  showBorderStyle = false,
23
- borderStyle
27
+ borderStyle,
28
+ ...rest
24
29
  } = _ref;
25
30
  // If needs border for error design or reset the component style
26
31
  const styleContainer = showBorderStyle && borderStyle ? borderStyle : _cssReset.default;
@@ -30,11 +35,13 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
30
35
  style: styleContainer,
31
36
  role: accessibilityRole,
32
37
  name: fieldsetName,
38
+ ...selectProps(rest),
33
39
  children: children
34
40
  });
35
41
  });
36
42
  FieldsetContainer.displayName = 'FieldsetContainer';
37
43
  FieldsetContainer.propTypes = {
44
+ ...selectedSystemPropTypes,
38
45
  accessibilityRole: _propTypes.default.string,
39
46
  children: _propTypes.default.node,
40
47
  inactive: _propTypes.default.bool,
@@ -7,25 +7,31 @@ exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
10
+ var _utils = require("../utils");
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
13
  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); }
13
14
  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; }
15
+ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
16
+
14
17
  // No equivalent of `<fieldset>` on native, so just apply accessibility role to container.
15
18
  // If a11y testing finds any additional handling is needed at the container level, add it here.
16
19
  const FieldsetContainer = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
17
20
  let {
18
21
  children,
19
- accessibilityRole
22
+ accessibilityRole,
23
+ ...rest
20
24
  } = _ref;
21
25
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
22
26
  ref: ref,
23
27
  accessibilityRole: accessibilityRole,
28
+ ...selectProps(rest),
24
29
  children: children
25
30
  });
26
31
  });
27
32
  FieldsetContainer.displayName = 'FieldsetContainer';
28
33
  FieldsetContainer.propTypes = {
34
+ ...selectedSystemPropTypes,
29
35
  children: _propTypes.default.node,
30
36
  accessibilityRole: _propTypes.default.string
31
37
  };
@@ -37,6 +37,7 @@ const FlexGrid = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
37
37
  tag,
38
38
  accessibilityRole,
39
39
  children,
40
+ dataSet,
40
41
  ...rest
41
42
  } = _ref;
42
43
  const reverseLevel = (0, _helpers.default)([xsReverse, smReverse, mdReverse, lgReverse, xlReverse]);
@@ -99,15 +100,17 @@ const FlexGrid = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
99
100
  ...(0, _utils.getA11yPropsFromHtmlTag)(tag, accessibilityRole),
100
101
  ...selectProps(rest)
101
102
  };
103
+ const dataSetValue = mediaIds ? {
104
+ media: mediaIds,
105
+ ...dataSet
106
+ } : dataSet;
102
107
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_GutterContext.default.Provider, {
103
108
  value: gutter,
104
109
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_utils.BaseView, {
105
110
  ref: ref,
106
111
  ...props,
107
112
  style: flexgridStyles,
108
- dataSet: mediaIds && {
109
- media: mediaIds
110
- },
113
+ dataSet: dataSetValue,
111
114
  children: children
112
115
  })
113
116
  });
@@ -9,7 +9,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
10
10
  var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
11
11
  var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
12
- var _portal = require("@gorhom/portal");
12
+ var _Portal = _interopRequireDefault(require("../Portal"));
13
13
  var _ThemeProvider = require("../ThemeProvider");
14
14
  var _Card = _interopRequireDefault(require("../Card"));
15
15
  var _jsxRuntime = require("react/jsx-runtime");
@@ -66,7 +66,7 @@ const DropdownOverlay = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
66
66
  const withPortal = Overlay => {
67
67
  // eslint-disable-next-line react/display-name, react/no-multi-comp
68
68
  return props => {
69
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_portal.Portal, {
69
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Portal.default, {
70
70
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Overlay, {
71
71
  ...props
72
72
  })
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = require("react");
8
+ var _reactDom = _interopRequireDefault(require("react-dom"));
9
+ var _propTypes = _interopRequireDefault(require("prop-types"));
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ /**
12
+ * Portal component renders its children in a separate portal container appended to the document body.
13
+ *
14
+ * While `@gorhom/portal` works well for a lot of use-cases, there are some issues with it, particularly around
15
+ * reading context values (see issues below). For web-only components, it is safe to replace `Portal` from `@gorhom/portal`
16
+ * to `Portal` to solve such issues
17
+ *
18
+ * https://github.com/gorhom/react-native-portal/issues/34
19
+ * https://github.com/gorhom/react-native-portal/issues/2
20
+ * https://github.com/gorhom/react-native-portal/issues/3
21
+ * https://github.com/gorhom/react-native-portal/issues/31
22
+ *
23
+ * @component
24
+ * @param {object} props - The component props.
25
+ * @param {React.ReactNode} props.children - The content to render within the portal.
26
+ * @returns {React.ReactPortal} The React portal component.
27
+ */
28
+
29
+ const Portal = _ref => {
30
+ let {
31
+ children
32
+ } = _ref;
33
+ const [portalContainer, setPortalContainer] = (0, _react.useState)(null);
34
+ const isWebClient = typeof document !== 'undefined' && typeof window !== 'undefined';
35
+ (0, _react.useEffect)(() => {
36
+ if (!isWebClient) {
37
+ return;
38
+ }
39
+ const container = document.createElement('div');
40
+ document.body.appendChild(container);
41
+ setPortalContainer(container);
42
+
43
+ // eslint-disable-next-line consistent-return
44
+ return () => {
45
+ if (container && container.parentNode) {
46
+ container.parentNode.removeChild(container);
47
+ }
48
+ };
49
+ }, [isWebClient]);
50
+ if (!portalContainer || !isWebClient) return null;
51
+ return /*#__PURE__*/_reactDom.default.createPortal(children, portalContainer);
52
+ };
53
+ Portal.propTypes = {
54
+ children: _propTypes.default.node.isRequired
55
+ };
56
+ var _default = Portal;
57
+ exports.default = _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _portal = require("@gorhom/portal");
8
+ var _default = _portal.Portal;
9
+ 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 _Portal = _interopRequireDefault(require("./Portal"));
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+ var _default = _Portal.default;
10
+ exports.default = _default;
@@ -80,6 +80,7 @@ TextInput.propTypes = {
80
80
  * A callback which if provided will get a clear button rendered and will be called whenever that button gets pressed.
81
81
  */
82
82
  onClear: _propTypes.default.func,
83
+ onKeyPress: _propTypes.default.func,
83
84
  tokens: (0, _utils.getTokensPropType)('TextInput'),
84
85
  variant: _utils.variantProp.propType
85
86
  };
@@ -203,6 +203,7 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref7, ref) => {
203
203
  value,
204
204
  variant = {},
205
205
  type,
206
+ onKeyPress,
206
207
  ...rest
207
208
  } = _ref7;
208
209
  const [isFocused, setIsFocused] = (0, _react.useState)(false);
@@ -335,7 +336,8 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref7, ref) => {
335
336
  onChange: handleChangeText,
336
337
  defaultValue: initialValue,
337
338
  maxLength: type === 'card' ? 19 : undefined,
338
- value: isControlled ? currentValue : undefined
339
+ value: isControlled ? currentValue : undefined,
340
+ onKeyPress
339
341
  };
340
342
  const {
341
343
  themeOptions
@@ -357,7 +359,7 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref7, ref) => {
357
359
  })
358
360
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextInput.default, {
359
361
  ref: inputRef,
360
- keyboardType: isNumeric && 'numeric',
362
+ keyboardType: isNumeric ? 'numeric' : 'default',
361
363
  inputMode: isNumeric && 'numeric',
362
364
  style: nativeInputStyle,
363
365
  secureTextEntry: isPassword && !showPassword,
@@ -404,6 +406,7 @@ TextInputBase.propTypes = {
404
406
  onFocus: _propTypes.default.func,
405
407
  onMouseOut: _propTypes.default.func,
406
408
  onMouseOver: _propTypes.default.func,
409
+ onKeyPress: _propTypes.default.func,
407
410
  readOnly: _propTypes.default.bool,
408
411
  tokens: (0, _utils.getTokensPropType)('TextInput', 'TextArea'),
409
412
  value: _propTypes.default.string,
package/lib/index.js CHANGED
@@ -277,7 +277,7 @@ Object.defineProperty(exports, "Pagination", {
277
277
  Object.defineProperty(exports, "Portal", {
278
278
  enumerable: true,
279
279
  get: function () {
280
- return _portal.Portal;
280
+ return _Portal.default;
281
281
  }
282
282
  });
283
283
  Object.defineProperty(exports, "PressableCardBase", {
@@ -695,7 +695,7 @@ Object.keys(_utils).forEach(function (key) {
695
695
  }
696
696
  });
697
697
  });
698
- var _portal = require("@gorhom/portal");
698
+ var _Portal = _interopRequireDefault(require("./Portal"));
699
699
  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); }
700
700
  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; }
701
701
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -22,7 +22,8 @@ const createStyleSheet = stylesWithQuery => {
22
22
  const mediaQueriesAndPseudoClasses = Object.keys(stylesWithQuery[key]).filter(_common.isMediaOrPseudo);
23
23
  mediaQueriesAndPseudoClasses.forEach(query => {
24
24
  var _ids;
25
- const css = (0, _createDeclarationBlock.default)(stylesWithQuery[key][query]);
25
+ const sanitizedStyle = (0, _common.sanitizeStyle)(stylesWithQuery[key][query]);
26
+ const css = (0, _createDeclarationBlock.default)(sanitizedStyle);
26
27
  const stringHash = `rnmq-${(0, _hash.default)(`${key}${query}${css}`)}`;
27
28
  const rule = (0, _common.createCssRule)(query, stringHash, css);
28
29
  (0, _inject.addCss)(`${stringHash}`, rule);
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isPseudo = exports.isMediaOrPseudo = exports.isMedia = exports.deepClone = exports.createCssRule = void 0;
6
+ exports.sanitizeStyle = exports.isPseudo = exports.isMediaOrPseudo = exports.isMedia = exports.deepClone = exports.createCssRule = void 0;
7
7
  const isMedia = query => query.indexOf('@media') === 0;
8
8
  exports.isMedia = isMedia;
9
9
  const isPseudo = query => query.indexOf(':') === 0;
@@ -22,4 +22,23 @@ const createCssRule = (query, stringHash, css) => {
22
22
  }
23
23
  return rule;
24
24
  };
25
- exports.createCssRule = createCssRule;
25
+
26
+ /**
27
+ * Sanitizes the style object by converting any functions to their string representation.
28
+ *
29
+ * @param {Object} style - The style object to sanitize.
30
+ * @returns {Object} - The sanitized style object.
31
+ */
32
+ exports.createCssRule = createCssRule;
33
+ const sanitizeStyle = style => {
34
+ const sanitizedStyle = {
35
+ ...style
36
+ };
37
+ Object.keys(sanitizedStyle).forEach(property => {
38
+ if (typeof sanitizedStyle[property] === 'function') {
39
+ sanitizedStyle[property] = sanitizedStyle[property].toString();
40
+ }
41
+ });
42
+ return sanitizedStyle;
43
+ };
44
+ exports.sanitizeStyle = sanitizeStyle;
@@ -185,7 +185,7 @@ const Autocomplete = /*#__PURE__*/forwardRef((_ref2, ref) => {
185
185
  const throttledUpdateInputWidth = throttle(updateInputWidth, 100, {
186
186
  leading: false
187
187
  });
188
- updateInputWidth();
188
+ throttledUpdateInputWidth();
189
189
  Dimensions.addEventListener('change', throttledUpdateInputWidth);
190
190
  return () => {
191
191
  Dimensions.removeEventListener('change', throttledUpdateInputWidth);
@@ -1,7 +1,6 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import View from "react-native-web/dist/exports/View";
3
3
  import StyleSheet from "react-native-web/dist/exports/StyleSheet";
4
- import Platform from "react-native-web/dist/exports/Platform";
5
4
  import PropTypes from 'prop-types';
6
5
  import { useThemeTokens } from '../ThemeProvider';
7
6
  import Typography from '../Typography';
@@ -77,15 +76,7 @@ const Badge = /*#__PURE__*/forwardRef((_ref6, ref) => {
77
76
  const themeTokens = useThemeTokens('Badge', tokens, variant);
78
77
  return /*#__PURE__*/_jsx(View, {
79
78
  ref: ref,
80
- style: Platform.select({
81
- native: {
82
- ...staticStyles.container,
83
- ...selectContainerBackground(themeTokens),
84
- ...selectContainerBorder(themeTokens),
85
- ...selectContainerPadding(themeTokens)
86
- },
87
- web: {}
88
- }),
79
+ style: [staticStyles.container, selectContainerBackground(themeTokens), selectContainerBorder(themeTokens), selectContainerPadding(themeTokens)],
89
80
  ...selectProps(rest),
90
81
  children: /*#__PURE__*/_jsx(Typography, {
91
82
  tokens: getTypographyTokens(themeTokens),
@@ -34,7 +34,8 @@ const Fieldset = /*#__PURE__*/forwardRef((_ref, ref) => {
34
34
  name: fieldsetName,
35
35
  children,
36
36
  variant = {},
37
- tokens = {}
37
+ tokens = {},
38
+ ...rest
38
39
  } = _ref;
39
40
  /* Fieldset tokenization:
40
41
  - error variant can only be activated by passing showErrorBorder and also having validaton as 'error'
@@ -120,6 +121,7 @@ const Fieldset = /*#__PURE__*/forwardRef((_ref, ref) => {
120
121
  name: fieldsetName,
121
122
  borderStyle: borderStyles(themeTokens),
122
123
  showBorderStyle: showErrorBorder,
124
+ ...rest,
123
125
  children: stackedContent
124
126
  });
125
127
  });
@@ -1,11 +1,13 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import cssReset from './cssReset';
4
+ import { selectSystemProps, a11yProps, htmlAttrs } from '../utils';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, htmlAttrs]);
4
7
 
5
8
  /**
6
9
  * On Web, wraps children with a HTML `<fieldset>` and sets its attributes as necessary.
7
10
  */
8
- import { jsx as _jsx } from "react/jsx-runtime";
9
11
  const FieldsetContainer = /*#__PURE__*/forwardRef((_ref, ref) => {
10
12
  let {
11
13
  children,
@@ -13,7 +15,8 @@ const FieldsetContainer = /*#__PURE__*/forwardRef((_ref, ref) => {
13
15
  accessibilityRole,
14
16
  name: fieldsetName,
15
17
  showBorderStyle = false,
16
- borderStyle
18
+ borderStyle,
19
+ ...rest
17
20
  } = _ref;
18
21
  // If needs border for error design or reset the component style
19
22
  const styleContainer = showBorderStyle && borderStyle ? borderStyle : cssReset;
@@ -23,11 +26,13 @@ const FieldsetContainer = /*#__PURE__*/forwardRef((_ref, ref) => {
23
26
  style: styleContainer,
24
27
  role: accessibilityRole,
25
28
  name: fieldsetName,
29
+ ...selectProps(rest),
26
30
  children: children
27
31
  });
28
32
  });
29
33
  FieldsetContainer.displayName = 'FieldsetContainer';
30
34
  FieldsetContainer.propTypes = {
35
+ ...selectedSystemPropTypes,
31
36
  accessibilityRole: PropTypes.string,
32
37
  children: PropTypes.node,
33
38
  inactive: PropTypes.bool,
@@ -1,21 +1,28 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import View from "react-native-web/dist/exports/View"; // No equivalent of `<fieldset>` on native, so just apply accessibility role to container.
4
- // If a11y testing finds any additional handling is needed at the container level, add it here.
3
+ import View from "react-native-web/dist/exports/View";
4
+ import { selectSystemProps, a11yProps, viewProps } from '../utils';
5
5
  import { jsx as _jsx } from "react/jsx-runtime";
6
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
7
+
8
+ // No equivalent of `<fieldset>` on native, so just apply accessibility role to container.
9
+ // If a11y testing finds any additional handling is needed at the container level, add it here.
6
10
  const FieldsetContainer = /*#__PURE__*/forwardRef((_ref, ref) => {
7
11
  let {
8
12
  children,
9
- accessibilityRole
13
+ accessibilityRole,
14
+ ...rest
10
15
  } = _ref;
11
16
  return /*#__PURE__*/_jsx(View, {
12
17
  ref: ref,
13
18
  accessibilityRole: accessibilityRole,
19
+ ...selectProps(rest),
14
20
  children: children
15
21
  });
16
22
  });
17
23
  FieldsetContainer.displayName = 'FieldsetContainer';
18
24
  FieldsetContainer.propTypes = {
25
+ ...selectedSystemPropTypes,
19
26
  children: PropTypes.node,
20
27
  accessibilityRole: PropTypes.string
21
28
  };
@@ -28,6 +28,7 @@ const FlexGrid = /*#__PURE__*/forwardRef((_ref, ref) => {
28
28
  tag,
29
29
  accessibilityRole,
30
30
  children,
31
+ dataSet,
31
32
  ...rest
32
33
  } = _ref;
33
34
  const reverseLevel = applyInheritance([xsReverse, smReverse, mdReverse, lgReverse, xlReverse]);
@@ -90,15 +91,17 @@ const FlexGrid = /*#__PURE__*/forwardRef((_ref, ref) => {
90
91
  ...getA11yPropsFromHtmlTag(tag, accessibilityRole),
91
92
  ...selectProps(rest)
92
93
  };
94
+ const dataSetValue = mediaIds ? {
95
+ media: mediaIds,
96
+ ...dataSet
97
+ } : dataSet;
93
98
  return /*#__PURE__*/_jsx(GutterContext.Provider, {
94
99
  value: gutter,
95
100
  children: /*#__PURE__*/_jsx(BaseView, {
96
101
  ref: ref,
97
102
  ...props,
98
103
  style: flexgridStyles,
99
- dataSet: mediaIds && {
100
- media: mediaIds
101
- },
104
+ dataSet: dataSetValue,
102
105
  children: children
103
106
  })
104
107
  });
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
4
4
  import View from "react-native-web/dist/exports/View";
5
5
  import StyleSheet from "react-native-web/dist/exports/StyleSheet";
6
6
  import Platform from "react-native-web/dist/exports/Platform";
7
- import { Portal } from '@gorhom/portal';
7
+ import Portal from '../Portal';
8
8
  import { useThemeTokens } from '../ThemeProvider';
9
9
  import Card from '../Card';
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -0,0 +1,50 @@
1
+ import { useState, useEffect } from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import PropTypes from 'prop-types';
4
+
5
+ /**
6
+ * Portal component renders its children in a separate portal container appended to the document body.
7
+ *
8
+ * While `@gorhom/portal` works well for a lot of use-cases, there are some issues with it, particularly around
9
+ * reading context values (see issues below). For web-only components, it is safe to replace `Portal` from `@gorhom/portal`
10
+ * to `Portal` to solve such issues
11
+ *
12
+ * https://github.com/gorhom/react-native-portal/issues/34
13
+ * https://github.com/gorhom/react-native-portal/issues/2
14
+ * https://github.com/gorhom/react-native-portal/issues/3
15
+ * https://github.com/gorhom/react-native-portal/issues/31
16
+ *
17
+ * @component
18
+ * @param {object} props - The component props.
19
+ * @param {React.ReactNode} props.children - The content to render within the portal.
20
+ * @returns {React.ReactPortal} The React portal component.
21
+ */
22
+
23
+ const Portal = _ref => {
24
+ let {
25
+ children
26
+ } = _ref;
27
+ const [portalContainer, setPortalContainer] = useState(null);
28
+ const isWebClient = typeof document !== 'undefined' && typeof window !== 'undefined';
29
+ useEffect(() => {
30
+ if (!isWebClient) {
31
+ return;
32
+ }
33
+ const container = document.createElement('div');
34
+ document.body.appendChild(container);
35
+ setPortalContainer(container);
36
+
37
+ // eslint-disable-next-line consistent-return
38
+ return () => {
39
+ if (container && container.parentNode) {
40
+ container.parentNode.removeChild(container);
41
+ }
42
+ };
43
+ }, [isWebClient]);
44
+ if (!portalContainer || !isWebClient) return null;
45
+ return /*#__PURE__*/ReactDOM.createPortal(children, portalContainer);
46
+ };
47
+ Portal.propTypes = {
48
+ children: PropTypes.node.isRequired
49
+ };
50
+ export default Portal;
@@ -0,0 +1,2 @@
1
+ import { Portal } from '@gorhom/portal';
2
+ export default Portal;
@@ -0,0 +1,2 @@
1
+ import Portal from './Portal';
2
+ export default Portal;
@@ -73,6 +73,7 @@ TextInput.propTypes = {
73
73
  * A callback which if provided will get a clear button rendered and will be called whenever that button gets pressed.
74
74
  */
75
75
  onClear: PropTypes.func,
76
+ onKeyPress: PropTypes.func,
76
77
  tokens: getTokensPropType('TextInput'),
77
78
  variant: variantProp.propType
78
79
  };
@@ -195,6 +195,7 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref7, ref) => {
195
195
  value,
196
196
  variant = {},
197
197
  type,
198
+ onKeyPress,
198
199
  ...rest
199
200
  } = _ref7;
200
201
  const [isFocused, setIsFocused] = useState(false);
@@ -327,7 +328,8 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref7, ref) => {
327
328
  onChange: handleChangeText,
328
329
  defaultValue: initialValue,
329
330
  maxLength: type === 'card' ? 19 : undefined,
330
- value: isControlled ? currentValue : undefined
331
+ value: isControlled ? currentValue : undefined,
332
+ onKeyPress
331
333
  };
332
334
  const {
333
335
  themeOptions
@@ -349,7 +351,7 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref7, ref) => {
349
351
  })
350
352
  }), /*#__PURE__*/_jsx(NativeTextInput, {
351
353
  ref: inputRef,
352
- keyboardType: isNumeric && 'numeric',
354
+ keyboardType: isNumeric ? 'numeric' : 'default',
353
355
  inputMode: isNumeric && 'numeric',
354
356
  style: nativeInputStyle,
355
357
  secureTextEntry: isPassword && !showPassword,
@@ -396,6 +398,7 @@ TextInputBase.propTypes = {
396
398
  onFocus: PropTypes.func,
397
399
  onMouseOut: PropTypes.func,
398
400
  onMouseOver: PropTypes.func,
401
+ onKeyPress: PropTypes.func,
399
402
  readOnly: PropTypes.bool,
400
403
  tokens: getTokensPropType('TextInput', 'TextArea'),
401
404
  value: PropTypes.string,
@@ -65,4 +65,4 @@ export { default as Validator } from './Validator';
65
65
  export { default as ViewportProvider, useViewport, ViewportContext } from './ViewportProvider';
66
66
  export { default as ThemeProvider, useTheme, useSetTheme, useThemeTokens, useThemeTokensCallback, getThemeTokens, applyOuterBorder, applyTextStyles, applyShadowToken } from './ThemeProvider';
67
67
  export * from './utils';
68
- export { Portal } from '@gorhom/portal';
68
+ export { default as Portal } from './Portal';
@@ -1,7 +1,7 @@
1
1
  import { addCss } from '../utils/inject';
2
2
  import createDeclarationBlock from '../utils/create-declaration-block';
3
3
  import hash from '../hash';
4
- import { isMediaOrPseudo, deepClone, createCssRule } from '../utils/common';
4
+ import { isMediaOrPseudo, deepClone, createCssRule, sanitizeStyle } from '../utils/common';
5
5
  const createStyleSheet = stylesWithQuery => {
6
6
  if (!stylesWithQuery) return {
7
7
  ids: {},
@@ -15,7 +15,8 @@ const createStyleSheet = stylesWithQuery => {
15
15
  const mediaQueriesAndPseudoClasses = Object.keys(stylesWithQuery[key]).filter(isMediaOrPseudo);
16
16
  mediaQueriesAndPseudoClasses.forEach(query => {
17
17
  var _ids;
18
- const css = createDeclarationBlock(stylesWithQuery[key][query]);
18
+ const sanitizedStyle = sanitizeStyle(stylesWithQuery[key][query]);
19
+ const css = createDeclarationBlock(sanitizedStyle);
19
20
  const stringHash = `rnmq-${hash(`${key}${query}${css}`)}`;
20
21
  const rule = createCssRule(query, stringHash, css);
21
22
  addCss(`${stringHash}`, rule);
@@ -12,4 +12,22 @@ const createCssRule = (query, stringHash, css) => {
12
12
  }
13
13
  return rule;
14
14
  };
15
- export { isMedia, isPseudo, isMediaOrPseudo, deepClone, createCssRule };
15
+
16
+ /**
17
+ * Sanitizes the style object by converting any functions to their string representation.
18
+ *
19
+ * @param {Object} style - The style object to sanitize.
20
+ * @returns {Object} - The sanitized style object.
21
+ */
22
+ const sanitizeStyle = style => {
23
+ const sanitizedStyle = {
24
+ ...style
25
+ };
26
+ Object.keys(sanitizedStyle).forEach(property => {
27
+ if (typeof sanitizedStyle[property] === 'function') {
28
+ sanitizedStyle[property] = sanitizedStyle[property].toString();
29
+ }
30
+ });
31
+ return sanitizedStyle;
32
+ };
33
+ export { isMedia, isPseudo, isMediaOrPseudo, deepClone, createCssRule, sanitizeStyle };
package/package.json CHANGED
@@ -85,6 +85,6 @@
85
85
  "standard-engine": {
86
86
  "skip": true
87
87
  },
88
- "version": "1.80.0",
88
+ "version": "1.81.0",
89
89
  "types": "types/index.d.ts"
90
90
  }
@@ -167,7 +167,7 @@ const Autocomplete = forwardRef(
167
167
 
168
168
  const throttledUpdateInputWidth = throttle(updateInputWidth, 100, { leading: false })
169
169
 
170
- updateInputWidth()
170
+ throttledUpdateInputWidth()
171
171
 
172
172
  Dimensions.addEventListener('change', throttledUpdateInputWidth)
173
173
 
@@ -1,5 +1,5 @@
1
1
  import React, { forwardRef } from 'react'
2
- import { View, StyleSheet, Platform } from 'react-native'
2
+ import { View, StyleSheet } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
4
  import { useThemeTokens } from '../ThemeProvider'
5
5
  import Typography from '../Typography'
@@ -38,15 +38,12 @@ const Badge = forwardRef(({ children, tokens, variant = {}, ...rest }, ref) => {
38
38
  return (
39
39
  <View
40
40
  ref={ref}
41
- style={Platform.select({
42
- native: {
43
- ...staticStyles.container,
44
- ...selectContainerBackground(themeTokens),
45
- ...selectContainerBorder(themeTokens),
46
- ...selectContainerPadding(themeTokens)
47
- },
48
- web: {}
49
- })}
41
+ style={[
42
+ staticStyles.container,
43
+ selectContainerBackground(themeTokens),
44
+ selectContainerBorder(themeTokens),
45
+ selectContainerPadding(themeTokens)
46
+ ]}
50
47
  {...selectProps(rest)}
51
48
  >
52
49
  <Typography
@@ -34,7 +34,8 @@ const Fieldset = forwardRef(
34
34
  name: fieldsetName,
35
35
  children,
36
36
  variant = {},
37
- tokens = {}
37
+ tokens = {},
38
+ ...rest
38
39
  },
39
40
  ref
40
41
  ) => {
@@ -118,6 +119,7 @@ const Fieldset = forwardRef(
118
119
  name={fieldsetName}
119
120
  borderStyle={borderStyles(themeTokens)}
120
121
  showBorderStyle={showErrorBorder}
122
+ {...rest}
121
123
  >
122
124
  {stackedContent}
123
125
  </FieldsetContainer>
@@ -3,6 +3,10 @@ import PropTypes from 'prop-types'
3
3
 
4
4
  import cssReset from './cssReset'
5
5
 
6
+ import { selectSystemProps, a11yProps, htmlAttrs } from '../utils'
7
+
8
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, htmlAttrs])
9
+
6
10
  /**
7
11
  * On Web, wraps children with a HTML `<fieldset>` and sets its attributes as necessary.
8
12
  */
@@ -14,7 +18,8 @@ const FieldsetContainer = forwardRef(
14
18
  accessibilityRole,
15
19
  name: fieldsetName,
16
20
  showBorderStyle = false,
17
- borderStyle
21
+ borderStyle,
22
+ ...rest
18
23
  },
19
24
  ref
20
25
  ) => {
@@ -28,6 +33,7 @@ const FieldsetContainer = forwardRef(
28
33
  style={styleContainer}
29
34
  role={accessibilityRole}
30
35
  name={fieldsetName}
36
+ {...selectProps(rest)}
31
37
  >
32
38
  {children}
33
39
  </fieldset>
@@ -37,6 +43,7 @@ const FieldsetContainer = forwardRef(
37
43
  FieldsetContainer.displayName = 'FieldsetContainer'
38
44
 
39
45
  FieldsetContainer.propTypes = {
46
+ ...selectedSystemPropTypes,
40
47
  accessibilityRole: PropTypes.string,
41
48
  children: PropTypes.node,
42
49
  inactive: PropTypes.bool,
@@ -2,16 +2,21 @@ import React, { forwardRef } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { View } from 'react-native'
4
4
 
5
+ import { selectSystemProps, a11yProps, viewProps } from '../utils'
6
+
7
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
8
+
5
9
  // No equivalent of `<fieldset>` on native, so just apply accessibility role to container.
6
10
  // If a11y testing finds any additional handling is needed at the container level, add it here.
7
- const FieldsetContainer = forwardRef(({ children, accessibilityRole }, ref) => (
8
- <View ref={ref} accessibilityRole={accessibilityRole}>
11
+ const FieldsetContainer = forwardRef(({ children, accessibilityRole, ...rest }, ref) => (
12
+ <View ref={ref} accessibilityRole={accessibilityRole} {...selectProps(rest)}>
9
13
  {children}
10
14
  </View>
11
15
  ))
12
16
  FieldsetContainer.displayName = 'FieldsetContainer'
13
17
 
14
18
  FieldsetContainer.propTypes = {
19
+ ...selectedSystemPropTypes,
15
20
  children: PropTypes.node,
16
21
  accessibilityRole: PropTypes.string
17
22
  }
@@ -39,6 +39,7 @@ const FlexGrid = forwardRef(
39
39
  tag,
40
40
  accessibilityRole,
41
41
  children,
42
+ dataSet,
42
43
  ...rest
43
44
  },
44
45
  ref
@@ -104,14 +105,11 @@ const FlexGrid = forwardRef(
104
105
  ...selectProps(rest)
105
106
  }
106
107
 
108
+ const dataSetValue = mediaIds ? { media: mediaIds, ...dataSet } : dataSet
109
+
107
110
  return (
108
111
  <GutterContext.Provider value={gutter}>
109
- <BaseView
110
- ref={ref}
111
- {...props}
112
- style={flexgridStyles}
113
- dataSet={mediaIds && { media: mediaIds }}
114
- >
112
+ <BaseView ref={ref} {...props} style={flexgridStyles} dataSet={dataSetValue}>
115
113
  {children}
116
114
  </BaseView>
117
115
  </GutterContext.Provider>
@@ -2,7 +2,7 @@
2
2
  import React, { forwardRef } from 'react'
3
3
  import PropTypes from 'prop-types'
4
4
  import { View, StyleSheet, Platform } from 'react-native'
5
- import { Portal } from '@gorhom/portal'
5
+ import Portal from '../Portal'
6
6
  import { useThemeTokens } from '../ThemeProvider'
7
7
  import Card from '../Card'
8
8
 
@@ -0,0 +1,52 @@
1
+ import { useState, useEffect } from 'react'
2
+ import ReactDOM from 'react-dom'
3
+ import PropTypes from 'prop-types'
4
+
5
+ /**
6
+ * Portal component renders its children in a separate portal container appended to the document body.
7
+ *
8
+ * While `@gorhom/portal` works well for a lot of use-cases, there are some issues with it, particularly around
9
+ * reading context values (see issues below). For web-only components, it is safe to replace `Portal` from `@gorhom/portal`
10
+ * to `Portal` to solve such issues
11
+ *
12
+ * https://github.com/gorhom/react-native-portal/issues/34
13
+ * https://github.com/gorhom/react-native-portal/issues/2
14
+ * https://github.com/gorhom/react-native-portal/issues/3
15
+ * https://github.com/gorhom/react-native-portal/issues/31
16
+ *
17
+ * @component
18
+ * @param {object} props - The component props.
19
+ * @param {React.ReactNode} props.children - The content to render within the portal.
20
+ * @returns {React.ReactPortal} The React portal component.
21
+ */
22
+
23
+ const Portal = ({ children }) => {
24
+ const [portalContainer, setPortalContainer] = useState(null)
25
+ const isWebClient = typeof document !== 'undefined' && typeof window !== 'undefined'
26
+
27
+ useEffect(() => {
28
+ if (!isWebClient) {
29
+ return
30
+ }
31
+ const container = document.createElement('div')
32
+ document.body.appendChild(container)
33
+ setPortalContainer(container)
34
+
35
+ // eslint-disable-next-line consistent-return
36
+ return () => {
37
+ if (container && container.parentNode) {
38
+ container.parentNode.removeChild(container)
39
+ }
40
+ }
41
+ }, [isWebClient])
42
+
43
+ if (!portalContainer || !isWebClient) return null
44
+
45
+ return ReactDOM.createPortal(children, portalContainer)
46
+ }
47
+
48
+ Portal.propTypes = {
49
+ children: PropTypes.node.isRequired
50
+ }
51
+
52
+ export default Portal
@@ -0,0 +1,3 @@
1
+ import { Portal } from '@gorhom/portal'
2
+
3
+ export default Portal
@@ -0,0 +1,3 @@
1
+ import Portal from './Portal'
2
+
3
+ export default Portal
@@ -71,6 +71,7 @@ TextInput.propTypes = {
71
71
  * A callback which if provided will get a clear button rendered and will be called whenever that button gets pressed.
72
72
  */
73
73
  onClear: PropTypes.func,
74
+ onKeyPress: PropTypes.func,
74
75
  tokens: getTokensPropType('TextInput'),
75
76
  variant: variantProp.propType
76
77
  }
@@ -182,6 +182,7 @@ const TextInputBase = forwardRef(
182
182
  value,
183
183
  variant = {},
184
184
  type,
185
+ onKeyPress,
185
186
  ...rest
186
187
  },
187
188
  ref
@@ -311,7 +312,8 @@ const TextInputBase = forwardRef(
311
312
  onChange: handleChangeText,
312
313
  defaultValue: initialValue,
313
314
  maxLength: type === 'card' ? 19 : undefined,
314
- value: isControlled ? currentValue : undefined
315
+ value: isControlled ? currentValue : undefined,
316
+ onKeyPress
315
317
  }
316
318
 
317
319
  const { themeOptions } = useTheme()
@@ -334,7 +336,7 @@ const TextInputBase = forwardRef(
334
336
  )}
335
337
  <NativeTextInput
336
338
  ref={inputRef}
337
- keyboardType={isNumeric && 'numeric'}
339
+ keyboardType={isNumeric ? 'numeric' : 'default'}
338
340
  inputMode={isNumeric && 'numeric'}
339
341
  style={nativeInputStyle}
340
342
  secureTextEntry={isPassword && !showPassword}
@@ -388,6 +390,7 @@ TextInputBase.propTypes = {
388
390
  onFocus: PropTypes.func,
389
391
  onMouseOut: PropTypes.func,
390
392
  onMouseOver: PropTypes.func,
393
+ onKeyPress: PropTypes.func,
391
394
  readOnly: PropTypes.bool,
392
395
  tokens: getTokensPropType('TextInput', 'TextArea'),
393
396
  value: PropTypes.string,
package/src/index.js CHANGED
@@ -77,4 +77,4 @@ export {
77
77
  } from './ThemeProvider'
78
78
 
79
79
  export * from './utils'
80
- export { Portal } from '@gorhom/portal'
80
+ export { default as Portal } from './Portal'
@@ -1,7 +1,7 @@
1
1
  import { addCss } from '../utils/inject'
2
2
  import createDeclarationBlock from '../utils/create-declaration-block'
3
3
  import hash from '../hash'
4
- import { isMediaOrPseudo, deepClone, createCssRule } from '../utils/common'
4
+ import { isMediaOrPseudo, deepClone, createCssRule, sanitizeStyle } from '../utils/common'
5
5
 
6
6
  const createStyleSheet = (stylesWithQuery) => {
7
7
  if (!stylesWithQuery) return { ids: {}, styles: {}, fullStyles: {} }
@@ -14,7 +14,8 @@ const createStyleSheet = (stylesWithQuery) => {
14
14
 
15
15
  const mediaQueriesAndPseudoClasses = Object.keys(stylesWithQuery[key]).filter(isMediaOrPseudo)
16
16
  mediaQueriesAndPseudoClasses.forEach((query) => {
17
- const css = createDeclarationBlock(stylesWithQuery[key][query])
17
+ const sanitizedStyle = sanitizeStyle(stylesWithQuery[key][query])
18
+ const css = createDeclarationBlock(sanitizedStyle)
18
19
  const stringHash = `rnmq-${hash(`${key}${query}${css}`)}`
19
20
  const rule = createCssRule(query, stringHash, css)
20
21
 
@@ -17,4 +17,22 @@ const createCssRule = (query, stringHash, css) => {
17
17
  return rule
18
18
  }
19
19
 
20
- export { isMedia, isPseudo, isMediaOrPseudo, deepClone, createCssRule }
20
+ /**
21
+ * Sanitizes the style object by converting any functions to their string representation.
22
+ *
23
+ * @param {Object} style - The style object to sanitize.
24
+ * @returns {Object} - The sanitized style object.
25
+ */
26
+ const sanitizeStyle = (style) => {
27
+ const sanitizedStyle = { ...style }
28
+
29
+ Object.keys(sanitizedStyle).forEach((property) => {
30
+ if (typeof sanitizedStyle[property] === 'function') {
31
+ sanitizedStyle[property] = sanitizedStyle[property].toString()
32
+ }
33
+ })
34
+
35
+ return sanitizedStyle
36
+ }
37
+
38
+ export { isMedia, isPseudo, isMediaOrPseudo, deepClone, createCssRule, sanitizeStyle }
@@ -0,0 +1,5 @@
1
+ import { ReactNode } from 'react'
2
+
3
+ export interface PortalProps {
4
+ children: ReactNode
5
+ }
package/types/index.d.ts CHANGED
@@ -59,4 +59,7 @@ export { TooltipTokens, TooltipVariants, TooltipProps } from './ToolTip'
59
59
  export { default as Typography } from './Typography'
60
60
  export { TypographyProps, TypographyVariants, TypographyTokens } from './Typography'
61
61
 
62
+ export { default as Portal } from './Portal'
63
+ export { PortalProps } from './Portal'
64
+
62
65
  export * from './Common'