Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 53 additions & 38 deletions docs/components/input.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script setup>
import FwbInputExample from './input/examples/FwbInputExample.vue'
import FwbInputExampleSize from './input/examples/FwbInputExampleSize.vue'
import FwbInputExampleDisabled from './input/examples/FwbInputExampleDisabled.vue'
import FwbInputExampleHelper from './input/examples/FwbInputExampleHelper.vue'
import FwbInputExampleBlockClasses from './input/examples/FwbInputExampleBlockClasses.vue'
import FwbInputExamplePrefix from './input/examples/FwbInputExamplePrefix.vue'
import FwbInputExampleSuffix from './input/examples/FwbInputExampleSuffix.vue'
import FwbInputExampleRequired from './input/examples/FwbInputExampleRequired.vue'
import FwbInputExampleSize from './input/examples/FwbInputExampleSize.vue'
import FwbInputExampleStyling from './input/examples/FwbInputExampleStyling.vue'
import FwbInputExampleSuffix from './input/examples/FwbInputExampleSuffix.vue'
import FwbInputExampleValidation from './input/examples/FwbInputExampleValidation.vue'
</script>

Expand Down Expand Up @@ -104,33 +104,6 @@ const name = ref('')
</script>
```

## Extra CSS classes

Sometimes it is required to add some customization to the input or the input wrapper.
By default, `class` attribute is bound to the input element. To customize the input wrapper you can use the `block-classes` property.
It accepts the values as the `class` attribute

<fwb-input-example-block-classes />
```vue
<template>
<fwb-input
v-model="name"
label="First name"
placeholder="enter your first name"
required
class="bg-green-200"
block-classes="border-2 border-green-500 p-2 rounded-lg"
/>
</template>

<script setup>
import { ref } from 'vue'
import { FwbInput } from 'flowbite-vue'

const name = ref('')
</script>
```

## Slot - Helper

<fwb-input-example-helper />
Expand Down Expand Up @@ -218,22 +191,26 @@ const query = ref('')
```vue
<template>
<fwb-input
v-model="email"
v-model="name"
label="Your name"
placeholder="Success input"
required
placeholder="enter your email address"
label="Email"
validation-status="success"
/>
>
<template #validationMessage>
<span class="font-medium">Well done!</span> Some success message.
</template>
</fwb-input>
<hr class="mt-4 border-0">
<fwb-input
v-model="email"
v-model="name"
label="Your name"
placeholder="Error input"
required
placeholder="enter your email address"
label="Email"
validation-status="error"
>
<template #validationMessage>
Please enter a valid email address
<span class="font-medium">Oh, snapp!</span> Some error message.
</template>
</fwb-input>
</template>
Expand All @@ -245,3 +222,41 @@ import { FwbInput } from 'flowbite-vue'
const email = ref('')
</script>
```

## Styling Inputs

Use dedicated props to pass classes to individual elements.


<fwb-input-example-styling />
```vue
<template>
<fwb-input
v-model="name"
class="p-2 border border-black rounded-none italic text-a"
input-class="p-0 text-center text-gray-700 dark:text-gray-200"
label-class="text-center text-gray-200 dark:text-gray-400 p-2 m-0"
label="First name"
placeholder="enter your first name"
wrapper-class=" background-gray-100 dark:bg-gray-800"
/>
</template>

<script setup>
import { ref } from 'vue'
import { FwbInput } from 'flowbite-vue'

