Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
db2aee7
update stacks docs
mukunku Dec 15, 2025
d59b2fc
implement svelte component
mukunku Dec 16, 2025
834a22a
fix link
mukunku Dec 16, 2025
734a14c
lint
mukunku Dec 16, 2025
79e61a8
update baseline
mukunku Dec 16, 2025
85f6c3e
fix test
mukunku Dec 16, 2025
e4f6018
upgrade expanding input to svelte 5
mukunku Dec 16, 2025
3d906e3
tweak tests
mukunku Dec 16, 2025
c24d2fb
lint
mukunku Dec 16, 2025
c24783d
simplify expanding input svelte code
mukunku Dec 16, 2025
fd216d9
Create lovely-hotels-arrive.md
mukunku Dec 16, 2025
68cdb17
Revert "simplify expanding input svelte code"
mukunku Dec 16, 2025
c8dc038
fix lint
mukunku Dec 16, 2025
7bb42fa
fix expanding-input
mukunku Dec 16, 2025
0388f4a
Update lovely-hotels-arrive.md
mukunku Dec 16, 2025
14c8cea
set width for textareas in docs
mukunku Dec 16, 2025
21a57a6
add examples with links
mukunku Dec 16, 2025
02bc4ee
better native color implementation
mukunku Dec 16, 2025
c7cc9b3
hack to fix visual tests
mukunku Dec 16, 2025
3310b2b
update baseline
mukunku Dec 19, 2025
eda831c
pr feedback
mukunku Dec 19, 2025
b4fb2ae
make header tag dynamic
mukunku Dec 19, 2025
09b1d00
optimize expanding input css class
mukunku Dec 19, 2025
80f46d3
Merge branch 'beta' into sal/SPARK-120-2
mukunku Dec 19, 2025
5f3229b
update baseline
mukunku Dec 19, 2025
8749ceb
try fix timeout
mukunku Dec 19, 2025
8f82547
switch back to ellipsis again
mukunku Dec 19, 2025
759b9ac
lint
mukunku Dec 19, 2025
306a2f3
prettier format
mukunku Dec 19, 2025
58c81e5
Merge branch 'beta' into sal/SPARK-120-2
mukunku Jan 5, 2026
6ca500c
Merge branch 'beta' into sal/SPARK-120-2
dancormier Jan 5, 2026
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
7 changes: 7 additions & 0 deletions .changeset/lovely-hotels-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@stackoverflow/stacks": patch
"@stackoverflow/stacks-svelte": minor
---

feat(empty-state): new SHINE styles and Svelte Component
fix(expanding-input): expands correctly now after textarea update
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { html } from "@open-wc/testing";
import { SpotEmptyXL } from "@stackoverflow/stacks-icons-legacy";
import { SpotEmpty } from "@stackoverflow/stacks-icons/spots";
import { runA11yTests } from "../../test/a11y-test-utils";
import "../../index";

