Kumo Svelte
  • Home
  • Installation
  • Colors
  • Accessibility
  • Changelog
  • Autocomplete
  • Badge
  • Banner
  • Breadcrumbs
  • Button
  • Checkbox
  • Clipboard Text
  • Cloudflare Logo
  • CodeHighlighted
  • Collapsible
  • Combobox
  • Command Palette
  • Date Picker
  • Dialog
  • Dropdown
  • Empty
  • Flow
  • Grid
  • Input
  • InputArea
  • InputGroup
  • Label
  • Layer Card
  • Link
  • Loader
  • MenuBar
  • Meter
  • Pagination
  • Popover
  • Radio
  • Select
  • Sensitive Input
  • Sidebar
  • Skeleton Line
  • Switch
  • Table
  • Table of Contents
  • Tabs
  • Text
  • Toast
  • Toolbar
  • Tooltip
  • Charts
  • Colors
  • Timeseries
  • Maps
  • Sankey
  • Custom Chart
  • Page Header
  • Resource List
  • Delete Resource
Layer Card
kumo-svelte

Layer Card

A card component with a layered visual effect, perfect for navigation or feature highlights.

Next Steps
Get started with Kumo
<script lang="ts">
  import ArrowRightIcon from "phosphor-svelte/lib/ArrowRightIcon";
  import { Button } from "kumo-svelte/components/button";
  import * as LayerCard from "kumo-svelte/components/layer-card";
</script>

<LayerCard.Root layered>
  <LayerCard.Secondary class="flex items-center justify-between">
    <div>Next Steps</div>
    <Button variant="ghost" size="sm" shape="square" aria-label="Go to next steps">
      <ArrowRightIcon size={16} />
    </Button>
  </LayerCard.Secondary>

  <LayerCard.Primary>Get started with Kumo</LayerCard.Primary>
</LayerCard.Root>

Import

import * as LayerCard from "kumo-svelte/components/layer-card";

Usage

<script lang="ts">
  import * as LayerCard from "kumo-svelte/components/layer-card";
</script>

<LayerCard.Root layered class="w-[250px]">
  <LayerCard.Secondary>Documentation</LayerCard.Secondary>
  <LayerCard.Primary>Learn how to use Kumo components</LayerCard.Primary>
</LayerCard.Root>

LayerCard also supports a simple surface-style mode for cases where you do not need a secondary header row. In those cases, render content directly inside LayerCard and omit the layered prop.

<LayerCard.Root class="w-[250px] p-4">
  Learn how to use Kumo components
</LayerCard.Root>

Examples

Basic Card

Getting Started

Quick start guide for new users

<script lang="ts">
  import * as LayerCard from "kumo-svelte/components/layer-card";
</script>

<LayerCard.Root layered class="w-[250px]">
  <LayerCard.Secondary>Getting Started</LayerCard.Secondary>
  <LayerCard.Primary>
    <p class="text-sm text-kumo-subtle">Quick start guide for new users</p>
  </LayerCard.Primary>
</LayerCard.Root>

Surface-style Card

For simple card containers, render content directly inside LayerCard without LayerCard.Primary.

Quick start guide for new users

<script lang="ts">
  import * as LayerCard from "kumo-svelte/components/layer-card";
</script>

<LayerCard.Root class="w-[250px] p-4">
  <p class="text-sm text-kumo-subtle">Quick start guide for new users</p>
</LayerCard.Root>

Multiple Cards

Components

Browse all components

Examples

View code examples

<script lang="ts">
  import * as LayerCard from "kumo-svelte/components/layer-card";
</script>

<div class="flex flex-wrap gap-4">
  <LayerCard.Root layered class="w-[200px]">
    <LayerCard.Secondary>Components</LayerCard.Secondary>
    <LayerCard.Primary>
      <p class="text-sm">Browse all components</p>
    </LayerCard.Primary>
  </LayerCard.Root>

  <LayerCard.Root layered class="w-[200px]">
    <LayerCard.Secondary>Examples</LayerCard.Secondary>
    <LayerCard.Primary>
      <p class="text-sm">View code examples</p>
    </LayerCard.Primary>
  </LayerCard.Root>
</div>

Filter Toolbar with Small Tabs

Combine Tabs size="sm" with Input size="sm" inside a LayerCard for compact filter toolbars. Both share the same 26px height.