const name = ref('')
</script>
```


## Input component API

### FwbInput Props
| Name | Type | Default | Description |
| ------------ | ---------------- | ------- | ------------------------------------------------------------ |
| wrapperClass | String \| Object | `''` | Added to main component wrapper |
| labelClass | String \| Object | `''` | Added to `<label>` element. |
| class | String \| Object | `''` | Added to wrapper around `<input>` element and prefix/suffix. |
| inputClass | String \| Object | `''` | Added to `<input>` element. |
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
<div class="vp-raw">
<fwb-input
v-model="name"
class="p-2 border border-black rounded-none italic text-a"
input-class="p-0 text-center text-gray-700 dark:text-gray-200"
label-class="text-center text-gray-200 dark:text-gray-400 p-2 m-0"
label="First name"
placeholder="enter your first name"
class="bg-green-200 dark:bg-green-700"
block-classes="border-2 border-green-500 p-2 rounded-lg"
wrapper-class=" background-gray-100 dark:bg-gray-800"
/>
</div>
</template>
Expand Down
22 changes: 13 additions & 9 deletions docs/components/input/examples/FwbInputExampleValidation.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
<template>
<div class="vp-raw">
<fwb-input
v-model="email"
v-model="name"
label="Your name"
placeholder="Success input"
required
placeholder="enter your email address"
label="Email"
validation-status="success"
/>
>
<template #validationMessage>
<span class="font-medium">Well done!</span> Some success message.
</template>
</fwb-input>
<hr class="mt-4 border-0">
<fwb-input
v-model="email"
v-model="name"
label="Your name"
placeholder="Error input"
required
placeholder="enter your email address"
label="Email"
validation-status="error"
>
<template #validationMessage>
Please enter a valid email address
<span class="font-medium">Oh, snapp!</span> Some error message.
</template>
</fwb-input>
</div>
Expand All @@ -27,5 +31,5 @@ import { ref } from 'vue'

import { FwbInput } from '../../../../src/index'

const email = ref('')
const name = ref('')
</script>
66 changes: 32 additions & 34 deletions src/components/FwbInput/FwbInput.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
<template>
<div :class="blockClasses">
<div :class="wrapperClass">
<label
v-if="label"
:class="labelClasses"
:class="labelClass"
>{{ label }}</label>
<div
class="relative flex items-center"
:class="[inputBlockClasses]"
>
<div :class="inputWrapperClass">
<div
v-if="$slots.prefix"
class="ms-2 flex shrink-0 items-center"
Expand All @@ -17,11 +14,11 @@
<input
v-bind="$attrs"
v-model="model"
:autocomplete="autocomplete"
:class="inputClass"
:disabled="disabled"
:type="type"
:required="required"
:autocomplete="autocomplete"
:class="[inputClasses]"
:type="type"
>
<div
v-if="$slots.suffix"
Expand All @@ -32,69 +29,70 @@
</div>
<p
v-if="$slots.validationMessage"
:class="validationWrapperClasses"
:class="validationMessageClass"
>
<slot name="validationMessage" />
</p>
<p
v-if="$slots.helper"
class="mt-2 text-sm text-gray-500 dark:text-gray-400"
:class="helperMessageClass"
class=""
>
<slot name="helper" />
</p>
</div>
</template>

<script lang="ts" setup>
import { useVModel } from '@vueuse/core'
import { twMerge } from 'tailwind-merge'
import { computed, toRefs } from 'vue'

import { toRefs } from 'vue'

import { useInputClasses } from './composables/useInputClasses'
import {
type CommonAutoFill,
type InputSize,
type InputType,
type ValidationStatus,
validationStatusMap,
} from './types'

import type { CommonAutoFill, InputSize, InputType, ValidationStatus } from './types'

interface InputProps {
autocomplete?: CommonAutoFill
class?: string | Record<string, boolean>
disabled?: boolean
inputClass?: string | Record<string, boolean>
label?: string
labelClass?: string | Record<string, boolean>
modelValue?: string | number
required?: boolean
size?: InputSize
type?: InputType
autocomplete?: CommonAutoFill
validationStatus?: ValidationStatus
blockClasses?: string | string[] | Record<string, unknown>
wrapperClass?: string | Record<string, boolean>
}

defineOptions({
inheritAttrs: false,
})

const props = withDefaults(defineProps<InputProps>(), {
autocomplete: 'off',
class: '',
disabled: false,
inputClass: '',
label: '',
labelClass: '',
modelValue: '',
required: false,
size: 'md',
type: 'text',
autocomplete: 'off',
validationStatus: undefined,
blockClasses: undefined,
wrapperClass: '',
})

const model = useVModel(props, 'modelValue')

const { inputClasses, inputBlockClasses, labelClasses } = useInputClasses(toRefs(props))

const validationWrapperClasses = computed(() => twMerge(
'mt-2 text-sm',
props.validationStatus === validationStatusMap.Success ? 'text-green-600 dark:text-green-500' : '',
props.validationStatus === validationStatusMap.Error ? 'text-red-600 dark:text-red-500' : '',
const model = defineModel({ type: String })

))
const {
wrapperClass,
helperMessageClass,
validationMessageClass,
labelClass,
inputWrapperClass,
inputClass,
} = useInputClasses(toRefs(props))
</script>
Loading
Loading