@hero-design/rn-work-uikit 1.1.0 → 1.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/.cursorrules +57 -0
  2. package/CHANGELOG.md +16 -0
  3. package/DEVELOPMENT.md +118 -0
  4. package/assets/fonts/BeVietnamPro-Bold.ttf +0 -0
  5. package/assets/fonts/BeVietnamPro-Light.ttf +0 -0
  6. package/assets/fonts/BeVietnamPro-Regular.ttf +0 -0
  7. package/assets/fonts/BeVietnamPro-SemiBold.ttf +0 -0
  8. package/assets/fonts/Saiga-Light.otf +0 -0
  9. package/assets/fonts/Saiga-Medium.otf +0 -0
  10. package/assets/fonts/Saiga-Regular.otf +0 -0
  11. package/assets/fonts/hero-icons-mobile.ttf +0 -0
  12. package/eslint.config.js +20 -0
  13. package/lib/index.js +871 -5
  14. package/package.json +4 -1
  15. package/rollup.config.mjs +2 -2
  16. package/src/__tests__/__snapshots__/index.spec.tsx.snap +90 -115
  17. package/src/__tests__/theme-export-override.spec.ts +6 -0
  18. package/src/components/TextInput/ErrorOrHelpText.tsx +58 -0
  19. package/src/components/TextInput/FloatingLabel.tsx +120 -0
  20. package/src/components/TextInput/InputComponent.tsx +61 -0
  21. package/src/components/TextInput/InputRow.tsx +103 -0
  22. package/src/components/TextInput/MaxLengthMessage.tsx +66 -0
  23. package/src/components/TextInput/PrefixComponent.tsx +77 -0
  24. package/src/components/TextInput/StyledTextInput.tsx +134 -0
  25. package/src/components/TextInput/SuffixComponent.tsx +73 -0
  26. package/src/components/TextInput/__tests__/ErrorOrHelpText.spec.tsx +20 -0
  27. package/src/components/TextInput/__tests__/FloatingLabel.spec.tsx +203 -0
  28. package/src/components/TextInput/__tests__/InputComponent.spec.tsx +39 -0
  29. package/src/components/TextInput/__tests__/InputRow.spec.tsx +275 -0
  30. package/src/components/TextInput/__tests__/MaxLengthMessage.spec.tsx +17 -0
  31. package/src/components/TextInput/__tests__/PrefixComponent.spec.tsx +14 -0
  32. package/src/components/TextInput/__tests__/StyledTextInput.spec.tsx +114 -0
  33. package/src/components/TextInput/__tests__/SuffixComponent.spec.tsx +20 -0
  34. package/src/components/TextInput/__tests__/__snapshots__/StyledTextInput.spec.tsx.snap +571 -0
  35. package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +5671 -0
  36. package/src/components/TextInput/__tests__/getState.spec.tsx +89 -0
  37. package/src/components/TextInput/__tests__/index.spec.tsx +699 -0
  38. package/src/components/TextInput/constants.ts +1 -0
  39. package/src/components/TextInput/index.tsx +327 -0
  40. package/src/components/TextInput/types.ts +95 -0
  41. package/src/emotion.d.ts +15 -0
  42. package/src/index.ts +3 -0
  43. package/src/jest.d.ts +24 -0
  44. package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +15 -8
  45. package/src/theme/components/textInput.ts +33 -0
  46. package/src/utils/__tests__/helpers.spec.ts +92 -0
  47. package/src/utils/helpers.ts +113 -0
  48. package/testUtils/renderWithTheme.tsx +6 -3
  49. package/stats/1.1.0/rn-work-uikit-stats.html +0 -4842
package/lib/index.js CHANGED
@@ -1,12 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var rn = require('@hero-design/rn');
4
3
  var React = require('react');
4
+ var reactNative = require('react-native');
5
+ var rn = require('@hero-design/rn');
5
6
 
6
7
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
7
8
 
8
9
  var React__default = /*#__PURE__*/_interopDefaultCompat(React);
9
10
 
11
+ function _arrayLikeToArray(r, a) {
12
+ (null == a || a > r.length) && (a = r.length);
13
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
14
+ return n;
15
+ }
16
+ function _arrayWithHoles(r) {
17
+ if (Array.isArray(r)) return r;
18
+ }
10
19
  function _defineProperty(e, r, t) {
11
20
  return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
12
21
  value: t,
@@ -15,6 +24,42 @@ function _defineProperty(e, r, t) {
15
24
  writable: !0
16
25
  }) : e[r] = t, e;
17
26
  }
