feat(ui): implement page header component
This commit is contained in:
parent
6daf2952ec
commit
541eca9c90
|
@ -0,0 +1,60 @@
|
|||
<script setup lang="ts">
|
||||
import type { RouterLinkProps } from 'vue-router'
|
||||
import { useAttrs } from 'vue'
|
||||
|
||||
import Layout from '~/components/ui/Layout.vue'
|
||||
import Spacer from '~/components/ui/Spacer.vue'
|
||||
import Button from '~/components/ui/Button.vue'
|
||||
import Link from '~/components/ui/Link.vue'
|
||||
import Heading from '~/components/ui/Heading.vue'
|
||||
|
||||
const actionComponents =
|
||||
{ Button, Link }
|
||||
|
||||
const props = defineProps<{
|
||||
[M in 'no-items' | 'tiny-items' | 'small-items' | 'medium-items']?: true }
|
||||
& { [H in 'h1' | 'h2' | 'h3']?: string }
|
||||
& { action?: { text: string } & (RouterLinkProps | { onClick: (...args: any[]) => void | Promise<void> }) }>()
|
||||
|
||||
const heading =
|
||||
props.h1 ? ({ h1: props.h1, pageHeading: true }) as const
|
||||
: props.h2 ? ({ h2: props.h2 }) as const
|
||||
: ({ h3: props.h3 }) as const
|
||||
|
||||
console.log("HEADING", heading)
|
||||
|
||||
const numberOfColumnsPerItem =
|
||||
'noItems' in props && props.noItems ? 1 : 'tinyItems' in props && props.tinyItems ? 2 : 'smallItems' in props && props['smallItems'] ? 3 : 4
|
||||
|
||||
const { style, ...fallthroughProps } = useAttrs()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Layout header flex>
|
||||
<div v-if="$slots.image">
|
||||
<slot name="image" />
|
||||
</div>
|
||||
<Layout stack no-gap style="flex-grow: 1;">
|
||||
<Layout flex no-gap
|
||||
style="align-self: baseline;"
|
||||
>
|
||||
<!-- Set distance between baseline and previous row -->
|
||||
<Spacer v
|
||||
:size="64"
|
||||
style="align-self: baseline;"
|
||||
/>
|
||||
<Heading v-bind="heading" style="align-self: baseline; padding:0 0 24px 0; margin:0;"/>
|
||||
<Spacer grow />
|
||||
<!-- Action! You can either specify `to` or `onClick`. -->
|
||||
<component v-if="action" :is="'onClick' in action ? actionComponents.Button : actionComponents.Link"
|
||||
ghost force-underline thin-font min-content align-self="baseline"
|
||||
:style="`margin-right: ${('primary' in props || 'secondary' in props || 'destructive' in props) ? '0px' : '-16px'}`"
|
||||
v-bind="{...fallthroughProps, ...action}"
|
||||
>
|
||||
{{ action?.text }}
|
||||
</component>
|
||||
</Layout>
|
||||
<slot />
|
||||
</Layout>
|
||||
</Layout>
|
||||
</template>
|
|
@ -52,6 +52,7 @@ export default defineConfig({
|
|||
text: 'Layout', link: '/components/ui/layout/',
|
||||
items: [
|
||||
{ text: "Spacer", link: "/components/ui/layout/spacer" },
|
||||
{ text: "Header", link: "/components/ui/layout/header" },
|
||||
{ text: "Section", link: "/components/ui/layout/section" },
|
||||
{ text: "Using `flex`", link: "/components/ui/layout/flex" },
|
||||
{ text: "Using `stack`", link: "/components/ui/layout/stack" },
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<script setup lang="ts">
|
||||
import Header from '~/components/ui/Header.vue'
|
||||
import Layout from '~/components/ui/Layout.vue'
|
||||
import Spacer from '~/components/ui/Spacer.vue'
|
||||
import Button from '~/components/ui/Button.vue'
|
||||
</script>
|
||||
|
||||
```ts
|
||||
import Header from "~/components/ui/Header.vue";
|
||||
```
|
||||
|
||||
# Page header
|
||||
|
||||
Place the `Header` at the beginning of a page. Choose an appropriate heading level: `h1` or `h2` or `h3`. Choose `h1` unless the header is part of a page subsection or a modal.
|
||||
|
||||
```vue-html
|
||||
<Header h1="My title" />
|
||||
```
|
||||
|
||||
<Header h1="My title" />
|
||||
|
||||
## Add an image
|
||||
|
||||
Use the `<template #image>` slot to place a picture to the left of the header.
|
||||
|
||||
```vue-html
|
||||
<Header h1="My title">
|
||||
<template #image>
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb" />
|
||||
</template>
|
||||
</Header>
|
||||
```
|
||||
|
||||
<Header h1="My title">
|
||||
<template #image>
|
||||
<img
|
||||
style="width: 196px;"
|
||||
src="https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb" />
|
||||
</template>
|
||||
<div style="height: 48px;">
|
||||
My subtitle
|
||||
</div>
|
||||
<Layout flex gap-8>
|
||||
<Button outline square>A</Button>
|
||||
<Button outline square>B</Button>
|
||||
<Spacer h grow />
|
||||
<Button outline square>C</Button>
|
||||
</Layout>
|
||||
</Header>
|
||||
|
||||
## Add an action to the right of the heading
|
||||
|
||||
-> Use the `action` prop [which is the same as in the `Section` component](/components/ui/layout/section).
|
Loading…
Reference in New Issue