Skip to content
Open
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
11 changes: 10 additions & 1 deletion packages/stacks-classic/lib/components/tag/tag.less
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@
}

// CHILD ELEMENTS
a {
&:focus-visible {
.focus-styles();
}

color: var(--_ta-fc) !important;
margin: calc(var(--_ta-pt) * -1) calc(var(--_ta-pr) * -1) calc(var(--_ta-pb) * -1) calc(var(--_ta-pl) * -1);
padding: var(--_ta-pt) var(--_ta-pr) var(--_ta-pb) var(--_ta-pl);
}
// Dismiss
&:has(> &--dismiss) {
--_ta-pr: var(--su2);
Expand Down Expand Up @@ -164,7 +173,7 @@
color: var(--_ta-fc);
font-size: var(--_ta-fs);
padding: var(--_ta-pt) var(--_ta-pr) var(--_ta-pb) var(--_ta-pl);

align-items: center;
display: inline-flex;
gap: var(--su4);
Expand Down
14 changes: 11 additions & 3 deletions packages/stacks-docs/product/components/tags.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,23 @@
{% header "h3", "Default tag" %}
<div class="docs-preview">
{% highlight html %}
<a class="s-tag" href="#">jquery</a>
<span class="s-tag">javascript <button class="s-tag--dismiss"><span class="v-visible-sr">Dismiss javascript tag</span>@Svg.ClearSm</button></span>
<a class="s-tag" href="#"><img class="s-tag--sponsor" src="https://i.stack.imgur.com/tKsDb.png" width="16" height="18" alt="Google Android"> android <div class="v-visible-sr">Sponsored tag</div></a>
<a class="s-tag" href="#">…</a>
<span class="s-tag">… <button class="s-tag--dismiss"><span class="v-visible-sr">Dismiss … tag</span>@Svg.ClearSm</button></span>
<a class="s-tag" href="…"><img class="s-tag--sponsor" src="…" …> … <div class="v-visible-sr">Sponsored tag</div></a>
<span class="s-tag">
<a href="…">…</a>
<button class="s-tag--dismiss"><span class="v-visible-sr">Dismiss … tag</span>@Svg.ClearSm</button>
</span>
{% endhighlight %}
<div class="docs-preview--example">
<div class="d-flex g4 fw-wrap">
<a class="s-tag" href="#">jquery</a>
<span class="s-tag">javascript <button class="s-tag--dismiss"><span class="v-visible-sr">Dismiss javascript tag</span>{% icon "ClearSm" %}</button></span>
<a class="s-tag" href="#"><img class="s-tag--sponsor" src="https://i.stack.imgur.com/tKsDb.png" width="16" height="18" alt="Google Android"> android <div class="v-visible-sr">Sponsored tag</div></a>
<span class="s-tag">
<a href="#">javascript</a>
<button class="s-tag--dismiss"><span class="v-visible-sr">Dismiss javascript tag</span>{% icon "ClearSm" %}</button>
</span>
</div>
</div>
</div>
Expand Down
33 changes: 22 additions & 11 deletions packages/stacks-svelte/src/components/Tag/Tag.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,32 @@
</script>

<svelte:element
this={href ? "a" : "span"}
this={href && !dismissable ? "a" : "span"}
class={classes}
{href}
role={role || (href && "link")}
tabindex={href ? undefined : 0}
href={href && !dismissable ? href : undefined}
role={role || (href && !dismissable ? "link" : undefined)}
{...restProps}
>
{#if sponsor}
<span class="s-tag--sponsor">
{@render sponsor()}
</span>
{#if href && dismissable}
<a {href}>
{#if sponsor}
<span class="s-tag--sponsor">
{@render sponsor()}
</span>
{/if}

{@render children()}
</a>
{:else}
{#if sponsor}
<span class="s-tag--sponsor">
{@render sponsor()}
</span>
{/if}

{@render children()}
{/if}

{@render children()}

{#if sponsor}
<div class="v-visible-sr">{i18nSponsorTagText}</div>
{/if}
Expand All @@ -191,7 +202,7 @@
<div class="v-visible-sr">{i18nRequiredTagText}</div>
{/if}

{#if dismissable && !href}
{#if dismissable}
<button class="s-tag--dismiss" type="button" onclick={ondismiss}>
<span class="v-visible-sr">{i18nDismissButtonText}</span><Icon
src={IconCross16}
Expand Down
21 changes: 15 additions & 6 deletions packages/stacks-svelte/src/components/Tag/Tag.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ describe("Tag", () => {
expect(screen.getByRole("link").textContent?.trim()).to.equal(
"test snippet"
);
expect(screen.getByRole("link")).not.to.have.attribute("tabindex"); // we only append tabindex when we use spans
});

it("should render the appropriate size class", () => {
Expand Down Expand Up @@ -50,24 +49,34 @@ describe("Tag", () => {
);
});

it("should render the dismiss element as span", () => {
it("should render the tag as a span when dismissable is true", () => {
render(Tag, { dismissable: true, children: snippet });
const childElement = screen.getByText("test snippet");
expect(childElement).to.exist;

const tagElement = childElement.parentElement;
expect(tagElement?.tagName).to.equal("SPAN");
expect(tagElement).to.have.attribute("tabindex", "0");

expect(screen.getByRole("button")).to.have.class("s-tag--dismiss");
expect(screen.getByText("Dismiss tag")).to.exist.and.have.class(
"v-visible-sr"
);
});

it("should not render the dismiss element if href prop is set", () => {
render(Tag, { href: "#", dismissable: true, children: snippet });
expect(screen.queryByRole("button")).to.be.null;
it("should render the tag as a span when both href has value and dismissable is true", () => {
render(Tag, { href: "#link", dismissable: true, children: snippet });
const childElement = screen.getByText("test snippet");
expect(childElement).to.exist;

const tagElement = childElement.closest(".s-tag");
expect(tagElement?.tagName).to.equal("SPAN");
expect(tagElement).not.to.have.attribute("href", "#link");
expect(tagElement).not.to.have.attribute("role", "link");

const anchorElement = tagElement?.querySelector("a");
expect(anchorElement).to.have.attribute("href", "#link");

expect(screen.getByRole("button")).to.have.class("s-tag--dismiss");
});

it("should render including the ignored class", () => {
Expand Down