Subrequests
Origin Requests Duration
challenges.cloudflare.com
2xx 1
95.4ms
Unknown
2xx 19 4xx 7
463.7ms
api.example.com
2xx 42 4xx 3
128.1ms
Showing 3 of 3
<script lang="ts">
  import { Badge } from "kumo-svelte/components/badge";
  import { Input } from "kumo-svelte/components/input";
  import * as LayerCard from "kumo-svelte/components/layer-card";
  import * as Tabs from "kumo-svelte/components/tabs";
  const origins = [
    { origin: "challenges.cloudflare.com", s2xx: 1, s4xx: 0, duration: "95.4ms" },
    { origin: "Unknown", s2xx: 19, s4xx: 7, duration: "463.7ms" },
    { origin: "api.example.com", s2xx: 42, s4xx: 3, duration: "128.1ms" },
  ];

  type StatusFilter = "all" | "2xx" | "3xx" | "4xx" | "5xx";

  let filter = $state<StatusFilter>("all");
  let search = $state("");

  let filtered = $derived(
    origins.filter((origin) => {
      if (filter === "2xx" && origin.s2xx === 0) return false;
      if (filter === "4xx" && origin.s4xx === 0) return false;
      if (search && !origin.origin.toLowerCase().includes(search.toLowerCase())) return false;
      return true;
    }),
  );
</script>

<LayerCard.Root layered class="w-full max-w-[540px]">
  <LayerCard.Secondary>Subrequests</LayerCard.Secondary>

  <LayerCard.Primary>
    <div class="mb-2 flex items-center gap-3">
      <Input
        size="sm"
        placeholder="Filter origins…"
        aria-label="Filter origins"
        bind:value={search}
        class="min-w-0 flex-1"
      />
      <Tabs.Root
        variant="segmented"
        size="sm"
        class="shrink-0"
        value={filter}
        onValueChange={(value) => {
          filter = value as StatusFilter;
        }}
      >
        <Tabs.List>
          <Tabs.Trigger value="all">All</Tabs.Trigger>
          <Tabs.Trigger value="2xx">2xx</Tabs.Trigger>
          <Tabs.Trigger value="3xx">3xx</Tabs.Trigger>
          <Tabs.Trigger value="4xx">4xx</Tabs.Trigger>
          <Tabs.Trigger value="5xx">5xx</Tabs.Trigger>
        </Tabs.List>
      </Tabs.Root>
    </div>

    <div class="-mx-1 text-sm">
      <div class="grid grid-cols-[1fr_auto_auto] gap-x-4 border-b border-kumo-fill px-1 pb-2 text-xs font-medium text-kumo-subtle">
        <span>Origin</span>
        <span class="w-28 text-right">Requests</span>
        <span class="w-20 text-right">Duration</span>
      </div>

      {#each filtered as row, index (row.origin)}
        <div
          class="grid grid-cols-[1fr_auto_auto] items-center gap-x-4 px-1 py-2.5"
          class:border-b={index < filtered.length - 1}
          class:border-kumo-hairline={index < filtered.length - 1}
        >
          <span class="truncate font-medium text-kumo-default">{row.origin}</span>
          <div class="flex w-28 items-center justify-end gap-1.5">
            {#if row.s2xx > 0}<Badge variant="success">2xx {row.s2xx}</Badge>{/if}
            {#if row.s4xx > 0}<Badge variant="error">4xx {row.s4xx}</Badge>{/if}
          </div>
          <span class="w-20 text-right text-kumo-subtle">{row.duration}</span>
        </div>
      {/each}
    </div>

    <div class="-mx-1 border-t border-kumo-fill pt-2 text-xs text-kumo-subtle">
      Showing {filtered.length} of {origins.length}
    </div>
  </LayerCard.Primary>
</LayerCard.Root>

Test IDs

LayerCard.Primary and LayerCard.Secondary accept all standard HTML attributes, including data-testid for testing.

Getting Started

Quick start guide for new users

<script lang="ts">
  import * as LayerCard from "kumo-svelte/components/layer-card";
</script>

<LayerCard.Root layered class="w-[250px]">
  <LayerCard.Secondary data-testid="card-header">Getting Started</LayerCard.Secondary>
  <LayerCard.Primary data-testid="card-body">
    <p class="text-sm text-kumo-subtle">Quick start guide for new users</p>
  </LayerCard.Primary>
</LayerCard.Root>

API Reference

LayerCard

PropTypeDefault
askeyof HTMLElementTagNameMap"div"
childrenSnippet—
classstring—
layeredbooleanfalse

LayerCard.Primary

PropTypeDefault
childrenSnippet—
classstring—

LayerCard.Secondary

PropTypeDefault
childrenSnippet—
classstring—

Layered Cards

Use layered on the root when composing the primary and secondary regions.

On this page

  • Import
  • Usage
  • Examples
    • Basic Card
    • Surface-style Card
    • Multiple Cards
    • Filter Toolbar with Small Tabs
    • Test IDs
  • API Reference
    • LayerCard
    • LayerCard.Primary
    • LayerCard.Secondary
  • Layered Cards