diff --git a/src/components/loading/loading.stories.ts b/src/components/loading/loading.stories.ts new file mode 100644 index 0000000..ff81dcb --- /dev/null +++ b/src/components/loading/loading.stories.ts @@ -0,0 +1,37 @@ +import { Meta, StoryObj } from '@storybook/web-components'; + +import './loading'; + +const meta: Meta = { + title: 'Components/Loading', + component: 'ewc-loading', + argTypes: { + label: { + name: 'Component label', + control: { + type: 'text', + }, + }, + size: { + name: 'Component size', + control: { + type: 'select', + }, + options: ['sm', 'md', 'lg'], + }, + active: { + name: 'Component display', + control: 'boolean', + }, + }, +}; + +export default meta; + +export const Loading: StoryObj = { + args: { + size: 'md', + active: true, + label: 'Sending data...', + }, +}; diff --git a/src/components/loading/loading.ts b/src/components/loading/loading.ts new file mode 100644 index 0000000..d64d1e5 --- /dev/null +++ b/src/components/loading/loading.ts @@ -0,0 +1,56 @@ +import { LitElement, css, html } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; + +@customElement('ewc-loading') +export class Loading extends LitElement { + @property({ type: Boolean }) active = false; + @property({ type: String }) label = 'Loading'; + @property({ type: String }) size: 'sm'|'md'|'lg' = 'md'; + + static styles = css` + .loading { + display: flex; + align-items: center; + column-gap: var(--spacing-lg); + } + + .loading__spinner { + border-radius: 50%; + display: inline-block; + animation: spin 1s linear infinite; + border: 4px solid rgba(0, 0, 0, 0.1); + border-left: 4px solid var(--color-primary-default); + } + + .loading__spinner[size="sm"] { + width: var(--size-lg); + height: var(--size-lg); + } + + .loading__spinner[size="md"] { + width: var(--size-xl); + height: var(--size-xl); + } + + .loading__spinner[size="lg"] { + width: var(--size-2xl); + height: var(--size-2xl); + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + `; + + render() { + return this.active ? html` +
+ +
+ ${this.label} +
+
+ ` : html``; + } +}