diff --git a/front/src/components/ui/Pill.vue b/front/src/components/ui/Pill.vue
index 55ba3d2aa..b0922cfc3 100644
--- a/front/src/components/ui/Pill.vue
+++ b/front/src/components/ui/Pill.vue
@@ -1,6 +1,5 @@
+
+
+
+
diff --git a/front/src/components/ui/Tab.vue b/front/src/components/ui/Tab.vue
index a53682f33..e821cd425 100644
--- a/front/src/components/ui/Tab.vue
+++ b/front/src/components/ui/Tab.vue
@@ -3,18 +3,17 @@ import { TABS_INJECTION_KEY } from '~/injection-keys'
import { whenever } from '@vueuse/core'
import { inject, ref } from 'vue'
-const title = defineProp('title', { required: true })
-const icon = defineProp('icon')
+const { title, icon } = defineProps<{ title:string, icon?:string }>()
const { currentTab, tabs, icons } = inject(TABS_INJECTION_KEY, {
- currentTab: ref(title.value),
+ currentTab: ref(title),
tabs: [],
icons: [],
})
-whenever(() => !tabs.includes(title.value), () => {
- tabs.push(title.value)
- icons.push(icon.value)
+whenever(() => !tabs.includes(title), () => {
+ tabs.push(title)
+ icons.push(icon)
}, { immediate: true })
diff --git a/front/src/components/ui/Tabs.vue b/front/src/components/ui/Tabs.vue
index 2ee624b21..a00978170 100644
--- a/front/src/components/ui/Tabs.vue
+++ b/front/src/components/ui/Tabs.vue
@@ -41,5 +41,5 @@ watch(() => tabs.length, (to, from) => {
diff --git a/front/src/components/ui/Textarea.vue b/front/src/components/ui/Textarea.vue
index af3838514..c826e5f22 100644
--- a/front/src/components/ui/Textarea.vue
+++ b/front/src/components/ui/Textarea.vue
@@ -1,22 +1,16 @@
@@ -20,5 +18,5 @@ const { modelValue: enabled } = defineModels<{
diff --git a/front/src/components/ui/button/Options.vue b/front/src/components/ui/button/Options.vue
index fc441633d..a3b0ce085 100644
--- a/front/src/components/ui/button/Options.vue
+++ b/front/src/components/ui/button/Options.vue
@@ -1,11 +1,11 @@
-
+
diff --git a/front/src/components/ui/button/Play.vue b/front/src/components/ui/button/Play.vue
index 3be267545..efd9f68ea 100644
--- a/front/src/components/ui/button/Play.vue
+++ b/front/src/components/ui/button/Play.vue
@@ -1,13 +1,13 @@
-
+
diff --git a/front/src/components/ui/popover/PopoverCheckbox.vue b/front/src/components/ui/popover/PopoverCheckbox.vue
index e4a3eeba5..5b8b2b5e3 100644
--- a/front/src/components/ui/popover/PopoverCheckbox.vue
+++ b/front/src/components/ui/popover/PopoverCheckbox.vue
@@ -1,9 +1,11 @@
-
@@ -13,5 +15,5 @@ const value = defineModel('modelValue', { required: true })
-
+
diff --git a/front/src/components/ui/popover/PopoverItem.vue b/front/src/components/ui/popover/PopoverItem.vue
index dbb98efe2..75066b6a8 100644
--- a/front/src/components/ui/popover/PopoverItem.vue
+++ b/front/src/components/ui/popover/PopoverItem.vue
@@ -4,8 +4,8 @@ import { POPOVER_CONTEXT_INJECTION_KEY, type PopoverContext } from '~/injection-
const setId = defineEmit<[value: number]>('internal:id')
-const parentPopoverContext = defineProp('vuiParentPopoverContext')
-const { items, hoveredItem } = parentPopoverContext.value ?? inject(POPOVER_CONTEXT_INJECTION_KEY, {
+const { parentPopoverContext } = defineProps<{ parentPopoverContext?: PopoverContext }>()
+const { items, hoveredItem } = parentPopoverContext ?? inject(POPOVER_CONTEXT_INJECTION_KEY, {
items: ref(0),
hoveredItem: ref(-2)
})
diff --git a/front/src/components/ui/popover/PopoverRadio.vue b/front/src/components/ui/popover/PopoverRadio.vue
index 1bb04d80f..ce54202a4 100644
--- a/front/src/components/ui/popover/PopoverRadio.vue
+++ b/front/src/components/ui/popover/PopoverRadio.vue
@@ -1,11 +1,11 @@
-
+
{{ choice }}
-
+
diff --git a/front/src/components/ui/popover/PopoverRadioItem.vue b/front/src/components/ui/popover/PopoverRadioItem.vue
index 9cd3d7cf3..19c77fa93 100644
--- a/front/src/components/ui/popover/PopoverRadioItem.vue
+++ b/front/src/components/ui/popover/PopoverRadioItem.vue
@@ -1,14 +1,16 @@
-
+
-
+
diff --git a/front/src/components/ui/popover/PopoverSubmenu.vue b/front/src/components/ui/popover/PopoverSubmenu.vue
index 30e98bd54..5e8799bdd 100644
--- a/front/src/components/ui/popover/PopoverSubmenu.vue
+++ b/front/src/components/ui/popover/PopoverSubmenu.vue
@@ -1,8 +1,10 @@
-
-
+
@@ -30,10 +32,10 @@ watchEffect(() => {
-
+
-
+
diff --git a/front/src/composables/colors.ts b/front/src/composables/colors.ts
index 108f652e0..e4d260736 100644
--- a/front/src/composables/colors.ts
+++ b/front/src/composables/colors.ts
@@ -1,6 +1,5 @@
import { toValue, type MaybeRefOrGetter } from "@vueuse/core"
import { computed } from 'vue'
-import type { Color, Pastel } from '~/types/common-props'
export function useColor(color: MaybeRefOrGetter, defaultColor: Color = 'primary') {
return computed(() => `is-${toValue(color) ?? defaultColor}`)
@@ -13,3 +12,13 @@ export function usePastel(color: MaybeRefOrGetter, defaultCo
export function useColorOrPastel(color: MaybeRefOrGetter, defaultColor: T) {
return computed(() => `is-${toValue(color) ?? defaultColor}`)
}
+
+export type Color = 'primary' | 'secondary' | 'destructive'
+export interface ColorProps {
+ color?: Color
+}
+
+export type Pastel = 'red' | 'blue' | 'purple' | 'green' | 'yellow'
+export interface PastelProps {
+ color?: Pastel
+}
diff --git a/front/src/utils/event-validators.ts b/front/src/utils/event-validators.ts
new file mode 100644
index 000000000..ddc8a30e5
--- /dev/null
+++ b/front/src/utils/event-validators.ts
@@ -0,0 +1,5 @@
+export const preventNonNumeric = (e: KeyboardEvent) => {
+ if (!e.key.match(/![0-9]$/)) {
+ e.preventDefault()
+ }
+}
diff --git a/front/ui-docs/components/ui/activity.md b/front/ui-docs/components/ui/activity.md
index 12a2f294b..08bd40e90 100644
--- a/front/ui-docs/components/ui/activity.md
+++ b/front/ui-docs/components/ui/activity.md
@@ -1,18 +1,94 @@
@@ -24,7 +100,7 @@ Activities display history entries for a Funkwhale pod. Each item contains the f
- A track title
- An artist name
- A username
-- A [popover](./../popover.md)
+- A [popover](./popover.md)
| Prop | Data type | Required? | Description |
| ------- | ------------ | --------- | -------------------------------------------- |
@@ -33,29 +109,25 @@ Activities display history entries for a Funkwhale pod. Each item contains the f
## Single items
-You can render a single activity item by passing the track and user information to the `` component.
+You can render a single activity item by passing the track and user information to the `` component.
```vue-html
-
+
```
-
+
## Activity lists
-You can display a list of activity items by passing a `v-for` directive and adding a `key` to the item. The `key` must be unique to the list.
+You can display a list of activity items by passing a `v-for` directive and adding a `key` to the item. The `key` must
+be unique to the list.
::: info
Items in a list are visually separated by a 1px border.
:::
```vue-html{4-5}
-
+
```
-
+
diff --git a/front/ui-docs/components/ui/alert.md b/front/ui-docs/components/ui/alert.md
index cf9915756..6faade58e 100644
--- a/front/ui-docs/components/ui/alert.md
+++ b/front/ui-docs/components/ui/alert.md
@@ -1,3 +1,8 @@
+
+
# Alert
| Prop | Data type | Required? | Default | Description |
@@ -21,78 +26,78 @@ Funkwhale alerts support a range of pastel colors for visual appeal.
### Blue
```vue-html
-
+
Blue alert
-
+
```
-
+
Blue alert
-
+
### Red
```vue-html
-
+
Red alert
-
+
```
-
+
Red alert
-
+
### Purple
```vue-html
-
+
Purple alert
-
+
```
-
+
Purple alert
-
+
### Green
```vue-html
-
+
Green alert
-
+
```
-
+
Green alert
-
+
### Yellow
```vue-html
-
+
Yellow alert
-
+
```
-
+
Yellow alert
-
+
## Alert actions
```vue-html{2-4}
-
+
Awesome artist
- Got it
+ Got it
-
+
```
-
+
Awesome artist
- Got it
+ Got it
-
+
diff --git a/front/ui-docs/components/ui/button.md b/front/ui-docs/components/ui/button.md
index e74ffa5cf..7e5b4341a 100644
--- a/front/ui-docs/components/ui/button.md
+++ b/front/ui-docs/components/ui/button.md
@@ -1,4 +1,6 @@
@@ -29,42 +31,42 @@ This is the default type. If you don't specify a type, a primary button is rende
:::
```vue-html
-
+
Primary button
-
+
```
-
+
Primary button
-
+
### Secondary
Secondary buttons represent **neutral** actions such as cancelling a change or dismissing a notification.
```vue-html
-
+
Secondary button
-
+
```
-
+
Secondary button
-
+
### Destructive
Desctrutive buttons represent **dangerous** actions including deleting items or purging domain information.
```vue-html
-
+
Destructive button
-
+
```
-
+
Destructive button
-
+
## Button variants
@@ -79,42 +81,42 @@ This is the default style. If you don't specify a style, a solid button is rende
:::
```vue-html
-
+
Filled button
-
+
```
-
+
Filled button
-
+
### Outline
Outline buttons have a transparent background. Use these to deemphasize the action the button performs.
```vue-html
-
+
Outline button
-
+
```
-
+
Outline button
-
+
### Ghost
Ghost buttons have a transparent background and border. Use these to deemphasize the action the button performs.
```vue-html
-
+
Ghost button
-
+
```
-
+
Ghost button
-
+
## Button styles
@@ -123,14 +125,14 @@ Ghost buttons have a transparent background and border. Use these to deemphasize
You can give a button a shadow to add depth.
```vue-html
-
+
Shadow button
-
+
```
-
+
Shadow button
-
+
## Button shapes
@@ -145,28 +147,28 @@ This is the default shape. If you don't specify a type, a normal button is rende
:::
```vue-html
-
+
Normal button
-
+
```
-
+
Normal button
-
+
### Round
Round buttons have fully rounded edges.
```vue-html
-
+
Round button
-
+
```
-
+
Round button
-
+
## Button states
@@ -177,49 +179,49 @@ You can pass a state to indicate whether a user can interact with a button.
A button is active when clicked by a user. You can force an active state by passing an `is-active` prop.
```vue-html
-
+
Active button
-
+
```
-
+
Active button
-
+
### Disabled
Disabled buttons are non-interactive and inherit a less bold color than the one provided. You can apply a disabled state by passing a `disabled` prop.
```vue-html
-
+
Disabled button
-
+
```
-
+
Disabled button
-
+
### Loading
If a user can't interact with a button until something has finished loading, you can add a spinner by passing the `is-loading` prop.
```vue-html
-
+
Loading button
-
+
```
-
+
Loading button
-
+
### Promise handling in `@click`
When a function passed to `@click` returns a promise, the button automatically toggles a loading state on click. When the promise resolves or is rejected, the loading state turns off.
::: danger
-There is no promise rejection mechanism implemented in the `` component. Make sure the `@click` handler never rejects.
+There is no promise rejection mechanism implemented in the `` component. Make sure the `@click` handler never rejects.
:::
```vue
@@ -228,25 +230,25 @@ const click = () => new Promise((resolve) => setTimeout(resolve, 1000));
- Click me
+ Click me
```
-
+
Click me
-
+
You can override the promise state by passing a false `is-loading` prop.
```vue-html
-
+
Click me
-
+
```
-
+
Click me
-
+
## Icons
@@ -257,20 +259,20 @@ Icon buttons shrink down to the icon size if you don't pass any content. If you
:::
```vue-html
-
+
-
+
-
+
-
+
Delete
-
+
```
-
-
-
-
+
+
+
+
Delete
-
+
diff --git a/front/ui-docs/components/ui/button/options.md b/front/ui-docs/components/ui/button/options.md
index bf4fecbe0..7d0b4ef29 100644
--- a/front/ui-docs/components/ui/button/options.md
+++ b/front/ui-docs/components/ui/button/options.md
@@ -1,9 +1,13 @@
+
+
# Options Button
-> For use cases, see [components/popover](../popover)
```vue-html
-
+
```
-
+
diff --git a/front/ui-docs/components/ui/button/play.md b/front/ui-docs/components/ui/button/play.md
index 355a3bc61..16a25759b 100644
--- a/front/ui-docs/components/ui/button/play.md
+++ b/front/ui-docs/components/ui/button/play.md
@@ -1,9 +1,13 @@
+
+
# Play Button
The play button is a specialized button used in many places across the Funkwhale app. Map a function to the `@play` event handler to toggle it on click.
```vue-html
-
+
```
-
+
diff --git a/front/ui-docs/components/ui/card.md b/front/ui-docs/components/ui/card.md
index 1721b4a31..9052d6edf 100644
--- a/front/ui-docs/components/ui/card.md
+++ b/front/ui-docs/components/ui/card.md
@@ -1,10 +1,13 @@
# Card
@@ -33,16 +36,26 @@ You have to set a title for the card by passing a `title` prop.
:::
+
+
```vue-html
- Access your personal music collection from anywhere. Funkwhale gives you access to publication and sharing tools that you can use to promote your content across the web.
+ Access your personal music
+ collection from anywhere.
+ Funkwhale gives you access to
+ publication and sharing tools
+ you can use to promote that
+ your content across the web.
```
Access your personal music collection from anywhere. Funkwhale gives you access to publication and sharing tools that you can use to promote your content across the web.
-
+
+
+
+
## Card as a Link
@@ -86,6 +99,8 @@ Category cards are basic cards that contain only a title. To create a category c
Pass an image source to the `image` prop or set `image.src` and `image.style`.
+
+
```vue-html{4,11-12}
```
-
-
+
## Add an Alert
@@ -143,11 +157,11 @@ Items in this region are secondary and will be displayed smaller than the main c
There are no items in this list
-
+
Upload
-
+
-
+
```
@@ -159,9 +173,9 @@ Items in this region are secondary and will be displayed smaller than the main c
-Upload
+Upload
-
+
@@ -175,8 +189,8 @@ Large Buttons or links at the bottom edge of the card serve as Call-to-Actions (
The easiest way to get started with Funkwhale is to register an account on a public pod.
- Action!
-
+ Action!
+
```
@@ -185,8 +199,8 @@ Large Buttons or links at the bottom edge of the card serve as Call-to-Actions (
The easiest way to get started with Funkwhale is to register an account on a public pod.
- Action!
-
+ Action!
+
@@ -197,12 +211,12 @@ If there are multiple actions, they will be presented in a row:
You cannot undo this action.
-
+
Back
-
-
+
+
Delete
-
+
```
@@ -211,12 +225,12 @@ If there are multiple actions, they will be presented in a row:
You cannot undo this action.
-
+
Back
-
-
+
+
Delete
-
+
diff --git a/front/ui-docs/components/ui/input.md b/front/ui-docs/components/ui/input.md
index 191b8c3a2..cac8b84b5 100644
--- a/front/ui-docs/components/ui/input.md
+++ b/front/ui-docs/components/ui/input.md
@@ -1,54 +1,53 @@
+
+
# Input
Inputs are areas in which users can enter information. In Funkwhale, these mostly take the form of search fields.
-| Prop | Data type | Required? | Description |
-| --------------- | --------- | --------- | --------------------------------------------------------------------------- |
-| `placeholder` | String | No | The placeholder text that appears when the input is empty. |
-| `icon` | String | No | The [Bootstrap icon](https://icons.getbootstrap.com/) to show on the input. |
-| `v-model:value` | String | Yes | The text entered in the input. |
+| Prop | Data type | Required? | Description |
+| ---- | --------- | --------- | ----------- |
+
+|
+| `placeholder` | String | No | The placeholder text that appears when the input is empty. |
+| `icon` | String | No | The [Bootstrap icon](https://icons.getbootstrap.com/) to show on the input. |
+| `v-model:value` | String | Yes | The text entered in the input. |
## Input model
You can link a user's input to form data by referencing the data in a `v-model` directive.
```vue-html{2}
-
+
```
-
+
## Input icons
Add a [Bootstrap icon](https://icons.getbootstrap.com/) to an input to make its purpose more visually clear.
```vue-html{3}
-
+
```
-
+
## Input-right slot
You can add a template on the right-hand side of the input to guide the user's input.
```vue-html{2-4}
-
+
suffix
-
+
```
-
+
suffix
-
+
diff --git a/front/ui-docs/components/ui/layout.md b/front/ui-docs/components/ui/layout.md
index 698adbf95..3eecc4cc2 100644
--- a/front/ui-docs/components/ui/layout.md
+++ b/front/ui-docs/components/ui/layout.md
@@ -1,15 +1,17 @@
# Layout
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.
-
-
+
+
Items are laid out in a row and wrapped as they overflow the container.
By default, all items in a row assume the same (maximum) height.
@@ -23,7 +25,7 @@ By default, all items in a row assume the same (maximum) height.
```
-
+
@@ -37,22 +39,20 @@ By default, all items in a row assume the same (maximum) height.
Find a list of all styles here: [Flexbox guide on css-tricks.com](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
-
-