diff --git a/.changeset/ninety-dogs-pump.md b/.changeset/ninety-dogs-pump.md new file mode 100644 index 0000000000..b3dc8dc68d --- /dev/null +++ b/.changeset/ninety-dogs-pump.md @@ -0,0 +1,10 @@ +--- +"@stackoverflow/stacks": minor +"@stackoverflow/stacks-svelte": minor +--- + +Add .bg-loading delete skeleton + +BREAKING CHANGES: + +Skeleton component deleted \ No newline at end of file diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 84dfd45d2e..e58bbe6496 100755 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -16,6 +16,10 @@ - `.blr-sm` removed - `.blr-lg` removed +#### Background +- Add `.bg-loading` +- Skeleton component deleted + #### Colors - `gold`, `silver`, `bronze` colors removed diff --git a/packages/stacks-classic/lib/atomic/__snapshots__/misc.less.test.ts.snap b/packages/stacks-classic/lib/atomic/__snapshots__/misc.less.test.ts.snap index 1e6f9f27d8..3724a544e5 100644 --- a/packages/stacks-classic/lib/atomic/__snapshots__/misc.less.test.ts.snap +++ b/packages/stacks-classic/lib/atomic/__snapshots__/misc.less.test.ts.snap @@ -125,6 +125,28 @@ exports[`atomic: misc > should output all atomic css classes 1`] = ` background-image: none !important; } +.bg-loading { + animation: loadingBgAnimation 1.5s ease-out infinite; + animation-delay: 1ms; +} + +@keyframes loadingBgAnimation { + 0% { + background-color: var(--black-150); + opacity: 1; + } + + 50% { + background-color: var(--black-100); + opacity: 0.7; + } + + 100% { + background-color: var(--black-150); + opacity: 1; + } +} + .bg-confetti-animated { background-repeat: repeat-x; background-position: top -10px center; diff --git a/packages/stacks-classic/lib/atomic/misc.less b/packages/stacks-classic/lib/atomic/misc.less index 5d6bb5e5b4..0e84027cc9 100644 --- a/packages/stacks-classic/lib/atomic/misc.less +++ b/packages/stacks-classic/lib/atomic/misc.less @@ -67,6 +67,26 @@ // ---------------------------------------------------------------------------- .bg-image-none { background-image: none !important; } +.bg-loading { + animation: loadingBgAnimation 1.5s ease-out infinite; + animation-delay: 1ms; +} + +@keyframes loadingBgAnimation { + 0% { + background-color: var(--black-150); + opacity: 1; + } + 50% { + background-color: var(--black-100); + opacity: 0.7; + } + 100% { + background-color: var(--black-150); + opacity: 1; + } +} + .bg-confetti-animated { background-repeat: repeat-x; background-position: top -10px center; diff --git a/packages/stacks-classic/lib/components/skeleton/skeleton.a11y.test.ts b/packages/stacks-classic/lib/components/skeleton/skeleton.a11y.test.ts deleted file mode 100644 index a0158a40fb..0000000000 --- a/packages/stacks-classic/lib/components/skeleton/skeleton.a11y.test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { runA11yTests } from "../../test/a11y-test-utils"; -import "../../index"; - -describe("skeleton", () => { - runA11yTests({ - baseClass: "s-skeleton", - variants: ["ai"], - }); -}); diff --git a/packages/stacks-classic/lib/components/skeleton/skeleton.less b/packages/stacks-classic/lib/components/skeleton/skeleton.less deleted file mode 100644 index c61c52a119..0000000000 --- a/packages/stacks-classic/lib/components/skeleton/skeleton.less +++ /dev/null @@ -1,73 +0,0 @@ -.s-skeleton { - // BASE COMPONENT-SPECIFIC CUSTOM PROPERTIES - // TODO verify colors with design - --_sk-bg-1: var(--black-400); - --_sk-bg-2: var(--black-350); - --_sk-bg-3: var(--black-300); - --_sk-o: 0.25; - - // CONTEXTUAL STYLES - .highcontrast-mode({ - --_sk-o: 0.4; - }); - - @keyframes flow { - 0% { - background-position: 400% 50%; - } - 100% { - background-position: 0% 50%; - } - } - - // VARIANTS - &&__ai { - --_sk-bg-1: #ac76f0; - --_sk-bg-2: #297fff; - --_sk-bg-3: #6abcf8; - } - - &, - &:after, - &:before { - @media (prefers-reduced-motion: no-preference) { - animation: flow 8s linear infinite; - } - - background-image: linear-gradient( - to right, - var(--_sk-bg-1) 8%, - var(--_sk-bg-2) 16%, - var(--_sk-bg-3) 25%, - var(--_sk-bg-1) 42%, - var(--_sk-bg-2) 58%, - var(--_sk-bg-3) 75%, - var(--_sk-bg-1) 83% - ); - background-size: 400% 100%; - border-radius: var(--br-md); - display: block; - height: var(--su16); - position: relative; - } - - &:after, - &:before { - content: ''; - position: relative; - } - - &:after { - top: calc(var(--su4)); - width: calc(2/3 * 100%); - } - - &:before { - top: calc(var(--su32) + var(--su8)); - width: calc(1/3 * 100%); - } - - margin-bottom: var(--su48); - opacity: var(--_sk-o); - width: 100%; -} \ No newline at end of file diff --git a/packages/stacks-classic/lib/components/skeleton/skeleton.visual.test.ts b/packages/stacks-classic/lib/components/skeleton/skeleton.visual.test.ts deleted file mode 100644 index 0b3fb4fbbc..0000000000 --- a/packages/stacks-classic/lib/components/skeleton/skeleton.visual.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { html } from "@open-wc/testing"; -import { runVisualTests } from "../../test/visual-test-utils"; -import "../../index"; - -describe("skeleton", () => { - runVisualTests({ - baseClass: "s-skeleton", - variants: ["ai"], - template: ({ component, testid }) => html` -
${component}
- `, - }); -}); diff --git a/packages/stacks-classic/lib/stacks-static.less b/packages/stacks-classic/lib/stacks-static.less index ddb182b0f3..9a8680da21 100644 --- a/packages/stacks-classic/lib/stacks-static.less +++ b/packages/stacks-classic/lib/stacks-static.less @@ -42,7 +42,6 @@ @import "components/prose/prose.less"; @import "components/select/select.less"; @import "components/sidebar-widget/sidebar-widget.less"; -@import "components/skeleton/skeleton.less"; @import "components/spinner/spinner.less"; @import "components/table/table.less"; @import "components/table-container/table-container.less"; diff --git a/packages/stacks-docs/_data/site-navigation.json b/packages/stacks-docs/_data/site-navigation.json index 6746192f9b..9425dd8f99 100644 --- a/packages/stacks-docs/_data/site-navigation.json +++ b/packages/stacks-docs/_data/site-navigation.json @@ -67,7 +67,8 @@ "links": [ { "title": "Backgrounds", - "url": "/product/base/backgrounds/" + "url": "/product/base/backgrounds/", + "new": true }, { "title": "Borders", @@ -335,10 +336,6 @@ "title": "Sidebar widgets", "url": "/product/components/sidebar-widgets/" }, - { - "title": "Skeleton", - "url": "/product/components/skeleton/" - }, { "title": "Spinner", "url": "/product/components/spinner/" diff --git a/packages/stacks-docs/_data/skeleton.json b/packages/stacks-docs/_data/skeleton.json deleted file mode 100644 index fb3f5341dd..0000000000 --- a/packages/stacks-docs/_data/skeleton.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "skeleton": [ - { - "class": ".s-skeleton", - "applies": "N/A", - "description": "Base monochrome style" - }, - { - "class": ".s-skeleton__ai", - "applies": ".s-skeleton", - "description": "Colorful skeleton style for AI elements" - } - ] -} diff --git a/packages/stacks-docs/product/base/backgrounds.html b/packages/stacks-docs/product/base/backgrounds.html index a1827f3daf..2d286ff43d 100644 --- a/packages/stacks-docs/product/base/backgrounds.html +++ b/packages/stacks-docs/product/base/backgrounds.html @@ -152,6 +152,37 @@
{% header "h2", "Background utilities" %} + {% header "h3", "Loading" %} +

The Loading utility applies a shimmering gradient animation to a container's background. Use this class to create flexible 'skeleton' placeholders that mimic the shape and layout of content while it loads.

+
+{% highlight html %} +
+
+
Loading…
+
+
+
+
+
+
+
+
+{% endhighlight %} +
+
+
+
Loading…
+
+
+
+
+
+
+
+
+
+
+ {% header "h3", "Confetti" %}

Adding the confetti background utility adds confetti to any block-level element. You can choose the animated version, or static version. The animated version respects prefers-reduced-motion and displays the static version of the background when necessary. No JavaScript required.

diff --git a/packages/stacks-docs/product/components/skeleton.html b/packages/stacks-docs/product/components/skeleton.html deleted file mode 100644 index d05c298b7d..0000000000 --- a/packages/stacks-docs/product/components/skeleton.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -layout: page -title: Skeleton -svelte: https://beta.svelte.stackoverflow.design/?path=/docs/components-skeleton--docs -description: A skeleton component is used to indicate that a large block of content, such as an AI responses or post summary, is loading. -tags: components ---- - -
- {% header "h2", "Classes" %} -
- - - - - - - - - - {% for item in skeleton.skeleton %} - - - - - - {% endfor %} - -
ClassApplied toDescription
{{ item.class }}{% if item.applies == "N/A" %}{{ item.applies }}{% else %}{{ item.applies }}{% endif %}{{ item.description }}
-
-
- -
- {% header "h2", "Examples" %} - {% header "h3", "Base style" %} -

The default skeleton should be used when loading large blocks will render multiple rows of content.

-
-{% highlight html %} -
-
Loading…
-
-{% endhighlight %} -
-
-
Loading…
-
-
-
- - {% header "h3", "AI" %} -

The ai variant of the skeleton should be used when loading AI responses.

-
-{% highlight html %} -
-
Loading…
-
-{% endhighlight %} -
-
-
Loading…
-
-
-
-
- -
- {% header "h2", "Accessibility" %} -

For accessibility, it’s important to add fallback loading text that is visible to screen readers. Additionally, you should add aria-busy="true" to the component that triggered the loading state while the skeleton is shown.

-
- diff --git a/packages/stacks-svelte/src/components/Skeleton/Skeleton.stories.svelte b/packages/stacks-svelte/src/components/Skeleton/Skeleton.stories.svelte deleted file mode 100644 index 3334d4c55d..0000000000 --- a/packages/stacks-svelte/src/components/Skeleton/Skeleton.stories.svelte +++ /dev/null @@ -1,13 +0,0 @@ - - - - diff --git a/packages/stacks-svelte/src/components/Skeleton/Skeleton.svelte b/packages/stacks-svelte/src/components/Skeleton/Skeleton.svelte deleted file mode 100644 index 72b784610c..0000000000 --- a/packages/stacks-svelte/src/components/Skeleton/Skeleton.svelte +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
-
{label}
-
diff --git a/packages/stacks-svelte/src/components/Skeleton/Skeleton.test.ts b/packages/stacks-svelte/src/components/Skeleton/Skeleton.test.ts deleted file mode 100644 index 8877bde972..0000000000 --- a/packages/stacks-svelte/src/components/Skeleton/Skeleton.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { expect } from "@open-wc/testing"; -import { render, screen } from "@testing-library/svelte"; - -import Skeleton from "./Skeleton.svelte"; - -describe("Skeleton", () => { - it("should render the skeleton with the label content", () => { - render(Skeleton, { label: "내용이 로드 중" }); - expect(screen.getByText("내용이 로드 중")).to.exist; - }); - - it("should render the skeleton with the ai variant class", () => { - render(Skeleton, { variant: "ai" }); - const item = screen.getByText("Loading…").closest(".s-skeleton"); - expect(item).to.have.class("s-skeleton__ai"); - }); -}); diff --git a/packages/stacks-svelte/src/components/index.ts b/packages/stacks-svelte/src/components/index.ts index 3893e8c96c..68f9a47e50 100644 --- a/packages/stacks-svelte/src/components/index.ts +++ b/packages/stacks-svelte/src/components/index.ts @@ -31,7 +31,6 @@ export { default as Radio } from "./RadioGroup/Radio.svelte"; export { default as RadioGroup } from "./RadioGroup/RadioGroup.svelte"; export { default as Select } from "./Select/Select.svelte"; export { default as SelectItem } from "./Select/SelectItem.svelte"; -export { default as Skeleton } from "./Skeleton/Skeleton.svelte"; export { default as Spinner } from "./Spinner/Spinner.svelte"; export { default as Tag } from "./Tag/Tag.svelte"; export { default as TextArea } from "./TextArea/TextArea.svelte";