feat(component): New component textarea
This commit is contained in:
@@ -68,6 +68,7 @@ function getFormComponents() {
|
||||
{ text: 'Checkbox', link: 'components/checkbox' },
|
||||
{ text: 'Select', link: 'components/select' },
|
||||
{ text: 'Toggle', link: 'components/toggle' },
|
||||
{ text: 'Textarea', link: 'components/textarea' },
|
||||
{ text: 'Range', link: 'components/range' },
|
||||
{ text: 'Radio', link: 'components/radio' },
|
||||
]
|
||||
|
||||
65
docs/components/textarea.md
Normal file
65
docs/components/textarea.md
Normal file
@@ -0,0 +1,65 @@
|
||||
<script setup>
|
||||
import DefaultTextarea from './textarea/examples/DefaultTextarea.vue'
|
||||
import CommentTextarea from './textarea/examples/CommentTextarea.vue'
|
||||
</script>
|
||||
|
||||
# Vue Textarea - Flowbite
|
||||
|
||||
#### Use the textarea component as a multi-line text field input and use it inside form elements available in multiple sizes, styles, and variants
|
||||
|
||||
---
|
||||
|
||||
:::tip
|
||||
Original reference: [https://flowbite.com/docs/forms/textarea/](https://flowbite.com/docs/forms/textarea/)
|
||||
:::
|
||||
|
||||
## Textarea example
|
||||
|
||||
Get started with the default example of a textarea component below.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<Textarea rows="4" placeholder="Write you message..." v-model="message" label="Your message" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import Textarea from 'flowbite-vue'
|
||||
|
||||
const message = ref('')
|
||||
</script>
|
||||
|
||||
```
|
||||
<DefaultTextarea />
|
||||
|
||||
## Comment box
|
||||
|
||||
Most often the textarea component is used as the main text field input element in comment sections. Use this example to also apply a helper text and buttons below the textarea itself.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<form>
|
||||
<Textarea custom rows="3" placeholder="Write you message..." label="Your message">
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-between">
|
||||
<Button type="submit">Post comment</Button>
|
||||
<div class="flex">
|
||||
<Button color="" class="rounded-lg hover:bg-gray-200 hover:dark:bg-gray-600" square><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M18.375 12.739l-7.693 7.693a4.5 4.5 0 01-6.364-6.364l10.94-10.94A3 3 0 1119.5 7.372L8.552 18.32m.009-.01l-.01.01m5.699-9.941l-7.81 7.81a1.5 1.5 0 002.112 2.13" /></svg></Button>
|
||||
<Button color="" class="rounded-lg hover:bg-gray-200 hover:dark:bg-gray-600" square><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z" /><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1115 0z" /></svg></Button>
|
||||
<Button color="" class="rounded-lg hover:bg-gray-200 hover:dark:bg-gray-600" square><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" /></svg></Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Textarea>
|
||||
</form>
|
||||
<p class="ml-auto text-xs text-gray-500 dark:text-gray-400">Remember, contributions to this topic should follow our <a href="/" class="text-primary-600 dark:text-primary-500 hover:underline">Community Guidelines</a>.</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Button, Textarea } from 'flowbite-vue'
|
||||
</script>
|
||||
```
|
||||
|
||||
<CommentTextarea />
|
||||
27
docs/components/textarea/examples/CommentTextarea.vue
Normal file
27
docs/components/textarea/examples/CommentTextarea.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div>
|
||||
<form>
|
||||
<Textarea custom rows="3" placeholder="Write you message..." v-model="message" label="Your message">
|
||||
<template #footer>
|
||||
<div class="flex items-center justify-between">
|
||||
<Button type="submit">Post comment</Button>
|
||||
<div class="flex">
|
||||
<Button color="" class="rounded-lg hover:bg-gray-200 hover:dark:bg-gray-600" square><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M18.375 12.739l-7.693 7.693a4.5 4.5 0 01-6.364-6.364l10.94-10.94A3 3 0 1119.5 7.372L8.552 18.32m.009-.01l-.01.01m5.699-9.941l-7.81 7.81a1.5 1.5 0 002.112 2.13" /></svg></Button>
|
||||
<Button color="" class="rounded-lg hover:bg-gray-200 hover:dark:bg-gray-600" square><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z" /><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1115 0z" /></svg></Button>
|
||||
<Button color="" class="rounded-lg hover:bg-gray-200 hover:dark:bg-gray-600" square><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" /></svg></Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Textarea>
|
||||
</form>
|
||||
<p class="ml-auto text-xs text-gray-500 dark:text-gray-400">Remember, contributions to this topic should follow our <a href="/" class="text-primary-600 dark:text-primary-500 hover:underline">Community Guidelines</a>.</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import Textarea from '../../../../src/components/Textarea/Textarea.vue'
|
||||
import Button from '../../../../src/components/Button/Button.vue'
|
||||
|
||||
const message = ref('')
|
||||
</script>
|
||||
12
docs/components/textarea/examples/DefaultTextarea.vue
Normal file
12
docs/components/textarea/examples/DefaultTextarea.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
<Textarea rows="4" placeholder="Write you message..." v-model="message" label="Your message" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import Textarea from '../../../../src/components/Textarea/Textarea.vue'
|
||||
|
||||
const message = ref('')
|
||||
</script>
|
||||
49
src/components/Textarea/Textarea.vue
Normal file
49
src/components/Textarea/Textarea.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<label>
|
||||
<div :class="labelClasses">{{ label }}</div>
|
||||
<div :class="wrapperClasses">
|
||||
<textarea v-model="model" :rows="rows" :class="textareaClasses" :placeholder="placeholder"></textarea>
|
||||
<div v-if="$slots.footer" :class="footerClasses">
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useTextareaClasses } from './composables/useTextareaClasses'
|
||||
|
||||
interface TextareaProps {
|
||||
modelValue?: string;
|
||||
label?: string;
|
||||
rows?: number;
|
||||
custom?: boolean;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<TextareaProps>(), {
|
||||
value: '',
|
||||
label: 'Your message',
|
||||
rows: 4,
|
||||
custom: false,
|
||||
placeholder: 'Write your message here...',
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const model = computed({
|
||||
get() {
|
||||
return props.modelValue
|
||||
},
|
||||
set(val) {
|
||||
emit('update:modelValue', val)
|
||||
},
|
||||
})
|
||||
|
||||
const {
|
||||
textareaClasses,
|
||||
labelClasses,
|
||||
wrapperClasses,
|
||||
footerClasses,
|
||||
} = useTextareaClasses(props.custom)
|
||||
</script>
|
||||
33
src/components/Textarea/composables/useTextareaClasses.ts
Normal file
33
src/components/Textarea/composables/useTextareaClasses.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { simplifyTailwindClasses } from '@/utils/simplifyTailwindClasses'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const textareaWrapperClasses = 'w-full mb-4 border border-gray-200 rounded-lg bg-gray-50 dark:bg-gray-700 dark:border-gray-600'
|
||||
const textareaDefaultClasses = 'block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-200 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'
|
||||
const textareaLabelClasses = 'block mb-2 text-sm font-medium text-gray-900 dark:text-white'
|
||||
const textareaFooterClasses = 'py-2 px-3 border-gray-200 dark:border-gray-600'
|
||||
|
||||
export function useTextareaClasses(custom: boolean) {
|
||||
const textareaClasses = computed(() => {
|
||||
return simplifyTailwindClasses(textareaDefaultClasses, custom? 'bg-white dark:bg-gray-800 border-none': 'border')
|
||||
})
|
||||
|
||||
const labelClasses = computed(() => {
|
||||
return textareaLabelClasses
|
||||
})
|
||||
|
||||
const wrapperClasses = computed(() => {
|
||||
if(custom) return textareaWrapperClasses
|
||||
return ''
|
||||
})
|
||||
|
||||
const footerClasses = computed(() => {
|
||||
return textareaFooterClasses
|
||||
})
|
||||
|
||||
return {
|
||||
textareaClasses,
|
||||
labelClasses,
|
||||
wrapperClasses,
|
||||
footerClasses,
|
||||
}
|
||||
}
|
||||
@@ -62,4 +62,6 @@ export { default as Range } from './components/Range/Range.vue'
|
||||
|
||||
export { default as Radio } from './components/Radio/Radio.vue'
|
||||
|
||||
export { default as Textarea } from './components/Textarea/Textarea.vue'
|
||||
|
||||
export * from './composables'
|
||||
|
||||
Reference in New Issue
Block a user