feat(ui-docs): custom grid layout; add examples
This commit is contained in:
parent
0cbed99311
commit
146d624d38
|
@ -12,11 +12,12 @@ import Spacer from './layout/Spacer.vue';
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
title: string
|
title: string
|
||||||
category?: true | "h1" | "h2" | "h3" | "h4" | "h5"
|
category?: true | "h1" | "h2" | "h3" | "h4" | "h5"
|
||||||
small?: true
|
|
||||||
|
|
||||||
tags?: string[]
|
tags?: string[]
|
||||||
image?: string | { src: string, style?: "withPadding" }
|
image?: string | { src: string, style?: "withPadding" }
|
||||||
icon?: string
|
icon?: string
|
||||||
|
} & {
|
||||||
|
[Size in 'small' | 'auto']?: true
|
||||||
} & Partial<RouterLinkProps> & (PastelProps | ColorProps | DefaultProps) & RaisedProps & VariantProps>()
|
} & Partial<RouterLinkProps> & (PastelProps | ColorProps | DefaultProps) & RaisedProps & VariantProps>()
|
||||||
|
|
||||||
const image = typeof props.image === 'string' ? { src: props.image } : props.image
|
const image = typeof props.image === 'string' ? { src: props.image } : props.image
|
||||||
|
@ -90,7 +91,7 @@ const isExternalLink = computed(() => {
|
||||||
<style module>
|
<style module>
|
||||||
.card {
|
.card {
|
||||||
/* Override --width with your preferred value */
|
/* Override --width with your preferred value */
|
||||||
--fw-card-width: var(--width, v-bind("props.small ? 'min-content' : '320px'"));
|
--fw-card-width: var(--width, v-bind("props.small ? 'min-content' : props.auto ? 'auto' : '320px'"));
|
||||||
--fw-card-padding: v-bind("props.small ? '16px' : '24px'");
|
--fw-card-padding: v-bind("props.small ? '16px' : '24px'");
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -4,7 +4,7 @@ const props = defineProps<{
|
||||||
noGap?:true,
|
noGap?:true,
|
||||||
noRule?:true
|
noRule?:true
|
||||||
}
|
}
|
||||||
& { [P in "stack" | "grid" | "flex" | "columns"]?: true }
|
& { [P in "stack" | "grid" | "flex" | "columns"]?: true | string }
|
||||||
& { [C in "nav" | "aside" | "header" | "footer" | "main"]?:true }>()
|
& { [C in "nav" | "aside" | "header" | "footer" | "main"]?:true }>()
|
||||||
const columnWidth = props.columnWidth ?? 320
|
const columnWidth = props.columnWidth ?? 320
|
||||||
</script>
|
</script>
|
||||||
|
@ -15,7 +15,7 @@ const columnWidth = props.columnWidth ?? 320
|
||||||
:class="[
|
:class="[
|
||||||
$style.layout,
|
$style.layout,
|
||||||
noGap || $style.gap,
|
noGap || $style.gap,
|
||||||
props.grid ? $style.grid
|
props.grid ? $style[props.grid===true ? 'grid' : 'grid-custom']
|
||||||
: props.flex ? $style.flex
|
: props.flex ? $style.flex
|
||||||
: props.columns? $style.columns
|
: props.columns? $style.columns
|
||||||
: $style.stack
|
: $style.stack
|
||||||
|
@ -26,68 +26,47 @@ const columnWidth = props.columnWidth ?? 320
|
||||||
|
|
||||||
<style module>
|
<style module>
|
||||||
.layout{
|
.layout{
|
||||||
transition:gap .15s;
|
transition:all .15s;
|
||||||
|
|
||||||
/* Override --gap with your preferred value */
|
/* Override --gap with your preferred value */
|
||||||
|
|
||||||
&.gap {
|
&.gap {
|
||||||
gap: var(--gap, 32px);
|
gap: var(--gap, 32px);
|
||||||
}
|
}
|
||||||
&:not(.gap) {
|
&:not(.gap) {
|
||||||
gap: 0;
|
gap: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Growth */
|
/* Growth */
|
||||||
|
|
||||||
&:has(:global(>.grow)){
|
&:has(:global(>.grow)){
|
||||||
>:not(:global(.grow)){
|
>:not(:global(.grow)){
|
||||||
flex-grow:0;
|
flex-grow:0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Layout strategy */
|
||||||
|
|
||||||
&.columns{
|
&.columns{
|
||||||
column-count: auto;
|
column-count: auto;
|
||||||
column-width: calc(v-bind(columnWidth) * 1px);
|
column-width: calc(v-bind(columnWidth) * 1px);
|
||||||
display: block;
|
display: block;
|
||||||
column-rule: 1px solid v-bind("noRule ? 'transparent' : 'var(--border-color)'");
|
column-rule: 1px solid v-bind("noRule ? 'transparent' : 'var(--border-color)'");
|
||||||
}
|
}
|
||||||
|
|
||||||
&.grid {
|
&.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns:
|
grid-template-columns:
|
||||||
repeat(auto-fit, minmax(calc(v-bind(columnWidth) * 1px), min-content));
|
repeat(auto-fit, minmax(min-content, calc(v-bind(columnWidth) * 1px)));
|
||||||
grid-auto-flow: row dense;
|
grid-auto-flow: row dense;
|
||||||
|
place-content: center; /* If the grid has a fixed size smaller than its container, center it */
|
||||||
:global(>.span-2-rows) {
|
|
||||||
grid-row: span 2;
|
|
||||||
height: auto;
|
|
||||||
--height: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(>.span-3-rows) {
|
&.grid-custom {
|
||||||
grid-row: span 3;
|
display: grid;
|
||||||
height: auto;
|
grid: v-bind("props.grid");
|
||||||
--height: auto;
|
grid-auto-flow: row dense;
|
||||||
}
|
place-content: center; /* If the grid has a fixed size smaller than its container, center it */
|
||||||
|
|
||||||
:global(>.span-4-rows) {
|
|
||||||
grid-row: span 4;
|
|
||||||
height: auto;
|
|
||||||
--height: auto;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(>.span-2-columns) {
|
|
||||||
grid-column: span 2;
|
|
||||||
width: auto;
|
|
||||||
--width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(>.span-3-columns) {
|
|
||||||
grid-column: span 3;
|
|
||||||
width: auto;
|
|
||||||
--width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(>.span-4-columns) {
|
|
||||||
grid-column: span 4;
|
|
||||||
width: auto;
|
|
||||||
--width: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.stack {
|
&.stack {
|
||||||
|
|
|
@ -43,7 +43,7 @@ You can either specify the column width (default: 320px) or set the desired num
|
||||||
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
### Let elements span multiple rows or columns:
|
### Let elements span multiple rows, columns, or areas:
|
||||||
|
|
||||||
```vue-html{1,2}
|
```vue-html{1,2}
|
||||||
<Alert purple style="grid-column: span 2;" />
|
<Alert purple style="grid-column: span 2;" />
|
||||||
|
@ -59,12 +59,44 @@ You can either specify the column width (default: 320px) or set the desired num
|
||||||
<Card title="1" />
|
<Card title="1" />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
### Custom grid configuration
|
You can also span an element to a rectangle of multiple columns and rows, in the format `<row-start> / <column-start> / <row-end> / <column-end>`:
|
||||||
|
|
||||||
You can pass any valid CSS `grid` value to the `grid` prop:
|
|
||||||
|
|
||||||
```vue-html
|
```vue-html
|
||||||
<Layout grid="auto / repeat(auto-fit, minmax(min-content, 100px))">
|
<Layout grid="auto / repeat(3, min-content)">
|
||||||
|
<Card auto title="A" />
|
||||||
|
<Card auto title="B" />
|
||||||
|
<Card auto title="C" />
|
||||||
|
<Card auto title="D" style="grid-area: 2 / 1 / 4 / 5;" />
|
||||||
|
<Card auto title="E" />
|
||||||
|
<Card auto title="F" />
|
||||||
|
<Card auto title="G" />
|
||||||
|
<Card auto title="H" />
|
||||||
|
<Card auto title="I" />
|
||||||
|
</Layout>
|
||||||
|
```
|
||||||
|
|
||||||
|
<Layout grid="auto / repeat(5, min-content)">
|
||||||
|
<Card auto title="A" />
|
||||||
|
<Card auto title="B" />
|
||||||
|
<Card auto title="C" />
|
||||||
|
<Card auto title="D" style="grid-area: 2 / 1 / 4 / 5;" />
|
||||||
|
<Card auto title="E" />
|
||||||
|
<Card auto title="F" />
|
||||||
|
<Card auto title="G" />
|
||||||
|
<Card auto title="H" />
|
||||||
|
<Card auto title="I" />
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
### Custom grid configuration
|
||||||
|
|
||||||
|
You can pass any valid CSS `grid` value to the `grid` prop.
|
||||||
|
|
||||||
|
#### Minimal width, fit as many as possible on one row:
|
||||||
|
|
||||||
|
```vue-html
|
||||||
|
<Layout
|
||||||
|
grid="auto / repeat(auto-fit, minmax(min-content, 100px))"
|
||||||
|
>
|
||||||
<Alert red />
|
<Alert red />
|
||||||
<Alert green />
|
<Alert green />
|
||||||
<Alert blue />
|
<Alert blue />
|
||||||
|
@ -76,3 +108,76 @@ You can pass any valid CSS `grid` value to the `grid` prop:
|
||||||
<Alert green />
|
<Alert green />
|
||||||
<Alert blue />
|
<Alert blue />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
#### Up to 2 in a row, between 230-x and 300px:
|
||||||
|
|
||||||
|
```vue-html
|
||||||
|
<Layout no-gap
|
||||||
|
grid="auto / repeat(auto-fit, minmax(230px, min(50%, 300px)))"
|
||||||
|
```
|
||||||
|
|
||||||
|
<Layout class="preview" no-gap grid="auto / repeat(auto-fit, minmax(230px, min(50%, 300px)))">
|
||||||
|
<Alert red />
|
||||||
|
<Alert yellow />
|
||||||
|
<Alert blue />
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
#### Up to 5 in a row, between 230-x and 300px:
|
||||||
|
|
||||||
|
```vue-html
|
||||||
|
<Layout no-gap
|
||||||
|
grid="auto / repeat(auto-fit, minmax(120px, min(20%, 130px)))"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
<Layout class="preview" no-gap grid="auto / repeat(auto-fit, minmax(120px, min(20%, 130px)))">
|
||||||
|
<Alert red />
|
||||||
|
<Alert yellow />
|
||||||
|
<Alert blue />
|
||||||
|
<Alert red />
|
||||||
|
<Alert yellow />
|
||||||
|
<Alert blue />
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
#### As many as fit, at least 100px, stretch them if necessary:
|
||||||
|
|
||||||
|
```vue-html
|
||||||
|
<Layout
|
||||||
|
grid="auto / repeat(auto-fit, minmax(100px, 2fr))"
|
||||||
|
```
|
||||||
|
|
||||||
|
<Layout class="preview" grid="auto / repeat(auto-fit, minmax(100px, 2fr))">
|
||||||
|
<Alert red />
|
||||||
|
<Alert yellow />
|
||||||
|
<Alert blue />
|
||||||
|
<Alert red />
|
||||||
|
<Alert yellow />
|
||||||
|
<Alert blue />
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
#### Three columns of different widths, stretch gaps if necessary:
|
||||||
|
|
||||||
|
```vue-html
|
||||||
|
<Layout
|
||||||
|
grid="auto / 100px 200px 100px"
|
||||||
|
style="justify-content: space-between"
|
||||||
|
```
|
||||||
|
|
||||||
|
<Layout class="preview" grid="auto / 100px 200px 100px" style="justify-content:space-between">
|
||||||
|
<Alert red />
|
||||||
|
<Alert yellow />
|
||||||
|
<Alert blue />
|
||||||
|
<Alert red />
|
||||||
|
<Alert yellow />
|
||||||
|
<Alert blue />
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
Note that on slim screens, the content will overflow here because the grid has no way to shrink under 464px.
|
||||||
|
|
||||||
|
### Debugging Layouts
|
||||||
|
|
||||||
|
The browser's devtools can visualize the components of a grid.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
And read [the illustrated overview of all grid properties on css-tricks.com](https://css-tricks.com/snippets/css/complete-guide-grid/).
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
Loading…
Reference in New Issue