@aws-amplify/ui-react-native 1.2.8 → 1.2.10

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 (40) hide show
  1. package/.eslintrc.js +8 -13
  2. package/.turbo/turbo-build.log +1 -1
  3. package/CHANGELOG.md +26 -0
  4. package/dist/Authenticator/common/DefaultContainer/DefaultContainer.js +1 -9
  5. package/dist/Authenticator/common/DefaultContainer/styles.d.ts +1 -1
  6. package/dist/Authenticator/common/DefaultFormFields/Field.d.ts +1 -0
  7. package/dist/Authenticator/common/DefaultFormFields/FieldErrors.d.ts +1 -0
  8. package/dist/InAppMessaging/hooks/useMessageProps/useMessageProps.js +1 -1
  9. package/dist/InAppMessaging/hooks/useMessageProps/utils.js +2 -1
  10. package/dist/hooks/useDeviceOrientation/useDeviceOrientation.js +2 -1
  11. package/dist/hooks/usePressableContainerStyles/usePressableContainerStyles.js +2 -1
  12. package/dist/primitives/Carousel/Carousel.js +3 -2
  13. package/dist/theme/createTheme.js +13 -16
  14. package/dist/version.d.ts +1 -1
  15. package/dist/version.js +1 -1
  16. package/package.json +12 -11
  17. package/src/Authenticator/common/DefaultContainer/DefaultContainer.tsx +1 -12
  18. package/src/Authenticator/common/DefaultContainer/styles.ts +1 -1
  19. package/src/Authenticator/hooks/useFieldValues/__tests__/useFieldValues.spec.ts +1 -1
  20. package/src/InAppMessaging/components/InAppMessageDisplay/__tests__/InAppMessageDisplay.spec.tsx +2 -2
  21. package/src/InAppMessaging/hooks/useMessageImage/__tests__/useMessageImage.spec.ts +1 -1
  22. package/src/InAppMessaging/hooks/useMessageProps/__tests__/utils.spec.ts +2 -1
  23. package/src/InAppMessaging/hooks/useMessageProps/useMessageProps.ts +1 -1
  24. package/src/InAppMessaging/hooks/useMessageProps/utils.ts +4 -4
  25. package/src/__mocks__/@react-native-community/netinfo.ts +1 -0
  26. package/src/hooks/useDeviceOrientation/__tests__/useDeviceOrientation.spec.ts +5 -3
  27. package/src/hooks/useDeviceOrientation/useDeviceOrientation.ts +3 -1
  28. package/src/hooks/usePressableContainerStyles/usePressableContainerStyles.ts +4 -4
  29. package/src/primitives/Carousel/Carousel.tsx +4 -4
  30. package/src/primitives/Checkbox/__tests__/Checkbox.spec.tsx +2 -7
  31. package/src/theme/createTheme.ts +18 -16
  32. package/src/version.ts +1 -1
  33. package/tsconfig.dist.json +1 -1
  34. package/tsconfig.json +2 -14
  35. package/dist/__mocks__/@react-native-async-storage/async-storage.d.ts +0 -1
  36. package/dist/__mocks__/@react-native-async-storage/async-storage.js +0 -2
  37. package/dist/__mocks__/@react-native-community/netinfo.d.ts +0 -1
  38. package/dist/__mocks__/@react-native-community/netinfo.js +0 -2
  39. package/dist/__mocks__/react-native-safe-area-context.d.ts +0 -8
  40. package/dist/__mocks__/react-native-safe-area-context.js +0 -6
