jfs-components 0.0.74 → 0.0.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +109 -0
- package/lib/commonjs/components/Accordion/Accordion.js +55 -55
- package/lib/commonjs/components/ActionFooter/ActionFooter.js +193 -82
- package/lib/commonjs/components/Avatar/Avatar.js +20 -0
- package/lib/commonjs/components/Badge/Badge.js +23 -0
- package/lib/commonjs/components/Button/Button.js +37 -0
- package/lib/commonjs/components/Checkbox/Checkbox.js +21 -9
- package/lib/commonjs/components/DropdownInput/DropdownInput.js +30 -16
- package/lib/commonjs/components/ExpandableCheckbox/ExpandableCheckbox.js +167 -0
- package/lib/commonjs/components/FormField/FormField.js +14 -1
- package/lib/commonjs/components/FullscreenModal/FullscreenModal.js +355 -0
- package/lib/commonjs/components/IconButton/IconButton.js +20 -0
- package/lib/commonjs/components/Image/Image.js +26 -1
- package/lib/commonjs/components/ListItem/ListItem.js +25 -10
- package/lib/commonjs/components/LottiePlayer/LottiePlayer.js +116 -0
- package/lib/commonjs/components/LottiePlayer/LottiePlayer.web.js +82 -0
- package/lib/commonjs/components/LottiePlayer/loadNativeLottieView.js +74 -0
- package/lib/commonjs/components/LottiePlayer/loadWebLottieView.js +50 -0
- package/lib/commonjs/components/MessageField/MessageField.js +318 -0
- package/lib/commonjs/components/NavArrow/NavArrow.js +58 -17
- package/lib/commonjs/components/PageHero/PageHero.js +41 -5
- package/lib/commonjs/components/RechargeCard/RechargeCard.js +32 -17
- package/lib/commonjs/components/Stepper/Step.js +47 -60
- package/lib/commonjs/components/Stepper/StepLabel.js +40 -10
- package/lib/commonjs/components/Stepper/Stepper.js +15 -17
- package/lib/commonjs/components/SuggestiveSearch/SuggestiveSearch.js +487 -0
- package/lib/commonjs/components/Text/Text.js +31 -1
- package/lib/commonjs/components/TextInput/TextInput.js +16 -1
- package/lib/commonjs/components/Title/Title.js +10 -2
- package/lib/commonjs/components/index.js +35 -0
- package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/commonjs/icons/Icon.js +16 -0
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/commonjs/index.js +12 -0
- package/lib/commonjs/skeleton/Skeleton.js +234 -0
- package/lib/commonjs/skeleton/SkeletonGroup.js +140 -0
- package/lib/commonjs/skeleton/index.js +58 -0
- package/lib/commonjs/skeleton/shimmer-tokens.js +189 -0
- package/lib/commonjs/skeleton/useReducedMotion.js +64 -0
- package/lib/module/components/Accordion/Accordion.js +56 -56
- package/lib/module/components/ActionFooter/ActionFooter.js +193 -83
- package/lib/module/components/Avatar/Avatar.js +19 -0
- package/lib/module/components/Badge/Badge.js +23 -0
- package/lib/module/components/Button/Button.js +37 -0
- package/lib/module/components/Checkbox/Checkbox.js +22 -10
- package/lib/module/components/DropdownInput/DropdownInput.js +30 -16
- package/lib/module/components/ExpandableCheckbox/ExpandableCheckbox.js +161 -0
- package/lib/module/components/FormField/FormField.js +16 -3
- package/lib/module/components/FullscreenModal/FullscreenModal.js +350 -0
- package/lib/module/components/IconButton/IconButton.js +20 -0
- package/lib/module/components/Image/Image.js +25 -1
- package/lib/module/components/ListItem/ListItem.js +25 -10
- package/lib/module/components/LottiePlayer/LottiePlayer.js +111 -0
- package/lib/module/components/LottiePlayer/LottiePlayer.web.js +77 -0
- package/lib/module/components/LottiePlayer/loadNativeLottieView.js +69 -0
- package/lib/module/components/LottiePlayer/loadWebLottieView.js +45 -0
- package/lib/module/components/MessageField/MessageField.js +313 -0
- package/lib/module/components/NavArrow/NavArrow.js +59 -18
- package/lib/module/components/PageHero/PageHero.js +41 -5
- package/lib/module/components/RechargeCard/RechargeCard.js +33 -17
- package/lib/module/components/Stepper/Step.js +48 -61
- package/lib/module/components/Stepper/StepLabel.js +40 -10
- package/lib/module/components/Stepper/Stepper.js +15 -17
- package/lib/module/components/SuggestiveSearch/SuggestiveSearch.js +481 -0
- package/lib/module/components/Text/Text.js +31 -1
- package/lib/module/components/TextInput/TextInput.js +17 -2
- package/lib/module/components/Title/Title.js +10 -2
- package/lib/module/components/index.js +5 -0
- package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/module/icons/Icon.js +16 -0
- package/lib/module/icons/registry.js +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/skeleton/Skeleton.js +229 -0
- package/lib/module/skeleton/SkeletonGroup.js +133 -0
- package/lib/module/skeleton/index.js +6 -0
- package/lib/module/skeleton/shimmer-tokens.js +181 -0
- package/lib/module/skeleton/useReducedMotion.js +61 -0
- package/lib/typescript/src/components/Accordion/Accordion.d.ts +14 -20
- package/lib/typescript/src/components/ActionFooter/ActionFooter.d.ts +26 -21
- package/lib/typescript/src/components/Avatar/Avatar.d.ts +7 -1
- package/lib/typescript/src/components/Badge/Badge.d.ts +7 -1
- package/lib/typescript/src/components/Button/Button.d.ts +8 -1
- package/lib/typescript/src/components/ExpandableCheckbox/ExpandableCheckbox.d.ts +63 -0
- package/lib/typescript/src/components/FullscreenModal/FullscreenModal.d.ts +99 -0
- package/lib/typescript/src/components/IconButton/IconButton.d.ts +7 -1
- package/lib/typescript/src/components/Image/Image.d.ts +8 -1
- package/lib/typescript/src/components/LottiePlayer/LottiePlayer.d.ts +85 -0
- package/lib/typescript/src/components/LottiePlayer/LottiePlayer.web.d.ts +28 -0
- package/lib/typescript/src/components/LottiePlayer/loadNativeLottieView.d.ts +11 -0
- package/lib/typescript/src/components/LottiePlayer/loadWebLottieView.d.ts +11 -0
- package/lib/typescript/src/components/MessageField/MessageField.d.ts +81 -0
- package/lib/typescript/src/components/NavArrow/NavArrow.d.ts +10 -5
- package/lib/typescript/src/components/PageHero/PageHero.d.ts +31 -5
- package/lib/typescript/src/components/Stepper/Step.d.ts +4 -1
- package/lib/typescript/src/components/Stepper/StepLabel.d.ts +4 -1
- package/lib/typescript/src/components/Stepper/Stepper.d.ts +3 -1
- package/lib/typescript/src/components/SuggestiveSearch/SuggestiveSearch.d.ts +123 -0
- package/lib/typescript/src/components/Text/Text.d.ts +20 -1
- package/lib/typescript/src/components/index.d.ts +8 -3
- package/lib/typescript/src/icons/Icon.d.ts +7 -1
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/skeleton/Skeleton.d.ts +60 -0
- package/lib/typescript/src/skeleton/SkeletonGroup.d.ts +78 -0
- package/lib/typescript/src/skeleton/index.d.ts +5 -0
- package/lib/typescript/src/skeleton/shimmer-tokens.d.ts +160 -0
- package/lib/typescript/src/skeleton/useReducedMotion.d.ts +15 -0
- package/package.json +11 -1
- package/src/components/Accordion/Accordion.tsx +113 -73
- package/src/components/ActionFooter/ActionFooter.tsx +210 -92
- package/src/components/Avatar/Avatar.tsx +26 -0
- package/src/components/Badge/Badge.tsx +27 -0
- package/src/components/Button/Button.tsx +40 -0
- package/src/components/Checkbox/Checkbox.tsx +22 -9
- package/src/components/DropdownInput/DropdownInput.tsx +67 -39
- package/src/components/ExpandableCheckbox/ExpandableCheckbox.tsx +237 -0
- package/src/components/FormField/FormField.tsx +19 -3
- package/src/components/FullscreenModal/FullscreenModal.tsx +414 -0
- package/src/components/IconButton/IconButton.tsx +27 -0
- package/src/components/Image/Image.tsx +25 -0
- package/src/components/ListItem/ListItem.tsx +21 -10
- package/src/components/LottiePlayer/LottiePlayer.tsx +145 -0
- package/src/components/LottiePlayer/LottiePlayer.web.tsx +94 -0
- package/src/components/LottiePlayer/loadNativeLottieView.tsx +87 -0
- package/src/components/LottiePlayer/loadWebLottieView.tsx +64 -0
- package/src/components/MessageField/MessageField.tsx +543 -0
- package/src/components/NavArrow/NavArrow.tsx +81 -17
- package/src/components/PageHero/PageHero.tsx +61 -4
- package/src/components/RechargeCard/RechargeCard.tsx +32 -24
- package/src/components/Stepper/Step.tsx +52 -51
- package/src/components/Stepper/StepLabel.tsx +46 -9
- package/src/components/Stepper/Stepper.tsx +20 -15
- package/src/components/SuggestiveSearch/SuggestiveSearch.tsx +756 -0
- package/src/components/Text/Text.tsx +54 -0
- package/src/components/TextInput/TextInput.tsx +14 -1
- package/src/components/Title/Title.tsx +13 -2
- package/src/components/index.ts +8 -3
- package/src/design-tokens/Coin Variables-variables-full.json +1 -1
- package/src/icons/Icon.tsx +17 -0
- package/src/icons/registry.ts +1 -1
- package/src/index.ts +1 -0
- package/src/skeleton/Skeleton.tsx +298 -0
- package/src/skeleton/SkeletonGroup.tsx +193 -0
- package/src/skeleton/index.ts +10 -0
- package/src/skeleton/shimmer-tokens.ts +221 -0
- package/src/skeleton/useReducedMotion.ts +72 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import React, { useMemo } from 'react'
|
|
2
|
+
import { View, type StyleProp, type ViewStyle } from 'react-native'
|
|
3
|
+
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
4
|
+
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
5
|
+
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
6
|
+
import { getNativeLottieView } from './loadNativeLottieView'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A parsed Lottie animation. The JSON object you get from
|
|
10
|
+
* `require('./animation.json')` or `fetch().then(r => r.json())`. We keep the
|
|
11
|
+
* type intentionally loose because both `lottie-react-native` and `lottie-react`
|
|
12
|
+
* accept slightly different shapes — `LottiePlayer` narrows back to the
|
|
13
|
+
* platform-specific type internally.
|
|
14
|
+
*/
|
|
15
|
+
export type LottieAnimationSource = Record<string, unknown>
|
|
16
|
+
|
|
17
|
+
export type LottiePlayerProps = {
|
|
18
|
+
/**
|
|
19
|
+
* Parsed Lottie animation JSON. Use `require('./animation.json')` in React
|
|
20
|
+
* Native or `import animation from './animation.json'` on web.
|
|
21
|
+
*
|
|
22
|
+
* URI sources (`{ uri: '...' }`) are intentionally not accepted here — web
|
|
23
|
+
* Lottie players require the animation data to be pre-parsed. Fetch and
|
|
24
|
+
* parse the JSON yourself before passing it in if you need a remote source.
|
|
25
|
+
*/
|
|
26
|
+
source: LottieAnimationSource
|
|
27
|
+
/**
|
|
28
|
+
* Override the rendered size. Pass a number for a square box, or
|
|
29
|
+
* `{ width, height }` for non-square.
|
|
30
|
+
*
|
|
31
|
+
* When omitted, size is resolved from the `media/width` and `media/height`
|
|
32
|
+
* design tokens (default `117 × 117`). The `Media / Output` collection
|
|
33
|
+
* exposes `L | M | S` modes (117 / 70 / 20) — pass
|
|
34
|
+
* `modes={{ 'Media / Output': 'M' }}` to render at 70×70, etc.
|
|
35
|
+
*/
|
|
36
|
+
size?: number | { width: number; height: number }
|
|
37
|
+
/** Play the animation on mount. Defaults to `true`. */
|
|
38
|
+
autoPlay?: boolean
|
|
39
|
+
/** Loop the animation. Defaults to `true`. */
|
|
40
|
+
loop?: boolean
|
|
41
|
+
/** Mode configuration for design-token theming. */
|
|
42
|
+
modes?: Record<string, any>
|
|
43
|
+
/** Style overrides applied to the underlying view. */
|
|
44
|
+
style?: StyleProp<ViewStyle>
|
|
45
|
+
/** Accessibility label. Lottie is decorative by default. */
|
|
46
|
+
accessibilityLabel?: string
|
|
47
|
+
testID?: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const DEFAULT_SIZE = 117
|
|
51
|
+
|
|
52
|
+
function resolveSize(
|
|
53
|
+
size: LottiePlayerProps['size'],
|
|
54
|
+
modes: Record<string, any>
|
|
55
|
+
) {
|
|
56
|
+
if (typeof size === 'number') return { width: size, height: size }
|
|
57
|
+
if (size && typeof size === 'object') return size
|
|
58
|
+
const width =
|
|
59
|
+
Number(getVariableByName('media/width', modes)) || DEFAULT_SIZE
|
|
60
|
+
const height =
|
|
61
|
+
Number(getVariableByName('media/height', modes)) || DEFAULT_SIZE
|
|
62
|
+
return { width, height }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Renders a Lottie animation using the consumer's installed
|
|
67
|
+
* `lottie-react-native` (native) or `lottie-react` (web) — both are declared
|
|
68
|
+
* as **optional peer dependencies** of `jfs-components`, so installing the
|
|
69
|
+
* library does not pull them in. Add the relevant package to your app only
|
|
70
|
+
* if you actually use `LottiePlayer`:
|
|
71
|
+
*
|
|
72
|
+
* ```sh
|
|
73
|
+
* # React Native (iOS / Android)
|
|
74
|
+
* npm install lottie-react-native
|
|
75
|
+
* cd ios && pod install
|
|
76
|
+
*
|
|
77
|
+
* # Web (or react-native-web)
|
|
78
|
+
* npm install lottie-react
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* The web build (`LottiePlayer.web.tsx`) is picked automatically by Metro /
|
|
82
|
+
* webpack via platform extensions — same pattern as `MediaCard/GlassFill`.
|
|
83
|
+
*
|
|
84
|
+
* Token-driven sizing: when `size` is omitted, `LottiePlayer` reads
|
|
85
|
+
* `media/width` and `media/height` from the Figma variables resolver, so the
|
|
86
|
+
* animation matches the surrounding component's `Media / Output` mode
|
|
87
|
+
* automatically. This is the same sizing contract `PageHero` and
|
|
88
|
+
* `LottieIntroBlock` use for their `media` slots.
|
|
89
|
+
*
|
|
90
|
+
* @component
|
|
91
|
+
* @example
|
|
92
|
+
* ```tsx
|
|
93
|
+
* import animation from './assets/loader.json';
|
|
94
|
+
*
|
|
95
|
+
* <LottiePlayer source={animation} /> // 117 × 117 (default)
|
|
96
|
+
* <LottiePlayer source={animation} size={70} /> // 70 × 70
|
|
97
|
+
* <LottiePlayer source={animation} modes={{ 'Media / Output': 'S' }} /> // 20 × 20
|
|
98
|
+
* <PageHero media={<LottiePlayer source={animation} />} />
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
function LottiePlayer({
|
|
102
|
+
source,
|
|
103
|
+
size,
|
|
104
|
+
autoPlay = true,
|
|
105
|
+
loop = true,
|
|
106
|
+
modes: propModes = EMPTY_MODES,
|
|
107
|
+
style,
|
|
108
|
+
accessibilityLabel,
|
|
109
|
+
testID,
|
|
110
|
+
}: LottiePlayerProps) {
|
|
111
|
+
const { modes: globalModes } = useTokens()
|
|
112
|
+
const modes = useMemo(
|
|
113
|
+
() =>
|
|
114
|
+
globalModes === EMPTY_MODES && propModes === EMPTY_MODES
|
|
115
|
+
? EMPTY_MODES
|
|
116
|
+
: { ...globalModes, ...propModes },
|
|
117
|
+
[globalModes, propModes]
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
const { width, height } = useMemo(
|
|
121
|
+
() => resolveSize(size, modes),
|
|
122
|
+
[size, modes]
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
const NativeLottieView = useMemo(() => getNativeLottieView(), [])
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<View
|
|
129
|
+
style={[{ width, height }, style]}
|
|
130
|
+
testID={testID}
|
|
131
|
+
accessibilityLabel={accessibilityLabel}
|
|
132
|
+
accessibilityElementsHidden={accessibilityLabel ? undefined : true}
|
|
133
|
+
importantForAccessibility={accessibilityLabel ? 'auto' : 'no'}
|
|
134
|
+
>
|
|
135
|
+
<NativeLottieView
|
|
136
|
+
source={source}
|
|
137
|
+
autoPlay={autoPlay}
|
|
138
|
+
loop={loop}
|
|
139
|
+
style={{ width: '100%', height: '100%' }}
|
|
140
|
+
/>
|
|
141
|
+
</View>
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export default React.memo(LottiePlayer)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React, { useMemo } from 'react'
|
|
2
|
+
import { type StyleProp, type ViewStyle } from 'react-native'
|
|
3
|
+
import { getVariableByName } from '../../design-tokens/figma-variables-resolver'
|
|
4
|
+
import { useTokens } from '../../design-tokens/JFSThemeProvider'
|
|
5
|
+
import { EMPTY_MODES } from '../../utils/react-utils'
|
|
6
|
+
import { getWebLottieView } from './loadWebLottieView'
|
|
7
|
+
|
|
8
|
+
export type LottieAnimationSource = Record<string, unknown>
|
|
9
|
+
|
|
10
|
+
export type LottiePlayerProps = {
|
|
11
|
+
source: LottieAnimationSource
|
|
12
|
+
size?: number | { width: number; height: number }
|
|
13
|
+
autoPlay?: boolean
|
|
14
|
+
loop?: boolean
|
|
15
|
+
modes?: Record<string, any>
|
|
16
|
+
style?: StyleProp<ViewStyle>
|
|
17
|
+
accessibilityLabel?: string
|
|
18
|
+
testID?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const DEFAULT_SIZE = 117
|
|
22
|
+
|
|
23
|
+
function resolveSize(
|
|
24
|
+
size: LottiePlayerProps['size'],
|
|
25
|
+
modes: Record<string, any>
|
|
26
|
+
) {
|
|
27
|
+
if (typeof size === 'number') return { width: size, height: size }
|
|
28
|
+
if (size && typeof size === 'object') return size
|
|
29
|
+
const width =
|
|
30
|
+
Number(getVariableByName('media/width', modes)) || DEFAULT_SIZE
|
|
31
|
+
const height =
|
|
32
|
+
Number(getVariableByName('media/height', modes)) || DEFAULT_SIZE
|
|
33
|
+
return { width, height }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Web build of `LottiePlayer` — picked automatically by webpack /
|
|
38
|
+
* Metro-for-web via the `.web.tsx` platform extension. Uses `lottie-react`
|
|
39
|
+
* (which wraps `lottie-web`) and renders a plain DOM container.
|
|
40
|
+
*
|
|
41
|
+
* Public API mirrors `LottiePlayer.tsx` (native). See that file for the
|
|
42
|
+
* documented prop reference and usage patterns.
|
|
43
|
+
*/
|
|
44
|
+
function LottiePlayer({
|
|
45
|
+
source,
|
|
46
|
+
size,
|
|
47
|
+
autoPlay = true,
|
|
48
|
+
loop = true,
|
|
49
|
+
modes: propModes = EMPTY_MODES,
|
|
50
|
+
style,
|
|
51
|
+
accessibilityLabel,
|
|
52
|
+
testID,
|
|
53
|
+
}: LottiePlayerProps) {
|
|
54
|
+
const { modes: globalModes } = useTokens()
|
|
55
|
+
const modes = useMemo(
|
|
56
|
+
() =>
|
|
57
|
+
globalModes === EMPTY_MODES && propModes === EMPTY_MODES
|
|
58
|
+
? EMPTY_MODES
|
|
59
|
+
: { ...globalModes, ...propModes },
|
|
60
|
+
[globalModes, propModes]
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
const { width, height } = useMemo(
|
|
64
|
+
() => resolveSize(size, modes),
|
|
65
|
+
[size, modes]
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
const WebLottieView = useMemo(() => getWebLottieView(), [])
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<div
|
|
72
|
+
style={{
|
|
73
|
+
width,
|
|
74
|
+
height,
|
|
75
|
+
display: 'flex',
|
|
76
|
+
alignItems: 'center',
|
|
77
|
+
justifyContent: 'center',
|
|
78
|
+
...(style as React.CSSProperties),
|
|
79
|
+
}}
|
|
80
|
+
data-testid={testID}
|
|
81
|
+
aria-label={accessibilityLabel}
|
|
82
|
+
aria-hidden={accessibilityLabel ? undefined : true}
|
|
83
|
+
>
|
|
84
|
+
<WebLottieView
|
|
85
|
+
animationData={source}
|
|
86
|
+
autoplay={autoPlay}
|
|
87
|
+
loop={loop}
|
|
88
|
+
style={{ width: '100%', height: '100%' }}
|
|
89
|
+
/>
|
|
90
|
+
</div>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default React.memo(LottiePlayer)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Text, View, type ViewStyle } from 'react-native'
|
|
3
|
+
|
|
4
|
+
/** Props we forward to the underlying native Lottie view. */
|
|
5
|
+
export type NativeLottieViewProps = {
|
|
6
|
+
source: Record<string, unknown>
|
|
7
|
+
autoPlay?: boolean
|
|
8
|
+
loop?: boolean
|
|
9
|
+
style?: ViewStyle
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const INSTALL_HINT =
|
|
13
|
+
'LottiePlayer requires lottie-react-native in your app.\n' +
|
|
14
|
+
' npm install lottie-react-native\n' +
|
|
15
|
+
' cd ios && pod install'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Metro resolves `require('lottie-react-native')` at bundle time even inside
|
|
19
|
+
* try/catch, which breaks apps that import `jfs-components` without having
|
|
20
|
+
* the optional peer installed. Splitting the module id into a runtime string
|
|
21
|
+
* keeps Metro from statically linking it — the native module is loaded only
|
|
22
|
+
* when present in the consumer's node_modules.
|
|
23
|
+
*/
|
|
24
|
+
function resolveNativeLottieModuleName() {
|
|
25
|
+
return ['lottie', '-react', '-native'].join('')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function LottieUnavailableView({ style }: Pick<NativeLottieViewProps, 'style'>) {
|
|
29
|
+
if (__DEV__) {
|
|
30
|
+
return (
|
|
31
|
+
<View
|
|
32
|
+
style={[
|
|
33
|
+
style,
|
|
34
|
+
{
|
|
35
|
+
alignItems: 'center',
|
|
36
|
+
justifyContent: 'center',
|
|
37
|
+
backgroundColor: 'rgba(255, 196, 0, 0.12)',
|
|
38
|
+
borderWidth: 1,
|
|
39
|
+
borderColor: 'rgba(255, 196, 0, 0.45)',
|
|
40
|
+
borderRadius: 8,
|
|
41
|
+
padding: 8,
|
|
42
|
+
},
|
|
43
|
+
]}
|
|
44
|
+
>
|
|
45
|
+
<Text
|
|
46
|
+
style={{
|
|
47
|
+
color: '#8a6d00',
|
|
48
|
+
fontSize: 11,
|
|
49
|
+
textAlign: 'center',
|
|
50
|
+
lineHeight: 15,
|
|
51
|
+
}}
|
|
52
|
+
>
|
|
53
|
+
{INSTALL_HINT}
|
|
54
|
+
</Text>
|
|
55
|
+
</View>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return <View style={style} />
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function LottieUnavailable(props: NativeLottieViewProps) {
|
|
63
|
+
React.useEffect(() => {
|
|
64
|
+
if (__DEV__) {
|
|
65
|
+
console.warn(`[jfs-components/LottiePlayer] ${INSTALL_HINT}`)
|
|
66
|
+
}
|
|
67
|
+
}, [])
|
|
68
|
+
|
|
69
|
+
return <LottieUnavailableView style={props.style} />
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let cachedView: React.ComponentType<NativeLottieViewProps> | undefined
|
|
73
|
+
|
|
74
|
+
export function getNativeLottieView(): React.ComponentType<NativeLottieViewProps> {
|
|
75
|
+
if (cachedView !== undefined) return cachedView
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
const mod = require(resolveNativeLottieModuleName()) as {
|
|
79
|
+
default?: React.ComponentType<NativeLottieViewProps>
|
|
80
|
+
}
|
|
81
|
+
cachedView = mod.default ?? LottieUnavailable
|
|
82
|
+
} catch {
|
|
83
|
+
cachedView = LottieUnavailable
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return cachedView
|
|
87
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { CSSProperties } from 'react'
|
|
3
|
+
|
|
4
|
+
/** Props we forward to the underlying web Lottie view. */
|
|
5
|
+
export type WebLottieViewProps = {
|
|
6
|
+
animationData: Record<string, unknown>
|
|
7
|
+
autoplay?: boolean
|
|
8
|
+
loop?: boolean
|
|
9
|
+
style?: CSSProperties
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const INSTALL_HINT =
|
|
13
|
+
'LottiePlayer requires lottie-react in your app.\n' +
|
|
14
|
+
' npm install lottie-react'
|
|
15
|
+
|
|
16
|
+
function resolveWebLottieModuleName() {
|
|
17
|
+
return ['lottie', '-react'].join('')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function LottieUnavailable(props: WebLottieViewProps) {
|
|
21
|
+
React.useEffect(() => {
|
|
22
|
+
if (typeof __DEV__ !== 'undefined' && __DEV__) {
|
|
23
|
+
console.warn(`[jfs-components/LottiePlayer] ${INSTALL_HINT}`)
|
|
24
|
+
}
|
|
25
|
+
}, [])
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
style={{
|
|
30
|
+
...props.style,
|
|
31
|
+
display: 'flex',
|
|
32
|
+
alignItems: 'center',
|
|
33
|
+
justifyContent: 'center',
|
|
34
|
+
backgroundColor: 'rgba(255, 196, 0, 0.12)',
|
|
35
|
+
border: '1px solid rgba(255, 196, 0, 0.45)',
|
|
36
|
+
borderRadius: 8,
|
|
37
|
+
padding: 8,
|
|
38
|
+
color: '#8a6d00',
|
|
39
|
+
fontSize: 11,
|
|
40
|
+
textAlign: 'center',
|
|
41
|
+
lineHeight: '15px',
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
{typeof __DEV__ !== 'undefined' && __DEV__ ? INSTALL_HINT : null}
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let cachedView: React.ComponentType<WebLottieViewProps> | undefined
|
|
50
|
+
|
|
51
|
+
export function getWebLottieView(): React.ComponentType<WebLottieViewProps> {
|
|
52
|
+
if (cachedView !== undefined) return cachedView
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const mod = require(resolveWebLottieModuleName()) as {
|
|
56
|
+
default?: React.ComponentType<WebLottieViewProps>
|
|
57
|
+
}
|
|
58
|
+
cachedView = mod.default ?? LottieUnavailable
|
|
59
|
+
} catch {
|
|
60
|
+
cachedView = LottieUnavailable
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return cachedView
|
|
64
|
+
}
|