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')"
|
||||
v-if="!store.state.auth.authenticated"
|
||||
style="--width:256px"
|
||||
width="256px"
|
||||
>
|
||||
|
||||
<template v-if="openRegistrations">
|
||||
|
@ -156,7 +156,7 @@ const federationEnabled = computed(() => {
|
|||
|
||||
<Card :title="t('components.About.message.greeting', {username: store.state.auth.username})"
|
||||
v-else
|
||||
style="--width:256px"
|
||||
width= "256px"
|
||||
>
|
||||
|
||||
<p v-if="defaultUploadQuota">
|
||||
|
@ -171,7 +171,7 @@ const federationEnabled = computed(() => {
|
|||
</Card>
|
||||
|
||||
<Card :title="podName"
|
||||
style="--width:256px"
|
||||
width="256px"
|
||||
>
|
||||
<section
|
||||
:class="['ui', 'head', {'with-background': banner}, 'vertical', 'center', 'aligned', 'stripe', 'segment']"
|
||||
|
@ -234,7 +234,7 @@ const federationEnabled = computed(() => {
|
|||
|
||||
<Layout flex style="justify-content: center;">
|
||||
|
||||
<Card style="--width:256px"
|
||||
<Card width="256px"
|
||||
to="/"
|
||||
:title="t('components.About.header.publicContent')"
|
||||
icon="bi-box-arrow-up-right"
|
||||
|
@ -243,7 +243,7 @@ const federationEnabled = computed(() => {
|
|||
{{ t('components.About.description.publicContent') }}
|
||||
</Card>
|
||||
|
||||
<Card style="--width:256px"
|
||||
<Card width="256px"
|
||||
:title="t('components.About.link.findOtherPod')"
|
||||
to="https://funkwhale.audio/#get-started"
|
||||
icon="bi-box-arrow-up-right"
|
||||
|
@ -251,7 +251,7 @@ const federationEnabled = computed(() => {
|
|||
{{ t('components.About.description.publicContent') }}
|
||||
</Card>
|
||||
|
||||
<Card style="--width:256px"
|
||||
<Card width="256px"
|
||||
:title="t('components.About.header.findApp')"
|
||||
to="https://funkwhale.audio/apps"
|
||||
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 =
|
||||
| { minContent?: true }
|
||||
|
@ -8,9 +8,10 @@ export type WidthProps =
|
|||
| { medium?: true }
|
||||
| { auto?: true }
|
||||
| { full?: true }
|
||||
| { width?: string }
|
||||
export type Key = KeysOfUnion<WidthProps>
|
||||
|
||||
const styles : Record<Key, string> = {
|
||||
const styles = {
|
||||
minContent: 'width: min-content;',
|
||||
tiny: "width: 124px; grid-column: span 2;",
|
||||
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;",
|
||||
auto: "width: auto;",
|
||||
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
|
||||
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.
|
||||
*
|
||||
* (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`.
|
||||
*
|
||||
* @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:
|
||||
Object.entries(props).reduce(
|
||||
(Object.entries(props) as Entries<TProps>).reduce(
|
||||
((acc, [key, value]) =>
|
||||
value && key in styles ?
|
||||
acc.filter(accKey => !conflicts.find(set => set.has(accKey) && set.has(key as Key)))
|
||||
.concat([key as Key])
|
||||
acc.filter(accKey => !conflicts.find(set => set.has(accKey) && set.has(key)))
|
||||
.concat([key])
|
||||
: acc
|
||||
),
|
||||
defaults
|
||||
).map(key => styles[key])
|
||||
).map(getStyle(props))
|
||||
.join(' ')
|
||||
})
|
||||
|
|
|
@ -26,6 +26,7 @@ const here = route.path
|
|||
<Card small title='small' />
|
||||
<Card medium title='medium' />
|
||||
<Card auto title='auto' />
|
||||
<Card width="170.5px" title='width=170.5px' />
|
||||
<Card full title='full' />
|
||||
```
|
||||
|
||||
|
@ -35,5 +36,16 @@ const here = route.path
|
|||
<Card small title='small' />
|
||||
<Card medium title='medium' />
|
||||
<Card auto title='auto' />
|
||||
<Card width="170.5px" title='width=170.5px' />
|
||||
<Card full title='full' />
|
||||
</Layout>
|
||||
|
||||
## Widths in the grid
|
||||
|
||||
::: details Default widths
|
||||
|
||||

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