refactor(ui): layout section header without subdivision ('no-items') for use case with only full-width items
This commit is contained in:
parent
f39b3353a3
commit
adf3bffc9b
|
@ -7,7 +7,7 @@ import Button from '~/components/ui/Button.vue'
|
||||||
import Link from '~/components/ui/Link.vue'
|
import Link from '~/components/ui/Link.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
[M in 'tiny-items' | 'small-items' | 'medium-items']?: true }
|
[M in 'no-items' | 'tiny-items' | 'small-items' | 'medium-items']?: true }
|
||||||
& { alignLeft?: boolean;}
|
& { alignLeft?: boolean;}
|
||||||
& { [H in 'h1' | 'h2' | 'h3']?: string }
|
& { [H in 'h1' | 'h2' | 'h3']?: string }
|
||||||
& { action?: { text: string } & (RouterLinkProps | { onClick: (...args: any[]) => void | Promise<void> }) }>()
|
& { action?: { text: string } & (RouterLinkProps | { onClick: (...args: any[]) => void | Promise<void> }) }>()
|
||||||
|
@ -18,7 +18,8 @@ const [headingLevel, title] =
|
||||||
: ['h3', props.h3]
|
: ['h3', props.h3]
|
||||||
|
|
||||||
const numberOfColumnsPerItem =
|
const numberOfColumnsPerItem =
|
||||||
'tinyItems' in props && props.tinyItems ? 2 : 'smallItems' in props && props['smallItems'] ? 3 : 4
|
'noItems' in props && props.noItems ? 1 : 'tinyItems' in props && props.tinyItems ? 2 : 'smallItems' in props && props['smallItems'] ? 3 : 4
|
||||||
|
|
||||||
|
|
||||||
const headerGrid =
|
const headerGrid =
|
||||||
`auto / repeat(auto-fit, calc(46px * ${numberOfColumnsPerItem} + 32px * ${numberOfColumnsPerItem - 1}))`
|
`auto / repeat(auto-fit, calc(46px * ${numberOfColumnsPerItem} + 32px * ${numberOfColumnsPerItem - 1}))`
|
||||||
|
@ -27,7 +28,8 @@ const headerGrid =
|
||||||
<template>
|
<template>
|
||||||
<section>
|
<section>
|
||||||
<Layout header :grid="headerGrid"
|
<Layout header :grid="headerGrid"
|
||||||
:style="`${'alignLeft' in props && props.alignLeft ? 'justify-content: start' : ''}; margin-top: -64px;`"
|
:style="`${'alignLeft' in props && props.alignLeft ? 'justify-content: start' : ''};
|
||||||
|
margin-top: -64px;`"
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- The title row's width is a multiple of the expected items' column span -->
|
<!-- The title row's width is a multiple of the expected items' column span -->
|
||||||
|
@ -41,14 +43,14 @@ const headerGrid =
|
||||||
/>
|
/>
|
||||||
<!-- Flexible row content -->
|
<!-- Flexible row content -->
|
||||||
<!-- Note that the `h3` uses its padding to create the 24px bottom gap -->
|
<!-- Note that the `h3` uses its padding to create the 24px bottom gap -->
|
||||||
<component :is="headingLevel" style="align-self: baseline; padding:0 0 24px 10px; margin:0;">
|
<component :is="headingLevel" style="align-self: baseline; padding:0 0 24px 0; margin:0;">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</component>
|
</component>
|
||||||
<Spacer grow />
|
<Spacer grow />
|
||||||
<!-- Action! You can either specify `to` or `onClick`. -->
|
<!-- Action! You can either specify `to` or `onClick`. -->
|
||||||
<Button v-if="props.action && 'onClick' in props.action"
|
<Button v-if="props.action && 'onClick' in props.action"
|
||||||
ghost thinFont auto align-self="baseline"
|
ghost thin-font minWidth align-self="baseline"
|
||||||
style="grid-column:-1;"
|
:style="`margin-right: ${('primary' in props || 'secondary' in props || 'destructive' in props) ? '0px' : '-16px'}`"
|
||||||
:onClick="props.action.onClick"
|
:onClick="props.action.onClick"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
>
|
>
|
||||||
|
@ -56,6 +58,7 @@ const headerGrid =
|
||||||
</Button>
|
</Button>
|
||||||
<Link v-if="props.action && 'to' in props.action"
|
<Link v-if="props.action && 'to' in props.action"
|
||||||
ghost force-underline thinFont align-self="baseline"
|
ghost force-underline thinFont align-self="baseline"
|
||||||
|
:style="`margin-right: ${('primary' in props || 'secondary' in props || 'destructive' in props) ? '0px' : '-16px'}`"
|
||||||
:to="props.action.to"
|
:to="props.action.to"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
>
|
>
|
||||||
|
|
|
@ -122,7 +122,9 @@ Sections divide the page vertically. Choose an appropriate heading level for eac
|
||||||
|
|
||||||
### Make the section header align with the section contents
|
### Make the section header align with the section contents
|
||||||
|
|
||||||
Do you want to align the header to tiny, small or medium items?
|
Do you want to align the header to no, tiny, small or medium items?
|
||||||
|
|
||||||
|
If all items stretch all columns (`style=grid-column: 1 / -1`), use `no-items`.
|
||||||
|
|
||||||
```vue-html
|
```vue-html
|
||||||
<Section medium-items />
|
<Section medium-items />
|
||||||
|
@ -180,6 +182,12 @@ You can add spacers (negatice or positive) if you want to manually make one dist
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
::: tip Let items cover the whole grid width
|
||||||
|
|
||||||
|
To prevent items from being put on a grid, add `style="grid-column: 1 / -1"` which means that they span "all existing columns".
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
```vue-html
|
```vue-html
|
||||||
|
|
Loading…
Reference in New Issue