describe("empty-state", () => {
runA11yTests({
baseClass: "s-empty-state",
children: {
default: `${SpotEmptyXL}<p class="mt24"><strong>Hello!</strong> This is a wonderful empty state component.</p>`,
default: `${SpotEmpty}
<h4 class="s-empty-state--title">No questions match your result.</h4>
<p>This is a wonderful empty state component.</p>`,
},
template: ({ component, testid }) => html`
<div class="ws3 p16" data-testid="${testid}">${component}</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
.s-empty-state {
// CHILD ELEMENTS
p {
strong {
color: var(--fc-dark);
}
color: var(--black-400);
margin-bottom: var(--su32);
}

&--title {
font-weight: 600;
font-size: var(--fs-body3);
margin-bottom: var(--su8);
color: var(--black-400);
}

.svg-spot {
margin-bottom: var(--su24);
}

font-size: var(--fs-body1);
margin-bottom: var(--su12);
// Remove margin from <p> if there are no buttons
&:last-child {
margin-bottom: 0;
}

color: var(--fc-light);
text-align: center;
margin-left: auto;
margin-right: auto;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { html } from "@open-wc/testing";
import { SpotEmptyXL } from "@stackoverflow/stacks-icons-legacy";
import { SpotEmpty } from "@stackoverflow/stacks-icons/spots";
import { runVisualTests } from "../../test/visual-test-utils";
import "../../index";

describe("empty-state", () => {
runVisualTests({
baseClass: "s-empty-state",
children: {
default: `${SpotEmptyXL}<p class="mt24"><strong>Hello!</strong> This is a wonderful empty state component.</p>`,
"default": `${SpotEmpty.replace("svg-spot", "svg-spot native")}
<p>This is a wonderful empty state component.</p>`,
"with-title": `${SpotEmpty.replace("svg-spot", "svg-spot native")}
<h4 class="s-empty-state--title">Amazing title for this empty state.</h4>
<p>This is a wonderful empty state component.</p>`,
},
template: ({ component, testid }) => html`
<div class="ws3 p16" data-testid="${testid}">${component}</div>
Expand Down
5 changes: 3 additions & 2 deletions packages/stacks-classic/lib/components/modal/modal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,9 @@ describe("modal", () => {

await user.click(trigger);
expect(modal).to.be.visible;

await waitFor(() => expect(initialFocusEl).to.have.focus);
await waitFor(() => expect(initialFocusEl).to.have.focus, {
timeout: 20000,
});
});

it("should focus on the first focusable element when modal is shown and no initialFocus is specified", async () => {
Expand Down
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
3 changes: 2 additions & 1 deletion packages/stacks-docs/_data/site-navigation.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@
},
{
"title": "Empty states",
"url": "/product/components/empty-states/"
"url": "/product/components/empty-states/",
"new": true
},
{
"title": "Expandable",
Expand Down
81 changes: 31 additions & 50 deletions packages/stacks-docs/product/components/empty-states.html
Original file line number Diff line number Diff line change
@@ -1,95 +1,76 @@
---
layout: page
title: Empty states
svelte: https://beta.svelte.stackoverflow.design/?path=/docs/components-emptystate--docs
figma: https://www.figma.com/design/do4Ug0Yws8xCfRjHe9cJfZ/Project-SHINE---Product-UI?node-id=610-18807&p=f&m=dev
description: Empty states are used when there is no data to show. Ideally they orient the user by providing feedback based on the the user’s last interaction or communicate the benefits of a feature. When appropriate, they should explain the next steps the user should take and provide guidance with a clear call-to-action.
tags: components
---
<section class="stacks-section">
{% header "h2", "No data" %}
{% header "h2", "No data or results" %}
<p class="stacks-copy">
Used when a user hasn’t interacted with a feature yet.
Typical use-case for an empty state is when a feature has no data or a search/filter operation yields no results.
</p>
{% header "h3", "No data actionable" %}
{% header "h3", "Actionable" %}
<p class="stacks-copy">
If the user can take an action to fix the situation, it's best to draw attention to it, explain next steps, and provide a call-to-action.
If the user is able to address the situation resulting in an empty state, it is appropriate to include a button for them to do so.
</p>
<div class="stacks-preview">
{% highlight html %}
<div class="s-empty-state wmx4 p48">
@Svg.Spot.EmptyXL.With("mb24")
<p>Why is this blank? Explain it.</p>
<a class="s-btn s-btn__filled">Call to action</a>
@Svg.Spot.Empty.With("native")
<h4 class="s-empty-state--title">No questions match your result.</h4>
<p>Try refining your search term or trying something more general.</p>
<button class="s-btn s-btn__tonal">Clear filters</a>
</div>
{% endhighlight %}
<div class="stacks-preview--example">
<div class="s-empty-state wmx4 p48">
{% spot, "EmptyXL", "mb24" %}
<p>We haven’t received any data yet. Have you connected your Stack Overflow account?</p>
<a class="s-btn s-btn__filled">Connect my account</a>
{% spot, "Empty", "native" %}
<h4 class="s-empty-state--title">No questions match your result.</h4>
<p>Try refining your search term or trying something more general.</p>
<button class="s-btn s-btn__tonal">Clear filters</button>
</div>
</div>
</div>
{% header "h3", "No data non-actionable" %}

{% header "h3", "Non-actionable" %}
<p class="stacks-copy">
If the user can’t take an action to fix the situation, it’s more appropriate to set expectations.
If the user can’t take an action to fix the situation, it’s appropriate to set expectations.
</p>
<div class="stacks-preview">
{% highlight html %}
<div class="s-empty-state wmx4 p48">
@Svg.Spot.EmptyXL.With("mb24")
<p>Why is this blank? Explain it.</p>
@Svg.Spot.Empty.With("native")
<h4 class="s-empty-state--title">User trends not ready</h4>
<p>Please check back in a few days.</p>
</div>
{% endhighlight %}
<div class="stacks-preview--example">
<div class="s-empty-state wmx4 p48">
{% spot, "EmptyXL", "mb24" %}
<p>There’s no data associated with your account yet. Please check back tomorrow.</p>
</div>
</div>
</div>
</section>
<section class="stacks-section">
{% header "h2", "No results" %}
<p class="stacks-copy">
When someone performs an action that returns nothing, a blank state can explain what happened and help get someone back on track.
</p>
{% header "h3", "No results actionable" %}
<p class="stacks-copy">
If the user can take an action to fix the situation, it’s best to draw attention to it and provide a call-to-action.
</p>
<div class="stacks-preview">
{% highlight html %}
<div class="s-empty-state wmx4 p48">
@Svg.Spot.EmptyXL.With("mb24")
<p>Why is this blank? Explain it.</p>
<a class="s-btn s-btn__filled">Call to action</a>
</div>
{% endhighlight %}
<div class="stacks-preview--example bg-black-100">
<div class="s-empty-state wmx4 p48">
{% spot, "EmptyXL", "mb24" %}
<p>We couldn’t find any tags matching <span class="s-tag d-inline-block">stacks-1-0-0</span>. It might not exist yet. Would you like to create it?</p>
<a href="#" class="s-btn s-btn__filled">Create this tag</a>
{% spot, "Empty", "native" %}
<h4 class="s-empty-state--title">User trends not ready</h4>
<p>Please check back in a few days.</p>
</div>
</div>
</div>

{% header "h3", "No results non-actionable" %}
{% header "h3", "Minimal" %}
<p class="stacks-copy">
If the user can’t take an action to fix the situation, it’s more appropriate to set expectations.
If desired, both the title and call-to-action may be omitted for a minimal look.
</p>
<div class="stacks-preview">
{% highlight html %}
<div class="s-empty-state wmx4 p48">
@Svg.Spot.EmptyXL.With("mb24")
<p>Why is this blank? Explain it.</p>
@Svg.Spot.Empty.With("native")
<p>There’s no data associated with <a href="#" class="s-link s-link__underlined">this account</a>.</p>
</div>
{% endhighlight %}
<div class="stacks-preview--example bg-black-100">
<div class="stacks-preview--example">
<div class="s-empty-state wmx4 p48">
{% spot, "EmptyXL", "mb24" %}
<p>We couldn’t match users for <strong>Namey McUser</strong>. Try refining your search or trying something more general.</p>
{% spot, "Empty", "native" %}
<p>There’s no data associated with <a href="#" class="s-link s-link__underlined">this account</a>.</p>
</div>
</div>
</div>
</section>
</section>
Loading