Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
28 changes: 28 additions & 0 deletions .changeset/loading-spinner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
'@leafygreen-ui/loading-indicator': major
---

[LG-4735](https://jira.mongodb.org/browse/LG-4735)

The `Spinner` component has been re-written as a lightweight SVG-based spinning loading indicator component, to eliminate the use of Lottie player (a heavy run-time animation library).
Importing `Spinner` component from the package root is not recommended, since this will also bundle the heavy `PageLoader` component, which still uses Lottie player.

For simple loading spinners, prefer importing the spinner directly from `@leafygreen-ui/loading-indicator/spinner`

Prop changes:
- Replaces `displayOption` (and `sizeOverride`) prop with a single `size` prop. The size mapping has also been updated to reflect the Figma spec.
```
Size.XSmall: 16px;
Size.Small: 24px;
Size.Default: 48px;
Size.Large: 64px;
```

- Removes `baseFontSize` prop
- Removes the explicit `description` prop.
```tsx
<div>
<Spinner size="default" />
<Description>Loading...</Description>
</div>
```
7 changes: 3 additions & 4 deletions packages/loading-indicator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ npm install @leafygreen-ui/loading-indicator
/>
```

| Prop | Type | Description | Default |
| --------------- | --------------- | ---------------------------------------------------------------------- | ------------------ |
| `displayOption` | `DisplayOption` | Determines the size or orientation of the spinner and description text | `default-vertical` |
| `description` | `string` | Description text | `-` |
| Prop | Type | Description | Default |
| ------ | ------------------ | ---------------------------------- | --------- |
| `size` | `Size` or `number` | Determines the size of the spinner | `default` |

## BlobLoader

Expand Down
35 changes: 27 additions & 8 deletions packages/loading-indicator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,32 @@
"main": "./dist/umd/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/types/index.d.ts",
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"types@<=5.0": "./dist/types/ts4.9/index.d.ts",
"import": "./dist/esm/index.js",
"require": "./dist/umd/index.js"
},
"./page-loader": {
"types": "./dist/types/page-loader/index.d.ts",
"types@<=5.0": "./dist/types/ts4.9/page-loader/index.d.ts",
"import": "./dist/esm/page-loader/index.js",
"require": "./dist/umd/page-loader/index.js"
},
"./spinner": {
"types": "./dist/types/spinner/index.d.ts",
"types@<=5.0": "./dist/types/ts4.9/spinner/index.d.ts",
"import": "./dist/esm/spinner/index.js",
"require": "./dist/umd/spinner/index.js"
},
"./testing": {
"types": "./dist/types/testing/index.d.ts",
"types@<=5.0": "./dist/types/ts4.9/testing/index.d.ts",
"import": "./dist/esm/testing/index.js",
"require": "./dist/umd/testing/index.js"
}
},
"scripts": {
"build": "lg-build bundle",
"tsc": "lg-build tsc",
Expand All @@ -28,6 +54,7 @@
"@leafygreen-ui/palette": "workspace:^",
"@leafygreen-ui/tokens": "workspace:^",
"@leafygreen-ui/typography": "workspace:^",
"@lg-tools/test-harnesses": "workspace:^",
"react-lottie-player": "^1.5.6"
},
"peerDependencies": {
Expand All @@ -36,13 +63,5 @@
"devDependencies": {
"@lg-tools/build": "workspace:^"
},
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"types@<=5.0": "./dist/types/ts4.9/index.d.ts",
"import": "./dist/esm/index.js",
"require": "./dist/umd/index.js"
}
},
"typesVersions": {}
}
68 changes: 68 additions & 0 deletions packages/loading-indicator/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
esmConfig,
umdConfig,
storiesConfig,
} from '@lg-tools/build/config/rollup.config.mjs';

const esmSpinnerConfig = {
...esmConfig,
input: 'src/Spinner/index.ts',
output: {
...esmConfig.output,
dir: 'dist/esm/spinner',
},
};
const umdSpinnerConfig = {
...umdConfig,
input: 'src/Spinner/index.ts',
output: {
...umdConfig.output,
dir: 'dist/esm/spinner',
},
};

const esmPageLoaderConfig = {
...esmConfig,
input: 'src/PageLoader/index.ts',
output: {
...esmConfig.output,
dir: 'dist/esm/page-loader',
},
};
const umdPageLoaderConfig = {
...umdConfig,
input: 'src/PageLoader/index.ts',
output: {
...umdConfig.output,
dir: 'dist/esm/page-loader',
},
};

const esmTestUtilsConfig = {
...esmConfig,
input: 'src/testing/index.ts',
output: {
...esmConfig.output,
dir: 'dist/esm/testing',
},
};
const umdTestUtilsConfig = {
...umdConfig,
input: 'src/testing/index.ts',
output: {
...umdConfig.output,
dir: 'dist/umd/testing',
},
};

export default [
esmConfig,
umdConfig,
esmSpinnerConfig,
umdSpinnerConfig,
esmPageLoaderConfig,
umdPageLoaderConfig,
esmTestUtilsConfig,
umdTestUtilsConfig,
storiesConfig,
];
16 changes: 6 additions & 10 deletions packages/loading-indicator/src/LoadingIndicator.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import { StoryFn } from '@storybook/react';

import { css } from '@leafygreen-ui/emotion';
import { DarkModeProps } from '@leafygreen-ui/lib';
import { spacing } from '@leafygreen-ui/tokens';
import { Size, spacing } from '@leafygreen-ui/tokens';
import { Body, InlineCode } from '@leafygreen-ui/typography';

import { DisplayOption } from './Spinner/Spinner.types';
import { PageLoader, Spinner } from '.';

const meta: StoryMetaType<any> = {
Expand Down Expand Up @@ -58,24 +57,21 @@ const Template: StoryFn<typeof Spinner> = (
} & DarkModeProps,
) => (
<div className={storyRootStyles}>
{Object.values(DisplayOption).map(displayOption => (
<div key={displayOption} className={displayOptionContainerStyles}>
<Spinner displayOption={displayOption} {...props} />
{Object.values(Size).map(size => (
<div key={size}>
<Spinner size={size} {...props} />
<Body className={labelStyles} weight="medium">
<InlineCode>{displayOption}</InlineCode> Spinner
<InlineCode>{size}</InlineCode> Spinner
</Body>
</div>
))}
<div className={displayOptionContainerStyles}>
<PageLoader {...props} />
<Body className={labelStyles} weight="medium">
Blob Loader
</Body>{' '}
</Body>
</div>
</div>
);

export const LiveExample = Template.bind({});
LiveExample.args = {
description: 'Loading dot dot...',
};
42 changes: 34 additions & 8 deletions packages/loading-indicator/src/Spinner/Spinner.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,47 @@ import React from 'react';
import { render } from '@testing-library/react';
import { axe } from 'jest-axe';

import Spinner from './Spinner';
import { Size } from '@leafygreen-ui/tokens';

describe('packages/loading-indicator/spinner', () => {
import { getTestUtils } from '../testing';

import { Spinner } from '.';

describe('packages/loading-spinner', () => {
describe('a11y', () => {
test('does not have basic accessibility issues', async () => {
const { container } = render(<Spinner />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
describe('description prop', () => {
test('renders description', async () => {
const descriptionText = 'test description';
const { getByText } = render(<Spinner description={descriptionText} />);
expect(getByText(descriptionText)).toBeInTheDocument();
});
test('renders with default props', () => {
render(<Spinner />);
const { getSpinner } = getTestUtils();

expect(getSpinner()).toBeInTheDocument();
});

test('renders with custom size', () => {
render(<Spinner size={Size.Large} />);
const { getSpinner } = getTestUtils();

expect(getSpinner()).toBeInTheDocument();
});

test('renders with custom size in pixels', () => {
render(<Spinner size={100} />);
const { getSpinner } = getTestUtils();
const spinner = getSpinner();

expect(spinner).toBeInTheDocument();
expect(spinner).toHaveAttribute('viewBox', '0 0 100 100');
});

test('renders with colorOverride', () => {
render(<Spinner colorOverride="red" />);
const { getSpinner } = getTestUtils();

expect(getSpinner()).toBeInTheDocument();
});
});
69 changes: 36 additions & 33 deletions packages/loading-indicator/src/Spinner/Spinner.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,52 @@
import React from 'react';
import { StoryMetaType } from '@lg-tools/storybook-utils';
import { StoryFn } from '@storybook/react';
import { StoryObj } from '@storybook/react';

import Spinner from './Spinner';
import { DisplayOption } from './Spinner.types';
import { Size } from '@leafygreen-ui/tokens';

const meta: StoryMetaType<typeof Spinner> = {
import { Spinner } from '.';

export default {
title: 'Composition/Loading/LoadingIndicator/Spinner',
component: Spinner,
parameters: {
default: 'LiveExample',
},
argTypes: {
description: { control: 'text' },
sizeOverride: { control: 'number' },
displayOption: { control: 'select', options: Object.values(DisplayOption) },
size: {
control: 'select',
options: Object.values(Size),
},
colorOverride: {
control: 'color',
},
},
args: {
size: Size.Default,
},
} satisfies StoryMetaType<typeof Spinner>;

export const LiveExample: StoryObj<typeof Spinner> = {
render: args => <Spinner {...args} />,
parameters: {
default: 'Default',
chromatic: {
disableSnapshot: true,
},
},
};

export default meta;

const Template: StoryFn<typeof Spinner> = props => <Spinner {...props} />;

export const Default = Template.bind({});

export const WithDescription = Template.bind({});
WithDescription.args = {
description: 'Loading dot dot...',
};

export const Horizontal = Template.bind({});
Horizontal.args = {
displayOption: 'default-horizontal',
description: 'Loading dot dot...',
};

export const SizeOverride = Template.bind({});
SizeOverride.args = {
sizeOverride: 10,
};

export const ColorOverride = Template.bind({});
ColorOverride.args = {
colorOverride: 'purple',
export const Generated: StoryObj<typeof Spinner> = {
render: () => <></>,
parameters: {
generate: {
args: {
disableAnimation: true,
},
combineArgs: {
darkMode: [false, true],
size: [...Object.values(Size), 87],
colorOverride: [undefined, '#f00'],
},
},
},
};
Loading
Loading