feat(ui): Layout section component
This commit is contained in:
parent
860f12512c
commit
3f2dfc95b3
|
@ -31,8 +31,6 @@ const attributes = computed(() => ({
|
|||
props.columns ? 'columns' :
|
||||
'stack'
|
||||
}))
|
||||
|
||||
console.log("GRID", props.grid, props.grid ? 'grid-custom' : 'none')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -12,6 +12,7 @@ import Activity from '~/components/ui/Activity.vue'
|
|||
|
||||
const props = defineProps<{
|
||||
[M in 'tiny-items' | 'small-items' | 'medium-items']?: true }
|
||||
& { alignLeft?: boolean;}
|
||||
& { [H in 'h1' | 'h2' | 'h3']?: string }
|
||||
& { action?: { text: string } & (RouterLinkProps | { onClick: (...args: any[]) => void | Promise<void> }) }>()
|
||||
|
||||
|
@ -20,15 +21,18 @@ const [headingLevel, title] =
|
|||
: props.h2 ? ['h2', props.h2]
|
||||
: ['h3', props.h3]
|
||||
|
||||
const headerGrid =
|
||||
`auto / repeat(auto-fit, calc(46px * ${props['tiny-items'] ? 2 : props['small-items'] ? 3 : 4} + 32px * 2))`
|
||||
const numberOfColumnsPerItem =
|
||||
'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>
|
||||
|
||||
<template>
|
||||
<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 -->
|
||||
<Layout flex no-gap
|
||||
|
@ -37,7 +41,7 @@ console.log(headerGrid);
|
|||
<!-- Set distance between baseline and previous row -->
|
||||
<Spacer v
|
||||
:size="64"
|
||||
style="outline:1px solid red; align-self: baseline;"
|
||||
style="align-self: baseline;"
|
||||
/>
|
||||
<!-- Flexible row content -->
|
||||
<!-- Note that the `h3` uses its padding to create the 24px bottom gap -->
|
||||
|
@ -62,69 +66,11 @@ console.log(headerGrid);
|
|||
</Layout>
|
||||
</Layout>
|
||||
<Layout main
|
||||
style="position:relative;"
|
||||
:style="'alignLeft' in props && props.alignLeft ? 'justify-content: start' : ''"
|
||||
grid="auto / repeat(auto-fit, 46px)"
|
||||
>
|
||||
<slot />
|
||||
</Layout>
|
||||
</section>
|
||||
</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 Button from '~/components/ui/Button.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)
|
||||
|
||||
|
@ -116,7 +116,7 @@ const user: User = {
|
|||
|
||||
<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">
|
||||
Artist Name
|
||||
13 tracks
|
||||
|
@ -129,99 +129,12 @@ const user: User = {
|
|||
Artist Name
|
||||
13 tracks
|
||||
</Card>
|
||||
</Section>
|
||||
</LayoutSection>
|
||||
|
||||
<Layout
|
||||
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"
|
||||
>
|
||||
<LayoutSection :alignLeft="alignLeft" medium-items h3="Activities (medium items)" :action="{ text:'more...', to:'/' }">
|
||||
<Activity :track="track" :user="user" />
|
||||
<Activity :track="track" :user="user" />
|
||||
<Activity :track="track" :user="user" />
|
||||
</Layout>
|
||||
</LayoutSection>
|
||||
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue