feat(ui): allow custom width (via composable props)
This commit is contained in:
parent
a588726a54
commit
2ebda850c7
|
@ -105,7 +105,7 @@ const federationEnabled = computed(() => {
|
||||||
|
|
||||||
<Card :title="t('components.About.header.signup')"
|
<Card :title="t('components.About.header.signup')"
|
||||||
v-if="!store.state.auth.authenticated"
|
v-if="!store.state.auth.authenticated"
|
||||||
style="--width:256px"
|
width="256px"
|
||||||
>
|
>
|
||||||
|
|
||||||
<template v-if="openRegistrations">
|
<template v-if="openRegistrations">
|
||||||
|
@ -156,7 +156,7 @@ const federationEnabled = computed(() => {
|
||||||
|
|
||||||
<Card :title="t('components.About.message.greeting', {username: store.state.auth.username})"
|
<Card :title="t('components.About.message.greeting', {username: store.state.auth.username})"
|
||||||
v-else
|
v-else
|
||||||
style="--width:256px"
|
width= "256px"
|
||||||
>
|
>
|
||||||
|
|
||||||
<p v-if="defaultUploadQuota">
|
<p v-if="defaultUploadQuota">
|
||||||
|
@ -171,7 +171,7 @@ const federationEnabled = computed(() => {
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card :title="podName"
|
<Card :title="podName"
|
||||||
style="--width:256px"
|
width="256px"
|
||||||
>
|
>
|
||||||
<section
|
<section
|
||||||
:class="['ui', 'head', {'with-background': banner}, 'vertical', 'center', 'aligned', 'stripe', 'segment']"
|
:class="['ui', 'head', {'with-background': banner}, 'vertical', 'center', 'aligned', 'stripe', 'segment']"
|
||||||
|
@ -234,7 +234,7 @@ const federationEnabled = computed(() => {
|
||||||
|
|
||||||
<Layout flex style="justify-content: center;">
|
<Layout flex style="justify-content: center;">
|
||||||
|
|
||||||
<Card style="--width:256px"
|
<Card width="256px"
|
||||||
to="/"
|
to="/"
|
||||||
:title="t('components.About.header.publicContent')"
|
:title="t('components.About.header.publicContent')"
|
||||||
icon="bi-box-arrow-up-right"
|
icon="bi-box-arrow-up-right"
|
||||||
|
@ -243,7 +243,7 @@ const federationEnabled = computed(() => {
|
||||||
{{ t('components.About.description.publicContent') }}
|
{{ t('components.About.description.publicContent') }}
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card style="--width:256px"
|
<Card width="256px"
|
||||||
:title="t('components.About.link.findOtherPod')"
|
:title="t('components.About.link.findOtherPod')"
|
||||||
to="https://funkwhale.audio/#get-started"
|
to="https://funkwhale.audio/#get-started"
|
||||||
icon="bi-box-arrow-up-right"
|
icon="bi-box-arrow-up-right"
|
||||||
|
@ -251,7 +251,7 @@ const federationEnabled = computed(() => {
|
||||||
{{ t('components.About.description.publicContent') }}
|
{{ t('components.About.description.publicContent') }}
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card style="--width:256px"
|
<Card width="256px"
|
||||||
:title="t('components.About.header.findApp')"
|
:title="t('components.About.header.findApp')"
|
||||||
to="https://funkwhale.audio/apps"
|
to="https://funkwhale.audio/apps"
|
||||||
icon="bi-box-arrow-up-right"
|
icon="bi-box-arrow-up-right"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { KeysOfUnion } from "type-fest"
|
import type { Entries, KeysOfUnion } from "type-fest"
|
||||||
|
|
||||||
export type WidthProps =
|
export type WidthProps =
|
||||||
| { minContent?: true }
|
| { minContent?: true }
|
||||||
|
@ -8,9 +8,10 @@ export type WidthProps =
|
||||||
| { medium?: true }
|
| { medium?: true }
|
||||||
| { auto?: true }
|
| { auto?: true }
|
||||||
| { full?: true }
|
| { full?: true }
|
||||||
|
| { width?: string }
|
||||||
export type Key = KeysOfUnion<WidthProps>
|
export type Key = KeysOfUnion<WidthProps>
|
||||||
|
|
||||||
const styles : Record<Key, string> = {
|
const styles = {
|
||||||
minContent: 'width: min-content;',
|
minContent: 'width: min-content;',
|
||||||
tiny: "width: 124px; grid-column: span 2;",
|
tiny: "width: 124px; grid-column: span 2;",
|
||||||
buttonWidth: "width: 136px; grid-column: span 2; flex-grow:0;",
|
buttonWidth: "width: 136px; grid-column: span 2; flex-grow:0;",
|
||||||
|
@ -18,7 +19,19 @@ const styles : Record<Key, string> = {
|
||||||
medium: "width: 280px; grid-column: span 4;",
|
medium: "width: 280px; grid-column: span 4;",
|
||||||
auto: "width: auto;",
|
auto: "width: auto;",
|
||||||
full: "width: auto; grid-column: 1 / -1; align-self: auto; flex-grow:1;",
|
full: "width: auto; grid-column: 1 / -1; align-self: auto; flex-grow:1;",
|
||||||
};
|
width: (w:string)=>`width: ${w}; flex-grow:0;`,
|
||||||
|
} as const satisfies Record<Key, string|((w:string)=>string)>;
|
||||||
|
|
||||||
|
const getStyle = (props : Partial<WidthProps>) => (key : Key) =>
|
||||||
|
(typeof styles[key] !== 'string' && key in props) ?
|
||||||
|
styles[key](
|
||||||
|
// TODO: Make the typescript compiler understand `key in props`
|
||||||
|
// @ts-ignore
|
||||||
|
props[key]
|
||||||
|
)
|
||||||
|
: styles[key]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// All keys are exclusive
|
// All keys are exclusive
|
||||||
const conflicts: Set<Key>[] = [
|
const conflicts: Set<Key>[] = [
|
||||||
|
@ -30,22 +43,25 @@ const conflicts: Set<Key>[] = [
|
||||||
* Widths are designed to work both in a page-grid context and in a flex or normal context.
|
* Widths are designed to work both in a page-grid context and in a flex or normal context.
|
||||||
*
|
*
|
||||||
* (1) Add `& WidthProps` to your `Props` type
|
* (1) Add `& WidthProps` to your `Props` type
|
||||||
* (2) Call `v-bind="propsToWidth(props)"` on your component template
|
* (2) Call `v-bind="width(props)"` on your component template
|
||||||
* (3) Now your component accepts width props such as `small`, `medium`, `stretch`.
|
* (3) Now your component accepts width props such as `small`, `medium`, `stretch`.
|
||||||
*
|
*
|
||||||
* @param props Your component's props (or ...rest props if you have destructured them already)
|
* @param props Your component's props (or ...rest props if you have destructured them already)
|
||||||
* @returns the corresponding `style` object
|
* @returns the corresponding `{ style }` object
|
||||||
*/
|
*/
|
||||||
export const width = (props: Partial<WidthProps>, defaults: Key[] = []) => ({
|
export const width = <TProps extends Partial<WidthProps>>(
|
||||||
|
props: TProps,
|
||||||
|
defaults: Key[] = []
|
||||||
|
) => ({
|
||||||
style:
|
style:
|
||||||
Object.entries(props).reduce(
|
(Object.entries(props) as Entries<TProps>).reduce(
|
||||||
((acc, [key, value]) =>
|
((acc, [key, value]) =>
|
||||||
value && key in styles ?
|
value && key in styles ?
|
||||||
acc.filter(accKey => !conflicts.find(set => set.has(accKey) && set.has(key as Key)))
|
acc.filter(accKey => !conflicts.find(set => set.has(accKey) && set.has(key)))
|
||||||
.concat([key as Key])
|
.concat([key])
|
||||||
: acc
|
: acc
|
||||||
),
|
),
|
||||||
defaults
|
defaults
|
||||||
).map(key => styles[key])
|
).map(getStyle(props))
|
||||||
.join(' ')
|
.join(' ')
|
||||||
})
|
})
|
||||||
|
|
|
@ -26,6 +26,7 @@ const here = route.path
|
||||||
<Card small title='small' />
|
<Card small title='small' />
|
||||||
<Card medium title='medium' />
|
<Card medium title='medium' />
|
||||||
<Card auto title='auto' />
|
<Card auto title='auto' />
|
||||||
|
<Card width="170.5px" title='width=170.5px' />
|
||||||
<Card full title='full' />
|
<Card full title='full' />
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -35,5 +36,16 @@ const here = route.path
|
||||||
<Card small title='small' />
|
<Card small title='small' />
|
||||||
<Card medium title='medium' />
|
<Card medium title='medium' />
|
||||||
<Card auto title='auto' />
|
<Card auto title='auto' />
|
||||||
|
<Card width="170.5px" title='width=170.5px' />
|
||||||
<Card full title='full' />
|
<Card full title='full' />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
## Widths in the grid
|
||||||
|
|
||||||
|
::: details Default widths
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
[Designing Pages — The grid](designing-pages#grid)
|
||||||
|
|
Loading…
Reference in New Issue