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

NameDescriptionPropertyTypeDefaultAllowed values
alignHow 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.alignkeyword—start, center, end, stretch
gapSpace 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.gapkeyword—xs, s, m, l, xl
limitMost children allowed in a horizontal row. When the count exceeds this value, every child stacks regardless of width. Omit it for no count limit.limitinteger——
thresholdThe 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.thresholdkeyword—xs, sm, md, lg

Framework props

NameTypeDefaultAllowed values
align"start" | "center" | "end" | "stretch"—start, center, end, stretch
gap"xs" | "s" | "m" | "l" | "xl"—xs, s, m, l, xl
limitnumber——
threshold"xs" | "sm" | "md" | "lg"—xs, sm, md, lg

Events

No events.

Slots

NamePurpose
defaultDefault child content.

Design tokens

Set shared theme properties on a theme boundary. Component hooks apply only to their owning component.

Component tokens

TokenDeclared valuesFallback
--ui-switcher-gapvar(--ui-space-4) | var(--ui-space-2) | var(--ui-space-3) | var(--ui-space-5) | var(--ui-space-6)—
--ui-switcher-threshold30rem | 20rem | 45rem | 60rem—

Shared tokens

TokenFallback
--ui-space-2—
--ui-space-3—
--ui-space-4—
--ui-space-5—
--ui-space-6—