feat : ajouts du composant input text area et fix sur le input text
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<div class="grid grid-cols-1 items-start gap-6 md:grid-cols-2">
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Simple</h2>
|
||||
<MalioInputText v-model="simpleValue"/>
|
||||
<MalioInputText/>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
@@ -16,7 +16,7 @@
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Avec icône</h2>
|
||||
<h2 class="mb-4 text-xl font-bold">Avec icône à droite</h2>
|
||||
<MalioInputText
|
||||
v-model="searchValue"
|
||||
label="Recherche"
|
||||
@@ -25,6 +25,16 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Avec icône à gauche</h2>
|
||||
<MalioInputText
|
||||
label="Recherche"
|
||||
icon-name="mdi:magnify"
|
||||
icon-size="20"
|
||||
icon-position="left"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Désactivé</h2>
|
||||
<MalioInputText
|
||||
@@ -142,7 +152,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const simpleValue = ref('')
|
||||
import { computed, ref } from 'vue'
|
||||
const nameValue = ref('')
|
||||
const searchValue = ref('')
|
||||
const codeValue = ref('')
|
||||
|
||||
104
.playground/pages/composant/inputTextArea.vue
Normal file
104
.playground/pages/composant/inputTextArea.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="grid grid-cols-1 items-start gap-6 p-4 md:grid-cols-2">
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Simple</h2>
|
||||
<MalioInputTextArea/>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Avec label + hint</h2>
|
||||
<MalioInputTextArea
|
||||
v-model="hintValue"
|
||||
label="Description"
|
||||
hint="Ajoutez un contexte clair"
|
||||
:size="4"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Avec icône</h2>
|
||||
<MalioInputTextArea
|
||||
v-model="iconValue"
|
||||
label="Commentaire"
|
||||
icon-name="mdi:comment-text-outline"
|
||||
:size="3"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Erreur / Succès</h2>
|
||||
<div class="space-y-4">
|
||||
<MalioInputTextArea
|
||||
v-model="errorValue"
|
||||
label="Message"
|
||||
error="Le message est trop court"
|
||||
:size="3"
|
||||
/>
|
||||
<MalioInputTextArea
|
||||
v-model="successValue"
|
||||
label="Message"
|
||||
success="Message valide"
|
||||
:size="3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Readonly / Disabled</h2>
|
||||
<div class="space-y-4">
|
||||
<MalioInputTextArea
|
||||
model-value="Contenu en lecture seule"
|
||||
label="Readonly"
|
||||
readonly
|
||||
:size="3"
|
||||
/>
|
||||
<MalioInputTextArea
|
||||
model-value="Champ indisponible"
|
||||
label="Disabled"
|
||||
disabled
|
||||
:size="3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Resize avec limites</h2>
|
||||
<MalioInputTextArea
|
||||
v-model="resizeValue"
|
||||
label="Notes"
|
||||
resize="both"
|
||||
:size="4"
|
||||
:min-resize-width="300"
|
||||
:max-resize-width="700"
|
||||
:min-resize-height="120"
|
||||
:max-resize-height="280"
|
||||
hint="Resize limite en largeur et hauteur"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="rounded-lg border p-4">
|
||||
<h2 class="mb-4 text-xl font-bold">Compteur (interne au composant)</h2>
|
||||
<MalioInputTextArea
|
||||
v-model="counterValue"
|
||||
label="Message"
|
||||
:size="5"
|
||||
:max-length="120"
|
||||
:show-counter="true"
|
||||
hint="Le compteur est en bas a gauche"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref} from 'vue'
|
||||
import MalioInputTextArea from '../../../app/components/malio/InputTextArea.vue'
|
||||
|
||||
const hintValue = ref('')
|
||||
const iconValue = ref('')
|
||||
const errorValue = ref('abc')
|
||||
const successValue = ref('Contenu ok')
|
||||
const resizeValue = ref('Vous pouvez redimensionner ce champ.')
|
||||
const counterValue = ref('')
|
||||
|
||||
</script>
|
||||
@@ -15,7 +15,7 @@
|
||||
:key="item.name"
|
||||
type="button"
|
||||
class="rounded px-3 py-2 text-left text-black font-bold hover:bg-m-primary hover:text-white"
|
||||
:class="selectedName === item.name ? 'bg-m-secondary text-white ' : ''"
|
||||
:class="selectedName === item.name ? 'bg-m-secondary text-white' : ''"
|
||||
@click="selectOrToggle(item.name)"
|
||||
>
|
||||
{{ item.label }}
|
||||
@@ -32,10 +32,13 @@
|
||||
v-else-if="selectedName"
|
||||
class="text-gray-700"
|
||||
>
|
||||
Page de demo introuvable: <code>.playground/pages/composant/{{ selectedDemoFileName }}.vue</code>
|
||||
Page de demo introuvable:
|
||||
<code>.playground/pages/composant/{{ selectedDemoFileName }}.vue</code>
|
||||
</p>
|
||||
<div v-else>
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Playground composants</h1>
|
||||
<h1 class="text-2xl font-semibold text-gray-900">
|
||||
Playground composants
|
||||
</h1>
|
||||
<p class="mt-2 text-gray-600">
|
||||
Selectionne un composant dans la liste pour afficher sa page de demo.
|
||||
</p>
|
||||
@@ -45,6 +48,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch, shallowRef } from 'vue'
|
||||
|
||||
type LoadedModule = {
|
||||
default: unknown
|
||||
}
|
||||
@@ -52,40 +57,42 @@ type LoadedModule = {
|
||||
type Item = {
|
||||
name: string
|
||||
label: string
|
||||
demoComponent?: unknown
|
||||
}
|
||||
|
||||
const componentModules = import.meta.glob('../../app/components/malio/*.vue', { eager: true }) as Record<string, LoadedModule>
|
||||
const demoModules = import.meta.glob('./composant/*.vue', { eager: true }) as Record<string, LoadedModule>
|
||||
const componentModules = import.meta.glob('../../app/components/malio/*.vue')
|
||||
const demoModules = import.meta.glob('./composant/*.vue')
|
||||
|
||||
const demoByName = Object.fromEntries(
|
||||
Object.entries(demoModules).map(([file, mod]) => {
|
||||
const demoByName: Record<string, () => Promise<LoadedModule>> =
|
||||
Object.fromEntries(
|
||||
Object.entries(demoModules).map(([file, loader]) => {
|
||||
const name = file.split('/').pop()?.replace('.vue', '') ?? ''
|
||||
return [name.toLowerCase(), loader as () => Promise<LoadedModule>]
|
||||
}),
|
||||
)
|
||||
|
||||
const items = computed<Item[]>(() =>
|
||||
Object.keys(componentModules).map((file) => {
|
||||
const name = file.split('/').pop()?.replace('.vue', '') ?? ''
|
||||
return [name.toLowerCase(), mod.default]
|
||||
}),
|
||||
)
|
||||
|
||||
const items = computed(() =>
|
||||
Object.entries(componentModules).map(([file]) => {
|
||||
const name = file.split('/').pop()?.replace('.vue', '') ?? ''
|
||||
|
||||
return {
|
||||
name,
|
||||
label: name,
|
||||
demoComponent: demoByName[name.toLowerCase()],
|
||||
}
|
||||
}) as Item[],
|
||||
}),
|
||||
)
|
||||
|
||||
const selectedName = ref('')
|
||||
const hasInitializedSelection = ref(false)
|
||||
|
||||
watchEffect(() => {
|
||||
if (!hasInitializedSelection.value && items.value.length > 0) {
|
||||
selectedName.value = items.value[0].name
|
||||
hasInitializedSelection.value = true
|
||||
}
|
||||
})
|
||||
watch(
|
||||
items,
|
||||
(val) => {
|
||||
if (!hasInitializedSelection.value && val.length > 0) {
|
||||
selectedName.value = val[0].name
|
||||
hasInitializedSelection.value = true
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
function selectOrToggle(name: string) {
|
||||
selectedName.value = selectedName.value === name ? '' : name
|
||||
@@ -95,9 +102,23 @@ function clearSelection() {
|
||||
selectedName.value = ''
|
||||
}
|
||||
|
||||
const selectedDemoComponent = computed(() =>
|
||||
items.value.find((item) => item.name === selectedName.value)?.demoComponent,
|
||||
)
|
||||
const selectedDemoComponent = shallowRef<unknown>(null)
|
||||
|
||||
watch(selectedName, async (name) => {
|
||||
if (!name) {
|
||||
selectedDemoComponent.value = null
|
||||
return
|
||||
}
|
||||
|
||||
const loader = demoByName[name.toLowerCase()]
|
||||
if (!loader) {
|
||||
selectedDemoComponent.value = null
|
||||
return
|
||||
}
|
||||
|
||||
const mod = await loader()
|
||||
selectedDemoComponent.value = mod.default
|
||||
})
|
||||
|
||||
const selectedDemoFileName = computed(() => {
|
||||
const name = selectedName.value
|
||||
|
||||
Reference in New Issue
Block a user