From 6e69a74b75d340ff187fc2516acdff7e50e4c64c Mon Sep 17 00:00:00 2001 From: upsiflu Date: Sun, 2 Feb 2025 20:14:29 +0100 Subject: [PATCH] refactor(ui): add color and `reset` props to Input component --- front/src/components/ui/Input.vue | 49 +++++++++++---------- front/src/components/ui/input.scss | 12 +++-- front/ui-docs/components/ui/input.md | 65 +++++++++++++++++----------- 3 files changed, 76 insertions(+), 50 deletions(-) diff --git a/front/src/components/ui/Input.vue b/front/src/components/ui/Input.vue index d3edb9afd..bf17aac5f 100644 --- a/front/src/components/ui/Input.vue +++ b/front/src/components/ui/Input.vue @@ -2,13 +2,12 @@ import { computed, onMounted, ref } from 'vue' import { useI18n } from 'vue-i18n'; import onKeyboardShortcut from '~/composables/onKeyboardShortcut'; -import { color } from "~/composables/color.ts"; +import { type ColorProps, type VariantProps, type DefaultProps, type RaisedProps, type PastelProps, color } from "~/composables/color.ts"; import Button from "~/components/ui/Button.vue" import Layout from "~/components/ui/Layout.vue" -const props = withDefaults( - defineProps<{ +const { icon, placeholder, ...props } = defineProps<{ icon?: string; placeholder?: string; password?: true; @@ -16,14 +15,10 @@ const props = withDefaults( numeric?: true; label?: string; autofocus?: boolean; - raised?: boolean; - }>(), - { - raised: false, // Default value - } -); - -const { icon, placeholder, ...restProps } = props; + reset?: () => void; + } & (ColorProps | DefaultProps | PastelProps ) + & VariantProps + & RaisedProps>() // TODO(A11y): Add `inputmode="numeric" pattern="[0-9]*"` to input if model type is number: // https://technology.blog.gov.uk/2020/02/24/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers/ @@ -37,9 +32,9 @@ onKeyboardShortcut('escape', () => showPassword.value = false) // TODO: Implement `copy password` button? const attributes = computed(() => ({ - ...(restProps.password && !showPassword.value? {type: 'password'} : {}), - ...(restProps.search? {type: 'search'} : {}), - ...(restProps.numeric? {type: 'numeric'} : {}), + ...(props.password && !showPassword.value? {type: 'password'} : {}), + ...(props.search? {type: 'search'} : {}), + ...(props.numeric? {type: 'numeric'} : {}), })) const { t } = useI18n() @@ -47,10 +42,10 @@ const { t } = useI18n() const input = ref() onMounted(() => { - if (restProps.autofocus) input.value.focus(); + if (props.autofocus) input.value.focus(); }) -const model = defineModel() +const model = defineModel({ required: true }) diff --git a/front/src/components/ui/input.scss b/front/src/components/ui/input.scss index 5b7ded67e..0bef742da 100644 --- a/front/src/components/ui/input.scss +++ b/front/src/components/ui/input.scss @@ -102,17 +102,23 @@ border-bottom-left-radius: 0; } } + &:has(>.search)>input { + padding-right: 140px; + } > .show-password { justify-content:center; } - &:has(>.show-password)>input { padding-right: 40px; } - &:has(>.search)>input { - padding-right: 140px; + >.reset { + min-width: auto; + margin: 4px; + + // Make button fit snuggly into rounded border + border-radius: 4px; } } diff --git a/front/ui-docs/components/ui/input.md b/front/ui-docs/components/ui/input.md index 69a8eb200..5b16fe5ed 100644 --- a/front/ui-docs/components/ui/input.md +++ b/front/ui-docs/components/ui/input.md @@ -7,16 +7,21 @@ import Layout from "~/components/ui/Layout.vue" import Spacer from "~/components/ui/Spacer.vue" import Alert from "~/components/ui/Alert.vue" -const value = ref("Value") +const value = ref("Preset Value") +const search = ref("") +const user = ref("") +const password = ref("") + +const reset = () => { console.log("Hello"); value.value = 'Original value' } ```ts -import Input from "~/components/ui/Input.vue" +import Input from "~/components/ui/Input.vue"; ``` # Input -Inputs are areas in which users can enter information. In Funkwhale, these mostly take the form of search fields. +Inputs are areas in which users can enter a single-line text or a number. Several [presets](#presets) are available. | Prop | Data type | Required? | Description | | ------------- | --------- | --------- | --------------------------------------------------------------------------- | @@ -24,13 +29,17 @@ Inputs are areas in which users can enter information. In Funkwhale, these mostl | `icon` | String | No | The [Bootstrap icon](https://icons.getbootstrap.com/) to show on the input. | | `v-model` | String | Yes | The text entered in the input. | -You can link a user's input to form data by referencing the data in a `v-model` directive. +Link a user's input to form data by referencing the data in a `v-model` of type `string`. + +```ts +const value = ref("Preset Value"); +``` ```vue-html{2} ``` - + ## Input icons @@ -45,14 +54,14 @@ Add a [Bootstrap icon](https://icons.getbootstrap.com/) to an input to make its ## Label slot ```vue-html{2-4} - + ``` - + @@ -61,10 +70,10 @@ Add a [Bootstrap icon](https://icons.getbootstrap.com/) to an input to make its If you just have a string, we have a convenience prop, so instead you can write: ```vue-html - + ``` - + ## Input-right slot @@ -78,29 +87,33 @@ You can add a template on the right-hand side of the input to guide the user's i ``` - + +## Color + +See [Button](./button.md#button-colors) for a detailed overview of available props. + ## Presets ### Search ```vue-html - + ``` - + ### Password ```vue-html - - + + @@ -110,8 +123,8 @@ You can add a template on the right-hand side of the input to guide the user's i - - + + @@ -124,28 +137,30 @@ We use the spacer to simulate the baseline alignment on page layouts (64px betwe ::: -## Value +### Add a reset option ```vue-html - - + + ``` - - - - + + ## Fallthrough attributes If you add attributes that are no props, they will be added to the component: ```vue-html - ``` -