Switcher
Intrinsic equal-column layout that stacks when its own container becomes too narrow.
Default
With no properties supplied, Switcher uses its default gap, threshold, and alignment.
Frodo
Sam
Sméagol
Code
<link
rel="component"
href="@threadlabs/looma/components/ui-switcher/ui-switcher.html"
>
<link
rel="component"
href="@threadlabs/looma/components/ui-card/ui-card.html"
>
<ui-switcher>
<ui-card
padding="sm"
>Frodo</ui-card>
<ui-card
padding="sm"
>Sam</ui-card>
<ui-card
padding="sm"
>Sméagol</ui-card>
</ui-switcher><script setup>
import { UiCard, UiSwitcher } from "@threadlabs/looma";
</script>
<template>
<UiSwitcher>
<UiCard
padding="sm"
>Frodo</UiCard>
<UiCard
padding="sm"
>Sam</UiCard>
<UiCard
padding="sm"
>Sméagol</UiCard>
</UiSwitcher>
</template>import { UiCard, UiSwitcher } from "@threadlabs/looma";
export default function Example() {
return <UiSwitcher>
<UiCard
padding="sm"
>Frodo</UiCard>
<UiCard
padding="sm"
>Sam</UiCard>
<UiCard
padding="sm"
>Sméagol</UiCard>
</UiSwitcher>;
}/** @jsxImportSource preact */
import { UiCard, UiSwitcher } from "@threadlabs/looma";
export default function Example() {
return <UiSwitcher>
<UiCard
padding="sm"
>Frodo</UiCard>
<UiCard
padding="sm"
>Sam</UiCard>
<UiCard
padding="sm"
>Sméagol</UiCard>
</UiSwitcher>;
}<script>
import { UiCard, UiSwitcher } from "@threadlabs/looma";
</script>
<UiSwitcher>
<UiCard
padding="sm"
>Frodo</UiCard>
<UiCard
padding="sm"
>Sam</UiCard>
<UiCard
padding="sm"
>Sméagol</UiCard>
</UiSwitcher>import { Component } from "@angular/core";
import { UiCard, UiSwitcher } from "@threadlabs/looma";
@Component({
selector: "example-view",
standalone: true,
imports: [UiSwitcher, UiCard],
template: `
<div
ui-switcher
>
<ng-template
ui-card
[padding]="'sm'"
>Frodo</ng-template>
<ng-template
ui-card
[padding]="'sm'"
>Sam</ng-template>
<ng-template
ui-card
[padding]="'sm'"
>Sméagol</ng-template>
</div>
`,
})
export default class Example {}Explore the example at a narrower width.
Gap, threshold, and alignment
Threshold sets the intrinsic switch point while gap and alignment control the resulting layout.
Frodo
Sam
Sméagol
Code
<link
rel="component"
href="@threadlabs/looma/components/ui-switcher/ui-switcher.html"
>
<link
rel="component"
href="@threadlabs/looma/components/ui-card/ui-card.html"
>
<ui-switcher
gap="m"
threshold="md"
align="stretch"
>
<ui-card
padding="sm"
>Frodo</ui-card>
<ui-card
padding="sm"
>Sam</ui-card>
<ui-card
padding="sm"
>Sméagol</ui-card>
</ui-switcher><script setup>
import { UiCard, UiSwitcher } from "@threadlabs/looma";
</script>
<template>
<UiSwitcher
gap="m"
threshold="md"
align="stretch"
>
<UiCard
padding="sm"
>Frodo</UiCard>
<UiCard
padding="sm"
>Sam</UiCard>
<UiCard
padding="sm"
>Sméagol</UiCard>
</UiSwitcher>
</template>import { UiCard, UiSwitcher } from "@threadlabs/looma";
export default function Example() {
return <UiSwitcher
gap="m"
threshold="md"
align="stretch"
>
<UiCard
padding="sm"
>Frodo</UiCard>
<UiCard
padding="sm"
>Sam</UiCard>
<UiCard
padding="sm"
>Sméagol</UiCard>
</UiSwitcher>;
}/** @jsxImportSource preact */
import { UiCard, UiSwitcher } from "@threadlabs/looma";
export default function Example() {
return <UiSwitcher
gap="m"
threshold="md"
align="stretch"
>
<UiCard
padding="sm"
>Frodo</UiCard>
<UiCard
padding="sm"
>Sam</UiCard>
<UiCard
padding="sm"
>Sméagol</UiCard>
</UiSwitcher>;
}<script>
import { UiCard, UiSwitcher } from "@threadlabs/looma";
</script>
<UiSwitcher
gap="m"
threshold="md"
align="stretch"
>
<UiCard
padding="sm"
>Frodo</UiCard>
<UiCard
padding="sm"
>Sam</UiCard>
<UiCard
padding="sm"
>Sméagol</UiCard>
</UiSwitcher>import { Component } from "@angular/core";
import { UiCard, UiSwitcher } from "@threadlabs/looma";
@Component({
selector: "example-view",
standalone: true,
imports: [UiSwitcher, UiCard],
template: `
<div
ui-switcher
[gap]="'m'"
[threshold]="'md'"
[align]="'stretch'"
>
<ng-template
ui-card
[padding]="'sm'"
>Frodo</ng-template>
<ng-template
ui-card
[padding]="'sm'"
>Sam</ng-template>
<ng-template
ui-card
[padding]="'sm'"
>Sméagol</ng-template>
</div>
`,
})
export default class Example {}Explore the example at a narrower width.
Limit a row
Four choices stack when the row permits only three, even in a wide container.
One
Two
Three
Four
Code
<link
rel="component"
href="@threadlabs/looma/components/ui-switcher/ui-switcher.html"
>
<link
rel="component"
href="@threadlabs/looma/components/ui-card/ui-card.html"
>
<ui-switcher
limit="3"
threshold="sm"
>
<ui-card>One</ui-card>
<ui-card>Two</ui-card>
<ui-card>Three</ui-card>
<ui-card>Four</ui-card>
</ui-switcher><script setup>
import { UiCard, UiSwitcher } from "@threadlabs/looma";
</script>
<template>
<UiSwitcher
:limit="3"
threshold="sm"
>
<UiCard>One</UiCard>
<UiCard>Two</UiCard>
<UiCard>Three</UiCard>
<UiCard>Four</UiCard>
</UiSwitcher>
</template>import { UiCard, UiSwitcher } from "@threadlabs/looma";
export default function Example() {
return <UiSwitcher
limit={3}
threshold="sm"
>
<UiCard>One</UiCard>
<UiCard>Two</UiCard>
<UiCard>Three</UiCard>
<UiCard>Four</UiCard>
</UiSwitcher>;
}/** @jsxImportSource preact */
import { UiCard, UiSwitcher } from "@threadlabs/looma";
export default function Example() {
return <UiSwitcher
limit={3}
threshold="sm"
>
<UiCard>One</UiCard>
<UiCard>Two</UiCard>
<UiCard>Three</UiCard>
<UiCard>Four</UiCard>
</UiSwitcher>;
}<script>
import { UiCard, UiSwitcher } from "@threadlabs/looma";
</script>
<UiSwitcher
limit={3}
threshold="sm"
>
<UiCard>One</UiCard>
<UiCard>Two</UiCard>
<UiCard>Three</UiCard>
<UiCard>Four</UiCard>
</UiSwitcher>import { Component } from "@angular/core";
import { UiCard, UiSwitcher } from "@threadlabs/looma";
@Component({
selector: "example-view",
standalone: true,
imports: [UiSwitcher, UiCard],
template: `
<div
ui-switcher
[limit]="3"
[threshold]="'sm'"
>
<ng-template
ui-card
>One</ng-template>
<ng-template
ui-card
>Two</ng-template>
<ng-template
ui-card
>Three</ng-template>
<ng-template
ui-card
>Four</ng-template>
</div>
`,
})
export default class Example {}Explore the example at a narrower width.
API
Package: @threadlabs/looma · Native root: div
Attributes
| Name | Description | Property | Type | Default | Allowed values |
|---|---|---|---|---|---|
align | How items line up while they sit in a row: stretch (the default) makes them equally tall; start, center, and end align their tops, middles, or bottoms. | align | keyword | — | start, center, end, stretch |
gap | Space between items, on the spacing scale: xs is 0.5rem, s 0.75rem, m 1rem (also the default), l 1.5rem, and xl 2rem. The --ui-switcher-gap custom property, set on :root, an ancestor, or the component itself, overrides it. | gap | keyword | — | xs, s, m, l, xl |
limit | Most children allowed in a horizontal row. When the count exceeds this value, every child stacks regardless of width. Omit it for no count limit. | limit | integer | — | — |
threshold | The container width at which items switch between a row and a stack: wider, they all sit side by side; narrower, each takes the full width. xs is 20rem, sm is 30rem (also the default), md is 45rem, and lg is 60rem. | threshold | keyword | — | xs, sm, md, lg |
Framework props
| Name | Type | Default | Allowed values |
|---|---|---|---|
align | "start" | "center" | "end" | "stretch" | — | start, center, end, stretch |
gap | "xs" | "s" | "m" | "l" | "xl" | — | xs, s, m, l, xl |
limit | number | — | — |
threshold | "xs" | "sm" | "md" | "lg" | — | xs, sm, md, lg |
Events
No events.
Slots
| Name | Purpose |
|---|---|
default | Default child content. |
Design tokens
Set shared theme properties on a theme boundary. Component hooks apply only to their owning component.
Component tokens
| Token | Declared values | Fallback |
|---|---|---|
--ui-switcher-gap | var(--ui-space-4) | var(--ui-space-2) | var(--ui-space-3) | var(--ui-space-5) | var(--ui-space-6) | — |
--ui-switcher-threshold | 30rem | 20rem | 45rem | 60rem | — |
Shared tokens
| Token | Fallback |
|---|---|
--ui-space-2 | — |
--ui-space-3 | — |
--ui-space-4 | — |
--ui-space-5 | — |
--ui-space-6 | — |