Card
A container for headers, content, and footer actions. Supports whole-card clickability with built-in button keyboard semantics, a loading placeholder, and sx quick layout.
Basic Usage
Basic Usage
Rain on Banana LhLeaves
Through the window I know the night rain; the banana leaves sound first.
vue
<script setup lang="ts">
</script>
<template>
<LhCard title="Rain on Banana LhLeaves">
Through the window I know the night rain; the banana leaves sound first.
</LhCard>
</template>vue
<script>
export default {}
</script>
<template>
<LhCard title="Rain on Banana LhLeaves">
Through the window I know the night rain; the banana leaves sound first.
</LhCard>
</template>Shadow
shadow controls when the shadow shows: always (default) / hover / never.
Shadow timing
Hover shadow
Shadow appears on hover.
No shadow
Never shows a shadow.
vue
<script setup lang="ts">
</script>
<template>
<LhCard shadow="hover" title="Hover shadow">Shadow appears on hover.</LhCard>
<LhCard shadow="never" title="No shadow">Never shows a shadow.</LhCard>
</template>vue
<script>
export default {}
</script>
<template>
<LhCard shadow="hover" title="Hover shadow">Shadow appears on hover.</LhCard>
<LhCard shadow="never" title="No shadow">Never shows a shadow.</LhCard>
</template>Header Slot and Extra
Custom Header
Custom headerAction
The
header slot takes over the whole title area. vue
<script setup lang="ts">
</script>
<template>
<LhCard>
<template #header><span>Custom header</span></template>
<template #extra>Action</template>
…
</LhCard>
</template>vue
<script>
export default {}
</script>
<template>
<LhCard>
<template #header><span>Custom header</span></template>
<template #extra>Action</template>
…
</LhCard>
</template>Cover and Footer
Cover and Footer
Cover area
Body content…
vue
<script setup lang="ts">
</script>
<template>
<!-- Cover and Footer -->
<LhCard>
<template #cover>…</template>
…
<template #footer>
<LhButton size="small">Collect</LhButton>
</template>
</LhCard>
</template>vue
<script>
export default {}
</script>
<template>
<!-- Cover and Footer -->
<LhCard>
<template #cover>…</template>
…
<template #footer>
<LhButton size="small">Collect</LhButton>
</template>
</LhCard>
</template>Clickable Card
With clickable, the whole card takes button semantics: Tab-focusable (with a :focus-visible ring), activated by Enter / Space.
Clickable
Click me
Use Tab to focus, then press Enter.
vue
<script setup lang="ts">
function onCardClick() {
console.log('card clicked')
}
</script>
<template>
<!-- Clickable -->
<LhCard clickable title="Click me" @click="onCardClick">…</LhCard>
</template>vue
<script>
export default {
methods: {
onCardClick() {
console.log('card clicked')
},
},
}
</script>
<template>
<!-- Clickable -->
<LhCard clickable title="Click me" @click="onCardClick">…</LhCard>
</template>Loading
Loading
Loading
vue
<script setup lang="ts">
</script>
<template>
<LhCard title="Loading" loading />
</template>vue
<script>
export default {}
</script>
<template>
<LhCard title="Loading" loading />
</template>API
Props
| Prop | Description | Type | Default |
|---|---|---|---|
| title | Card title (or use the header slot) | string | — |
| shadow | When the shadow is shown | "always" | "hover" | "never" | 'always' |
| clickable | Whole card clickable (carries button keyboard semantics) | boolean | false |
| loading | Loading state: the body shows a skeleton placeholder | boolean | false |
| themeVars | Component-level theme variables (keys get the --lh- prefix automatically) | { [x: string]: string; } | — |
| bgPattern | Pattern background URL (e.g. var(--lh-pattern-willow)), not limited by the global whitelist | string | — |
| sx | sx quick-layout properties | LhSxProps | — |
Events
| Event | Description | Callback |
|---|---|---|
| click | Fired by mouse click or Enter/Space on clickable cards | (e: Event) => void |
Theme Variables
The following CSS variables are defined on .lh-card and can be overridden via themeVars:
| Variable | Description | Default |
|---|---|---|
--lh-card-border-radius | Radius | border-radius-base + 2px |
--lh-card-bg | Background | --lh-bg-color |
--lh-card-border-color | Border color | --lh-border-color-light |
--lh-card-header-padding / --lh-card-body-padding / --lh-card-footer-padding | Section paddings | 14px 20px / 18px 20px / 12px 20px |
--lh-card-shadow / --lh-card-shadow-hover | Rest/hover shadows | Warm ink-tone soft two-layer shadows |
--lh-card-loading-bg / --lh-card-loading-highlight | Loading placeholder base / shimmer highlight | --lh-border-color-light / lightened toward paper tone |
Slots
| Slot | Description |
|---|---|
| header | Custom header |
| extra | Extra content on the header row |
| cover | Cover |
| default | Body |
| footer | Footer |
Accessibility
- Clickable cards:
role="button"+tabindex="0"+ Enter/Space activation (APG button pattern) - Loading: container has
aria-busy="true"; placeholders are hidden from screen readers - Focus ring uses
:focus-visible— not shown on mouse click
Type Definitions
The TypeScript type structures exported by this component (auto-extracted from packages/components/card/src/types.ts and @lh-ui/share/core/* sources; click each entry to expand; see the Props table above for attribute descriptions):
LhCardProps
ts
export interface LhCardProps {
title?: string
shadow?: LhCardShadow
clickable?: boolean
loading?: boolean
themeVars?: Record<string, string>
bgPattern?: string
sx?: LhSxProps
}LhCardShadow (from @lh-ui/share/core/card)
ts
export type LhCardShadow = 'always' | 'hover' | 'never'