Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 3.6.0

### Features

- Add optional `children` prop. If set, the skeleton will render its children with `visibility: hidden`. (#239)

## 3.5.0

### Features
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import Skeleton from 'react-loading-skeleton'
import 'react-loading-skeleton/dist/skeleton.css'

<Skeleton /> // Simple, single-line loading skeleton
<Skeleton>
<div>Loading...</div>
</Skeleton> // Simple, with children
<Skeleton count={5} /> // Five-line loading skeleton
```

Expand Down Expand Up @@ -166,6 +169,14 @@ return (
</td>
<td></td>
</tr>
<tr>
<td><code>children?: React.ReactNode | JSX.Element | string</code></td>
<td>
If you pass children to the <code>Skeleton</code> component, the
children will be rendered with <code>visibility: hidden</code>.
</td>
<td></td>
</tr>
</tbody>
</table>

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-loading-skeleton",
"version": "3.5.0",
"version": "3.6.0",
"description": "Make beautiful, animated loading skeletons that automatically adapt to your app.",
"keywords": [
"react",
Expand Down
19 changes: 17 additions & 2 deletions src/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
/* eslint-disable react/no-array-index-key */
import React, { CSSProperties, PropsWithChildren, ReactElement } from 'react';
import React, {
CSSProperties,
PropsWithChildren,
ReactElement,
ReactNode,
} from 'react';
import { SkeletonThemeContext } from './SkeletonThemeContext.js';
import { SkeletonStyleProps } from './SkeletonStyleProps.js';

Expand Down Expand Up @@ -59,6 +64,8 @@ export interface SkeletonProps extends SkeletonStyleProps {

circle?: boolean;
style?: CSSProperties;

children?: ReactNode | JSX.Element | string;
}

export function Skeleton({
Expand All @@ -72,6 +79,8 @@ export function Skeleton({
circle = false,

style: styleProp,

children,
...originalPropsStyleOptions
}: SkeletonProps): ReactElement {
const contextStyleOptions = React.useContext(SkeletonThemeContext);
Expand Down Expand Up @@ -104,6 +113,12 @@ export function Skeleton({

const inline = styleOptions.inline ?? false;

const childrenContent = children ? (
<div style={{ visibility: 'hidden' }}>{children}</div>
) : (
<>&zwnj;</>
);

const elements: ReactElement[] = [];

const countCeil = Math.ceil(count);
Expand Down Expand Up @@ -133,7 +148,7 @@ export function Skeleton({

const skeletonSpan = (
<span className={className} style={thisStyle} key={i}>
&zwnj;
{childrenContent}
</span>
);

Expand Down
10 changes: 10 additions & 0 deletions src/__stories__/Skeleton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ export const Inline: React.FC = () => (
</SideBySide>
);

export const WithChildren: React.FC = () => (
<SideBySide>
<div>
<Skeleton width={100} inline style={{ marginRight: '0.5rem' }}>
<div>Loading...</div>
</Skeleton>
</div>
</SideBySide>
);

export const InlineWithText: React.FC = () => (
<div>
Some random text <Skeleton width={150} inline /> Some more random text
Expand Down
15 changes: 15 additions & 0 deletions src/__tests__/Skeleton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@ it('renders a skeleton', () => {
expect(skeletonElements[0]).not.toHaveAttribute('style');
});

it('renders a skeleton with children', () => {
render(
<Skeleton>
<div>Loading...</div>
</Skeleton>
);

const skeletonElements = getAllSkeletons();

expect(skeletonElements).toHaveLength(1);
expect(skeletonElements[0]).toBeVisible();

expect(skeletonElements[0]).toHaveTextContent('Loading...');
});

it('renders the required number of skeletons', () => {
render(<Skeleton count={4} />);

Expand Down