feat(ui-docs): minor improvements and corrections
This commit is contained in:
parent
008d8e2a8a
commit
e1bd30eb9d
|
@ -9,15 +9,15 @@ import Alert from './Alert.vue'
|
|||
import Layout from './Layout.vue';
|
||||
import Spacer from './layout/Spacer.vue';
|
||||
|
||||
interface Props extends Partial<RouterLinkProps> {
|
||||
const props = defineProps<{
|
||||
title: string
|
||||
category?: true | "h1" | "h2" | "h3" | "h4" | "h5"
|
||||
image?: string | { src: string, style?: "withPadding" }
|
||||
tags?: string[]
|
||||
small?: true
|
||||
}
|
||||
|
||||
const props = defineProps<Props & (PastelProps | ColorProps | DefaultProps) & RaisedProps & VariantProps>()
|
||||
tags?: string[]
|
||||
image?: string | { src: string, style?: "withPadding" }
|
||||
icon?: string
|
||||
} & Partial<RouterLinkProps> & (PastelProps | ColorProps | DefaultProps) & RaisedProps & VariantProps>()
|
||||
|
||||
const image = typeof props.image === 'string' ? { src: props.image } : props.image
|
||||
|
||||
|
@ -28,6 +28,65 @@ const isExternalLink = computed(() => {
|
|||
// const fallbackWidth =
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Layout stack
|
||||
:class="{ [$style.card]: true, [$style['is-category']]: category }"
|
||||
style="--gap:16px"
|
||||
v-bind="propsToColor({...(props.to? { interactive: true, solid: true, default: true } : {}), ...props})"
|
||||
>
|
||||
|
||||
<!-- Link -->
|
||||
|
||||
<a v-if="props.to && isExternalLink" :class="$style.covering" :href="to?.toString()" target="_blank" />
|
||||
<RouterLink v-if="props.to && !isExternalLink" :class="$style.covering" :to="props.to" />
|
||||
|
||||
<!-- Image -->
|
||||
|
||||
<div v-if="$slots.image" :class="$style.image">
|
||||
<slot name="image" :src="image" />
|
||||
</div>
|
||||
<img v-else-if="image" :src="image?.src"
|
||||
:class="{ [$style.image]: true, [$style['with-padding']]: image?.style === 'withPadding' }" />
|
||||
<Spacer v-else :size="props.small? 4 : 12" />
|
||||
|
||||
<!-- Icon -->
|
||||
|
||||
<i v-if="props.icon" :class="[$style.icon, 'bi', icon]" />
|
||||
|
||||
<!-- Title -->
|
||||
|
||||
<component :class="$style.title" :is="typeof category === 'string' ? category : 'h6'">{{ title }}</component>
|
||||
|
||||
<!-- Content -->
|
||||
|
||||
<Alert blue v-if="$slots.alert" :class="$style.alert">
|
||||
<slot name="alert" />
|
||||
</Alert>
|
||||
|
||||
<div v-if="tags" :class="$style.tags">
|
||||
<Pill v-for="tag in tags" :key="tag">
|
||||
#{{ tag }}
|
||||
</Pill>
|
||||
</div>
|
||||
|
||||
<Layout no-gap v-if="$slots.default" :class="$style.content">
|
||||
<slot />
|
||||
</Layout>
|
||||
|
||||
<!-- Footer and Action -->
|
||||
<div v-if="$slots.footer" :class="$style.footer">
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
|
||||
<div v-if="$slots.action" :class="$style.action">
|
||||
<slot name="action" />
|
||||
</div>
|
||||
|
||||
<Spacer v-if="!$slots.footer && !$slots.action" :size="props.small? 8 : 16" />
|
||||
|
||||
</Layout>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
.card {
|
||||
/* Override --width with your preferred value */
|
||||
|
@ -76,6 +135,14 @@ const isExternalLink = computed(() => {
|
|||
}
|
||||
}
|
||||
|
||||
>.icon {
|
||||
position: absolute;
|
||||
top: var(--fw-card-padding);
|
||||
right: var(--fw-card-padding);
|
||||
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
>.title {
|
||||
padding: 0 var(--fw-card-padding);
|
||||
line-height: 1.3em;
|
||||
|
@ -146,54 +213,3 @@ const isExternalLink = computed(() => {
|
|||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<Layout stack
|
||||
:class="{ [$style.card]: true, [$style['is-category']]: category }"
|
||||
style="--gap:16px"
|
||||
v-bind="propsToColor({...(props.to? { interactive: true, solid: true, default: true } : {}), ...props})"
|
||||
>
|
||||
|
||||
<!-- Link -->
|
||||
<a v-if="props.to && isExternalLink" :class="$style.covering" :href="to?.toString()" target="_blank" />
|
||||
<RouterLink v-if="props.to && !isExternalLink" :class="$style.covering" :to="props.to"
|
||||
/>
|
||||
|
||||
<!-- Image -->
|
||||
<div v-if="$slots.image" :class="$style.image">
|
||||
<slot name="image" :src="image" />
|
||||
</div>
|
||||
<img v-else-if="image" :src="image?.src"
|
||||
:class="{ [$style.image]: true, [$style['with-padding']]: image?.style === 'withPadding' }" />
|
||||
<Spacer v-else :size="props.small? 4 : 12" />
|
||||
|
||||
<!-- Content -->
|
||||
<component :class="$style.title" :is="typeof category === 'string' ? category : 'h6'">{{ title }}</component>
|
||||
|
||||
<Alert blue v-if="$slots.alert" :class="$style.alert">
|
||||
<slot name="alert" />
|
||||
</Alert>
|
||||
|
||||
<div v-if="tags" :class="$style.tags">
|
||||
<Pill v-for="tag in tags" :key="tag">
|
||||
#{{ tag }}
|
||||
</Pill>
|
||||
</div>
|
||||
|
||||
<Layout no-gap v-if="$slots.default" :class="$style.content">
|
||||
<slot />
|
||||
</Layout>
|
||||
|
||||
<!-- Footer and Action -->
|
||||
<div v-if="$slots.footer" :class="$style.footer">
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
|
||||
<div v-if="$slots.action" :class="$style.action">
|
||||
<slot name="action" />
|
||||
</div>
|
||||
|
||||
<Spacer v-if="!$slots.footer && !$slots.action" :size="props.small? 8 : 16" />
|
||||
|
||||
</Layout>
|
||||
</template>
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<script setup lang="ts">
|
||||
const props = defineProps<
|
||||
{ columnWidth?: number, noGap?:true }
|
||||
const props = defineProps<{
|
||||
columnWidth?: number,
|
||||
noGap?:true,
|
||||
noRule?:true
|
||||
}
|
||||
& { [P in "stack" | "grid" | "flex" | "columns"]?: true }
|
||||
& { [C in "nav" | "aside" | "header" | "footer" | "main"]?:true }>()
|
||||
const columnWidth = props.columnWidth ?? 320
|
||||
|
@ -41,7 +44,7 @@ const columnWidth = props.columnWidth ?? 320
|
|||
column-count: auto;
|
||||
column-width: calc(v-bind(columnWidth) * 1px);
|
||||
display: block;
|
||||
column-rule: 1px solid var(--border-color);
|
||||
column-rule: 1px solid v-bind("noRule ? 'transparent' : 'var(--border-color)'");
|
||||
}
|
||||
&.grid {
|
||||
display: grid;
|
||||
|
|
|
@ -7,11 +7,15 @@ const minSize = 32
|
|||
|
||||
const measure = ref()
|
||||
|
||||
console.log("SIZE", size)
|
||||
|
||||
watchEffect(() => { measure.value = {
|
||||
size: `${Math.max(size, minSize)}px`,
|
||||
margin: `${Math.min(size/2-minSize/2, 0)}px`
|
||||
margin: `${(size-Math.max(size, minSize))/2}px`
|
||||
}
|
||||
})
|
||||
|
||||
console.log("MEASURE", measure)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -24,7 +24,10 @@ const { Theme } = DefaultTheme
|
|||
}
|
||||
|
||||
.language-template:has(~.preview){
|
||||
flex-grow:1000;
|
||||
flex-grow:1;
|
||||
&~.preview{
|
||||
flex-grow:0;
|
||||
}
|
||||
}
|
||||
|
||||
.preview,
|
||||
|
@ -36,8 +39,8 @@ const { Theme } = DefaultTheme
|
|||
&:not(.transparent){
|
||||
background-color:var(--background-color);
|
||||
box-shadow: 0px 0px 16px 16px var(--background-color);
|
||||
margin-top:16px;
|
||||
padding-top:0;
|
||||
margin:16px 0;
|
||||
padding:0;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -301,17 +301,14 @@ You can override the promise state by passing a false `is-loading` prop.
|
|||
You can use [Bootstrap Icons](https://icons.getbootstrap.com/) in your button component
|
||||
|
||||
::: info
|
||||
Icon buttons shrink down to the icon size if you don't pass any content. If you want to keep the button at full width with just an icon, add ` ` into the slot.
|
||||
Icon buttons shrink down to the icon size if you don't pass any content. If you want to keep the button at full width with just an icon, add `width=standard`
|
||||
:::
|
||||
|
||||
```vue-html
|
||||
<Button color="secondary" icon="bi-three-dots-vertical" />
|
||||
|
||||
<Button color="secondary" is-round icon="bi-x" />
|
||||
|
||||
<Button icon="bi-save" />
|
||||
|
||||
<Button color="destructive" icon="bi-trash">
|
||||
<Button icon="bi-three-dots-vertical" />
|
||||
<Button round icon="bi-x" />
|
||||
<Button primary icon="bi-save" width="standard" />
|
||||
<Button destructive icon="bi-trash">
|
||||
Delete
|
||||
</Button>
|
||||
```
|
||||
|
|
|
@ -59,12 +59,6 @@ You have to set a title for the card by passing a `title` prop.
|
|||
|
||||
## Card as a Link
|
||||
|
||||
::: warning
|
||||
|
||||
TODO: Test if it works. Set up a mock router in vitest.
|
||||
|
||||
:::
|
||||
|
||||
Add a `:to` prop, either containing an external link (`"https://..."`) or a Vue Router destination:
|
||||
|
||||
<Layout flex>
|
||||
|
@ -103,7 +97,7 @@ Category cards are basic cards that contain only a title. To create a category c
|
|||
|
||||
## Add an Image
|
||||
|
||||
Pass an image source to the `image` prop or set `image.src` and `image.style`.
|
||||
Pass an image source to the `image` prop or set both `image.src` and `image.style` by passing an object.
|
||||
|
||||
<Layout :columnWidth="200" grid>
|
||||
|
||||
|
@ -112,31 +106,56 @@ Pass an image source to the `image` prop or set `image.src` and `image.style`.
|
|||
style="--width:208px"
|
||||
title="For music lovers"
|
||||
image="https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb">
|
||||
</Card>
|
||||
/>
|
||||
|
||||
|
||||
<Card
|
||||
style="--width:208px"
|
||||
title="For music lovers"
|
||||
:image="{ src:'https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb',
|
||||
style:'withPadding' }">
|
||||
</Card>
|
||||
style:'withPadding' }"
|
||||
/>
|
||||
```
|
||||
|
||||
<Layout stack class="preview">
|
||||
<Card
|
||||
title="For music lovers"
|
||||
style="--width:208px"
|
||||
title="For music lovers"
|
||||
image="https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb" />
|
||||
image="https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb"
|
||||
/>
|
||||
|
||||
<Card
|
||||
title="For music lovers"
|
||||
style="--width:208px"
|
||||
title="For music lovers"
|
||||
:image="{ src:'https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb',
|
||||
style:'withPadding' }" />
|
||||
:image="{ src:'https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb',
|
||||
style:'withPadding' }"
|
||||
/>
|
||||
</Layout>
|
||||
</Layout>
|
||||
|
||||
## Add an Icon
|
||||
|
||||
<Layout columns>
|
||||
|
||||
```vue-html{4}
|
||||
<Card
|
||||
title="Uploading..."
|
||||
image="https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb"
|
||||
icon="bi-cloud-arrow-up-fill"
|
||||
/>
|
||||
```
|
||||
|
||||
<Layout class="preview">
|
||||
<Card
|
||||
title="Uploading..."
|
||||
image="https://images.unsplash.com/photo-1524650359799-842906ca1c06?ixlib=rb-1.2.1&dl=te-nguyen-Wt7XT1R6sjU-unsplash.jpg&w=640&q=80&fm=jpg&crop=entropy&cs=tinysrgb"
|
||||
icon="bi-cloud-arrow-up-fill"
|
||||
/>
|
||||
</Layout>
|
||||
</Layout>
|
||||
|
||||
You can combine this prop with any other prop configuration. If you combine it with an image, keep an eye on the contrast ratio between the icon color and the image.
|
||||
|
||||
## Add an Alert
|
||||
|
||||
```vue-html{2-4}
|
||||
|
|
|
@ -18,7 +18,7 @@ const noGap = ref(true)
|
|||
|
||||
The following containers are responsive. Change your window's size or select a device preset from your browser's dev tools to see how layouts are affected by available space.
|
||||
|
||||
<Tabs>
|
||||
<Tabs class="solid" style="border: 32px solid var(--background-color);border-radius: 8px;outline: 1px solid var(--border-color);margin: 0 -32px;">
|
||||
<Tab title="Flex (default)" icon="⠖">
|
||||
|
||||
Items are laid out in a row and wrapped as they overflow the container.
|
||||
|
@ -49,10 +49,10 @@ Find a list of all styles here: [Flexbox guide on css-tricks.com](https://css-tr
|
|||
<Layout flex>
|
||||
<div class="preview" style="font-size:11px; font-weight:bold; mix-blend-mode:luminosity;">
|
||||
<Layout flex style="--gap: 4px;"> --gap: 4px
|
||||
<Alert style="align-self: flex-end">align-self: flex-end</Alert>
|
||||
<Alert style="flex-grow: 1">flex-grow: 1</Alert>
|
||||
<Alert style="height: 5rem;">height: 5rem</Alert>
|
||||
<Alert style="width: 100%">width: 100%</Alert>
|
||||
<Alert red style="align-self: flex-end">align-self: flex-end</Alert>
|
||||
<Alert red style="flex-grow: 1">flex-grow: 1</Alert>
|
||||
<Alert red style="height: 5rem;">height: 5rem</Alert>
|
||||
<Alert red style="width: 100%">width: 100%</Alert>
|
||||
</Layout>
|
||||
</div>
|
||||
</Layout>
|
||||
|
@ -76,8 +76,7 @@ Align items both vertically and horizontally
|
|||
</Layout>
|
||||
```
|
||||
|
||||
<div class="preview">
|
||||
<Layout grid :column-width=90>
|
||||
<Layout grid :column-width="90" class="preview" :style="`width:${2 * 90 + 32}px`">
|
||||
<Alert>A</Alert>
|
||||
<Alert>B</Alert>
|
||||
<Alert>C</Alert>
|
||||
|
@ -86,7 +85,6 @@ Align items both vertically and horizontally
|
|||
<Alert>F</Alert>
|
||||
<Alert>G</Alert>
|
||||
</Layout>
|
||||
</div>
|
||||
|
||||
</Layout>
|
||||
|
||||
|
@ -156,7 +154,7 @@ Add space between vertically stacked items
|
|||
|
||||
Let items flow like words on a printed newspaper, Great for very long lists of buttons or links.
|
||||
|
||||
<Layout stack>
|
||||
<Layout stack no-gap>
|
||||
|
||||
```vue-html
|
||||
<Layout columns :column-width="120">
|
||||
|
@ -198,6 +196,32 @@ Normal paragraph. Text flows like in a newspaper. Set the column width in px. Co
|
|||
|
||||
</Layout>
|
||||
|
||||
### `no-rule`: Remove the rule (thin line) between columns
|
||||
|
||||
<Layout grid>
|
||||
|
||||
```vue-html
|
||||
<Layout columns colummn-width>
|
||||
<div>Lorem ipsum dolor sit amet.</div>
|
||||
</Layout>
|
||||
|
||||
<Layout columns no-rule>
|
||||
<div>Lorem ipsum dolor sit amet.</div>
|
||||
</Layout>
|
||||
```
|
||||
|
||||
<Layout class="preview">
|
||||
<Layout columns :column-width="120">
|
||||
<div>Lorem ipsum dolor sit amet.</div>
|
||||
</Layout>
|
||||
|
||||
<Layout columns no-rule :column-width="120">
|
||||
<div>Lorem ipsum dolor sit amet.</div>
|
||||
</Layout>
|
||||
</Layout>
|
||||
|
||||
</Layout>
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
@ -217,24 +241,24 @@ const noGap = ref(true);
|
|||
<Toggle v-model="noGap" />
|
||||
|
||||
<Layout flex :no-gap="noGap || undefined">
|
||||
<Card title="A" style="width:100px; min-width:100px" />
|
||||
<Card title="B" />
|
||||
<Card title="C" style="width:100px; min-width:100px" />
|
||||
<Card title="D" />
|
||||
<Card title="A" small />
|
||||
<Card title="B" small />
|
||||
<Card title="C" small />
|
||||
<Card title="D" small />
|
||||
</Layout>
|
||||
</template>
|
||||
```
|
||||
|
||||
<div class="preview">
|
||||
<div class="preview" style="width:0">
|
||||
<Toggle v-model="noGap" /> {{ noGap ? 'no-gap' : '-' }}
|
||||
|
||||
---
|
||||
|
||||
<Layout flex :no-gap="noGap || undefined">
|
||||
<Card title="A" style="width:100px; min-width:100px" />
|
||||
<Card title="B" />
|
||||
<Card title="C" style="width:100px; min-width:100px" />
|
||||
<Card title="D" />
|
||||
<Card title="A" small />
|
||||
<Card title="B" small />
|
||||
<Card title="C" small />
|
||||
<Card title="D" small />
|
||||
</Layout>
|
||||
</div>
|
||||
|
||||
|
@ -242,6 +266,13 @@ const noGap = ref(true);
|
|||
|
||||
### Add fixed or flexible Spacers
|
||||
|
||||
::: info Only available on:
|
||||
|
||||
- **stack**
|
||||
- **flex**
|
||||
|
||||
:::
|
||||
|
||||
If you add a spacer with attribute `grow`, it will push the other item until the Layout fills the available space. This only works if the parent element itself grows beyond its minimal contents.
|
||||
|
||||
<Layout flex>
|
||||
|
@ -254,11 +285,11 @@ const isGrowing = ref(true);
|
|||
<template>
|
||||
<Toggle v-model="isGrowing" />
|
||||
|
||||
<Layout stack style="height:30em;">
|
||||
<Alert>A</Alert>
|
||||
<Alert>B</Alert>
|
||||
<Layout stack style="height:20em;">
|
||||
<Alert red />
|
||||
<Alert purple />
|
||||
<Spacer :grow="isGrowing || undefined" />
|
||||
<Alert>C (footer)</Alert>
|
||||
<Alert blue />
|
||||
</Layout>
|
||||
</template>
|
||||
```
|
||||
|
@ -268,11 +299,11 @@ const isGrowing = ref(true);
|
|||
|
||||
---
|
||||
|
||||
<Layout stack style="height:30em; background:rgba(155,200,20,.3)">
|
||||
<Alert>A</Alert>
|
||||
<Alert>B</Alert>
|
||||
<Spacer :grow="isGrowing || undefined" />
|
||||
<Alert>C (footer)</Alert>
|
||||
<Layout stack style="height:20em">
|
||||
<Alert red />
|
||||
<Alert purple />
|
||||
<Spacer :grow="isGrowing || undefined" />
|
||||
<Alert blue />
|
||||
</Layout>
|
||||
</div>
|
||||
|
||||
|
@ -280,7 +311,7 @@ const isGrowing = ref(true);
|
|||
|
||||
Multiple spacers will distribute their growth evenly.
|
||||
|
||||
Note that you can set the minimum space occupied by the `Spacer` with its `size` prop [(docs)](layout/spacer). Negative values can offset the gap of the `Layout`:
|
||||
Note that you can set the minimum space occupied by the `Spacer` with its `size` prop [(docs)](layout/spacer). Negative values can offset the gap of the `Layout` (but, due to a limitation of flexbox, not eat into the space occupied by adjacent items):
|
||||
|
||||
<Layout flex>
|
||||
|
||||
|
@ -289,12 +320,12 @@ Note that you can set the minimum space occupied by the `Spacer` with its `size`
|
|||
<Toggle v-model="isGrowing" />
|
||||
|
||||
<Layout stack style="height:25em;">
|
||||
<Alert>A</Alert>
|
||||
<Alert blue />
|
||||
<Spacer :size="-32" :grow="isGrowing || undefined" />
|
||||
<Alert>B1</Alert>
|
||||
<Alert>B2</Alert>
|
||||
<Alert green />
|
||||
<Alert yellow />
|
||||
<Spacer :size="-32" :grow="isGrowing || undefined" />
|
||||
<Alert>C (footer)</Alert>
|
||||
<Alert red />
|
||||
</Layout>
|
||||
</template>
|
||||
```
|
||||
|
@ -304,13 +335,13 @@ Note that you can set the minimum space occupied by the `Spacer` with its `size`
|
|||
|
||||
---
|
||||
|
||||
<Layout stack style="height:25em; background:rgba(155,200,20,.3)">
|
||||
<Alert>A</Alert>
|
||||
<Layout stack style="height:25em;">
|
||||
<Alert blue />
|
||||
<Spacer :size="-32" :grow="isGrowing || undefined" />
|
||||
<Alert>B1</Alert>
|
||||
<Alert>B2</Alert>
|
||||
<Alert green />
|
||||
<Alert yellow />
|
||||
<Spacer :size="-32" :grow="isGrowing || undefined" />
|
||||
<Alert>C (footer)</Alert>
|
||||
<Alert red />
|
||||
</Layout>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in New Issue