diff --git a/docs/_sidebar.md b/docs/_sidebar.md
index 5f0fbe19..a1404fb0 100644
--- a/docs/_sidebar.md
+++ b/docs/_sidebar.md
@@ -33,6 +33,7 @@
- [Range](/components/range.md)
- [Rating](/components/rating.md)
- [Select](/components/select.md)
+ - [Skeleton](/components/skeleton.md)
- [Spinner](/components/spinner.md)
- [Switch](/components/switch.md)
- [Tab Group](/components/tab-group.md)
diff --git a/docs/components/skeleton.md b/docs/components/skeleton.md
new file mode 100644
index 00000000..73baf5e6
--- /dev/null
+++ b/docs/components/skeleton.md
@@ -0,0 +1,29 @@
+# Skeleton
+
+[component-header:sl-skeleton]
+
+Skeletons are used to show where content will eventually be drawn.
+
+```html preview
+
+
+
+
+
+
+
+```
+
+[component-metadata:sl-skeleton]
diff --git a/src/components.d.ts b/src/components.d.ts
index c36be66d..d15b5ea0 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -667,6 +667,12 @@ export namespace Components {
*/
"value": string | Array;
}
+ interface SlSkeleton {
+ /**
+ * When enabled, the skeleton will be animated to indicate that content is loading.
+ */
+ "loading": boolean;
+ }
interface SlSpinner {
}
interface SlSwitch {
@@ -1050,6 +1056,12 @@ declare global {
prototype: HTMLSlSelectElement;
new (): HTMLSlSelectElement;
};
+ interface HTMLSlSkeletonElement extends Components.SlSkeleton, HTMLStencilElement {
+ }
+ var HTMLSlSkeletonElement: {
+ prototype: HTMLSlSkeletonElement;
+ new (): HTMLSlSkeletonElement;
+ };
interface HTMLSlSpinnerElement extends Components.SlSpinner, HTMLStencilElement {
}
var HTMLSlSpinnerElement: {
@@ -1124,6 +1136,7 @@ declare global {
"sl-range": HTMLSlRangeElement;
"sl-rating": HTMLSlRatingElement;
"sl-select": HTMLSlSelectElement;
+ "sl-skeleton": HTMLSlSkeletonElement;
"sl-spinner": HTMLSlSpinnerElement;
"sl-switch": HTMLSlSwitchElement;
"sl-tab": HTMLSlTabElement;
@@ -1880,6 +1893,12 @@ declare namespace LocalJSX {
*/
"value"?: string | Array;
}
+ interface SlSkeleton {
+ /**
+ * When enabled, the skeleton will be animated to indicate that content is loading.
+ */
+ "loading"?: boolean;
+ }
interface SlSpinner {
}
interface SlSwitch {
@@ -2145,6 +2164,7 @@ declare namespace LocalJSX {
"sl-range": SlRange;
"sl-rating": SlRating;
"sl-select": SlSelect;
+ "sl-skeleton": SlSkeleton;
"sl-spinner": SlSpinner;
"sl-switch": SlSwitch;
"sl-tab": SlTab;
@@ -2184,6 +2204,7 @@ declare module "@stencil/core" {
"sl-range": LocalJSX.SlRange & JSXBase.HTMLAttributes;
"sl-rating": LocalJSX.SlRating & JSXBase.HTMLAttributes;
"sl-select": LocalJSX.SlSelect & JSXBase.HTMLAttributes;
+ "sl-skeleton": LocalJSX.SlSkeleton & JSXBase.HTMLAttributes;
"sl-spinner": LocalJSX.SlSpinner & JSXBase.HTMLAttributes;
"sl-switch": LocalJSX.SlSwitch & JSXBase.HTMLAttributes;
"sl-tab": LocalJSX.SlTab & JSXBase.HTMLAttributes;
diff --git a/src/components/skeleton/skeleton.scss b/src/components/skeleton/skeleton.scss
new file mode 100644
index 00000000..e5a09557
--- /dev/null
+++ b/src/components/skeleton/skeleton.scss
@@ -0,0 +1,34 @@
+@import 'component';
+
+/**
+ * @prop --color: The color of the skeleton.
+ * @prop --sheen-color: The sheen color when the skeleton is in its loading state.
+ */
+:host {
+ --color: var(--sl-color-gray-90);
+ --sheen-color: var(--sl-color-gray-95);
+
+ display: flex;
+ height: 1em;
+}
+
+.skeleton {
+ flex: 1 1 auto;
+ background: var(--color);
+ border-radius: var(--sl-border-radius-pill);
+}
+
+.skeleton--loading {
+ background: linear-gradient(90deg, var(--sheen-color) 20%, var(--color) 40%, var(--sheen-color) 60%);
+ background-size: 400% 100%;
+ animation: loading 1.5s ease infinite;
+}
+
+@keyframes loading {
+ 0% {
+ background-position: 100% 50%;
+ }
+ 100% {
+ background-position: 0 50%;
+ }
+}
diff --git a/src/components/skeleton/skeleton.tsx b/src/components/skeleton/skeleton.tsx
new file mode 100644
index 00000000..feaf0b1f
--- /dev/null
+++ b/src/components/skeleton/skeleton.tsx
@@ -0,0 +1,32 @@
+import { Component, Prop, h } from '@stencil/core';
+
+/**
+ * @since 2.0
+ * @status stable
+ *
+ * @part base - The component's base wrapper.
+ */
+
+@Component({
+ tag: 'sl-skeleton',
+ styleUrl: 'skeleton.scss',
+ shadow: true
+})
+export class Skeleton {
+ /** When enabled, the skeleton will be animated to indicate that content is loading. */
+ @Prop() loading = false;
+
+ render() {
+ return (
+
+ );
+ }
+}