27
+ function _extends() {
28
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
29
+ for (var e = 1; e < arguments.length; e++) {
30
+ var t = arguments[e];
31
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
32
+ }
33
+ return n;
34
+ }, _extends.apply(null, arguments);
35
+ }
36
+ function _iterableToArrayLimit(r, l) {
37
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
38
+ if (null != t) {
39
+ var e,
40
+ n,
41
+ i,
42
+ u,
43
+ a = [],
44
+ f = !0,
45
+ o = !1;
46
+ try {
47
+ if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
48
+ } catch (r) {
49
+ o = !0, n = r;
50
+ } finally {
51
+ try {
52
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
53
+ } finally {
54
+ if (o) throw n;
55
+ }
56
+ }
57
+ return a;
58
+ }
59
+ }
60
+ function _nonIterableRest() {
61
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
62
+ }
18
63
  function ownKeys(e, r) {
19
64
  var t = Object.keys(e);
20
65
  if (Object.getOwnPropertySymbols) {
@@ -36,6 +81,29 @@ function _objectSpread2(e) {
36
81
  }
37
82
  return e;
38
83
  }
84
+ function _objectWithoutProperties(e, t) {
85
+ if (null == e) return {};
86
+ var o,
87
+ r,
88
+ i = _objectWithoutPropertiesLoose(e, t);
89
+ if (Object.getOwnPropertySymbols) {
90
+ var n = Object.getOwnPropertySymbols(e);
91
+ for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
92
+ }
93
+ return i;
94
+ }
95
+ function _objectWithoutPropertiesLoose(r, e) {
96
+ if (null == r) return {};
97
+ var t = {};
98
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
99
+ if (-1 !== e.indexOf(n)) continue;
100
+ t[n] = r[n];
101
+ }
102
+ return t;
103
+ }
104
+ function _slicedToArray(r, e) {
105
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
106
+ }
39
107
  function _toPrimitive(t, r) {
40
108
  if ("object" != typeof t || !t) return t;
41
109
  var e = t[Symbol.toPrimitive];
@@ -50,17 +118,187 @@ function _toPropertyKey(t) {
50
118
  var i = _toPrimitive(t, "string");
51
119
  return "symbol" == typeof i ? i : i + "";
52
120
  }
121
+ function _unsupportedIterableToArray(r, a) {
122
+ if (r) {
123
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
124
+ var t = {}.toString.call(r).slice(8, -1);
125
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
126
+ }
127
+ }
128
+
129
+ var StyledContainer = rn.styled(reactNative.Pressable)(function (_ref) {
130
+ var theme = _ref.theme;
131
+ return {
132
+ width: '100%',
133
+ flexDirection: 'row',
134
+ paddingHorizontal: theme.__hd__.textInput.space.containerPadding,
135
+ minHeight: theme.__hd__.textInput.sizes.containerMinHeight,
136
+ marginTop: theme.__hd__.textInput.space.containerMarginTop
137
+ };
138
+ });
139
+ var StyledFloatingLabelContainer = rn.styled(reactNative.Animated.View)(function (_ref2) {
140
+ var themeVariant = _ref2.themeVariant;
141
+ return {
142
+ flexDirection: 'row',
143
+ flex: 1,
144
+ alignItems: themeVariant === 'text' ? 'center' : 'flex-start',
145
+ backgroundColor: 'transparent'
146
+ };
147
+ });
148
+ var StyledLabel = rn.styled(rn.Typography.Caption)(function (_ref3) {
149
+ var theme = _ref3.theme,
150
+ themeState = _ref3.themeState;
151
+ return {
152
+ color: theme.__hd__.textInput.colors.labels[themeState]
153
+ };
154
+ });
155
+ var StyledErrorRow = rn.styled(reactNative.View)(function (_ref4) {
156
+ var theme = _ref4.theme;
157
+ return {
158
+ marginRight: theme.__hd__.textInput.space.errorContainerMarginRight,
159
+ flexDirection: 'row',
160
+ alignItems: 'center',
161
+ flex: 1,
162
+ flexGrow: 4
163
+ };
164
+ });
165
+ var StyledError = rn.styled(rn.Typography.Caption)(function (_ref5) {
166
+ var theme = _ref5.theme;
167
+ return {
168
+ color: theme.__hd__.textInput.colors.error,
169
+ marginLeft: theme.__hd__.textInput.space.errorMarginLeft
170
+ };
171
+ });
172
+ var StyledCharacterCount = rn.styled(rn.Typography.Caption)(function (_ref6) {
173
+ var theme = _ref6.theme,
174
+ themeState = _ref6.themeState;
175
+ return {
176
+ color: theme.__hd__.textInput.colors.maxLengthLabels[themeState],
177
+ flex: 1,
178
+ flexGrow: 1,
179
+ textAlign: 'right'
180
+ };
181
+ });
182
+ var StyledHelperText = rn.Typography.Caption;
183
+ var StyledTextInput = rn.styled(reactNative.TextInput)(function (_ref7) {
184
+ var theme = _ref7.theme,
185
+ themeVariant = _ref7.themeVariant;
186
+ return {
187
+ textAlignVertical: themeVariant === 'text' ? 'center' : 'top',
188
+ fontSize: theme.__hd__.textInput.fontSizes.text,
189
+ flexGrow: 2,
190
+ paddingVertical: 0,
191
+ maxHeight: theme.__hd__.textInput.sizes.textInputMaxHeight,
192
+ minHeight: theme.__hd__.textInput.sizes.textInputMinHeight,
193
+ height: themeVariant === 'text' ? undefined : theme.__hd__.textInput.sizes.textareaHeight,
194
+ fontFamily: theme.__hd__.textInput.fonts.text
195
+ };
196
+ });
197
+ var StyledBorder = rn.styled(reactNative.View)(function (_ref8) {
198
+ var theme = _ref8.theme,
199
+ themeFocused = _ref8.themeFocused,
200
+ themeState = _ref8.themeState;
201
+ return _objectSpread2(_objectSpread2({}, reactNative.StyleSheet.absoluteFillObject), {}, {
202
+ borderWidth: theme.__hd__.textInput.borderWidths.container.normal,
203
+ borderRadius: theme.__hd__.textInput.radii.container,
204
+ borderColor: themeFocused ? theme.__hd__.textInput.colors.borders.focused : theme.__hd__.textInput.colors.borders[themeState]
205
+ });
206
+ });
207
+ var StyledInputWrapper = rn.styled(reactNative.View)(function (_ref9) {
208
+ var theme = _ref9.theme;
209
+ return {
210
+ flexDirection: 'column',
211
+ flex: 1,
212
+ backgroundColor: 'transparent',
213
+ borderRadius: theme.__hd__.textInput.radii.container,
214
+ marginBottom: theme.__hd__.textInput.space.inputWrapperMarginVertical,
215
+ marginTop: theme.__hd__.textInput.space.inputWrapperMarginVertical,
216
+ overflow: 'hidden'
217
+ };
218
+ });
219
+ var StyledInputRow = rn.styled(reactNative.View)(function (_ref10) {
220
+ var theme = _ref10.theme;
221
+ return {
222
+ flexDirection: 'row',
223
+ alignItems: 'center',
224
+ flexGrow: 2,
225
+ flexShrink: 1,
226
+ gap: theme.__hd__.textInput.space.prefixAndInputContainerGap
227
+ };
228
+ });
229
+ rn.styled(reactNative.View)(function (_ref11) {
230
+ var theme = _ref11.theme;
231
+ return {
232
+ paddingHorizontal: theme.__hd__.textInput.space.errorAndHelpTextContainerHorizontalPadding,
233
+ minHeight: theme.__hd__.textInput.sizes.errorAndHelpTextContainerHeight,
234
+ paddingTop: theme.__hd__.textInput.space.errorAndHelpTextContainerPaddingTop
235
+ };
236
+ });
237
+ var StyledBottomContainer = rn.styled(reactNative.View)(function () {
238
+ return {
239
+ flexDirection: 'row',
240
+ justifyContent: 'space-between',
241
+ alignItems: 'flex-start'
242
+ };
243
+ });
244
+ var StyledSuffixContainer = rn.styled(reactNative.View)(function () {
245
+ return {
246
+ flexDirection: 'row',
247
+ alignItems: 'center',
248
+ justifyContent: 'flex-end'
249
+ };
250
+ });
53
251
 
54
252
  var getTextInputTheme = function getTextInputTheme(theme) {
55
253
  var baseTextInputTheme = theme.__hd__.textInput;
56
254
  // Override specific values here as needed
57
- var colors = _objectSpread2({}, baseTextInputTheme.colors);
58
- var space = _objectSpread2({}, baseTextInputTheme.space);
255
+ var colors = _objectSpread2(_objectSpread2({}, baseTextInputTheme.colors), {}, {
256
+ // Example: override specific colors
257
+ // text: theme.colors.customTextColor,
258
+ borders: {
259
+ "default": theme.colors.secondaryOutline,
260
+ error: theme.colors.onErrorSurface,
261
+ disabled: theme.colors.disabledOutline,
262
+ readonly: theme.colors.disabledOutline,
263
+ filled: theme.colors.secondaryOutline,
264
+ focused: theme.colors.primaryOutline
265
+ },
266
+ labels: {
267
+ "default": theme.colors.inactiveOnDefaultGlobalSurface,
268
+ error: theme.colors.onErrorSurface,
269
+ disabled: theme.colors.disabledOnDefaultGlobalSurface,
270
+ readonly: theme.colors.inactiveOnDefaultGlobalSurface,
271
+ filled: theme.colors.inactiveOnDefaultGlobalSurface,
272
+ focused: theme.colors.onDefaultGlobalSurface
273
+ },
274
+ maxLengthLabels: {
275
+ "default": theme.colors.onDefaultGlobalSurface,
276
+ error: theme.colors.onErrorSurface,
277
+ disabled: theme.colors.disabledOnDefaultGlobalSurface,
278
+ readonly: theme.colors.inactiveOnDefaultGlobalSurface,
279
+ filled: theme.colors.onDefaultGlobalSurface,
280
+ focused: theme.colors.onDefaultGlobalSurface
281
+ }
282
+ });
283
+ var space = _objectSpread2(_objectSpread2({}, baseTextInputTheme.space), {}, {
284
+ // Example: override specific spacing
285
+ // containerPadding: theme.space.large,
286
+ inputWrapperMarginVertical: theme.space.small,
287
+ prefixAndInputContainerGap: theme.space.xsmall
288
+ });
59
289
  var fonts = _objectSpread2({}, baseTextInputTheme.fonts);
60
290
  var fontSizes = _objectSpread2({}, baseTextInputTheme.fontSizes);
61
- var borderWidths = _objectSpread2({}, baseTextInputTheme.borderWidths);
291
+ var borderWidths = _objectSpread2(_objectSpread2({}, baseTextInputTheme.borderWidths), {}, {
292
+ container: _objectSpread2(_objectSpread2({}, baseTextInputTheme.borderWidths.container), {}, {
293
+ normal: theme.borderWidths.medium
294
+ })
295
+ });
62
296
  var radii = _objectSpread2({}, baseTextInputTheme.radii);
63
- var sizes = _objectSpread2({}, baseTextInputTheme.sizes);
297
+ var sizes = _objectSpread2(_objectSpread2({}, baseTextInputTheme.sizes), {}, {
298
+ containerMinHeight: theme.sizes.xxxxlarge,
299
+ errorAndHelpTextContainerHeight: 0,
300
+ textInputMinHeight: baseTextInputTheme.fontSizes.text + theme.space.small
301
+ });
64
302
  var lineHeights = _objectSpread2({}, baseTextInputTheme.lineHeights);
65
303
  return {
66
304
  colors: colors,
@@ -128,6 +366,634 @@ var withWorkTheme = function withWorkTheme(C, themeName) {
128
366
 
129
367
  var defaultTheme = getTheme();
130
368
 
369
+ /**
370
+ * ErrorOrHelpText Component
371
+ *
372
+ * Displays either error messages or help text below the TextInput.
373
+ * Shows error messages with a danger icon when present, otherwise displays help text.
374
+ *
375
+ * Key Features:
376
+ * - Conditional rendering: error takes priority over help text
377
+ * - Error messages include a danger icon for visual clarity
378
+ * - Uses styled components for consistent theming
379
+ * - Includes proper test IDs for testing
380
+ *
381
+ * Rendering Logic:
382
+ * 1. If error exists: Show error message with danger icon
383
+ * 2. If no error but helpText exists: Show help text
384
+ * 3. If neither exists: Render nothing
385
+ *
386
+ * @param props - The component props (see ErrorOrHelpTextProps interface for details)
387
+ */
388
+ var ErrorOrHelpText = function ErrorOrHelpText(_ref) {
389
+ var error = _ref.error,
390
+ helpText = _ref.helpText;
391
+ return error ?
392
+ /*#__PURE__*/
393
+ // Error state: Show error message with danger icon
394
+ React__default.default.createElement(StyledErrorRow, null, /*#__PURE__*/React__default.default.createElement(rn.Icon, {
395
+ testID: "input-error-icon",
396
+ icon: "circle-info",
397
+ size: "xsmall",
398
+ intent: "danger"
399
+ }), /*#__PURE__*/React__default.default.createElement(StyledError, {
400
+ testID: "input-error-message"
401
+ }, error)) :
402
+ // Help text state: Show help text if provided
403
+ !!helpText && /*#__PURE__*/React__default.default.createElement(StyledHelperText, null, helpText);
404
+ };
405
+ ErrorOrHelpText.displayName = 'ErrorOrHelpText';
406
+ var ErrorOrHelpText$1 = /*#__PURE__*/React__default.default.memo(ErrorOrHelpText);
407
+
408
+ /**
409
+ * SuffixComponent
410
+ *
411
+ * Renders suffix content (icons or custom elements) on the right side of the TextInput.
412
+ * Handles loading states and custom elements.
413
+ *
414
+ * Key Features:
415
+ * - Loading state handling: shows spinner when loading is true
416
+ * - Icon rendering: supports string icon names from the design system
417
+ * - Custom element support: can render any React element as suffix
418
+ * - State-aware styling: adjusts icon intent based on input state
419
+ * - Spinning animation: loading icons automatically spin
420
+ * - Proper test IDs for automated testing
421
+ *
422
+ * Rendering Priority:
423
+ * 1. Loading state: Shows 'loading' icon with spin animation
424
+ * 2. String icon name: Renders Icon component with state-based intent
425
+ * 3. Custom element: Renders the provided React element as-is
426
+ * 4. No suffix: Renders null
427
+ *
428
+ * Icon Intent Logic:
429
+ * - Disabled state: Uses 'disabled-text' intent
430
+ * - All other states: Uses 'text' intent
431
+ *
432
+ * @param props - The component props (see SuffixComponentProps interface for details)
433
+ */
434
+ var SuffixComponent = function SuffixComponent(_ref) {
435
+ var state = _ref.state,
436
+ loading = _ref.loading,
437
+ suffix = _ref.suffix;
438
+ // Loading state overrides suffix
439
+ var actualSuffix = loading ? 'loading' : suffix;
440
+ if (typeof actualSuffix === 'string') {
441
+ // Render icon from design system
442
+ return /*#__PURE__*/React__default.default.createElement(rn.Icon, {
443
+ intent: state === 'disabled' ? 'disabled-text' : 'text',
444
+ testID: "input-suffix",
445
+ accessibilityLabel: "Suffix icon: ".concat(actualSuffix),
446
+ accessibilityRole: "image",
447
+ icon: actualSuffix,
448
+ spin: actualSuffix === 'loading' // Animate loading icon
449
+ ,
450
+ size: "medium"
451
+ });
452
+ }
453
+ if (actualSuffix) {
454
+ // Render custom element
455
+ return suffix;
456
+ }
457
+ return null;
458
+ };
459
+ SuffixComponent.displayName = 'SuffixComponent';
460
+ var SuffixComponent$1 = /*#__PURE__*/React__default.default.memo(SuffixComponent);
461
+
462
+ /**
463
+ * MaxLengthMessage Component
464
+ *
465
+ * Displays character count information for TextInput fields with maximum length restrictions.
466
+ * Shows current/max character count with state-aware styling.
467
+ *
468
+ * Key Features:
469
+ * - Character count display: Shows "currentLength/maxLength" format
470
+ * - Conditional rendering: Only shows when maxLength is set and not hidden
471
+ * - State-aware styling: Colors change based on input state (error, disabled, etc.)
472
+ * - Real-time updates: Updates as user types to show current progress
473
+ * - Hide capability: Can be hidden via hideCharacterCount prop
474
+ *
475
+ * Display Logic:
476
+ * - Shows only when: maxLength is defined AND hideCharacterCount is false
477
+ * - Format: "currentLength/maxLength" (e.g., "25/100")
478
+ * - Hidden when: maxLength is undefined OR hideCharacterCount is true
479
+ *
480
+ * State-based Styling:
481
+ * - Uses themeState to apply appropriate colors from theme
482
+ * - Error state: Shows error color to indicate validation issues
483
+ * - Disabled state: Shows muted color for disabled inputs
484
+ * - Normal states: Shows standard text colors
485
+ *
486
+ * Usage Example:
487
+ * - Input with 25 characters and 100 max: displays "25/100"
488
+ * - Input approaching limit: color may change based on theme
489
+ * - Input over limit: error state styling applied
490
+ *
491
+ * @param props - The component props (see MaxLengthMessageProps interface for details)
492
+ */
493
+ var MaxLengthMessage = function MaxLengthMessage(_ref) {
494
+ var maxLength = _ref.maxLength,
495
+ state = _ref.state,
496
+ currentLength = _ref.currentLength,
497
+ hideCharacterCount = _ref.hideCharacterCount;
498
+ if (!maxLength || hideCharacterCount) {
499
+ return null;
500
+ }
501
+ return /*#__PURE__*/React__default.default.createElement(StyledCharacterCount, {
502
+ themeState: state
503
+ }, currentLength, "/", maxLength);
504
+ };
505
+ MaxLengthMessage.displayName = 'MaxLengthMessage';
506
+ var MaxLengthMessage$1 = /*#__PURE__*/React__default.default.memo(MaxLengthMessage);
507
+
508
+ var LABEL_ANIMATION_DURATION = 150;
509
+
510
+ /**
511
+ * FloatingLabel Component
512
+ *
513
+ * Handles the animated floating label behavior for TextInput.
514
+ * The label starts positioned over the input and animates to a smaller size above the input
515
+ * when the field is focused or has content.
516
+ *
517
+ * Key Features:
518
+ * - Smooth scale and translate animations using React Native Animated API
519
+ * - Responds to focus state and content presence
520
+ * - Automatically appends "(Optional)" text for non-required fields
521
+ * - Supports different variants (text/textarea) with appropriate positioning
522
+ * - Maintains accessibility features with proper IDs and test IDs
523
+ * - Self-contained animation management
524
+ *
525
+ * Animation Behavior:
526
+ * - Scale: 1.5 → 1 (label shrinks when floating)
527
+ * - TranslateY: Variable based on variant → 0 (moves up)
528
+ * - Uses bezier easing for smooth transitions
529
+ *
530
+ * @param props - The component props (see FloatingLabelProps for details)
531
+ */
532
+ var FloatingLabel = function FloatingLabel(_ref) {
533
+ var label = _ref.label,
534
+ variant = _ref.variant,
535
+ state = _ref.state,
536
+ isFocused = _ref.isFocused,
537
+ required = _ref.required,
538
+ accessibilityLabelledBy = _ref.accessibilityLabelledBy,
539
+ isEmptyValue = _ref.isEmptyValue;
540
+ var theme = useWorkTheme();
541
+ var shouldFloat = isFocused || !isEmptyValue;
542
+ var focusAnimation = React.useRef(new reactNative.Animated.Value(shouldFloat ? 1 : 0)).current;
543
+ React.useEffect(function () {
544
+ reactNative.Animated.timing(focusAnimation, {
545
+ toValue: shouldFloat ? 1 : 0,
546
+ duration: LABEL_ANIMATION_DURATION,
547
+ easing: reactNative.Easing.bezier(0.4, 0, 0.2, 1),
548
+ useNativeDriver: true
549
+ }).start();
550
+ }, [shouldFloat, focusAnimation]);
551
+ return /*#__PURE__*/React__default.default.createElement(StyledFloatingLabelContainer, {
552
+ themeVariant: variant,
553
+ style: [{
554
+ transformOrigin: 'left center'
555
+ }, {
556
+ transform: [{
557
+ translateY: focusAnimation.interpolate({
558
+ inputRange: [0, 1],
559
+ outputRange: [variant !== 'textarea' ? 12 : theme.space.small, 0]
560
+ })
561
+ }, {
562
+ scale: focusAnimation.interpolate({
563
+ inputRange: [0, 1],
564
+ outputRange: [1.333, 1]
565
+ })
566
+ }]
567
+ }]
568
+ }, /*#__PURE__*/React__default.default.createElement(reactNative.Animated.View, null, /*#__PURE__*/React__default.default.createElement(StyledLabel, {
569
+ nativeID: accessibilityLabelledBy,
570
+ testID: "input-label",
571
+ themeState: state,
572
+ numberOfLines: 1,
573
+ style: {
574
+ backgroundColor: 'transparent'
575
+ }
576
+ }, label, !required && ' (Optional)')));
577
+ };
578
+ FloatingLabel.displayName = 'FloatingLabel';
579
+ var FloatingLabel$1 = /*#__PURE__*/React__default.default.memo(FloatingLabel);
580
+
581
+ var _excluded$1 = ["state", "prefix"];
582
+ /**
583
+ * PrefixComponent
584
+ *
585
+ * Renders prefix content (icons or custom elements) on the left side of the TextInput,
586
+ * before the user's input cursor.
587
+ *
588
+ * Key Features:
589
+ * - Icon rendering: supports string icon names from the design system
590
+ * - Custom element support: can render any React element as prefix
591
+ * - State-aware styling: adjusts icon intent based on input state
592
+ * - Consistent sizing: uses 'xsmall' size for visual balance
593
+ * - Proper test IDs for automated testing
594
+ *
595
+ * Rendering Logic:
596
+ * 1. String icon name: Renders Icon component with state-based intent
597
+ * 2. Custom element: Renders the provided React element as-is
598
+ * 3. No prefix: Renders null
599
+ *
600
+ * Icon Intent Logic:
601
+ * - Disabled state: Uses 'disabled-text' intent for muted appearance
602
+ * - All other states: Uses 'text' intent for normal appearance
603
+ *
604
+ * Visual Positioning:
605
+ * - Positioned before the text input cursor
606
+ * - Uses smaller 'xsmall' size to avoid overwhelming the input
607
+ * - Maintains proper spacing via parent container
608
+ *
609
+ * @param props - The component props (see PrefixComponentProps interface for details)
610
+ */
611
+ var PrefixComponent = function PrefixComponent(_ref) {
612
+ var state = _ref.state,
613
+ prefix = _ref.prefix,
614
+ rest = _objectWithoutProperties(_ref, _excluded$1);
615
+ var actualPrefix = typeof prefix === 'string' ? prefix : '';
616
+ if (typeof prefix === 'string' && actualPrefix) {
617
+ return /*#__PURE__*/React__default.default.createElement(reactNative.View, _extends({
618
+ testID: "input-prefix"
619
+ }, rest), /*#__PURE__*/React__default.default.createElement(rn.Icon, {
620
+ intent: state === 'disabled' ? 'disabled-text' : 'text',
621
+ icon: actualPrefix,
622
+ size: "xsmall",
623
+ testID: "input-prefix-icon",
624
+ accessibilityLabel: "Prefix icon: ".concat(actualPrefix),
625
+ accessibilityRole: "image"
626
+ }));
627
+ }
628
+ if (/*#__PURE__*/React__default.default.isValidElement(prefix)) {
629
+ return /*#__PURE__*/React__default.default.createElement(reactNative.View, _extends({
630
+ testID: "input-prefix"
631
+ }, rest), prefix);
632
+ }
633
+ return null;
634
+ };
635
+ PrefixComponent.displayName = 'PrefixComponent';
636
+ var PrefixComponent$1 = /*#__PURE__*/React__default.default.memo(PrefixComponent);
637
+
638
+ /**
639
+ * InputComponent
640
+ *
641
+ * Renders the actual text input element. Supports custom input rendering or uses the default StyledTextInput.
642
+ *
643
+ * Key Features:
644
+ * - Flexible rendering: supports custom input renderers via renderInputValue prop
645
+ * - Variant support: handles both 'text' and 'textarea' input types
646
+ * - Multiline handling: automatically enables multiline for textarea variant
647
+ * - Theme integration: applies theme colors for placeholder text
648
+ * - Ref forwarding: properly forwards refs to the underlying TextInput
649
+ *
650
+ * Rendering Logic:
651
+ * 1. If renderInputValue provided: Use custom renderer
652
+ * 2. Otherwise: Use default StyledTextInput with theme and variant support
653
+ *
654
+ * Multiline Behavior:
655
+ * - 'textarea' variant: Always multiline
656
+ * - 'text' variant: Single line unless explicitly set via nativeInputProps
657
+ *
658
+ * @param props - The component props (see InputComponentProps interface for details)
659
+ */
660
+ var InputComponent = /*#__PURE__*/React__default.default.forwardRef(function (_ref, ref) {
661
+ var variant = _ref.variant,
662
+ nativeInputProps = _ref.nativeInputProps,
663
+ renderInputValue = _ref.renderInputValue;
664
+ var theme = useWorkTheme();
665
+ return renderInputValue ?
666
+ /*#__PURE__*/
667
+ // Custom input renderer provided
668
+ React__default.default.createElement(React__default.default.Fragment, null, renderInputValue(nativeInputProps)) :
669
+ /*#__PURE__*/
670
+ // Default styled input with theme and variant support
671
+ React__default.default.createElement(StyledTextInput, _extends({}, nativeInputProps, {
672
+ themeVariant: variant,
673
+ multiline: variant === 'textarea' || nativeInputProps.multiline,
674
+ ref: ref,
675
+ placeholderTextColor: theme.__hd__.textInput.colors.placeholder
676
+ }));
677
+ });
678
+ InputComponent.displayName = 'InputComponent';
679
+ var InputComponent$1 = /*#__PURE__*/React__default.default.memo(InputComponent);
680
+
681
+ /**
682
+ * InputRow Component
683
+ *
684
+ * Layout Structure:
685
+ * ┌─────────────────────────────────────────────────────────┐
686
+ * │ StyledInputRow │
687
+ * │ ┌──────────┐ ┌─────────────────────────────────────┐ │
688
+ * │ │ Prefix │ │ Input Field │ │
689
+ * │ │ (Icon or │ │ (TextInput or Custom) │ │
690
+ * │ │ Custom) │ │ flex: 1 │ │
691
+ * │ └──────────┘ └─────────────────────────────────────┘ │
692
+ * └─────────────────────────────────────────────────────────┘
693
+ *
694
+ * Rendering Behavior:
695
+ * - Components are always rendered but hidden with opacity in idle state
696
+ * - Uses accessibility props to hide components from screen readers when not visible
697
+ *
698
+ * Renders the main input row containing:
699
+ * 1. Conditionally visible prefix component (icon or custom element)
700
+ * 2. Conditionally visible input component (TextInput or custom rendered input)
701
+ */
702
+ var InputRow = /*#__PURE__*/React__default.default.forwardRef(function (_ref, ref) {
703
+ var state = _ref.state,
704
+ isFocused = _ref.isFocused,
705
+ prefix = _ref.prefix,
706
+ variant = _ref.variant,
707
+ nativeInputProps = _ref.nativeInputProps,
708
+ renderInputValue = _ref.renderInputValue,
709
+ isEmptyValue = _ref.isEmptyValue;
710
+ var shouldShow = isFocused || !isEmptyValue;
711
+ var opacity = React.useRef(new reactNative.Animated.Value(shouldShow ? 1 : 0)).current;
712
+ React.useEffect(function () {
713
+ reactNative.Animated.timing(opacity, {
714
+ toValue: shouldShow ? 1 : 0,
715
+ duration: LABEL_ANIMATION_DURATION,
716
+ useNativeDriver: true
717
+ }).start();
718
+ }, [shouldShow, opacity]);
719
+ return /*#__PURE__*/React__default.default.createElement(StyledInputRow, null, /*#__PURE__*/React__default.default.createElement(reactNative.Animated.View, {
720
+ style: {
721
+ opacity: opacity
722
+ }
723
+ }, /*#__PURE__*/React__default.default.createElement(PrefixComponent$1, {
724
+ state: state,
725
+ prefix: prefix,
726
+ accessibilityElementsHidden: !shouldShow
727
+ })), /*#__PURE__*/React__default.default.createElement(reactNative.Animated.View, {
728
+ style: {
729
+ flex: 1,
730
+ opacity: opacity
731
+ },
732
+ testID: "input-row-input-wrapper",
733
+ accessibilityLabel: "Text input field",
734
+ accessibilityElementsHidden: !shouldShow
735
+ }, /*#__PURE__*/React__default.default.createElement(InputComponent$1, {
736
+ variant: variant,
737
+ nativeInputProps: nativeInputProps,
738
+ renderInputValue: renderInputValue,
739
+ ref: ref
740
+ })));
741
+ });
742
+
743
+ var _excluded = ["label", "prefix", "suffix", "style", "textStyle", "testID", "accessibilityLabelledBy", "error", "required", "editable", "disabled", "loading", "maxLength", "hideCharacterCount", "helpText", "value", "defaultValue", "renderInputValue", "allowFontScaling", "variant"];
744
+ var getState = function getState(_ref) {
745
+ var disabled = _ref.disabled,
746
+ error = _ref.error,
747
+ editable = _ref.editable,
748
+ loading = _ref.loading,
749
+ isEmptyValue = _ref.isEmptyValue;
750
+ if (disabled) {
751
+ return 'disabled';
752
+ }
753
+ if (error) {
754
+ return 'error';
755
+ }
756
+ if (!editable || loading) {
757
+ return 'readonly';
758
+ }
759
+ if (!isEmptyValue) {
760
+ return 'filled';
761
+ }
762
+ return 'default';
763
+ };
764
+ // Fix issue: Placeholder is not shown on iOS when multiline is true
765
+ // https://github.com/callstack/react-native-paper/pull/3331
766
+ var EMPTY_PLACEHOLDER_VALUE = ' ';
767
+ // Simplified style extraction functions
768
+ var extractBackgroundColor = function extractBackgroundColor(style) {
769
+ var flattened = reactNative.StyleSheet.flatten(style);
770
+ return flattened === null || flattened === void 0 ? void 0 : flattened.backgroundColor;
771
+ };
772
+ var extractBorderStyles = function extractBorderStyles(style) {
773
+ var flattened = reactNative.StyleSheet.flatten(style);
774
+ if (!flattened) return {};
775
+ var borderKeys = Object.keys(flattened).filter(function (key) {
776
+ return key.startsWith('border');
777
+ });
778
+ var borderStyles = {};
779
+ borderKeys.forEach(function (key) {
780
+ borderStyles[key] = flattened[key];
781
+ });
782
+ return borderStyles;
783
+ };
784
+ /**
785
+ * TextInput Layout Structure:
786
+ *
787
+ * ┌─────────────────────────────────────────────────────────────────────────┐
788
+ * │ StyledContainer (with StyledBorder overlay) │
789
+ * │ ┌─────────────────────────────────────────────────────────┐ │
790
+ * │ │ StyledInputWrapper │ │
791
+ * │ │ ┌─────────────────────────────────────────────────┐ │ │
792
+ * │ │ │ FloatingLabel (Optional) │ │ │
793
+ * │ │ │ "Label" or animated position │ │ ┌──────┐ │
794
+ * │ │ └─────────────────────────────────────────────────┘ │ │Suffix│ │
795
+ * │ │ │ │ Icon │ │
796
+ * │ │ ┌─────────────────────────────────────────────────┐ │ │ or │ │
797
+ * │ │ │ InputRow Component │ │ │Custom│ │
798
+ * │ │ │ ┌──────────┐ ┌─────────────────────────────┐ │ │ │(V- │ │
799
+ * │ │ │ │ Prefix │ │ Input Field │ │ │ │Center│ │
800
+ * │ │ │ │(Animated)│ │ (Animated TextInput) │ │ │ │ ed) │ │
801
+ * │ │ │ └──────────┘ └─────────────────────────────┘ │ │ └──────┘ │
802
+ * │ │ └─────────────────────────────────────────────────┘ │ │
803
+ * │ │ │ │
804
+ * │ │ ┌─────────────────────────────────────────────────┐ │ │
805
+ * │ │ │ StyledBottomContainer │ │ │
806
+ * │ │ │ ┌─────────────────┐ ┌─────────────────────┐ │ │ │
807
+ * │ │ │ │ Error/Help Text │ │ Character Count │ │ │ │
808
+ * │ │ │ │ (flex: 4) │ │ (flex: 1) │ │ │ │
809
+ * │ │ │ └─────────────────┘ └─────────────────────┘ │ │ │
810
+ * │ │ └─────────────────────────────────────────────────┘ │ │
811
+ * │ └─────────────────────────────────────────────────────────┘ │
812
+ * └─────────────────────────────────────────────────────────────────────────┘
813
+ *
814
+ * Note: StyledBorder uses StyleSheet.absoluteFillObject to overlay the entire
815
+ * StyledContainer, providing the border and background styling.
816
+ */
817
+ var TextInput = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
818
+ var _ref3;
819
+ var label = _ref2.label,
820
+ prefix = _ref2.prefix,
821
+ suffix = _ref2.suffix,
822
+ style = _ref2.style,
823
+ textStyle = _ref2.textStyle,
824
+ testID = _ref2.testID,
825
+ accessibilityLabelledBy = _ref2.accessibilityLabelledBy,
826
+ error = _ref2.error,
827
+ required = _ref2.required,
828
+ _ref2$editable = _ref2.editable,
829
+ editable = _ref2$editable === void 0 ? true : _ref2$editable,
830
+ _ref2$disabled = _ref2.disabled,
831
+ disabled = _ref2$disabled === void 0 ? false : _ref2$disabled,
832
+ _ref2$loading = _ref2.loading,
833
+ loading = _ref2$loading === void 0 ? false : _ref2$loading,
834
+ maxLength = _ref2.maxLength,
835
+ _ref2$hideCharacterCo = _ref2.hideCharacterCount,
836
+ hideCharacterCount = _ref2$hideCharacterCo === void 0 ? false : _ref2$hideCharacterCo,
837
+ helpText = _ref2.helpText,
838
+ value = _ref2.value,
839
+ defaultValue = _ref2.defaultValue,
840
+ renderInputValue = _ref2.renderInputValue,
841
+ _ref2$allowFontScalin = _ref2.allowFontScaling,
842
+ allowFontScaling = _ref2$allowFontScalin === void 0 ? false : _ref2$allowFontScalin,
843
+ _ref2$variant = _ref2.variant,
844
+ variant = _ref2$variant === void 0 ? 'text' : _ref2$variant,
845
+ nativeProps = _objectWithoutProperties(_ref2, _excluded);
846
+ // Inline the simple getDisplayText function
847
+ var displayText = (_ref3 = value !== undefined ? value : defaultValue) !== null && _ref3 !== void 0 ? _ref3 : '';
848
+ var isEmptyValue = displayText.length === 0;
849
+ var _React$useState = React__default.default.useState(false),
850
+ _React$useState2 = _slicedToArray(_React$useState, 2),
851
+ isFocused = _React$useState2[0],
852
+ setIsFocused = _React$useState2[1];
853
+ var state = getState({
854
+ disabled: disabled,
855
+ error: error,
856
+ editable: editable,
857
+ loading: loading,
858
+ isEmptyValue: isEmptyValue
859
+ });
860
+ var theme = useWorkTheme();
861
+ var innerTextInput = React__default.default.useRef(null);
862
+ React__default.default.useImperativeHandle(ref, function () {
863
+ return {
864
+ // we don't expose this method, it's for testing https://medium.com/developer-rants/how-to-test-useref-without-mocking-useref-699165f4994e
865
+ getNativeTextInputRef: function getNativeTextInputRef() {
866
+ return innerTextInput.current;
867
+ },
868
+ focus: function focus() {
869
+ var _innerTextInput$curre;
870
+ (_innerTextInput$curre = innerTextInput.current) === null || _innerTextInput$curre === void 0 || _innerTextInput$curre.focus();
871
+ },
872
+ clear: function clear() {
873
+ var _innerTextInput$curre2;
874
+ return (_innerTextInput$curre2 = innerTextInput.current) === null || _innerTextInput$curre2 === void 0 ? void 0 : _innerTextInput$curre2.clear();
875
+ },
876
+ setNativeProps: function setNativeProps(args) {
877
+ var _innerTextInput$curre3;
878
+ return (_innerTextInput$curre3 = innerTextInput.current) === null || _innerTextInput$curre3 === void 0 ? void 0 : _innerTextInput$curre3.setNativeProps(args);
879
+ },
880
+ isFocused: function isFocused() {
881
+ var _innerTextInput$curre4;
882
+ return ((_innerTextInput$curre4 = innerTextInput.current) === null || _innerTextInput$curre4 === void 0 ? void 0 : _innerTextInput$curre4.isFocused()) || false;
883
+ },
884
+ blur: function blur() {
885
+ var _innerTextInput$curre5;
886
+ return (_innerTextInput$curre5 = innerTextInput.current) === null || _innerTextInput$curre5 === void 0 ? void 0 : _innerTextInput$curre5.blur();
887
+ }
888
+ };
889
+ }, [innerTextInput]);
890
+ // Simplified style extraction
891
+ var borderStyles = extractBorderStyles(textStyle);
892
+ var customBackgroundColor = extractBackgroundColor(style);
893
+ var backgroundColor = customBackgroundColor !== null && customBackgroundColor !== void 0 ? customBackgroundColor : theme.__hd__.textInput.colors.containerBackground;
894
+ // Simplified callback functions (removed unnecessary memoization for simple cases)
895
+ var handleFocus = React.useCallback(function (event) {
896
+ var _nativeProps$onFocus;
897
+ setIsFocused(true);
898
+ (_nativeProps$onFocus = nativeProps.onFocus) === null || _nativeProps$onFocus === void 0 || _nativeProps$onFocus.call(nativeProps, event);
899
+ }, [nativeProps]);
900
+ var handleBlur = React.useCallback(function (event) {
901
+ var _nativeProps$onBlur;
902
+ setIsFocused(false);
903
+ (_nativeProps$onBlur = nativeProps.onBlur) === null || _nativeProps$onBlur === void 0 || _nativeProps$onBlur.call(nativeProps, event);
904
+ }, [nativeProps]);
905
+ var handleChangeText = React.useCallback(function (text) {
906
+ var _nativeProps$onChange;
907
+ (_nativeProps$onChange = nativeProps.onChangeText) === null || _nativeProps$onChange === void 0 || _nativeProps$onChange.call(nativeProps, text);
908
+ }, [nativeProps]);
909
+ // Simplified callbacks - these don't need memoization as they're stable
910
+ var handleContainerPress = function handleContainerPress() {
911
+ var _innerTextInput$curre6;
912
+ (_innerTextInput$curre6 = innerTextInput.current) === null || _innerTextInput$curre6 === void 0 || _innerTextInput$curre6.focus();
913
+ };
914
+ // Create text input style without border properties
915
+ var textInputStyle = textStyle ? _objectSpread2({}, reactNative.StyleSheet.flatten(textStyle)) : {};
916
+ Object.keys(borderStyles).forEach(function (key) {
917
+ delete textInputStyle[key];
918
+ });
919
+ var nativeInputProps = _objectSpread2(_objectSpread2({
920
+ style: reactNative.StyleSheet.flatten([{
921
+ backgroundColor: backgroundColor,
922
+ color: theme.__hd__.textInput.colors.text
923
+ }, textInputStyle]),
924
+ testID: 'text-input',
925
+ accessibilityState: {
926
+ disabled: state === 'disabled' || state === 'readonly'
927
+ },
928
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
929
+ // @ts-ignore
930
+ accessibilityLabelledBy: accessibilityLabelledBy,
931
+ allowFontScaling: allowFontScaling
932
+ }, nativeProps), {}, {
933
+ onFocus: handleFocus,
934
+ onBlur: handleBlur,
935
+ onChangeText: handleChangeText,
936
+ editable: editable,
937
+ maxLength: maxLength,
938
+ value: value,
939
+ defaultValue: defaultValue,
940
+ placeholder: isFocused || label === undefined ? nativeProps.placeholder : EMPTY_PLACEHOLDER_VALUE
941
+ });
942
+ // Create container style without background color
943
+ var containerStyle = style ? _objectSpread2({}, reactNative.StyleSheet.flatten(style)) : {};
944
+ if (customBackgroundColor) {
945
+ delete containerStyle.backgroundColor;
946
+ }
947
+ var isDisabledOrReadonly = state === 'disabled' || state === 'readonly';
948
+ return /*#__PURE__*/React__default.default.createElement(StyledContainer, {
949
+ style: containerStyle,
950
+ onPress: handleContainerPress,
951
+ disabled: isDisabledOrReadonly,
952
+ accessibilityState: {
953
+ disabled: isDisabledOrReadonly
954
+ },
955
+ testID: testID
956
+ }, /*#__PURE__*/React__default.default.createElement(StyledBorder, {
957
+ themeFocused: isFocused,
958
+ themeState: state,
959
+ testID: "text-input-border",
960
+ pointerEvents: "none",
961
+ style: [{
962
+ backgroundColor: backgroundColor
963
+ }, borderStyles]
964
+ }), /*#__PURE__*/React__default.default.createElement(StyledInputWrapper, null, !!label && /*#__PURE__*/React__default.default.createElement(FloatingLabel$1, {
965
+ label: label,
966
+ variant: variant,
967
+ state: state,
968
+ isFocused: isFocused,
969
+ required: required,
970
+ accessibilityLabelledBy: accessibilityLabelledBy,
971
+ isEmptyValue: isEmptyValue
972
+ }), /*#__PURE__*/React__default.default.createElement(InputRow, {
973
+ state: state,
974
+ isFocused: isFocused,
975
+ prefix: prefix,
976
+ variant: variant,
977
+ nativeInputProps: nativeInputProps,
978
+ renderInputValue: renderInputValue,
979
+ ref: innerTextInput,
980
+ isEmptyValue: isEmptyValue
981
+ }), /*#__PURE__*/React__default.default.createElement(StyledBottomContainer, null, /*#__PURE__*/React__default.default.createElement(ErrorOrHelpText$1, {
982
+ error: error,
983
+ helpText: helpText
984
+ }), /*#__PURE__*/React__default.default.createElement(MaxLengthMessage$1, {
985
+ state: state,
986
+ currentLength: displayText.length,
987
+ maxLength: maxLength,
988
+ hideCharacterCount: hideCharacterCount
989
+ }))), /*#__PURE__*/React__default.default.createElement(StyledSuffixContainer, null, /*#__PURE__*/React__default.default.createElement(SuffixComponent$1, {
990
+ state: state,
991
+ loading: loading,
992
+ suffix: suffix
993
+ })));
994
+ });
995
+
996
+ exports.TextInput = TextInput;
131
997
  exports.ThemeProvider = WorkThemeProvider;
132
998
  exports.ThemeSwitcher = WorkThemeSwitcher;
133
999
  exports.getTheme = getTheme;