サクラノ詩
Makura · 2015-10-23 · Written by Sca-ji
The synopsis and details go here.
PageBody sets the spacing between sections.
<script setup lang="ts">
import { Button, Card, NavLink, Page, PageAside, PageBody, PageHeader, Text } from '@hina-ui/vue'
</script>
<template>
<Card :padded="false" class="w-full overflow-hidden">
<Page size="lg">
<PageHeader
eyebrow="Galgame"
title="サクラノ詩"
description="Makura · 2015-10-23 · Written by Sca-ji"
>
<template #actions>
<Button variant="soft" tone="neutral" size="sm">Favourite</Button>
<Button size="sm">Mark as playing</Button>
</template>
</PageHeader>
<PageBody>
<Text size="sm" tone="muted">The synopsis and details go here.</Text>
<Text size="sm" tone="muted">PageBody sets the spacing between sections.</Text>
</PageBody>
<template #aside>
<PageAside label="On this page">
<NavLink href="#" label="Overview">Overview</NavLink>
<NavLink href="#" label="Characters">Characters</NavLink>
<NavLink href="#" label="Staff">Staff</NavLink>
</PageAside>
</template>
</Page>
</Card>
</template>
Usage
import { Page, PageAside, PageBody, PageHeader } from '@hina-ui/vue'
Page is the container for a page’s content and handles the maximum width, centring and vertical padding. PageHeader is the title region, PageBody the main content and PageAside the secondary column on the right, passed through the aside slot.
Page and AppShell work at two different levels: AppShell divides the sidebar, top bar and main area, while Page structures what sits inside that main area. They stack, and either can be used alone.
My shelf
48 titles collected.
Page content.
<script setup lang="ts">
import { Card, Page, PageBody, PageHeader, Text } from '@hina-ui/vue'
</script>
<template>
<Card :padded="false" class="w-full overflow-hidden">
<Page size="sm">
<PageHeader title="My shelf" description="48 titles collected." />
<PageBody>
<Text size="sm" tone="muted">Page content.</Text>
</PageBody>
</Page>
</Card>
</template>
The title on PageHeader renders as the page’s top-level heading, so a page should hold only one PageHeader.
size sets the maximum width of the content and passes through to the underlying Container: sm is 48rem, md 64rem, lg 72rem and xl 80rem, defaulting to md. Long-form reading wants a narrower step; a detail page with an aside wants a wider one.
Examples
Header
eyebrow is a small line above the title, usually a category or parent; title is the heading; description is a sentence beneath it. All three are optional.
The actions slot holds page-level actions, sitting below the title on narrow screens and to its right on wider ones. The default slot comes at the end of the header, for tags, ratings and anything else that belongs directly under the title.
Spring and Asura
Three volumes, ongoing.
<script setup lang="ts">
import { Button, Card, Inline, Page, PageHeader, Tag } from '@hina-ui/vue'
</script>
<template>
<Card :padded="false" class="w-full overflow-hidden">
<Page size="sm">
<PageHeader
eyebrow="Light novel"
title="Spring and Asura"
description="Three volumes, ongoing."
>
<template #actions>
<Button variant="soft" tone="neutral" size="sm">Favourite</Button>
<Button size="sm">Start reading</Button>
</template>
<Inline gap="xs">
<Tag>Fantasy</Tag>
<Tag>School</Tag>
<Tag tone="accent">Editor's pick</Tag>
</Inline>
</PageHeader>
</Page>
</Card>
</template>
Aside
PageAside suits an in-page contents list, related entries and similar secondary content. It sticks to the top as the page scrolls and is hidden entirely below a viewport width of 1280 pixels, so nothing that exists only here may go in it.
label renders as the aside’s small heading and doubles as the accessible name of the region.
Staff
Main column. The aside is hidden below a viewport width of 1280 pixels.
<script setup lang="ts">
import { Card, NavLink, Page, PageAside, PageBody, PageHeader, Text } from '@hina-ui/vue'
</script>
<template>
<Card :padded="false" class="w-full overflow-hidden">
<Page size="lg">
<PageHeader title="Staff" />
<PageBody>
<Text size="sm" tone="muted">
Main column. The aside is hidden below a viewport width of 1280 pixels.
</Text>
</PageBody>
<template #aside>
<PageAside label="Related">
<NavLink href="#" label="Same brand">Same brand</NavLink>
<NavLink href="#" label="Same writer">Same writer</NavLink>
</PageAside>
</template>
</Page>
</Card>
</template>
Behaviour
- Direct children of
Pageare spaced 8 units apart, and children ofPageBody6 units apart. - The aside sits beside the main column, which takes the remaining width, with 10 units between them.
- The aside sticks to the top of the container and stays in view while the page scrolls.
- From medium screens up the header moves its actions to the right of the title; on narrow screens they wrap underneath.
Accessibility
PageHeaderrenders asheaderandPageAsideas anasidelandmark.titleis the page’s top-level heading and should appear only once per page.- Given a
label,PageAsidegenerates a second-level heading and links it witharia-labelledby, so several asides can be told apart in a screen reader’s landmark list. - The aside is hidden on narrow screens, so its content must be reachable elsewhere too.
API
Page
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Maximum width of the content |
class | string | — | Classes appended to the root |
| Slot | Description |
|---|---|
default | Content of the main column |
aside | The secondary column on the right |
PageHeader
| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | — | Small line above the title |
title | string | — | Page title, rendered as the top-level heading |
description | string | — | Sentence beneath the title |
class | string | — | Classes appended to the root |
| Slot | Description |
|---|---|
default | Content at the end of the header |
actions | Page-level actions |
PageBody
| Prop | Type | Default | Description |
|---|---|---|---|
class | string | — | Classes appended to the root |
| Slot | Description |
|---|---|
default | Main content |
PageAside
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Small heading, doubling as the accessible name |
class | string | — | Classes appended to the root |
| Slot | Description |
|---|---|
default | Content of the aside |