Shion Hoshimi
Translator
<script setup lang="ts">
import { Avatar, Button, Card, Inline, Stack, Tag, Text } from '@hina-ui/vue'
</script>
<template>
<Card class="w-full max-w-md">
<Inline justify="between">
<Inline gap="sm">
<Avatar size="lg" src="/avatars/selfie.webp" alt="Shion Hoshimi" />
<Stack gap="none">
<Text class="font-medium">Shion Hoshimi</Text>
<Text tone="muted" size="sm">Translator</Text>
</Stack>
</Inline>
<Inline gap="xs">
<Tag>Verified</Tag>
<Button size="sm" variant="soft" tone="neutral">Follow</Button>
</Inline>
</Inline>
</Card>
</template>
Usage
import { Inline } from '@hina-ui/vue'
Inline is a horizontal flex container: its children sit centred on the cross axis and wrap when they run out of room.
<script setup lang="ts">
import { Button, Inline } from '@hina-ui/vue'
</script>
<template>
<Inline>
<Button variant="soft" tone="neutral">Save</Button>
<Button variant="soft" tone="neutral">Save as</Button>
<Button variant="soft" tone="neutral">Export</Button>
</Inline>
</template>
Examples
Gap
gap takes steps rather than arbitrary values. The default md comes from --hn-inline-gap, which is 12 pixels at the regular density and 8 at the compact one; the other five steps are 0, 4, 8, 24 and 32 pixels.
none
xs
sm
md
lg
xl
<script setup lang="ts">
import { Card, Inline, Stack, Text } from '@hina-ui/vue'
const gaps = ['none', 'xs', 'sm', 'md', 'lg', 'xl'] as const
</script>
<template>
<Stack>
<Stack v-for="gap in gaps" :key="gap" gap="xs">
<Text tone="muted" size="sm">{{ gap }}</Text>
<Inline :gap="gap">
<Card class="bg-inset size-8" :padded="false" />
<Card class="bg-inset size-8" :padded="false" />
<Card class="bg-inset size-8" :padded="false" />
</Inline>
</Stack>
</Stack>
</template>
Cross-axis alignment
align decides how the children line up vertically; the default is centred. Use baseline when the text sizes differ, so the baselines line up instead of the boxes.
start
Heading
Body
Note
center
Heading
Body
Note
end
Heading
Body
Note
baseline
Heading
Body
Note
stretch
Heading
Body
Note
<script setup lang="ts">
import { Heading, Inline, Stack, Text } from '@hina-ui/vue'
const aligns = ['start', 'center', 'end', 'baseline', 'stretch'] as const
</script>
<template>
<Stack>
<Stack v-for="align in aligns" :key="align" gap="xs">
<Text tone="muted" size="sm">{{ align }}</Text>
<Inline :align="align" class="bg-inset rounded-md p-3">
<Heading :level="3" size="xl">Heading</Heading>
<Text>Body</Text>
<Text tone="muted" size="sm">Note</Text>
</Inline>
</Stack>
</Stack>
</template>
Main-axis distribution
justify decides how the children are distributed horizontally. between pushes the first and last to the ends, which is how a heading row with a trailing button is written.
Reading history
<script setup lang="ts">
import { Button, Heading, Inline } from '@hina-ui/vue'
</script>
<template>
<Inline justify="between" class="bg-inset w-full rounded-md p-3">
<Heading :level="3" size="md">Reading history</Heading>
<Button size="sm" variant="soft" tone="neutral">Clear all</Button>
</Inline>
</template>
Wrapping
wrap defaults to true. Set it to false to keep everything on one line, together with overflow handling on the container around it.
wrap defaults to true, so items wrap when they run out of room
With wrap false they stay on one line
<script setup lang="ts">
import { Inline, Stack, Tag, Text } from '@hina-ui/vue'
const tags = [
'Sci-fi',
'Mystery',
'School',
'Coming of age',
'Healing',
'Slice of life',
'Ensemble',
'Isekai',
]
</script>
<template>
<Stack class="w-full max-w-sm">
<Stack gap="xs">
<Text tone="muted" size="sm">
wrap defaults to true, so items wrap when they run out of room
</Text>
<Inline gap="xs">
<Tag v-for="tag in tags" :key="tag">{{ tag }}</Tag>
</Inline>
</Stack>
<Stack gap="xs">
<Text tone="muted" size="sm">With wrap false they stay on one line</Text>
<Inline :wrap="false" gap="xs" class="overflow-hidden">
<Tag v-for="tag in tags" :key="tag">{{ tag }}</Tag>
</Inline>
</Stack>
</Stack>
</template>
Root element
as changes the rendered tag; use nav for navigation.
It also accepts Vue components, such as :as="RouterLink" or :as="NuxtLink". Import the component or obtain it through resolveComponent; object, functional and async components are supported. Layout classes, extra attributes, event listeners and the default slot are forwarded without an extra wrapper. Custom components must forward attributes and classes to their rendered root.
<script setup lang="ts">
import { Inline, Link } from '@hina-ui/vue'
</script>
<template>
<Inline as="nav" gap="lg" aria-label="Footer navigation">
<Link href="#">About</Link>
<Link href="#">Help</Link>
<Link href="#">Terms</Link>
</Inline>
</template>
API
| Prop | Type | Default | Description |
|---|---|---|---|
gap | 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Space between the children |
align | 'start' | 'center' | 'end' | 'baseline' | 'stretch' | 'center' | Cross-axis alignment |
justify | 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly' | — | Main-axis distribution |
wrap | boolean | true | Whether children wrap |
as | string | Component | 'div' | The rendered tag or Vue component |
class | string | — | Classes appended to the container |
| Slot | Description |
|---|---|
default | The children |