Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sbb-loading): add indicator color variants #1998

Merged
merged 3 commits into from
Sep 30, 2023
Merged
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
8 changes: 8 additions & 0 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,10 @@ export namespace Components {
"titleLevel"?: InterfaceTitleAttributes['level'];
}
interface SbbLoadingIndicator {
/**
* Color variant.
*/
"color": InterfaceSbbLoadingIndicatorAttributes['color'];
/**
* Whether the animation is enabled.
*/
Expand Down Expand Up @@ -3810,6 +3814,10 @@ declare namespace LocalJSX {
"titleLevel"?: InterfaceTitleAttributes['level'];
}
interface SbbLoadingIndicator {
/**
* Color variant.
*/
"color"?: InterfaceSbbLoadingIndicatorAttributes['color'];
/**
* Whether the animation is enabled.
*/
Expand Down
11 changes: 6 additions & 5 deletions src/components/sbb-loading-indicator/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ and then append the `sbb-loading-indicator` on it after giving it the correct `a

## Properties

| Property | Attribute | Description | Type | Default |
| ------------------ | ------------------- | ------------------------------------------------------------------------------------------------- | ---------------------- | ----------- |
| `disableAnimation` | `disable-animation` | Whether the animation is enabled. | `boolean` | `false` |
| `size` | `size` | Size variant, either s or m. | `"l" \| "s"` | `'s'` |
| `variant` | `variant` | Variant of the loading indicator; `circle` is meant to be used inline, while `window` as overlay. | `"circle" \| "window"` | `undefined` |
| Property | Attribute | Description | Type | Default |
| ------------------ | ------------------- | ------------------------------------------------------------------------------------------------- | --------------------------------- | ----------- |
| `color` | `color` | Color variant. | `"default" \| "smoke" \| "white"` | `'default'` |
| `disableAnimation` | `disable-animation` | Whether the animation is enabled. | `boolean` | `false` |
| `size` | `size` | Size variant, either s or m. | `"l" \| "s"` | `'s'` |
| `variant` | `variant` | Variant of the loading indicator; `circle` is meant to be used inline, while `window` as overlay. | `"circle" \| "window"` | `undefined` |


----------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface InterfaceSbbLoadingIndicatorAttributes {
variant: 'window' | 'circle';
size: 's' | 'l';
color: 'default' | 'smoke' | 'white';
}
18 changes: 18 additions & 0 deletions src/components/sbb-loading-indicator/sbb-loading-indicator.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@
--sbb-loading-indicator-duration: 0;
}

:host([color='smoke']) {
--sbb-loading-indicator-color: var(--sbb-color-smoke-default);
}

:host([color='white']) {
--sbb-loading-indicator-color: var(--sbb-color-white-default);
}

:host([variant='circle']) {
--sbb-loading-indicator-height: var(--sbb-size-icon-ui-small);
--sbb-loading-indicator-width: var(--sbb-size-icon-ui-small);
Expand All @@ -31,6 +39,10 @@
--sbb-loading-indicator-circle-animated-border-radius: 50%;
}

:host([color='white'][variant='circle']) {
--sbb-loading-indicator-background-color: var(--sbb-color-iron-default);
}

:host([variant='circle']) .sbb-loading-indicator {
display: inline-flex;
height: auto;
Expand Down Expand Up @@ -85,6 +97,12 @@
}
}

:host([color='white'][variant='circle']) .sbb-loading-indicator__animated-element::after {
@include sbb.if-forced-colors {
--sbb-loading-indicator-color: var(--sbb-color-white-default);
}
}

:host([variant='window']) {
--sbb-loading-indicator-height: sbb.px-to-rem-build(32);
--sbb-loading-indicator-width: sbb.px-to-rem-build(55);
Expand Down
92 changes: 90 additions & 2 deletions src/components/sbb-loading-indicator/sbb-loading-indicator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,61 @@ describe('sbb-loading-indicator', () => {
});

expect(root).toEqualHtml(`
<sbb-loading-indicator variant="window" size="m" role="progressbar" aria-busy='true'>
<sbb-loading-indicator variant="window" size="m" color="default" role="progressbar" aria-busy='true'>
<mock:shadow-root>
<span class="sbb-loading-indicator">
<span class="sbb-loading-indicator__animated-element">
<span>
<span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</span>
</span>
</span>
</span>
</mock:shadow-root>
</sbb-loading-indicator>
`);
});

it('renders with variant `window` and color smoke', async () => {
const { root } = await newSpecPage({
components: [SbbLoadingIndicator],
html: '<sbb-loading-indicator variant="window" size="m" color="smoke"/>',
});

expect(root).toEqualHtml(`
<sbb-loading-indicator variant="window" size="m" color="smoke" role="progressbar" aria-busy='true'>
<mock:shadow-root>
<span class="sbb-loading-indicator">
<span class="sbb-loading-indicator__animated-element">
<span>
<span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</span>
</span>
</span>
</span>
</mock:shadow-root>
</sbb-loading-indicator>
`);
});

it('renders with variant `window` and color white', async () => {
const { root } = await newSpecPage({
components: [SbbLoadingIndicator],
html: '<sbb-loading-indicator variant="window" size="m" color="white"/>',
});

expect(root).toEqualHtml(`
<sbb-loading-indicator variant="window" size="m" color="white" role="progressbar" aria-busy='true'>
<mock:shadow-root>
<span class="sbb-loading-indicator">
<span class="sbb-loading-indicator__animated-element">
Expand All @@ -36,7 +90,41 @@ describe('sbb-loading-indicator', () => {
});

expect(root).toEqualHtml(`
<sbb-loading-indicator variant="circle" size="s" role="progressbar" aria-busy="true">
<sbb-loading-indicator variant="circle" size="s" color="default" role="progressbar" aria-busy="true">
<mock:shadow-root>
<span class="sbb-loading-indicator">
<span class="sbb-loading-indicator__animated-element"></span>
</span>
</mock:shadow-root>
</sbb-loading-indicator>
`);
});