package/.eslintrc.js CHANGED
@@ -23,7 +23,7 @@ module.exports = {
23
23
  parserOptions: {
24
24
  ecmaFeatures: { jsx: true },
25
25
  ecmaVersion: 12,
26
- project: ['./tsconfig.json'],
26
+ project: ['tsconfig.json'],
27
27
  tsconfigRootDir: __dirname,
28
28
  sourceType: 'module',
29
29
  },
@@ -36,13 +36,8 @@ module.exports = {
36
36
  {
37
37
  files: ['**/*.spec.*', '**/*.test.*'],
38
38
  parser: '@typescript-eslint/parser',
39
- parserOptions: {
40
- project: ['./tsconfig.json'],
41
- },
42
39
  plugins: ['@typescript-eslint', 'jest'],
43
40
  rules: {
44
- // Turn the original rule off for test files, turn on the jest rule
45
- '@typescript-eslint/unbound-method': 'off',
46
41
  'jest/unbound-method': 'error',
47
42
  '@typescript-eslint/no-unsafe-assignment': 'off',
48
43
  },
@@ -53,19 +48,19 @@ module.exports = {
53
48
  '@typescript-eslint/explicit-module-boundary-types': 2,
54
49
  '@typescript-eslint/member-ordering': 'error',
55
50
  '@typescript-eslint/no-extra-semi': 'error',
56
- '@typescript-eslint/no-floating-promises': ['off'],
51
+ '@typescript-eslint/no-floating-promises': 'off',
57
52
  '@typescript-eslint/no-unused-expressions': [
58
53
  'error',
59
54
  { allowTernary: true },
60
55
  ],
61
- '@typescript-eslint/no-use-before-define': ['error'],
56
+ '@typescript-eslint/no-use-before-define': 'error',
62
57
  '@typescript-eslint/no-unused-vars': [
63
58
  'error',
64
59
  { argsIgnorePattern: '_', varsIgnorePattern: '_' },
65
60
  ],
66
61
  '@typescript-eslint/prefer-nullish-coalescing': 'error',
67
- '@typescript-eslint/restrict-template-expressions': ['off'],
68
- '@typescript-eslint/unbound-method': 'error',
62
+ '@typescript-eslint/restrict-template-expressions': 'off',
63
+ '@typescript-eslint/unbound-method': 'off',
69
64
 
70
65
  // eslint rules either not in recommended rule set or overridden
71
66
  'comma-dangle': ['error', 'only-multiline'],
@@ -89,13 +84,13 @@ module.exports = {
89
84
  // react rules either not in recommended rule set or overridden
90
85
  'react/destructuring-assignment': ['error', 'always'],
91
86
  'react/jsx-boolean-value': 'error',
92
- 'react/jsx-no-constructed-context-values': ['error'],
87
+ 'react/jsx-no-constructed-context-values': 'error',
93
88
  'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
94
89
  'react/jsx-props-no-spreading': 'off',
95
90
  'react/jsx-wrap-multilines': ['error', { declaration: 'ignore' }],
96
91
  'react/no-array-index-key': 'off',
97
- 'react/no-danger': ['error'],
98
- 'react/no-unused-prop-types': ['error'],
92
+ 'react/no-danger': 'error',
93
+ 'react/no-unused-prop-types': 'error',
99
94
  'react/prop-types': 'off',
100
95
  'react/static-property-placement': ['error', 'static public field'],
101
96
 
@@ -1,3 +1,3 @@
1
1
  $ rimraf dist
2
- $ yarn dist && cp -a src/assets dist
2
+ $ yarn build:dist && cp -a src/assets dist
3
3
  $ tsc --project tsconfig.dist.json
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @aws-amplify/ui-react-native
2
2
 
3
+ ## 1.2.10
4
+
5
+ ### Patch Changes
6
+
7
+ - [#3497](https://github.com/aws-amplify/amplify-ui/pull/3497) [`5249a450d`](https://github.com/aws-amplify/amplify-ui/commit/5249a450dcd07487188fc57d5b6b04dbf52e1970) Thanks [@calebpollman](https://github.com/calebpollman)! - chore(tsconfig): add configs directory and ts configuration
8
+
9
+ - Updated dependencies [[`a55aa4584`](https://github.com/aws-amplify/amplify-ui/commit/a55aa4584dd9aba4e97d4e36acc289238710d30e), [`6501852a7`](https://github.com/aws-amplify/amplify-ui/commit/6501852a7916cc2afb90bfb52461877c1e637b99), [`50fbe91de`](https://github.com/aws-amplify/amplify-ui/commit/50fbe91defab6172c09eb03c71671a5cc5f4d265), [`5249a450d`](https://github.com/aws-amplify/amplify-ui/commit/5249a450dcd07487188fc57d5b6b04dbf52e1970)]:
10
+ - @aws-amplify/ui@5.5.7
11
+ - @aws-amplify/ui-react-core@2.1.15
12
+
13
+ ## 1.2.9
14
+
15
+ ### Patch Changes
16
+
17
+ - [#3483](https://github.com/aws-amplify/amplify-ui/pull/3483) [`d7cc72c72`](https://github.com/aws-amplify/amplify-ui/commit/d7cc72c72844733d42a9504aa2ae1f2249abc178) Thanks [@calebpollman](https://github.com/calebpollman)! - chore(ui-react-native): add TS noImplicitAny for dist build
18
+
19
+ - [#3473](https://github.com/aws-amplify/amplify-ui/pull/3473) [`12d166209`](https://github.com/aws-amplify/amplify-ui/commit/12d166209b91ee94661e586a2f77e9fbf75b3d64) Thanks [@calebpollman](https://github.com/calebpollman)! - chore(ui): remove type-fest
20
+
21
+ - [#3486](https://github.com/aws-amplify/amplify-ui/pull/3486) [`eb9df76f0`](https://github.com/aws-amplify/amplify-ui/commit/eb9df76f0b46aa577965740b476b18d070ccb276) Thanks [@calebpollman](https://github.com/calebpollman)! - chore(ui-react-native): remove extraneous optional chaining
22
+
23
+ - [#3446](https://github.com/aws-amplify/amplify-ui/pull/3446) [`ef40fcc76`](https://github.com/aws-amplify/amplify-ui/commit/ef40fcc7673a1d1ed7c7a006fa34d3d5b029956f) Thanks [@calebpollman](https://github.com/calebpollman)! - refactor(ui-react-native): update default keyboardVerticalOffset handling of RNA DefaultContainer
24
+
25
+ - Updated dependencies [[`3c5fef84c`](https://github.com/aws-amplify/amplify-ui/commit/3c5fef84cb6ad0cb830416e70028c0bb313dd99c), [`e08e62234`](https://github.com/aws-amplify/amplify-ui/commit/e08e6223473f56cbbc2d0ce4bab85ebd1caf020c), [`12d166209`](https://github.com/aws-amplify/amplify-ui/commit/12d166209b91ee94661e586a2f77e9fbf75b3d64), [`e283f14ca`](https://github.com/aws-amplify/amplify-ui/commit/e283f14cadf54c6f6ab7e729151ea5fe97776c6a), [`d28e31c36`](https://github.com/aws-amplify/amplify-ui/commit/d28e31c36a243d04737b6c13ce0307495680498a), [`c3116b894`](https://github.com/aws-amplify/amplify-ui/commit/c3116b89470587c127d53a5cb370b2574bde553a)]:
26
+ - @aws-amplify/ui@5.5.6
27
+ - @aws-amplify/ui-react-core@2.1.14
28
+
3
29
  ## 1.2.8
4
30
 
5
31
  ### Patch Changes
@@ -1,7 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { KeyboardAvoidingView, ScrollView } from 'react-native';
3
3
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
- import { useDeviceOrientation } from '../../../hooks';
5
4
  import { useTheme } from '../../../theme';
6
5
  import { platform } from '../../../utils';
7
6
  import { getThemedStyles } from './styles';
@@ -11,16 +10,9 @@ const BEHAVIOR = platform.IS_IOS ? 'padding' : 'height';
11
10
  // prevent keyboard dismiss when press is handled by `ScrollView` children,
12
11
  // otherwise dismiss
13
12
  const KEYBOARD_SHOULD_PERSIST_TAPS = 'handled';
14
- // TEMPORARY: value to prevent initial `TextField` from being pushed too high
15
- // in default use case
16
- const KEYBOARD_VERTICAL_OFFSET = platform.IS_IOS ? -160 : -80;
17
13
  export default function DefaultContainer({ alwaysBounceVertical = ALWAYS_BOUNCE_VERTICAL, behavior = BEHAVIOR, children, keyboardAvoidingViewStyle, keyboardShouldPersistTaps = KEYBOARD_SHOULD_PERSIST_TAPS, keyboardVerticalOffset, scrollViewContentContainerStyle, style, ...rest }) {
18
14
  const theme = useTheme();
19
- const { isPortraitMode } = useDeviceOrientation();
20
15
  const insets = useSafeAreaInsets();
21
- const verticalOffset = keyboardVerticalOffset ?? isPortraitMode
22
- ? KEYBOARD_VERTICAL_OFFSET
23
- : undefined;
24
16
  const themedStyle = useMemo(() => {
25
17
  const { bottom, left, right, top } = insets;
26
18
  return getThemedStyles(theme, {
@@ -30,7 +22,7 @@ export default function DefaultContainer({ alwaysBounceVertical = ALWAYS_BOUNCE_
30
22
  paddingTop: top,
31
23
  });
32
24
  }, [insets, theme]);
33
- return (<KeyboardAvoidingView behavior={behavior} keyboardVerticalOffset={verticalOffset} style={[themedStyle.keyboardAvoidingView, keyboardAvoidingViewStyle]}>
25
+ return (<KeyboardAvoidingView behavior={behavior} keyboardVerticalOffset={keyboardVerticalOffset} style={[themedStyle.keyboardAvoidingView, keyboardAvoidingViewStyle]}>
34
26
  <ScrollView {...rest} alwaysBounceVertical={alwaysBounceVertical} keyboardShouldPersistTaps={keyboardShouldPersistTaps} contentContainerStyle={[
35
27
  themedStyle.scrollViewContentContainer,
36
28
  scrollViewContentContainerStyle,
@@ -1,5 +1,5 @@
1
1
  import { ViewStyle } from 'react-native';
2
- import { StrictTheme } from 'src/theme';
2
+ import { StrictTheme } from '../../../theme';
3
3
  import { ContainerStyles, InnerContainerStyles } from './types';
4
4
  export declare const getThemedStyles: ({ tokens: { colors } }: StrictTheme, insetPadding: Pick<ViewStyle, 'paddingBottom' | 'paddingLeft' | 'paddingRight' | 'paddingTop'>) => Required<ContainerStyles>;
5
5
  export declare const getInnerContainerStyles: ({ tokens: { space }, }: StrictTheme) => InnerContainerStyles;
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { FieldProps } from './types';
2
3
  declare const Field: {
3
4
  ({ type, ...rest }: FieldProps): JSX.Element;
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  import { FieldErrorsProps } from './types';
2
3
  export declare const FieldErrors: ({ errors, errorStyle, style, }: FieldErrorsProps) => JSX.Element | null;
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useMemo, useRef } from 'react';
2
- import isEmpty from 'lodash/isEmpty';
2
+ import { isEmpty } from '@aws-amplify/ui';
3
3
  import { useMessageImage } from '../useMessageImage';
4
4
  import { getPayloadStyle, getMessageStyles } from './utils';
5
5
  /**
@@ -1,4 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { isFunction } from '@aws-amplify/ui';
2
3
  import { DEFAULT_CAROUSEL_INDICATOR_SIZE } from '../../../primitives';
3
4
  import { BUTTON_PRESSED_OPACITY, SPACING_EXTRA_LARGE } from '../../constants';
4
5
  // Carousel page indicator size + margins
@@ -31,7 +32,7 @@ export const getComponentButtonStyle = ({ styleParams, buttonType, }) => {
31
32
  const pressedOpacity = pressed ? { opacity: BUTTON_PRESSED_OPACITY } : {};
32
33
  // pass `pressed` to containerOverrideStyle and evaluate if the consumer passed a function for custom
33
34
  // button style
34
- const containerOverrideFinalStyle = typeof containerOverrideStyle === 'function'
35
+ const containerOverrideFinalStyle = isFunction(containerOverrideStyle)
35
36
  ? containerOverrideStyle({ pressed })
36
37
  : containerOverrideStyle;
37
38
  return [
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useState } from 'react';
2
2
  import { Dimensions } from 'react-native';
3
+ import { isFunction } from '@aws-amplify/ui';
3
4
  const getDeviceOrientation = () => {
4
5
  const { height, width } = Dimensions.get('screen');
5
6
  return height >= width ? 'portrait' : 'landscape';
@@ -21,7 +22,7 @@ export default function useDeviceOrientation() {
21
22
  // which is deprecated in v0.65
22
23
  const subscription = Dimensions.addEventListener('change', handler);
23
24
  return () => {
24
- if (typeof subscription?.remove === 'function') {
25
+ if (isFunction(subscription?.remove)) {
25
26
  subscription.remove();
26
27
  }
27
28
  else {
@@ -1,7 +1,8 @@
1
1
  import { useCallback } from 'react';
2
+ import { isFunction } from '@aws-amplify/ui';
2
3
  export const usePressableContainerStyles = ({ overrideStyle, containerStyle, pressedStyle, }) => {
3
4
  return useCallback(({ pressed }) => {
4
- const pressedOverrideStyle = typeof overrideStyle === 'function'
5
+ const pressedOverrideStyle = isFunction(overrideStyle)
5
6
  ? overrideStyle({ pressed })
6
7
  : overrideStyle;
7
8
  return [
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { Dimensions, FlatList, View, } from 'react-native';
3
+ import { isFunction } from '@aws-amplify/ui';
3
4
  import CarouselPageIndicator from './CarouselPageIndicator';
4
5
  import { VIEWABILITY_CONFIG } from './constants';
5
6
  import { styles } from './styles';
@@ -39,8 +40,8 @@ export default function Carousel(props) {
39
40
  // Clean up listener. Dimensions.removeEventListener is deprecated as of React Native 0.65 but it is technically
40
41
  // available so try to remove via a `EmitterSubscription` first before falling back to `removeEventListener`
41
42
  return () => {
42
- if (typeof subscription?.remove === 'function') {
43
- subscription?.remove();
43
+ if (isFunction(subscription?.remove)) {
44
+ subscription.remove();
44
45
  }
45
46
  else {
46
47
  Dimensions.removeEventListener('change', orientationHandler);
@@ -1,27 +1,21 @@
1
1
  import deepExtend from 'style-dictionary/lib/utils/deepExtend';
2
2
  import resolveObject from 'style-dictionary/lib/utils/resolveObject';
3
3
  import usesReference from 'style-dictionary/lib/utils/references/usesReference';
4
- import { setupTokens } from '@aws-amplify/ui';
4
+ import { isFunction, setupTokens } from '@aws-amplify/ui';
5
5
  import { defaultTheme } from './defaultTheme';
6
6
  // This will resolve all references in component themes by either
7
7
  // calling the component theme function with the already resolved base tokens
8
8
  // OR
9
9
  // resolving the component theme object
10
- const setupComponents = (theme) => {
11
- const output = {};
12
- if (theme.components) {
13
- const { components } = theme;
14
- for (const [key, value] of Object.entries(components)) {
15
- if (typeof value === 'function') {
16
- output[key] = value(theme.tokens);
17
- }
18
- else {
19
- output[key] = value;
20
- }
21
- }
22
- }
10
+ const setupComponents = ({ components, tokens }) => {
11
+ const output = components
12
+ ? Object.entries(components).reduce((acc, [key, value]) => ({
13
+ ...acc,
14
+ [key]: isFunction(value) ? value(tokens) : value,
15
+ }), {})
16
+ : {};
23
17
  return resolveObject({
24
- ...theme.tokens,
18
+ ...tokens,
25
19
  components: output,
26
20
  }).components;
27
21
  };
@@ -99,7 +93,10 @@ export const createTheme = (theme, colorMode) => {
99
93
  let { components } = mergedTheme;
100
94
  // Resolve component token references too
101
95
  if (mergedTheme.components) {
102
- components = setupComponents({ ...mergedTheme, tokens });
96
+ components = setupComponents({
97
+ ...mergedTheme,
98
+ tokens,
99
+ });
103
100
  }
104
101
  return { ...mergedTheme, tokens, components };
105
102
  };
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "1.2.8";
1
+ export declare const VERSION = "1.2.10";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '1.2.8';
1
+ export const VERSION = '1.2.10';
package/package.json CHANGED
@@ -1,19 +1,21 @@
1
1
  {
2
2
  "name": "@aws-amplify/ui-react-native",
3
- "version": "1.2.8",
3
+ "version": "1.2.10",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "Apache-2.0",
8
8
  "scripts": {
9
- "build": "yarn dist && cp -a src/assets dist",
9
+ "build": "yarn build:dist && cp -a src/assets dist",
10
+ "build:dist": "tsc --project tsconfig.dist.json",
10
11
  "clean": "rimraf dist",
11
- "dev": "yarn dist --watch",
12
- "dist": "tsc --project tsconfig.dist.json",
13
- "lint": "tsc --noEmit && eslint src",
12
+ "dev": "yarn build:dist --watch",
13
+ "lint": "yarn typecheck && eslint src",
14
14
  "prebuild": "rimraf dist",
15
- "test": "jest --coverage --verbose",
16
- "test:watch": "yarn test --watch"
15
+ "test": "yarn test:unit",
16
+ "test:unit": "jest",
17
+ "test:unit:watch": "yarn test:unit --watch",
18
+ "typecheck": "tsc --noEmit"
17
19
  },
18
20
  "devDependencies": {
19
21
  "@babel/cli": "^7.17.10",
@@ -39,12 +41,11 @@
39
41
  "react-native": "^0.68.1",
40
42
  "react-native-safe-area-context": "^4.2.5",
41
43
  "react-test-renderer": "^17.0.2",
42
- "rimraf": "^3.0.2",
43
- "type-fest": "^2.3.4"
44
+ "rimraf": "^3.0.2"
44
45
  },
45
46
  "dependencies": {
46
- "@aws-amplify/ui": "5.5.5",
47
- "@aws-amplify/ui-react-core": "2.1.13"
47
+ "@aws-amplify/ui": "5.5.7",
48
+ "@aws-amplify/ui-react-core": "2.1.15"
48
49
  },
49
50
  "peerDependencies": {
50
51
  "aws-amplify": ">= 5.0.1",
@@ -2,7 +2,6 @@ import React, { useMemo } from 'react';
2
2
  import { KeyboardAvoidingView, ScrollView } from 'react-native';
3
3
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
4
 
5
- import { useDeviceOrientation } from '../../../hooks';
6
5
  import { useTheme } from '../../../theme';
7
6
  import { platform } from '../../../utils';
8
7
 
@@ -17,10 +16,6 @@ const BEHAVIOR = platform.IS_IOS ? 'padding' : 'height';
17
16
  // otherwise dismiss
18
17
  const KEYBOARD_SHOULD_PERSIST_TAPS = 'handled';
19
18
 
20
- // TEMPORARY: value to prevent initial `TextField` from being pushed too high
21
- // in default use case
22
- const KEYBOARD_VERTICAL_OFFSET = platform.IS_IOS ? -160 : -80;
23
-
24
19
  export default function DefaultContainer({
25
20
  alwaysBounceVertical = ALWAYS_BOUNCE_VERTICAL,
26
21
  behavior = BEHAVIOR,
@@ -33,14 +28,8 @@ export default function DefaultContainer({
33
28
  ...rest
34
29
  }: ContainerProps): JSX.Element | null {
35
30
  const theme = useTheme();
36
- const { isPortraitMode } = useDeviceOrientation();
37
31
  const insets = useSafeAreaInsets();
38
32
 
39
- const verticalOffset =
40
- keyboardVerticalOffset ?? isPortraitMode
41
- ? KEYBOARD_VERTICAL_OFFSET
42
- : undefined;
43
-
44
33
  const themedStyle = useMemo(() => {
45
34
  const { bottom, left, right, top } = insets;
46
35
  return getThemedStyles(theme, {
@@ -54,7 +43,7 @@ export default function DefaultContainer({
54
43
  return (
55
44
  <KeyboardAvoidingView
56
45
  behavior={behavior}
57
- keyboardVerticalOffset={verticalOffset}
46
+ keyboardVerticalOffset={keyboardVerticalOffset}
58
47
  style={[themedStyle.keyboardAvoidingView, keyboardAvoidingViewStyle]}
59
48
  >
60
49
  <ScrollView
@@ -1,5 +1,5 @@
1
1
  import { StyleSheet, ViewStyle } from 'react-native';
2
- import { StrictTheme } from 'src/theme';
2
+ import { StrictTheme } from '../../../theme';
3
3
 
4
4
  import { ContainerStyles, InnerContainerStyles } from './types';
5
5
 
@@ -27,7 +27,7 @@ const radioField = {
27
27
  onChange: jest.fn,
28
28
  } as RadioFieldOptions;
29
29
 
30
- const mockfields = [];
30
+ const mockfields = [] as TypedField[];
31
31
  const props: UseFieldValuesParams<TypedField> = {
32
32
  componentName: 'SignIn',
33
33
  fields: mockfields,
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Text, View } from 'react-native';
3
3
  import { render } from '@testing-library/react-native';
4
- import { useMessage } from '@aws-amplify/ui-react-core';
4
+ import { MessageLayout, useMessage } from '@aws-amplify/ui-react-core';
5
5
 
6
6
  import InAppMessageDisplay from '../InAppMessageDisplay';
7
7
 
@@ -15,7 +15,7 @@ describe('InAppMessageDisplay', () => {
15
15
  });
16
16
 
17
17
  it('renders the expected component in the happy path', () => {
18
- const Component = ({ layout }) => (
18
+ const Component = ({ layout }: { layout: MessageLayout }) => (
19
19
  <View>
20
20
  <Text>{layout}</Text>
21
21
  </View>
@@ -60,7 +60,7 @@ describe('useMessageImage', () => {
60
60
 
61
61
  (prefetchNetworkImage as jest.Mock).mockResolvedValue('loaded');
62
62
  (Image.getSize as jest.Mock).mockImplementationOnce(
63
- (_, __, onError: (error) => void) => {
63
+ (_, __, onError: (error: string) => void) => {
64
64
  onError(error);
65
65
  }
66
66
  );
@@ -139,7 +139,8 @@ describe('getComponentButtonStyle', () => {
139
139
  const unpressedStyle = { backgroundColor: 'fuschia' };
140
140
  const overrideStyle = {
141
141
  primaryButton: {
142
- container: ({ pressed }) => (pressed ? pressedStyle : unpressedStyle),
142
+ container: ({ pressed }: { pressed: boolean }) =>
143
+ pressed ? pressedStyle : unpressedStyle,
143
144
  },
144
145
  };
145
146
  const styleParams = {
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useMemo, useRef } from 'react';
2
- import isEmpty from 'lodash/isEmpty';
2
+ import { isEmpty } from '@aws-amplify/ui';
3
3
  import { MessageComponentBaseProps } from '@aws-amplify/ui-react-core';
4
4
 
5
5
  import { useMessageImage } from '../useMessageImage';
@@ -1,4 +1,5 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { isFunction } from '@aws-amplify/ui';
2
3
  import {
3
4
  MessageComponentBaseProps,
4
5
  MessageLayout,
@@ -64,10 +65,9 @@ export const getComponentButtonStyle = ({
64
65
 
65
66
  // pass `pressed` to containerOverrideStyle and evaluate if the consumer passed a function for custom
66
67
  // button style
67
- const containerOverrideFinalStyle =
68
- typeof containerOverrideStyle === 'function'
69
- ? containerOverrideStyle({ pressed })
70
- : containerOverrideStyle;
68
+ const containerOverrideFinalStyle = isFunction(containerOverrideStyle)
69
+ ? containerOverrideStyle({ pressed })
70
+ : containerOverrideStyle;
71
71
 
72
72
  return [
73
73
  pressedOpacity,
@@ -1,2 +1,3 @@
1
1
  // mock RN NetInfo module to prevent errors from Amplify JS usage of the module
2
+ // @ts-ignore - ignoring as this is a JS mock
2
3
  export { default } from '@react-native-community/netinfo/jest/netinfo-mock.js';
@@ -1,6 +1,8 @@
1
- import { Dimensions, EventSubscription, ScaledSize } from 'react-native';
1
+ import { Dimensions, EventSubscription } from 'react-native';
2
2
  import { renderHook } from '@testing-library/react-hooks';
3
- import useDeviceOrientation from '../useDeviceOrientation';
3
+ import useDeviceOrientation, {
4
+ DeviceOrientation,
5
+ } from '../useDeviceOrientation';
4
6
 
5
7
  const dimensions = {
6
8
  landscape: { height: 100, width: 300 },
@@ -74,7 +76,7 @@ describe('useDeviceOrientation', () => {
74
76
  'returns the expected values when the device is in %s mode',
75
77
  (deviceOrientation, isLandscapeMode, isPortraitMode) => {
76
78
  getSpy.mockImplementation(
77
- (_: string) => dimensions[deviceOrientation] as ScaledSize
79
+ (_: string) => dimensions[deviceOrientation as DeviceOrientation]
78
80
  );
79
81
 
80
82
  const { result } = renderHook(() => useDeviceOrientation());
@@ -1,6 +1,8 @@
1
1
  import { useEffect, useState } from 'react';
2
2
  import { Dimensions, EventSubscription } from 'react-native';
3
3
 
4
+ import { isFunction } from '@aws-amplify/ui';
5
+
4
6
  export type DeviceOrientation = 'portrait' | 'landscape';
5
7
  const getDeviceOrientation = (): DeviceOrientation => {
6
8
  const { height, width } = Dimensions.get('screen');
@@ -35,7 +37,7 @@ export default function useDeviceOrientation(): {
35
37
  ) as unknown as EventSubscription;
36
38
 
37
39
  return () => {
38
- if (typeof subscription?.remove === 'function') {
40
+ if (isFunction(subscription?.remove)) {
39
41
  subscription.remove();
40
42
  } else {
41
43
  Dimensions.removeEventListener('change', handler);
@@ -1,4 +1,5 @@
1
1
  import { useCallback } from 'react';
2
+ import { isFunction } from '@aws-amplify/ui';
2
3
  import {
3
4
  PressableProps,
4
5
  PressableStateCallbackType,
@@ -35,10 +36,9 @@ export const usePressableContainerStyles = ({
35
36
  }: PressableStateCallbackType) => StyleProp<ViewStyle>) => {
36
37
  return useCallback(
37
38
  ({ pressed }: PressableStateCallbackType): StyleProp<ViewStyle> => {
38
- const pressedOverrideStyle =
39
- typeof overrideStyle === 'function'
40
- ? overrideStyle({ pressed })
41
- : overrideStyle;
39
+ const pressedOverrideStyle = isFunction(overrideStyle)
40
+ ? overrideStyle({ pressed })
41
+ : overrideStyle;
42
42
  return [
43
43
  containerStyle,
44
44
  pressed ? pressedStyle : undefined,
@@ -1,13 +1,13 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import {
3
3
  Dimensions,
4
- EventSubscription,
5
4
  FlatList,
6
5
  ListRenderItemInfo,
7
6
  ScaledSize,
8
7
  View,
9
8
  ViewToken,
10
9
  } from 'react-native';
10
+ import { isFunction } from '@aws-amplify/ui';
11
11
 
12
12
  import CarouselPageIndicator from './CarouselPageIndicator';
13
13
  import { VIEWABILITY_CONFIG } from './constants';
@@ -63,13 +63,13 @@ export default function Carousel<T>(
63
63
  const subscription = Dimensions.addEventListener(
64
64
  'change',
65
65
  orientationHandler
66
- ) as unknown as EventSubscription;
66
+ );
67
67
 
68
68
  // Clean up listener. Dimensions.removeEventListener is deprecated as of React Native 0.65 but it is technically
69
69
  // available so try to remove via a `EmitterSubscription` first before falling back to `removeEventListener`
70
70
  return () => {
71
- if (typeof subscription?.remove === 'function') {
72
- subscription?.remove();
71
+ if (isFunction(subscription?.remove)) {
72
+ subscription.remove();
73
73
  } else {
74
74
  Dimensions.removeEventListener('change', orientationHandler);
75
75
  }
@@ -6,7 +6,6 @@ import Checkbox from '../Checkbox';
6
6
  import { useTheme } from '../../../theme';
7
7
  import { getThemedStyles } from '../styles';
8
8
  import { icons } from '../../../assets';
9
- import { IconStyles } from '../../Icon/types';
10
9
 
11
10
  const onChange = jest.fn();
12
11
  const testID = 'checkboxTestID';
@@ -106,9 +105,7 @@ describe('Checkbox', () => {
106
105
  undefined,
107
106
  ]);
108
107
 
109
- const iconStyle = (
110
- getByRole('image').props.style as IconStyles
111
- )[0] as ImageStyle;
108
+ const iconStyle = (getByRole('image').props.style as ImageStyle[])[0];
112
109
  expect(iconStyle.height).toBe(customSize);
113
110
  expect(iconStyle.width).toBe(customSize);
114
111
  });
@@ -121,9 +118,7 @@ describe('Checkbox', () => {
121
118
 
122
119
  expect(toJSON()).toMatchSnapshot();
123
120
 
124
- const checkboxStyle = (
125
- getByTestId(testID).props.style as IconStyles
126
- )[0] as ViewStyle;
121
+ const checkboxStyle = (getByTestId(testID).props.style as ViewStyle[])[0];
127
122
  expect(checkboxStyle.flexDirection).toBe('column');
128
123
  });
129
124
 
@@ -1,28 +1,27 @@
1
1
  import deepExtend from 'style-dictionary/lib/utils/deepExtend';
2
2
  import resolveObject from 'style-dictionary/lib/utils/resolveObject';
3
3
  import usesReference from 'style-dictionary/lib/utils/references/usesReference';
4
- import { setupTokens } from '@aws-amplify/ui';
5
- import { Theme, StrictTheme, ColorMode } from './types';
4
+ import { isFunction, setupTokens } from '@aws-amplify/ui';
5
+ import { Theme, StrictTheme, ColorMode, Components } from './types';
6
6
  import { defaultTheme } from './defaultTheme';
7
7
 
8
8
  // This will resolve all references in component themes by either
9
9
  // calling the component theme function with the already resolved base tokens
10
10
  // OR
11
11
  // resolving the component theme object
12
- const setupComponents = (theme: StrictTheme) => {
13
- const output = {};
14
- if (theme.components) {
15
- const { components } = theme;
16
- for (const [key, value] of Object.entries(components)) {
17
- if (typeof value === 'function') {
18
- output[key] = value(theme.tokens) as object;
19
- } else {
20
- output[key] = value;
21
- }
22
- }
23
- }
12
+ const setupComponents = ({ components, tokens }: StrictTheme) => {
13
+ const output = components
14
+ ? Object.entries(components).reduce(
15
+ (acc, [key, value]) => ({
16
+ ...acc,
17
+ [key]: isFunction(value) ? (value(tokens) as typeof value) : value,
18
+ }),
19
+ {} as Components<'components'>
20
+ )
21
+ : {};
22
+
24
23
  return resolveObject({
25
- ...theme.tokens,
24
+ ...tokens,
26
25
  components: output,
27
26
  }).components;
28
27
  };
@@ -123,7 +122,10 @@ export const createTheme = (
123
122
 
124
123
  // Resolve component token references too
125
124
  if (mergedTheme.components) {
126
- components = setupComponents({ ...mergedTheme, tokens });
125
+ components = setupComponents({
126
+ ...mergedTheme,
127
+ tokens,
128
+ }) as Components<'output'>;
127
129
  }
128
130
 
129
131
  return { ...mergedTheme, tokens, components };
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = '1.2.8';
1
+ export const VERSION = '1.2.10';
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
- "exclude": ["node_modules", "**/__tests__/**.*"]
3
+ "exclude": ["node_modules", "**/__mocks__", "**/__tests__"]
4
4
  }
package/tsconfig.json CHANGED
@@ -1,20 +1,8 @@
1
1
  {
2
+ "extends": "../configs/ts/tsconfig.react-native.json",
2
3
  "compilerOptions": {
3
- "allowSyntheticDefaultImports": true,
4
- "baseUrl": ".",
5
- "declaration": true,
6
- "downlevelIteration": true,
7
- "esModuleInterop": true,
8
- "jsx": "react-native",
9
- "noImplicitAny": false,
10
- "module": "es2015",
11
- "moduleResolution": "node",
12
- "noEmitOnError": true,
13
4
  "outDir": "./dist",
14
- "rootDir": "src",
15
- "skipLibCheck": true,
16
- "strict": true,
17
- "target": "esnext"
5
+ "rootDir": "src"
18
6
  },
19
7
  "include": ["src/**/*.ts", "src/**/*.tsx"],
20
8
  "exclude": ["node_modules"]
@@ -1 +0,0 @@
1
- export { default } from '@react-native-async-storage/async-storage/jest/async-storage-mock';
@@ -1,2 +0,0 @@
1
- // mock RN AsyncStorage module to prevent errors from Amplify JS usage of the module
2
- export { default } from '@react-native-async-storage/async-storage/jest/async-storage-mock';
@@ -1 +0,0 @@
1
- export { default } from '@react-native-community/netinfo/jest/netinfo-mock.js';
@@ -1,2 +0,0 @@
1
- // mock RN NetInfo module to prevent errors from Amplify JS usage of the module
2
- export { default } from '@react-native-community/netinfo/jest/netinfo-mock.js';
@@ -1,8 +0,0 @@
1
- /// <reference types="jest" />
2
- declare const SafeAreaProvider = "SafeAreaProvider";
3
- declare const SafeAreaView = "SafeAreaView";
4
- declare const useSafeAreaInsets: jest.Mock<{
5
- bottom: number;
6
- top: number;
7
- }, []>;
8
- export { SafeAreaProvider, SafeAreaView, useSafeAreaInsets };
@@ -1,6 +0,0 @@
1
- jest.mock('react-native-safe-area-context');
2
- const SafeAreaProvider = 'SafeAreaProvider';
3
- const SafeAreaView = 'SafeAreaView';
4
- // return somewhat arbitrary values, safe area insets of iPhone 13
5
- const useSafeAreaInsets = jest.fn(() => ({ bottom: 44, top: 47 }));
6
- export { SafeAreaProvider, SafeAreaView, useSafeAreaInsets };