Skip to content

Commit

Permalink
feat(design-system): Skeleton update (#5052)
Browse files Browse the repository at this point in the history
  • Loading branch information
romainseb authored Dec 11, 2023
1 parent 266df87 commit b71e4e6
Show file tree
Hide file tree
Showing 15 changed files with 178 additions and 16 deletions.
8 changes: 8 additions & 0 deletions .changeset/blue-students-invent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@talend/design-system': minor
---

feat(design-system): There is some limitation when designing skeletons

Add new width for header and paragraph skeletons
Add new SkeletonSized that can be shaped for any needs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { forwardRef, HTMLAttributes, Ref } from 'react';

import classNames from 'classnames';

import styles from './Skeleton.module.scss';
Expand Down
9 changes: 8 additions & 1 deletion packages/design-system/src/components/Skeleton/Skeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import SkeletonButtonIcon, { SkeletonButtonIconProps } from './variations/Skelet
import SkeletonHeading, { SkeletonHeadingProps } from './variations/SkeletonHeading';
import SkeletonInput, { SkeletonInputProps } from './variations/SkeletonInput';
import SkeletonParagraph, { SkeletonParagraphProps } from './variations/SkeletonParagraph';
import SkeletonSized, { SkeletonSizedProps } from './variations/SkeletonSized';

export type SkeletonProps =
| ({ variant: 'button' } & SkeletonButtonProps)
| ({ variant: 'buttonIcon' } & SkeletonButtonIconProps)
| ({ variant: 'heading' } & SkeletonHeadingProps)
| ({ variant: 'paragraph' } & SkeletonParagraphProps)
| ({ variant: 'input' } & SkeletonInputProps);
| ({ variant: 'input' } & SkeletonInputProps)
| ({ variant: 'sized' } & SkeletonSizedProps);

export const Skeleton = forwardRef((props: SkeletonProps, ref: Ref<HTMLSpanElement>) => {
switch (props.variant) {
Expand Down Expand Up @@ -40,6 +42,11 @@ export const Skeleton = forwardRef((props: SkeletonProps, ref: Ref<HTMLSpanEleme
return <SkeletonInput {...rest} ref={ref} />;
}

case 'sized': {
const { variant, ...rest } = props;
return <SkeletonSized {...rest} ref={ref} />;
}

default: {
return null;
}
Expand Down
13 changes: 11 additions & 2 deletions packages/design-system/src/components/Skeleton/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
export * from './Skeleton';
import SkeletonButton from './variations/SkeletonButton';
import SkeletonButtonIcon from './variations/SkeletonButtonIcon';
import SkeletonHeading from './variations/SkeletonHeading';
import SkeletonInput from './variations/SkeletonInput';
import SkeletonParagraph from './variations/SkeletonParagraph';
import SkeletonSized from './variations/SkeletonSized';

export * from './Skeleton';

export { SkeletonHeading, SkeletonButtonIcon, SkeletonButton, SkeletonParagraph, SkeletonInput };
export {
SkeletonHeading,
SkeletonButtonIcon,
SkeletonButton,
SkeletonParagraph,
SkeletonInput,
SkeletonSized,
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { forwardRef, Ref } from 'react';

import classNames from 'classnames';

import SkeletonPrimitive, { SkeletonPrimitiveProps } from '../Primitive/Skeleton.Primitive';

import PrimitiveStyles from '../Primitive/Skeleton.module.scss';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { forwardRef, Ref } from 'react';

import classNames from 'classnames';

import SkeletonPrimitive, { SkeletonPrimitiveProps } from '../Primitive/Skeleton.Primitive';

import PrimitiveStyles from '../Primitive/Skeleton.module.scss';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,28 @@
&.size-S {
height: 1.4rem;
}

&.width-XS {
max-width: 10%;
}

&.width-S {
max-width: 20%;
}

&.width-M {
max-width: 40%;
}

&.width-L {
max-width: 60%;
}

&.width-XL {
max-width: 80%;
}

&.width-100 {
max-width: 100%;
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { forwardRef, Ref } from 'react';

import classNames from 'classnames';

import SkeletonPrimitive, { SkeletonPrimitiveProps } from '../Primitive/Skeleton.Primitive';

import styles from './SkeletonHeading.module.scss';

export type SkeletonHeadingProps = Omit<SkeletonPrimitiveProps, 'className'> & {
size?: 'L' | 'M' | 'S';
width?: 'XS' | 'S' | 'M' | 'L' | 'XL' | '100';
};

const SkeletonHeading = forwardRef(
({ size = 'L', ...props }: SkeletonHeadingProps, ref: Ref<HTMLSpanElement>) => {
({ size = 'L', width, ...props }: SkeletonHeadingProps, ref: Ref<HTMLSpanElement>) => {
return (
<SkeletonPrimitive
isBlock
className={classNames(styles.skeletonHeading, {
[styles['size-L']]: size === 'L',
[styles['size-M']]: size === 'M',
[styles['size-S']]: size === 'S',
[styles[`size-${size}`]]: size,
[styles[`width-${width}`]]: width,
})}
{...props}
ref={ref}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { forwardRef, Ref } from 'react';

import { StackVertical } from '../../Stack';
import SkeletonPrimitive, { SkeletonPrimitiveProps } from '../Primitive/Skeleton.Primitive';
import styles from './SkeletonInput.module.scss';
import SkeletonParagraph from './SkeletonParagraph';
import { forwardRef, Ref } from 'react';

import styles from './SkeletonInput.module.scss';

export type SkeletonInputProps = Omit<SkeletonPrimitiveProps, 'className'>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,28 @@
&.size-S {
height: 1.2rem;
}

&.width-XS {
max-width: 10%;
}

&.width-S {
max-width: 20%;
}

&.width-M {
max-width: 40%;
}

&.width-L {
max-width: 60%;
}

&.width-XL {
max-width: 80%;
}

&.width-100 {
max-width: 100%;
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { forwardRef, Ref } from 'react';

import classNames from 'classnames';

import SkeletonPrimitive, { SkeletonPrimitiveProps } from '../Primitive/Skeleton.Primitive';

import styles from './SkeletonParagraph.module.scss';

export type SkeletonParagraphProps = Omit<SkeletonPrimitiveProps, 'className'> & {
size?: 'M' | 'S';
width?: 'XS' | 'S' | 'M' | 'L' | 'XL' | '100';
};

const SkeletonParagraph = forwardRef(
({ size = 'M', ...props }: SkeletonParagraphProps, ref: Ref<HTMLSpanElement>) => {
({ size = 'M', width, ...props }: SkeletonParagraphProps, ref: Ref<HTMLSpanElement>) => {
return (
<SkeletonPrimitive
isBlock
className={classNames(styles.skeletonParagraph, {
[styles['size-M']]: size === 'M',
[styles['size-S']]: size === 'S',
[styles[`size-${size}`]]: size,
[styles[`width-${width}`]]: width,
})}
{...props}
ref={ref}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@use '~@talend/design-tokens/lib/tokens';

.skeleton-sized-circle {
border-radius: tokens.$coral-radius-round;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { forwardRef, Ref } from 'react';

import classNames from 'classnames';

import SkeletonPrimitive, { SkeletonPrimitiveProps } from '../Primitive/Skeleton.Primitive';

import style from './SkeletonSized.module.scss';

export type SkeletonSizedProps = Omit<SkeletonPrimitiveProps, 'className'> & {
height?: number;
width?: number;
isCircle?: boolean;
};

const SkeletonSized = forwardRef(
(
{ height = 1.4, width = 2, isCircle, ...props }: SkeletonSizedProps,
ref: Ref<HTMLSpanElement>,
) => {
return (
<SkeletonPrimitive
// @ts-expect-error style is valid
style={{ height: `${height}rem`, width: `${width}rem` }}
className={classNames({ [style['skeleton-sized-circle']]: isCircle })}
{...props}
ref={ref}
/>
);
},
);
SkeletonSized.displayName = 'SkeletonSized';

export default SkeletonSized;
17 changes: 14 additions & 3 deletions packages/design-system/src/stories/feedback/Skeleton.mdx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Meta, Canvas, Story, Controls } from '@storybook/blocks';
import { Canvas, Controls, Meta, Story } from '@storybook/blocks';

import { FigmaImage } from '@talend/storybook-docs';

import {
Skeleton,
SkeletonButton,
SkeletonParagraph,
SkeletonHeading,
SkeletonInput,
Skeleton,
SkeletonParagraph,
StackHorizontal,
StackVertical,
} from '../../';
Expand Down Expand Up @@ -82,6 +84,15 @@ It illustrates any input element.
<Story of={Stories.SkeletonInputStory} />
</Canvas>

#### Sized

It can be the size needed

<Canvas>
<Story of={Stories.SkeletonSizedStory} />
</Canvas>
<Controls of={Stories.SkeletonSizedStory} />

#### Composition example

Combine all of them to mock content!
Expand Down
31 changes: 30 additions & 1 deletion packages/design-system/src/stories/feedback/Skeleton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import {
SkeletonHeading,
SkeletonInput,
SkeletonParagraph,
SkeletonSized,
StackHorizontal,
StackVertical,
} from '../../';

import SkeletonPrimitive from '../../components/Skeleton/Primitive/Skeleton.Primitive';

export default {
Expand All @@ -34,6 +34,10 @@ const SkeletonParagraphTemplate: StoryFn<typeof SkeletonParagraph> = args => {
return <SkeletonParagraph {...args} />;
};

const SkeletonSizedTemplate: StoryFn<typeof SkeletonSized> = args => {
return <SkeletonSized {...args} />;
};

const SkeletonInputTemplate: StoryFn<typeof SkeletonInput> = args => {
return <SkeletonInput {...args} />;
};
Expand Down Expand Up @@ -71,6 +75,11 @@ SkeletonHeadingStory.argTypes = {
control: { type: 'select' },
description: 'optional (default is "L")',
},
width: {
options: ['100', 'XL', 'L', 'M', 'S', 'XS'],
control: { type: 'select' },
description: 'optional',
},
};

export const SkeletonParagraphStory = SkeletonParagraphTemplate.bind({});
Expand All @@ -83,6 +92,26 @@ SkeletonParagraphStory.argTypes = {
control: { type: 'select' },
description: 'optional (default is "M")',
},
width: {
options: ['100', 'XL', 'L', 'M', 'S', 'XS'],
control: { type: 'select' },
description: 'optional',
},
};

export const SkeletonSizedStory = SkeletonSizedTemplate.bind({});
SkeletonSizedStory.args = {
isCircle: true,
};
SkeletonSizedStory.argTypes = {
height: {
control: { type: 'number' },
defaultValue: 10,
},
width: {
control: { type: 'number' },
defaultValue: 10,
},
};

export const SkeletonInputStory = SkeletonInputTemplate.bind({});
Expand Down

0 comments on commit b71e4e6

Please sign in to comment.