feat(ui): Layout section component
This commit is contained in:
parent
860f12512c
commit
3f2dfc95b3
|
@ -31,8 +31,6 @@ const attributes = computed(() => ({
|
||||||
props.columns ? 'columns' :
|
props.columns ? 'columns' :
|
||||||
'stack'
|
'stack'
|
||||||
}))
|
}))
|
||||||
|
|
||||||
console.log("GRID", props.grid, props.grid ? 'grid-custom' : 'none')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -12,6 +12,7 @@ import Activity from '~/components/ui/Activity.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
[M in 'tiny-items' | 'small-items' | 'medium-items']?: true }
|
[M in 'tiny-items' | 'small-items' | 'medium-items']?: true }
|
||||||
|
& { 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> }) }>()
|
||||||
|
|
||||||
|
@ -20,15 +21,18 @@ const [headingLevel, title] =
|
||||||
: props.h2 ? ['h2', props.h2]
|
: props.h2 ? ['h2', props.h2]
|
||||||
: ['h3', props.h3]
|
: ['h3', props.h3]
|
||||||
|
|
||||||
const headerGrid =
|
const numberOfColumnsPerItem =
|
||||||
`auto / repeat(auto-fit, calc(46px * ${props['tiny-items'] ? 2 : props['small-items'] ? 3 : 4} + 32px * 2))`
|
'tinyItems' in props && props.tinyItems ? 2 : 'smallItems' in props && props['smallItems'] ? 3 : 4
|
||||||
|
|
||||||
console.log(headerGrid);
|
const headerGrid =
|
||||||
|
`auto / repeat(auto-fit, calc(46px * ${numberOfColumnsPerItem} + 32px * ${numberOfColumnsPerItem - 1}))`
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section>
|
<section>
|
||||||
<Layout header :grid="headerGrid">
|
<Layout header :grid="headerGrid"
|
||||||
|
:style="'alignLeft' in props && props.alignLeft ? 'justify-content: start' : ''"
|
||||||
|
>
|
||||||
|
|
||||||
<!-- 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 -->
|
||||||
<Layout flex no-gap
|
<Layout flex no-gap
|
||||||
|
@ -37,7 +41,7 @@ console.log(headerGrid);
|
||||||
<!-- Set distance between baseline and previous row -->
|
<!-- Set distance between baseline and previous row -->
|
||||||
<Spacer v
|
<Spacer v
|
||||||
:size="64"
|
:size="64"
|
||||||
style="outline:1px solid red; align-self: baseline;"
|
style="align-self: baseline;"
|
||||||
/>
|
/>
|
||||||
<!-- 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 -->
|
||||||
|
@ -62,69 +66,11 @@ console.log(headerGrid);
|
||||||
</Layout>
|
</Layout>
|
||||||
</Layout>
|
</Layout>
|
||||||
<Layout main
|
<Layout main
|
||||||
|
style="position:relative;"
|
||||||
|
:style="'alignLeft' in props && props.alignLeft ? 'justify-content: start' : ''"
|
||||||
grid="auto / repeat(auto-fit, 46px)"
|
grid="auto / repeat(auto-fit, 46px)"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</Layout>
|
</Layout>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style module>
|
|
||||||
.layout {
|
|
||||||
transition: all .15s;
|
|
||||||
|
|
||||||
/* Override --gap with your preferred value */
|
|
||||||
|
|
||||||
gap: var(--gap, v-bind(gapWidth));
|
|
||||||
|
|
||||||
&:not(.gap) {
|
|
||||||
gap: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Growth */
|
|
||||||
|
|
||||||
&:has(:global(>.grow)) {
|
|
||||||
>:not(:global(.grow)) {
|
|
||||||
flex-grow: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Layout strategy */
|
|
||||||
|
|
||||||
&[layout=columns] {
|
|
||||||
column-count: auto;
|
|
||||||
column-width: v-bind(columnWidth);
|
|
||||||
display: block;
|
|
||||||
column-rule: 1px solid v-bind("noRule ? 'transparent' : 'var(--border-color)'");
|
|
||||||
}
|
|
||||||
|
|
||||||
&[layout=grid] {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns:
|
|
||||||
repeat(auto-fit, v-bind(columnWidth));
|
|
||||||
grid-auto-flow: row dense;
|
|
||||||
place-content: center;
|
|
||||||
/* If the grid has a fixed size smaller than its container, center it */
|
|
||||||
}
|
|
||||||
|
|
||||||
&[layout=grid-custom] {
|
|
||||||
display: grid;
|
|
||||||
grid: v-bind(grid);
|
|
||||||
grid-auto-flow: row dense;
|
|
||||||
place-content: center;
|
|
||||||
/* If the grid has a fixed size smaller than its container, center it */
|
|
||||||
}
|
|
||||||
|
|
||||||
&[layout=stack] {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[layout=flex] {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: v-bind('props.noWrap ? "nowrap" : "wrap"');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import Toggle from '~/components/ui/Toggle.vue'
|
||||||
import Spacer from '~/components/ui/layout/Spacer.vue'
|
import Spacer from '~/components/ui/layout/Spacer.vue'
|
||||||
import Button from '~/components/ui/Button.vue'
|
import Button from '~/components/ui/Button.vue'
|
||||||
import Activity from '~/components/ui/Activity.vue'
|
import Activity from '~/components/ui/Activity.vue'
|
||||||
import Section from '~/components/ui/layout/Section.vue'
|
import LayoutSection from '~/components/ui/layout/Section.vue'
|
||||||
|
|
||||||
const alignLeft = ref(false)
|
const alignLeft = ref(false)
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ const user: User = {
|
||||||
|
|
||||||
<div class="preview" style="margin: 0 -40px; padding: 0 25px;">
|
<div class="preview" style="margin: 0 -40px; padding: 0 25px;">
|
||||||
|
|
||||||
<Section small-items h1="Hello" :action="{ text:'more...', to:'/' }">
|
<LayoutSection :alignLeft="alignLeft" small-items h3="Cards (small items)" :action="{ text:'more...', to:'/' }">
|
||||||
<Card small title="Relatively Long Album Name">
|
<Card small title="Relatively Long Album Name">
|
||||||
Artist Name
|
Artist Name
|
||||||
13 tracks
|
13 tracks
|
||||||
|
@ -129,99 +129,12 @@ const user: User = {
|
||||||
Artist Name
|
Artist Name
|
||||||
13 tracks
|
13 tracks
|
||||||
</Card>
|
</Card>
|
||||||
</Section>
|
</LayoutSection>
|
||||||
|
|
||||||
<Layout
|
<LayoutSection :alignLeft="alignLeft" medium-items h3="Activities (medium items)" :action="{ text:'more...', to:'/' }">
|
||||||
grid="auto / repeat(auto-fit, calc(46px _ 3 + 32px _ 2))"
|
|
||||||
v-bind="attributes"
|
|
||||||
|
|
||||||
>
|
|
||||||
|
|
||||||
<!-- The title row's width is a multiple of 3 rows -->
|
|
||||||
<Layout flex no-gap
|
|
||||||
style="grid-column: 1 / -1; align-self: baseline;"
|
|
||||||
>
|
|
||||||
<!-- Set distance between baseline and previous row -->
|
|
||||||
<Spacer v
|
|
||||||
:size="64"
|
|
||||||
style="outline:1px solid red; align-self: baseline;"
|
|
||||||
/>
|
|
||||||
<!-- Flexible row content -->
|
|
||||||
<!-- Note that the `h3` uses its padding to create the 24px bottom gap -->
|
|
||||||
<h3 style="align-self: baseline; padding:0 0 24px 10px; margin:0;">
|
|
||||||
Albums
|
|
||||||
</h3>
|
|
||||||
<Spacer grow />
|
|
||||||
<Button ghost thin auto align-self="baseline"
|
|
||||||
style="grid-column:-1;"
|
|
||||||
>
|
|
||||||
Show all
|
|
||||||
</Button>
|
|
||||||
</Layout>
|
|
||||||
|
|
||||||
</Layout>
|
|
||||||
<Layout solid default
|
|
||||||
style="position:relative;"
|
|
||||||
grid="auto / repeat(auto-fit, 46px)"
|
|
||||||
v-bind="attributes"
|
|
||||||
>
|
|
||||||
<Card small title="Relatively Long Album Name">
|
|
||||||
Artist Name
|
|
||||||
13 tracks
|
|
||||||
</Card>
|
|
||||||
<Card small title="Relatively Long Album Name">
|
|
||||||
Artist Name
|
|
||||||
13 tracks
|
|
||||||
</Card>
|
|
||||||
<Card small title="Relatively Long Album Name">
|
|
||||||
Artist Name
|
|
||||||
13 tracks
|
|
||||||
</Card>
|
|
||||||
<Card small title="Relatively Long Album Name">
|
|
||||||
Artist Name
|
|
||||||
13 tracks
|
|
||||||
</Card>
|
|
||||||
<Card small title="Relatively Long Album Name">
|
|
||||||
Artist Name
|
|
||||||
13 tracks
|
|
||||||
</Card>
|
|
||||||
</Layout>
|
|
||||||
|
|
||||||
<Layout
|
|
||||||
grid="auto / repeat(auto-fit, calc(46px _ 4 + 32px _ 3))"
|
|
||||||
v-bind="attributes"
|
|
||||||
|
|
||||||
>
|
|
||||||
|
|
||||||
<Layout flex no-gap
|
|
||||||
style="grid-column: 1 / -1; align-self: baseline;"
|
|
||||||
>
|
|
||||||
<!-- Set distance between baseline and previous row -->
|
|
||||||
<Spacer v
|
|
||||||
:size="64"
|
|
||||||
style="outline:1px solid red; align-self: baseline;"
|
|
||||||
/>
|
|
||||||
<!-- Flexible row content -->
|
|
||||||
<!-- Note that the `h3` uses its padding to create the 24px bottom gap -->
|
|
||||||
<h3 style="align-self: baseline; padding:0 0 24px 10px; margin:0;">
|
|
||||||
Tracks
|
|
||||||
</h3>
|
|
||||||
<Spacer grow />
|
|
||||||
<Button ghost thin auto align-self="baseline"
|
|
||||||
style="grid-column:-1;"
|
|
||||||
>
|
|
||||||
Show all
|
|
||||||
</Button>
|
|
||||||
</Layout>
|
|
||||||
|
|
||||||
</Layout>
|
|
||||||
<Layout solid default
|
|
||||||
style="position:relative;"
|
|
||||||
grid="auto / repeat(auto-fit, 46px)"
|
|
||||||
v-bind="attributes"
|
|
||||||
>
|
|
||||||
<Activity :track="track" :user="user" />
|
<Activity :track="track" :user="user" />
|
||||||
<Activity :track="track" :user="user" />
|
<Activity :track="track" :user="user" />
|
||||||
<Activity :track="track" :user="user" />
|
<Activity :track="track" :user="user" />
|
||||||
</Layout>
|
</LayoutSection>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue