@ledgerhq/lumen-ui-rnative 0.0.71 → 0.0.72
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/dist/package.json +3 -3
- package/dist/src/i18n/locales/de.json +3 -0
- package/dist/src/i18n/locales/en.json +3 -0
- package/dist/src/i18n/locales/es.json +3 -0
- package/dist/src/i18n/locales/fr.json +3 -0
- package/dist/src/i18n/locales/ja.json +3 -0
- package/dist/src/i18n/locales/ko.json +3 -0
- package/dist/src/i18n/locales/pt.json +3 -0
- package/dist/src/i18n/locales/ru.json +3 -0
- package/dist/src/i18n/locales/th.json +3 -0
- package/dist/src/i18n/locales/tr.json +3 -0
- package/dist/src/i18n/locales/zh.json +3 -0
- package/dist/src/lib/Components/Skeleton/Skeleton.d.ts +21 -0
- package/dist/src/lib/Components/Skeleton/Skeleton.d.ts.map +1 -0
- package/dist/src/lib/Components/Skeleton/Skeleton.js +81 -0
- package/dist/src/lib/Components/Skeleton/Skeleton.stories.d.ts +11 -0
- package/dist/src/lib/Components/Skeleton/Skeleton.stories.d.ts.map +1 -0
- package/dist/src/lib/Components/Skeleton/Skeleton.stories.js +49 -0
- package/dist/src/lib/Components/Skeleton/index.d.ts +3 -0
- package/dist/src/lib/Components/Skeleton/index.d.ts.map +1 -0
- package/dist/src/lib/Components/Skeleton/index.js +2 -0
- package/dist/src/lib/Components/Skeleton/types.d.ts +10 -0
- package/dist/src/lib/Components/Skeleton/types.d.ts.map +1 -0
- package/dist/src/lib/Components/Skeleton/types.js +1 -0
- package/dist/src/lib/Components/Stepper/Stepper.d.ts +16 -0
- package/dist/src/lib/Components/Stepper/Stepper.d.ts.map +1 -0
- package/dist/src/lib/Components/Stepper/Stepper.js +74 -0
- package/dist/src/lib/Components/Stepper/Stepper.stories.d.ts +9 -0
- package/dist/src/lib/Components/Stepper/Stepper.stories.d.ts.map +1 -0
- package/dist/src/lib/Components/Stepper/Stepper.stories.js +35 -0
- package/dist/src/lib/Components/Stepper/index.d.ts +3 -0
- package/dist/src/lib/Components/Stepper/index.d.ts.map +1 -0
- package/dist/src/lib/Components/Stepper/index.js +2 -0
- package/dist/src/lib/Components/Stepper/types.d.ts +21 -0
- package/dist/src/lib/Components/Stepper/types.d.ts.map +1 -0
- package/dist/src/lib/Components/Stepper/types.js +1 -0
- package/dist/src/lib/Components/index.d.ts +3 -0
- package/dist/src/lib/Components/index.d.ts.map +1 -1
- package/dist/src/lib/Components/index.js +3 -0
- package/package.json +1 -1
- package/src/i18n/locales/de.json +3 -0
- package/src/i18n/locales/en.json +3 -0
- package/src/i18n/locales/es.json +3 -0
- package/src/i18n/locales/fr.json +3 -0
- package/src/i18n/locales/ja.json +3 -0
- package/src/i18n/locales/ko.json +3 -0
- package/src/i18n/locales/pt.json +3 -0
- package/src/i18n/locales/ru.json +3 -0
- package/src/i18n/locales/th.json +3 -0
- package/src/i18n/locales/tr.json +3 -0
- package/src/i18n/locales/zh.json +3 -0
- package/src/lib/Components/Skeleton/Skeleton.mdx +200 -0
- package/src/lib/Components/Skeleton/Skeleton.stories.tsx +89 -0
- package/src/lib/Components/Skeleton/Skeleton.test.tsx +54 -0
- package/src/lib/Components/Skeleton/Skeleton.tsx +137 -0
- package/src/lib/Components/Skeleton/index.ts +2 -0
- package/src/lib/Components/Skeleton/types.ts +10 -0
- package/src/lib/Components/Stepper/Stepper.mdx +217 -0
- package/src/lib/Components/Stepper/Stepper.stories.tsx +62 -0
- package/src/lib/Components/Stepper/Stepper.test.tsx +132 -0
- package/src/lib/Components/Stepper/Stepper.tsx +159 -0
- package/src/lib/Components/Stepper/index.ts +2 -0
- package/src/lib/Components/Stepper/types.ts +21 -0
- package/src/lib/Components/index.ts +3 -0
package/src/i18n/locales/ko.json
CHANGED
package/src/i18n/locales/pt.json
CHANGED
package/src/i18n/locales/ru.json
CHANGED
package/src/i18n/locales/th.json
CHANGED
package/src/i18n/locales/tr.json
CHANGED
package/src/i18n/locales/zh.json
CHANGED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as SkeletonStories from './Skeleton.stories';
|
|
3
|
+
import { Skeleton } from './Skeleton';
|
|
4
|
+
import {
|
|
5
|
+
CustomTabs,
|
|
6
|
+
Tab,
|
|
7
|
+
DoVsDontRow,
|
|
8
|
+
DoBlockItem,
|
|
9
|
+
DontBlockItem,
|
|
10
|
+
} from '../../../../.storybook/components';
|
|
11
|
+
import CommonRulesDoAndDont from '../../../../.storybook/components/DoVsDont/CommonRulesDoAndDont.mdx';
|
|
12
|
+
|
|
13
|
+
<Meta title='Communication/Skeleton' of={SkeletonStories} />
|
|
14
|
+
|
|
15
|
+
# Skeleton
|
|
16
|
+
|
|
17
|
+
<CustomTabs>
|
|
18
|
+
<Tab label="Overview">
|
|
19
|
+
|
|
20
|
+
## Introduction
|
|
21
|
+
|
|
22
|
+
Skeleton components provide visual placeholders for content that is loading. They use a pulsing animation to indicate that content is being fetched or processed, improving perceived performance and user experience.
|
|
23
|
+
|
|
24
|
+
> View in [Figma](https://www.figma.com/design/JxaLVMTWirCpU0rsbZ30k7/2.-Components-Library?node-id=10196-8001&m=dev).
|
|
25
|
+
|
|
26
|
+
## Anatomy
|
|
27
|
+
|
|
28
|
+
<Canvas of={SkeletonStories.Base} />
|
|
29
|
+
|
|
30
|
+
- **Shape**: Defines the visual placeholder shape (rectangle, circle, etc.)
|
|
31
|
+
- **Animation**: Built-in pulse animation to indicate loading state
|
|
32
|
+
|
|
33
|
+
## Properties
|
|
34
|
+
|
|
35
|
+
### Overview
|
|
36
|
+
|
|
37
|
+
<Canvas of={SkeletonStories.Base} />
|
|
38
|
+
<Controls of={SkeletonStories.Base} />
|
|
39
|
+
|
|
40
|
+
### Component Variants
|
|
41
|
+
|
|
42
|
+
The `component` prop provides pre-built skeleton patterns for common UI elements.
|
|
43
|
+
|
|
44
|
+
#### **List Item**
|
|
45
|
+
|
|
46
|
+
<Canvas of={SkeletonStories.WithListItem} />
|
|
47
|
+
|
|
48
|
+
#### **Tile**
|
|
49
|
+
|
|
50
|
+
<Canvas of={SkeletonStories.WithTile} />
|
|
51
|
+
|
|
52
|
+
> **Note**: List item and Tile width are fixed
|
|
53
|
+
|
|
54
|
+
### Sizes
|
|
55
|
+
|
|
56
|
+
Skeletons can be sized using the `lx` prop with design system size tokens.
|
|
57
|
+
|
|
58
|
+
<Canvas of={SkeletonStories.SizeShowcase} />
|
|
59
|
+
|
|
60
|
+
### Shapes
|
|
61
|
+
|
|
62
|
+
Skeletons can take various shapes depending on the content they're representing.
|
|
63
|
+
|
|
64
|
+
<Canvas of={SkeletonStories.ShapeShowcase} />
|
|
65
|
+
|
|
66
|
+
## Best Practices
|
|
67
|
+
|
|
68
|
+
- **Use Component Variants**: Prefer using the `component` prop for common patterns like list items and tiles
|
|
69
|
+
- **Match Content Shape**: Make skeleton shapes match the actual content they represent
|
|
70
|
+
- **Consistent Spacing**: Use consistent spacing between skeleton elements
|
|
71
|
+
- **Appropriate Sizing**: Size skeletons to match the expected content dimensions
|
|
72
|
+
- **Loading States**: Show skeletons only during actual loading states
|
|
73
|
+
|
|
74
|
+
</Tab>
|
|
75
|
+
<Tab label="Implementation">
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm install @ledgerhq/lumen-ui-rnative
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
> **Note**: `@ledgerhq/lumen-design-core` and other peer dependencies (`react`, `react-native`, etc.) are required. See our [Setup Guide →](?path=/docs/getting-started-setup--docs) for complete installation.
|
|
82
|
+
|
|
83
|
+
## Basic Usage
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { Skeleton } from '@ledgerhq/lumen-ui-rnative';
|
|
87
|
+
|
|
88
|
+
function MyComponent() {
|
|
89
|
+
return <Skeleton lx={{ height: 's16', width: 's256' }} />;
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Component Variants
|
|
94
|
+
|
|
95
|
+
Use the `component` prop for pre-built skeleton patterns:
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
import { Skeleton } from '@ledgerhq/lumen-ui-rnative';
|
|
99
|
+
|
|
100
|
+
// List item skeleton - horizontal layout with avatar and text lines
|
|
101
|
+
<Skeleton component='list-item' />
|
|
102
|
+
|
|
103
|
+
// Tile skeleton - vertical centered layout
|
|
104
|
+
<Skeleton component='tile' />
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Custom Styling
|
|
108
|
+
|
|
109
|
+
While the component comes with predefined styles, you can extend them using the `lx` prop:
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
<Skeleton lx={{ height: 's40', width: 's256', borderRadius: 'lg' }} />
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Manual Composition
|
|
116
|
+
|
|
117
|
+
For custom layouts, compose multiple skeleton elements:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import { Box, Skeleton } from '@ledgerhq/lumen-ui-rnative';
|
|
121
|
+
|
|
122
|
+
<Box lx={{ flexDirection: 'row', alignItems: 'center', gap: 's16' }}>
|
|
123
|
+
<Skeleton lx={{ width: 's48', height: 's48', borderRadius: 'full' }} />
|
|
124
|
+
<Box lx={{ flex: 1, flexDirection: 'column', gap: 's8' }}>
|
|
125
|
+
<Skeleton lx={{ height: 's16', width: 's160' }} />
|
|
126
|
+
<Skeleton lx={{ height: 's16', width: 's128' }} />
|
|
127
|
+
</Box>
|
|
128
|
+
</Box>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Do's and Don'ts
|
|
132
|
+
|
|
133
|
+
<div className='flex flex-col gap-24'>
|
|
134
|
+
<DoVsDontRow>
|
|
135
|
+
<DoBlockItem
|
|
136
|
+
title='Use component prop for common patterns'
|
|
137
|
+
description='Use pre-built variants for consistent loading states'
|
|
138
|
+
>
|
|
139
|
+
|
|
140
|
+
{/* prettier-ignore */}
|
|
141
|
+
```tsx
|
|
142
|
+
<Skeleton component='list-item' />
|
|
143
|
+
<Skeleton component='tile' />
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
</DoBlockItem>
|
|
147
|
+
<DontBlockItem
|
|
148
|
+
title="Don't manually recreate common patterns"
|
|
149
|
+
description='Avoid recreating patterns that already exist as component variants'
|
|
150
|
+
>
|
|
151
|
+
|
|
152
|
+
{/* prettier-ignore */}
|
|
153
|
+
```tsx
|
|
154
|
+
import { Box, Skeleton } from '@ledgerhq/lumen-ui-rnative';
|
|
155
|
+
|
|
156
|
+
<Box lx={{ flexDirection: 'row', alignItems: 'center', gap: 's16' }}>
|
|
157
|
+
<Skeleton lx={{ width: 's48', height: 's48', borderRadius: 'full' }} />
|
|
158
|
+
<Box lx={{ flex: 1, flexDirection: 'column', gap: 's8' }}>
|
|
159
|
+
<Skeleton lx={{ height: 's12', width: 's176' }} />
|
|
160
|
+
<Skeleton lx={{ height: 's12', width: 's112' }} />
|
|
161
|
+
</Box>
|
|
162
|
+
</Box>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
</DontBlockItem>
|
|
166
|
+
|
|
167
|
+
</DoVsDontRow>
|
|
168
|
+
|
|
169
|
+
<DoVsDontRow>
|
|
170
|
+
<DoBlockItem
|
|
171
|
+
title='Use lx prop for sizing'
|
|
172
|
+
description='Use design system size tokens for consistent sizing'
|
|
173
|
+
>
|
|
174
|
+
|
|
175
|
+
{/* prettier-ignore */}
|
|
176
|
+
```tsx
|
|
177
|
+
<Skeleton lx={{ height: 's16', width: 's256' }} />
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
</DoBlockItem>
|
|
181
|
+
<DontBlockItem
|
|
182
|
+
title="Don't use arbitrary style values"
|
|
183
|
+
description='Avoid using the style prop or arbitrary values'
|
|
184
|
+
>
|
|
185
|
+
|
|
186
|
+
{/* prettier-ignore */}
|
|
187
|
+
```tsx
|
|
188
|
+
<Skeleton style={{ height: 16, width: 200 }} />
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
</DontBlockItem>
|
|
192
|
+
|
|
193
|
+
</DoVsDontRow>
|
|
194
|
+
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<CommonRulesDoAndDont />
|
|
198
|
+
|
|
199
|
+
</Tab>
|
|
200
|
+
</CustomTabs>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-native-web-vite';
|
|
2
|
+
import { Box } from '../Utility/Box';
|
|
3
|
+
import { Skeleton } from './Skeleton';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Skeleton> = {
|
|
6
|
+
title: 'Communication/Skeleton',
|
|
7
|
+
component: Skeleton,
|
|
8
|
+
parameters: {
|
|
9
|
+
actions: { disable: true },
|
|
10
|
+
},
|
|
11
|
+
argTypes: {
|
|
12
|
+
component: {
|
|
13
|
+
control: 'select',
|
|
14
|
+
options: [undefined, 'list-item', 'tile'],
|
|
15
|
+
description: 'Pre-built skeleton component variant',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
type Story = StoryObj<typeof Skeleton>;
|
|
22
|
+
|
|
23
|
+
export const Base: Story = {
|
|
24
|
+
args: {
|
|
25
|
+
lx: {
|
|
26
|
+
height: 's16',
|
|
27
|
+
width: 's256',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
render: (args) => (
|
|
31
|
+
<Box lx={{ padding: 's16', backgroundColor: 'canvas', borderRadius: 'md' }}>
|
|
32
|
+
<Skeleton
|
|
33
|
+
component={args.component}
|
|
34
|
+
lx={args.component ? undefined : args.lx}
|
|
35
|
+
/>
|
|
36
|
+
</Box>
|
|
37
|
+
),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const WithListItem: Story = {
|
|
41
|
+
render: () => (
|
|
42
|
+
<Box lx={{ padding: 's16', backgroundColor: 'canvas', borderRadius: 'md' }}>
|
|
43
|
+
<Skeleton component='list-item' />
|
|
44
|
+
</Box>
|
|
45
|
+
),
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const WithTile: Story = {
|
|
49
|
+
render: () => (
|
|
50
|
+
<Box lx={{ padding: 's16', backgroundColor: 'canvas', borderRadius: 'md' }}>
|
|
51
|
+
<Skeleton component='tile' />
|
|
52
|
+
</Box>
|
|
53
|
+
),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const SizeShowcase: Story = {
|
|
57
|
+
render: () => (
|
|
58
|
+
<Box
|
|
59
|
+
lx={{
|
|
60
|
+
padding: 's16',
|
|
61
|
+
backgroundColor: 'canvas',
|
|
62
|
+
borderRadius: 'md',
|
|
63
|
+
gap: 's4',
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<Skeleton lx={{ height: 's40', width: 's56' }} />
|
|
67
|
+
<Skeleton lx={{ height: 's12', width: 's112' }} />
|
|
68
|
+
<Skeleton lx={{ height: 's128', width: 's256' }} />
|
|
69
|
+
</Box>
|
|
70
|
+
),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const ShapeShowcase: Story = {
|
|
74
|
+
render: () => (
|
|
75
|
+
<Box
|
|
76
|
+
lx={{
|
|
77
|
+
padding: 's16',
|
|
78
|
+
backgroundColor: 'canvas',
|
|
79
|
+
borderRadius: 'md',
|
|
80
|
+
gap: 's4',
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
<Skeleton lx={{ height: 's40', width: 's256', borderRadius: 'none' }} />
|
|
84
|
+
<Skeleton lx={{ height: 's40', width: 's256', borderRadius: 'lg' }} />
|
|
85
|
+
<Skeleton lx={{ width: 's48', height: 's48', borderRadius: 'full' }} />
|
|
86
|
+
<Skeleton lx={{ width: 's48', height: 's48', borderRadius: 'md' }} />
|
|
87
|
+
</Box>
|
|
88
|
+
),
|
|
89
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { describe, it, expect } from '@jest/globals';
|
|
2
|
+
import { ledgerLiveThemes } from '@ledgerhq/lumen-design-core';
|
|
3
|
+
import { render } from '@testing-library/react-native';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { ThemeProvider } from '../ThemeProvider/ThemeProvider';
|
|
6
|
+
import { Skeleton } from './Skeleton';
|
|
7
|
+
|
|
8
|
+
const TestWrapper = ({ children }: { children: React.ReactNode }) => (
|
|
9
|
+
<ThemeProvider themes={ledgerLiveThemes} colorScheme='dark' locale='en'>
|
|
10
|
+
{children}
|
|
11
|
+
</ThemeProvider>
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
describe('Skeleton Component', () => {
|
|
15
|
+
it('should render correctly', () => {
|
|
16
|
+
const { getByTestId } = render(
|
|
17
|
+
<TestWrapper>
|
|
18
|
+
<Skeleton />
|
|
19
|
+
</TestWrapper>,
|
|
20
|
+
);
|
|
21
|
+
const skeletonElement = getByTestId('skeleton');
|
|
22
|
+
expect(skeletonElement).toBeTruthy();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should render list-item variant', () => {
|
|
26
|
+
const { getByTestId } = render(
|
|
27
|
+
<TestWrapper>
|
|
28
|
+
<Skeleton testID='list-item-skeleton' component='list-item' />
|
|
29
|
+
</TestWrapper>,
|
|
30
|
+
);
|
|
31
|
+
const skeletonElement = getByTestId('list-item-skeleton');
|
|
32
|
+
expect(skeletonElement).toBeTruthy();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should render tile variant', () => {
|
|
36
|
+
const { getByTestId } = render(
|
|
37
|
+
<TestWrapper>
|
|
38
|
+
<Skeleton testID='tile-skeleton' component='tile' />
|
|
39
|
+
</TestWrapper>,
|
|
40
|
+
);
|
|
41
|
+
const skeletonElement = getByTestId('tile-skeleton');
|
|
42
|
+
expect(skeletonElement).toBeTruthy();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should accept additional props', () => {
|
|
46
|
+
const { getByTestId } = render(
|
|
47
|
+
<TestWrapper>
|
|
48
|
+
<Skeleton testID='custom-skeleton' />
|
|
49
|
+
</TestWrapper>,
|
|
50
|
+
);
|
|
51
|
+
const skeletonElement = getByTestId('custom-skeleton');
|
|
52
|
+
expect(skeletonElement).toBeTruthy();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Pulse } from '../../Animations/Pulse';
|
|
2
|
+
import { Box } from '../Utility';
|
|
3
|
+
import type { SkeletonProps } from './types';
|
|
4
|
+
|
|
5
|
+
/** Internal base skeleton element */
|
|
6
|
+
const BaseSkeleton = ({ lx, ...props }: SkeletonProps) => {
|
|
7
|
+
return (
|
|
8
|
+
<Box
|
|
9
|
+
lx={{
|
|
10
|
+
borderRadius: 'md',
|
|
11
|
+
backgroundColor: 'mutedTransparent',
|
|
12
|
+
...lx,
|
|
13
|
+
}}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
BaseSkeleton.displayName = 'BaseSkeleton';
|
|
19
|
+
|
|
20
|
+
const ListItemSkeleton = ({ lx, ...props }: SkeletonProps) => {
|
|
21
|
+
return (
|
|
22
|
+
<Box
|
|
23
|
+
lx={{
|
|
24
|
+
flexDirection: 'row',
|
|
25
|
+
width: 'full',
|
|
26
|
+
alignItems: 'center',
|
|
27
|
+
gap: 's16',
|
|
28
|
+
paddingVertical: 's8',
|
|
29
|
+
...lx,
|
|
30
|
+
}}
|
|
31
|
+
{...props}
|
|
32
|
+
>
|
|
33
|
+
<BaseSkeleton
|
|
34
|
+
lx={{
|
|
35
|
+
width: 's48',
|
|
36
|
+
height: 's48',
|
|
37
|
+
borderRadius: 'full',
|
|
38
|
+
flexShrink: 0,
|
|
39
|
+
}}
|
|
40
|
+
/>
|
|
41
|
+
<Box lx={{ flex: 1, flexDirection: 'column', gap: 's10' }}>
|
|
42
|
+
<BaseSkeleton
|
|
43
|
+
lx={{ height: 's12', width: 's176', borderRadius: 'full' }}
|
|
44
|
+
/>
|
|
45
|
+
<BaseSkeleton
|
|
46
|
+
lx={{ height: 's12', width: 's112', borderRadius: 'full' }}
|
|
47
|
+
/>
|
|
48
|
+
</Box>
|
|
49
|
+
</Box>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
ListItemSkeleton.displayName = 'ListItemSkeleton';
|
|
53
|
+
|
|
54
|
+
const TileSkeleton = ({ lx, ...props }: SkeletonProps) => {
|
|
55
|
+
return (
|
|
56
|
+
<Box
|
|
57
|
+
lx={{
|
|
58
|
+
flexDirection: 'column',
|
|
59
|
+
width: 's112',
|
|
60
|
+
alignItems: 'center',
|
|
61
|
+
gap: 's12',
|
|
62
|
+
borderRadius: 'md',
|
|
63
|
+
paddingHorizontal: 's8',
|
|
64
|
+
paddingVertical: 's16',
|
|
65
|
+
...lx,
|
|
66
|
+
}}
|
|
67
|
+
{...props}
|
|
68
|
+
>
|
|
69
|
+
<BaseSkeleton
|
|
70
|
+
lx={{
|
|
71
|
+
width: 's48',
|
|
72
|
+
height: 's48',
|
|
73
|
+
borderRadius: 'full',
|
|
74
|
+
flexShrink: 0,
|
|
75
|
+
}}
|
|
76
|
+
/>
|
|
77
|
+
<Box
|
|
78
|
+
lx={{
|
|
79
|
+
width: 'full',
|
|
80
|
+
flexDirection: 'column',
|
|
81
|
+
alignItems: 'center',
|
|
82
|
+
gap: 's8',
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
<BaseSkeleton
|
|
86
|
+
lx={{ height: 's12', width: 's48', borderRadius: 'full' }}
|
|
87
|
+
/>
|
|
88
|
+
<BaseSkeleton
|
|
89
|
+
lx={{ height: 's12', width: 's64', borderRadius: 'full' }}
|
|
90
|
+
/>
|
|
91
|
+
</Box>
|
|
92
|
+
</Box>
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
TileSkeleton.displayName = 'TileSkeleton';
|
|
96
|
+
|
|
97
|
+
const componentsMap = {
|
|
98
|
+
'list-item': ListItemSkeleton,
|
|
99
|
+
tile: TileSkeleton,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* A skeleton component that displays a pulsing placeholder for loading content.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* <Skeleton lx={{ height: 's16', width: 's256' }} />
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* // List item variant
|
|
110
|
+
* <Skeleton component='list-item' lx={{ width: 's320' }} />
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* // Tile variant
|
|
114
|
+
* <Skeleton component='tile' />
|
|
115
|
+
*/
|
|
116
|
+
const Skeleton = ({ lx, component, ...props }: SkeletonProps) => {
|
|
117
|
+
/**
|
|
118
|
+
* Check if the component is a valid pre-built variant and return the corresponding component.
|
|
119
|
+
*/
|
|
120
|
+
if (component && componentsMap[component]) {
|
|
121
|
+
const Component = componentsMap[component];
|
|
122
|
+
return (
|
|
123
|
+
<Pulse animate>
|
|
124
|
+
<Component {...props} lx={lx} />
|
|
125
|
+
</Pulse>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<Pulse animate>
|
|
131
|
+
<BaseSkeleton testID='skeleton' lx={lx} {...props} />
|
|
132
|
+
</Pulse>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
Skeleton.displayName = 'Skeleton';
|
|
136
|
+
|
|
137
|
+
export { Skeleton };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { StyledViewProps } from '../../../styles';
|
|
2
|
+
|
|
3
|
+
export type SkeletonProps = {
|
|
4
|
+
/**
|
|
5
|
+
* Pre-built skeleton component variant
|
|
6
|
+
* - `list-item`: Horizontal layout with circle and two text lines
|
|
7
|
+
* - `tile`: Vertical centered layout with circle and two text lines in a rounded container
|
|
8
|
+
*/
|
|
9
|
+
component?: 'list-item' | 'tile';
|
|
10
|
+
} & Omit<StyledViewProps, 'children'>;
|