it('renders with variant `circle` and color smoke', async () => {
const { root } = await newSpecPage({
components: [SbbLoadingIndicator],
html: '<sbb-loading-indicator variant="circle" color="smoke"/>',
});

expect(root).toEqualHtml(`
<sbb-loading-indicator variant="circle" color="smoke" size="s" role="progressbar" aria-busy="true">
<mock:shadow-root>
<span class="sbb-loading-indicator">
<span class="sbb-loading-indicator__animated-element"></span>
</span>
</mock:shadow-root>
</sbb-loading-indicator>
`);
});

it('renders with variant `circle` and color white', async () => {
const { root } = await newSpecPage({
components: [SbbLoadingIndicator],
html: '<sbb-loading-indicator variant="circle" color="white"/>',
});

expect(root).toEqualHtml(`
<sbb-loading-indicator variant="circle" color="white" size="s" role="progressbar" aria-busy="true">
<mock:shadow-root>
<span class="sbb-loading-indicator">
<span class="sbb-loading-indicator__animated-element"></span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ const textBlockStyle: Args = {
borderRadius: 'var(--sbb-border-radius-4x)',
};

const negativeBlockStyle: Args = {
backgroundColor: 'var(--sbb-color-iron-default)',
color: 'var(--sbb-color-white-default)',
padding: '2rem',
};

const createLoadingIndicator = (args): void => {
const loader: HTMLSbbLoadingIndicatorElement = document.createElement(
'SBB-LOADING-INDICATOR',
Expand Down Expand Up @@ -50,6 +56,12 @@ const TemplateAccessibility = (args): JSX.Element => (

const Template = (args): JSX.Element => <sbb-loading-indicator {...args}></sbb-loading-indicator>;

const NegativeTemplate = (args): JSX.Element => (
<div style={negativeBlockStyle}>
<sbb-loading-indicator {...args}></sbb-loading-indicator>
</div>
);

const InlineTemplate = (args): JSX.Element => (
<div>
<p>
Expand All @@ -61,6 +73,17 @@ const InlineTemplate = (args): JSX.Element => (
</div>
);

const NegativeInlineTemplate = (args): JSX.Element => (
<div style={negativeBlockStyle}>
<p>
<sbb-loading-indicator {...args}></sbb-loading-indicator> Inline loading indicator
</p>
<h2>
<sbb-loading-indicator {...args}></sbb-loading-indicator> Adaptive to font size
</h2>
</div>
);

const variant: InputType = {
control: {
type: 'select',
Expand All @@ -75,6 +98,13 @@ const size: InputType = {
options: ['small', 'large'],
};

const color: InputType = {
control: {
type: 'inline-radio',
},
options: ['default', 'smoke', 'white'],
};

const disableAnimation: InputType = {
control: {
type: 'boolean',
Expand All @@ -84,33 +114,71 @@ const disableAnimation: InputType = {
const defaultArgTypes: ArgTypes = {
variant,
size,
color,
'disable-animation': disableAnimation,
};

const defaultArgs: Args = {
variant: variant.options[0],
size: size.options[0],
color: color.options[0],
'disable-animation': isChromatic(),
};

export const WindowSmall: StoryObj = {
export const WindowSmallDefault: StoryObj = {
render: Template,
argTypes: defaultArgTypes,
args: { ...defaultArgs },
};

export const WindowLarge: StoryObj = {
export const WindowSmallSmoke: StoryObj = {
render: Template,
argTypes: defaultArgTypes,
args: { ...defaultArgs, color: color.options[1] },
};

export const WindowSmallWhite: StoryObj = {
render: NegativeTemplate,
argTypes: defaultArgTypes,
args: { ...defaultArgs, color: color.options[2] },
};

export const WindowLargeDefault: StoryObj = {
render: Template,
argTypes: defaultArgTypes,
args: { ...defaultArgs, size: size.options[1] },
};

export const Circle: StoryObj = {
export const WindowLargeSmoke: StoryObj = {
render: Template,
argTypes: defaultArgTypes,
args: { ...defaultArgs, color: color.options[1], size: size.options[1] },
};

export const WindowLargeWhite: StoryObj = {
render: NegativeTemplate,
argTypes: defaultArgTypes,
args: { ...defaultArgs, color: color.options[2], size: size.options[1] },
};

export const CircleDefault: StoryObj = {
render: InlineTemplate,
argTypes: defaultArgTypes,
args: { ...defaultArgs, variant: variant.options[1] },
};

export const CircleSmoke: StoryObj = {
render: InlineTemplate,
argTypes: defaultArgTypes,
args: { ...defaultArgs, color: color.options[1], variant: variant.options[1] },
};

export const CircleWhite: StoryObj = {
render: NegativeInlineTemplate,
argTypes: defaultArgTypes,
args: { ...defaultArgs, color: color.options[2], variant: variant.options[1] },
};

export const Accessibility: StoryObj = {
render: TemplateAccessibility,
argTypes: defaultArgTypes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export class SbbLoadingIndicator implements ComponentInterface {
/** Size variant, either s or m. */
@Prop({ reflect: true }) public size: InterfaceSbbLoadingIndicatorAttributes['size'] = 's';

/** Color variant. */
@Prop({ reflect: true }) public color: InterfaceSbbLoadingIndicatorAttributes['color'] =
'default';

/** Whether the animation is enabled. */
@Prop({ reflect: true }) public disableAnimation = false;

Expand Down