feat(ui-docs): custom grid layout; add examples

This commit is contained in:
upsiflu 2024-12-20 10:37:56 +01:00
parent 0cbed99311
commit 146d624d38
4 changed files with 132 additions and 47 deletions

View File

@ -12,11 +12,12 @@ import Spacer from './layout/Spacer.vue';
const props = defineProps<{
title: string
category?: true | "h1" | "h2" | "h3" | "h4" | "h5"
small?: true
tags?: string[]
image?: string | { src: string, style?: "withPadding" }
icon?: string
} & {
[Size in 'small' | 'auto']?: true
} & Partial<RouterLinkProps> & (PastelProps | ColorProps | DefaultProps) & RaisedProps & VariantProps>()
const image = typeof props.image === 'string' ? { src: props.image } : props.image
@ -90,7 +91,7 @@ const isExternalLink = computed(() => {
<style module>
.card {
/* 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'");
position: relative;

View File

@ -4,7 +4,7 @@ const props = defineProps<{
noGap?: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 }>()
const columnWidth = props.columnWidth ?? 320
</script>
@ -15,7 +15,7 @@ const columnWidth = props.columnWidth ?? 320
:class="[
$style.layout,
noGap || $style.gap,
props.grid ? $style.grid
props.grid ? $style[props.grid===true ? 'grid' : 'grid-custom']
: props.flex ? $style.flex
: props.columns? $style.columns
: $style.stack
@ -26,68 +26,47 @@ const columnWidth = props.columnWidth ?? 320
<style module>
.layout{
transition:gap .15s;
transition:all .15s;
/* Override --gap with your preferred value */
&.gap {
gap: var(--gap, 32px);
}
&:not(.gap) {
gap: 0;
}
/* Growth */
&:has(:global(>.grow)){
>:not(:global(.grow)){
flex-grow:0;
}
}
/* Layout strategy */
&.columns{
column-count: auto;
column-width: calc(v-bind(columnWidth) * 1px);
display: block;
column-rule: 1px solid v-bind("noRule ? 'transparent' : 'var(--border-color)'");
}
&.grid {
display: grid;
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;
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-row: span 3;
height: auto;
--height: auto;
}
: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;
}
&.grid-custom {
display: grid;
grid: v-bind("props.grid");
grid-auto-flow: row dense;
place-content: center; /* If the grid has a fixed size smaller than its container, center it */
}
&.stack {

View File

@ -43,7 +43,7 @@ You can either specify the column width (default: 320px) or set the desired num
</Layout>
### Let elements span multiple rows or columns:
### Let elements span multiple rows, columns, or areas:
```vue-html{1,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" />
</Layout>
### Custom grid configuration
You can pass any valid CSS `grid` value to the `grid` prop:
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>`:
```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 green />
<Alert blue />
@ -76,3 +108,76 @@ You can pass any valid CSS `grid` value to the `grid` prop:
<Alert green />
<Alert blue />
</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.
![alt text](image.png)
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