@@ -123,14 +122,14 @@ const size = ref(1);
- A
+ A
- B
- C
+ B
+ C
- D
+ D
- E
+ E
```
@@ -141,14 +140,14 @@ const size = ref(1);
{{ size }}%
- A
+ A
- B
- C
+ B
+ C
- D
+ D
- E
+ E
diff --git a/front/ui-docs/components/ui/modal.md b/front/ui-docs/components/ui/modal.md
index 0620fcbaa..eefba6dfc 100644
--- a/front/ui-docs/components/ui/modal.md
+++ b/front/ui-docs/components/ui/modal.md
@@ -70,7 +70,7 @@ Make sure to add `autofocus` to the preferred button.
Modal content
-
+
Cancel
@@ -88,7 +88,7 @@ Make sure to add `autofocus` to the preferred button.
Modal content
-
+
Cancel
@@ -120,13 +120,13 @@ Note that confirmation dialogs interrupt the user's workflow. Consider adding a
:::
```vue-html
-
+
Delete my account ...
-
+
1 082 music files that you uploaded will be deleted.
7 879 items in your collections will be unlinked.
@@ -135,22 +135,22 @@ Do you want to delete your account forever?
You will not be able to restore your account.
-
+
Keep my account
-
+
I understand. Delete my account now!
```
-
+
Delete my account ...
-
+
1 082 music files that you uploaded will be deleted.
7 879 items in your collections will be unlinked.
@@ -159,10 +159,10 @@ Do you want to delete your account forever?
You will not be able to restore your account.
-
+
Keep my account
-
+
I understand. Delete my account now!
@@ -239,7 +239,7 @@ You can nest [Funkwhale alerts](./alert) to visually highlight content within th
Modal content
-
+
Alert content
Close alert
@@ -250,7 +250,7 @@ You can nest [Funkwhale alerts](./alert) to visually highlight content within th
Cancel
-
+
Ok
diff --git a/front/ui-docs/components/ui/pill.md b/front/ui-docs/components/ui/pill.md
index cc5c7fa64..56a1aab38 100644
--- a/front/ui-docs/components/ui/pill.md
+++ b/front/ui-docs/components/ui/pill.md
@@ -12,29 +12,17 @@ You can add text to pills by adding it between the `` tags.
| ------- | ----------------------------------------------------------------------------------------------- | --------- | ----------- | ---------------------- |
| `color` | `primary` \| `secondary` \| `destructive` \| `blue` \| `red` \| `purple` \| `green` \| `yellow` | No | `secondary` | Renders a colored pill |
-## Pill types
-
-You can assign a type to your pill to indicate what kind of information it conveys.
-
-::: details Types
-
-- Primary
-- Secondary
-- Destructive
-
-:::
-
### Primary
Primary pills convey **positive** information.
```vue-html
-
+
Primary pill
```
-
+
Primary pill
@@ -61,12 +49,12 @@ This is the default type for pills. If you don't specify a type, a **secondary**
Destructive pills convey **destructive** or **negative** information. Use these to indicate that information could cause issues such as data loss.
```vue-html
-
+
Destructive pill
```
-
+
Destructive pill
@@ -74,73 +62,63 @@ Destructive pills convey **destructive** or **negative** information. Use these
Funkwhale pills support a range of pastel colors to create visually appealing interfaces.
-::: details Colors
-
-- Red
-- Blue
-- Purple
-- Green
-- Yellow
-
-:::
-
### Blue
```vue-html
-
+
Blue pill
```
-
+
Blue pill
### Red
```vue-html
-
+
Red pill
```
-
+
Red pill
### Purple
```vue-html
-
+
Purple pill
```
-
+
Purple pill
### Green
```vue-html
-
+
Green pill
```
-
+
Green pill
### Yellow
```vue-html
-
+
Yellow pill
```
-
+
Yellow pill
diff --git a/front/ui-docs/using-color.md b/front/ui-docs/using-color.md
index 82416999a..5dd24d72c 100644
--- a/front/ui-docs/using-color.md
+++ b/front/ui-docs/using-color.md
@@ -1 +1,292 @@
+
+
# Using Color
+
+## Add color via props
+
+[Alerts](components/ui/alert) support [Pastel](#pastel) attributes. [Buttons](components/ui/button) accept [Color](#color) and [Variant](#variant) attributes. [Cards](components/ui/card) accept [Pastel](#pastel), [Variant](#variant), [Neutral](#neutral) and [Raised](#raised) attributes.
+
+```vue-html
+
+```
+
+
+
+## Add color to a any component or Html tag
+
+1. Choose a
+ - [base color](#colors) (`primary | secondary | destructive`) or
+ - [pastel color](#pastel) (`blue | red | green | yellow`) or
+ - [neutral beige or gray](#neutral) (`default`) for surfaces
+2. Choose a [variant](#color-variants) (`solid | ghost | outline`)
+3. Add [interactivity and raise the surface](#interactive-andor-raised)
+
+```vue
+
+
+
+
+
+```
+
+
+
+## Base colors
+
+### Neutral
+
+
+
+
+
+
+### Color
+
+Primary
+
+
+
+
+
+
+Secondary
+
+
+
+
+
+
+Destructive
+
+
+
+
+
+
+### Pastel
+
+Blue, Red, Purple, Green, Yellow
+
+
+
+
+
+
+
+---
+
+### Variant
+
+Solid (default), Ghost, Outline
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+### Interactive and/or Raised
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Palette
+
+The color palette consists of Blues, Reds, Grays, Beiges, as well as pastel blue/red/green/yellow.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+In addition, we have a single shade of orange used for secondary indicators such as active tabs:
+
+
+
+## Theme
+
+Many browsers automatically turn on "night mode" to lower the light emission of the screen. Users can override the browser theme in their settings menu.
+
+In both "dark mode" and "light mode", the colors must provide adequate contrast and consistency.
+
+## Semantic colors
+
+We use semantic color variables that can mean a different shade depending on the currently chosen theme
+
+- primary
+- secondary (default)
+- destructive
+
+## Color variants
+
+For each semantic color, we set a foreground and a background. In addition, we need to check context: A button should have a stronger shade when the mouse is hovering over it. When a surface is raised over another surface, it should have a stronger shade, too.
+
+- ghost (default for most other things)
+
+ - text color
+
+- outline
+
+ - border color
+
+- solid (default for buttons)
+ - bg color
+ - border color
+
+Variants can be made interactive and/or raised:
+
+- no alteration (default)
+
+- raised
+
+ - text color
+ - border color
+ - bg color
+
+- interactive
+
+ - can be disabled
+ - can be active
+ - can be exact-active
+ - can be hovering
+
+- interactive-raised
+ - combine `raised` and `interactive`
+
+
diff --git a/front/ui-docs/using-components.md b/front/ui-docs/using-components.md
index 9dceede6c..c68109c4d 100644
--- a/front/ui-docs/using-components.md
+++ b/front/ui-docs/using-components.md
@@ -71,7 +71,96 @@ import Button from "~/components/ui/Button.vue";
-
+
```
+
+## Limitations of component props
+
+While Vue can infer props based on a type, it will fail with mysterious errors if the type is an exclusive union or has union types as keys.
+
+I hope this will be resolved soon so we can use this more elegant way of injecting non-trivial props with full autocomplete, 21st century style:
+
+```vue
+
+
+
+
+
+
+ {{ Error: }} {{ Error: }}
+
+```
+
+::: details Example
+
+````ts
+// Color from props
+
+type SingleOrNoProp = RequireOneOrNone, T>;
+type SingleProp = RequireExactlyOne, T>;
+
+export type Props = Simplify<
+ SingleProp &
+ SingleOrNoProp &
+ SingleOrNoProp<"interactive"> &
+ SingleOrNoProp<"raised">
+>;
+
+// Limit the choices:
+
+export type ColorProps = Simplify<
+ SingleProp & SingleOrNoProp & SingleOrNoProp<"raised">
+>;
+
+export type PastelProps = Simplify<
+ SingleProp & SingleOrNoProp<"raised">
+>;
+
+// Note that as of now, Vue does not support unions of props.
+// So instead, we give it a single string:
+
+export type ColorProp = Simplify<`${Color}${
+ | ""
+ | `-${Variant}${"" | "-raised"}`}`>;
+export type PastelProp = Simplify<`${Pastel}${"" | "-raised"}`>;
+
+// Using like this:
+// type Props = {...} & { [k in ColorProp]? : true }
+// This will also lead to runtime errors. Why?
+
+export const isColorProp = (k: string) =>
+ !![...colors, ...defaults, ...pastels].find(k.startsWith);
+
+console.log(true, isColorProp("primary"));
+console.log(true, isColorProp("secondary"));
+console.log(true, isColorProp("red"));
+console.log(false, isColorProp("Jes"));
+console.log(false, isColorProp("raised"));
+
+/**
+ * Convenience function in case you want to hand over the props in the form
+ * ```
+ * ...
+ * ```
+ *
+ * @param props Any superset of type `Props`
+ * @returns the corresponding `class` object
+ *
+ * Note: Make sure to implement the necessary classes in `colors.scss`!
+ */
+export const colorFromProps = (props: Record) =>
+ color(
+ Object.keys(props)
+ .filter(isColorProp)
+ .join(" ")
+ .replace("-", " ") as ColorSelector,
+ );
+````
+
+:::
diff --git a/front/yarn.lock b/front/yarn.lock
index 8f4c707a2..7b432477e 100644
--- a/front/yarn.lock
+++ b/front/yarn.lock
@@ -10668,6 +10668,11 @@ type-detect@^4.0.0, type-detect@^4.1.0:
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c"
integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==
+type-fest@4.30.1:
+ version "4.30.1"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.30.1.tgz#120b9e15177310ec4e9d5d6f187d86c0f4b55e0e"
+ integrity sha512-ojFL7eDMX2NF0xMbDwPZJ8sb7ckqtlAi1GsmgsFXvErT9kFTk1r0DuQKvrCh73M6D4nngeHJmvogF9OluXs7Hw==
+
type-fest@^0.16.0:
version "0.16.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860"