fix: emit events across the app (#10227)
This PR makes the following changes 1. Update v-model bindings for components using the old `value` prop and `input` event method 2. Remove components that were not used anywhere --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
@@ -84,10 +84,10 @@ const shouldShowEmptyState = computed(() => {
|
|||||||
<slot name="search">
|
<slot name="search">
|
||||||
<DropdownSearch
|
<DropdownSearch
|
||||||
v-if="enableSearch"
|
v-if="enableSearch"
|
||||||
:input-value="searchTerm"
|
v-model="searchTerm"
|
||||||
:input-placeholder="inputPlaceholder"
|
:input-placeholder="inputPlaceholder"
|
||||||
:show-clear-filter="showClearFilter"
|
:show-clear-filter="showClearFilter"
|
||||||
@input="onSearch"
|
@update:model-value="onSearch"
|
||||||
@remove="$emit('removeFilter')"
|
@remove="$emit('removeFilter')"
|
||||||
/>
|
/>
|
||||||
</slot>
|
</slot>
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { defineEmits } from 'vue';
|
import { defineEmits, defineModel } from 'vue';
|
||||||
defineProps({
|
defineProps({
|
||||||
inputValue: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
inputPlaceholder: {
|
inputPlaceholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
@@ -15,7 +11,12 @@ defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['input', 'remove']);
|
const emit = defineEmits(['remove']);
|
||||||
|
|
||||||
|
const value = defineModel({
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -29,16 +30,15 @@ const emit = defineEmits(['input', 'remove']);
|
|||||||
class="text-slate-400 dark:text-slate-400 flex-shrink-0"
|
class="text-slate-400 dark:text-slate-400 flex-shrink-0"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
|
v-model="value"
|
||||||
|
:placeholder="inputPlaceholder"
|
||||||
type="text"
|
type="text"
|
||||||
class="w-full mb-0 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-slate-75 reset-base"
|
class="w-full mb-0 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-slate-75 reset-base"
|
||||||
:placeholder="inputPlaceholder"
|
|
||||||
:value="inputValue"
|
|
||||||
@input="emit('input', $event.target.value)"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- Clear filter button -->
|
<!-- Clear filter button -->
|
||||||
<woot-button
|
<woot-button
|
||||||
v-if="!inputValue && showClearFilter"
|
v-if="!modelValue && showClearFilter"
|
||||||
size="small"
|
size="small"
|
||||||
variant="clear"
|
variant="clear"
|
||||||
color-scheme="primary"
|
color-scheme="primary"
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
// The value types are dynamic, hence prop validation removed to work with our action schema
|
props: {
|
||||||
// eslint-disable-next-line vue/require-prop-types
|
teams: { type: Array, required: true },
|
||||||
props: ['teams', 'value'],
|
modelValue: { type: Object, required: true },
|
||||||
emits: ['input'],
|
},
|
||||||
|
emits: ['update:modelValue'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedTeams: [],
|
selectedTeams: [],
|
||||||
@@ -11,13 +12,13 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
const { team_ids: teamIds } = this.value;
|
const { team_ids: teamIds } = this.modelValue;
|
||||||
this.selectedTeams = teamIds;
|
this.selectedTeams = teamIds;
|
||||||
this.message = this.value.message;
|
this.message = this.modelValue.message;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateValue() {
|
updateValue() {
|
||||||
this.$emit('input', {
|
this.$emit('update:modelValue', {
|
||||||
team_ids: this.selectedTeams.map(team => team.id),
|
team_ids: this.selectedTeams.map(team => team.id),
|
||||||
message: this.message,
|
message: this.message,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default {
|
|||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ['input', 'openPopover', 'openModal'],
|
emits: ['openPopover', 'openModal'],
|
||||||
computed: {
|
computed: {
|
||||||
hasCategory() {
|
hasCategory() {
|
||||||
return (
|
return (
|
||||||
@@ -50,9 +50,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onSearch(value) {
|
|
||||||
this.$emit('input', value);
|
|
||||||
},
|
|
||||||
openPortalPopover() {
|
openPortalPopover() {
|
||||||
this.$emit('openPopover');
|
this.$emit('openPopover');
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
<script>
|
|
||||||
export default {
|
|
||||||
emits: ['input'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchValue: '',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onSearch(e) {
|
|
||||||
this.$emit('input', e.target.value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="search-input--wrap">
|
|
||||||
<div class="search-icon--wrap">
|
|
||||||
<fluent-icon icon="search" size="18" class="search-icon" />
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
v-model="searchValue"
|
|
||||||
class="search-input"
|
|
||||||
:placeholder="$t('HELP_CENTER.SIDEBAR.SEARCH.PLACEHOLDER')"
|
|
||||||
@input="onSearch"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.search-input--wrap {
|
|
||||||
display: flex;
|
|
||||||
padding: var(--space-small) var(--space-zero);
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-input {
|
|
||||||
width: 100%;
|
|
||||||
height: var(--space-large);
|
|
||||||
border-radius: var(--border-radius-normal);
|
|
||||||
background: var(--s-25);
|
|
||||||
font-size: var(--font-size-small);
|
|
||||||
padding: var(--space-small) var(--space-small) var(--space-small)
|
|
||||||
var(--space-large);
|
|
||||||
border: 1px solid var(--s-50);
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
border-color: var(--w-500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-icon--wrap {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-icon {
|
|
||||||
position: absolute;
|
|
||||||
color: var(--s-500);
|
|
||||||
top: var(--space-small);
|
|
||||||
left: var(--space-small);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -5,12 +5,12 @@ import { mapGetters } from 'vuex';
|
|||||||
export default {
|
export default {
|
||||||
components: { LoadingState },
|
components: { LoadingState },
|
||||||
props: {
|
props: {
|
||||||
value: {
|
modelValue: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ['input'],
|
emits: ['update:modelValue'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
iframeLoading: true,
|
iframeLoading: true,
|
||||||
@@ -30,7 +30,7 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const csmlContent = e.data.replace('chatwoot-csml-editor:update', '');
|
const csmlContent = e.data.replace('chatwoot-csml-editor:update', '');
|
||||||
this.$emit('input', csmlContent);
|
this.$emit('update:modelValue', csmlContent);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -38,7 +38,7 @@ export default {
|
|||||||
const frameElement = document.getElementById(`csml-editor--frame`);
|
const frameElement = document.getElementById(`csml-editor--frame`);
|
||||||
const eventData = {
|
const eventData = {
|
||||||
event: 'editorContext',
|
event: 'editorContext',
|
||||||
data: this.value || '',
|
data: this.modelValue || '',
|
||||||
};
|
};
|
||||||
frameElement.contentWindow.postMessage(JSON.stringify(eventData), '*');
|
frameElement.contentWindow.postMessage(JSON.stringify(eventData), '*');
|
||||||
this.iframeLoading = false;
|
this.iframeLoading = false;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
value: {
|
modelValue: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
@@ -20,9 +20,9 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['input']);
|
const emit = defineEmits(['update:modelValue', 'input']);
|
||||||
|
|
||||||
const localValue = ref(props.value);
|
const localValue = ref(props.modelValue);
|
||||||
const localFlags = ref(props.selectedFlags);
|
const localFlags = ref(props.selectedFlags);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -33,6 +33,7 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleInput = e => {
|
const handleInput = e => {
|
||||||
|
emit('update:modelValue', props.type, e);
|
||||||
emit('input', props.type, e);
|
emit('input', props.type, e);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -257,8 +257,8 @@ export default {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<FormSwitch
|
<FormSwitch
|
||||||
:value="hasEnabledPushPermissions"
|
:model-value="hasEnabledPushPermissions"
|
||||||
@input="onRequestPermissions"
|
@update:model-value="onRequestPermissions"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
<script>
|
|
||||||
import WithLabel from './WithLabel.vue';
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
WithLabel,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
options: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
hasError: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
errorMessage: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: ['input'],
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<WithLabel
|
|
||||||
:label="label"
|
|
||||||
:name="name"
|
|
||||||
:has-error="hasError"
|
|
||||||
:error-message="errorMessage"
|
|
||||||
>
|
|
||||||
<div class="flex flex-wrap gap-2">
|
|
||||||
<woot-button
|
|
||||||
v-for="option in options"
|
|
||||||
:key="option.value"
|
|
||||||
:variant="value === option.value ? '' : 'hollow'"
|
|
||||||
:color-scheme="value === option.value ? 'primary' : 'secondary'"
|
|
||||||
size="small"
|
|
||||||
@click="$emit('input', option.value)"
|
|
||||||
>
|
|
||||||
{{ option.label }}
|
|
||||||
</woot-button>
|
|
||||||
</div>
|
|
||||||
</WithLabel>
|
|
||||||
</template>
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
value: { type: Boolean, default: false },
|
modelValue: { type: Boolean, default: false },
|
||||||
},
|
},
|
||||||
emits: ['input'],
|
emits: ['update:modelValue'],
|
||||||
methods: {
|
methods: {
|
||||||
onClick() {
|
onClick() {
|
||||||
this.$emit('input', !this.value);
|
this.$emit('update:modelValue', !this.modelValue);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -17,17 +17,19 @@ export default {
|
|||||||
type="button"
|
type="button"
|
||||||
class="relative flex-shrink-0 h-4 p-0 border-none shadow-inner w-7 rounded-3xl"
|
class="relative flex-shrink-0 h-4 p-0 border-none shadow-inner w-7 rounded-3xl"
|
||||||
:class="
|
:class="
|
||||||
value ? 'bg-primary-600 shadow-primary-800' : 'shadow-ash-400 bg-ash-200'
|
modelValue
|
||||||
|
? 'bg-primary-600 shadow-primary-800'
|
||||||
|
: 'shadow-ash-400 bg-ash-200'
|
||||||
"
|
"
|
||||||
role="switch"
|
role="switch"
|
||||||
:aria-checked="value.toString()"
|
:aria-checked="modelValue.toString()"
|
||||||
@click="onClick"
|
@click="onClick"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class="rounded-full bg-white top-0.5 absolute dark:bg-white w-3 h-3 translate-y-0 duration-200 transition-transform ease-in-out"
|
class="rounded-full bg-white top-0.5 absolute dark:bg-white w-3 h-3 translate-y-0 duration-200 transition-transform ease-in-out"
|
||||||
:class="
|
:class="
|
||||||
value
|
modelValue
|
||||||
? 'ltr:translate-x-0 rtl:translate-x-[12px]'
|
? 'ltr:translate-x-0 rtl:translate-x-[12px]'
|
||||||
: 'ltr:-translate-x-[12px] rtl:translate-x-0'
|
: 'ltr:-translate-x-[12px] rtl:translate-x-0'
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
value: {
|
modelValue: {
|
||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
@@ -46,10 +46,10 @@ export default {
|
|||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ['input', 'blur'],
|
emits: ['update:modelValue', 'blur'],
|
||||||
methods: {
|
methods: {
|
||||||
onInput(e) {
|
onInput(e) {
|
||||||
this.$emit('input', e.target.value);
|
this.$emit('update:modelValue', e.target.value);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -69,7 +69,7 @@ export default {
|
|||||||
:required="required"
|
:required="required"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:data-testid="dataTestid"
|
:data-testid="dataTestid"
|
||||||
:value="value"
|
:value="modelValue"
|
||||||
:rows="rows"
|
:rows="rows"
|
||||||
:class="{
|
:class="{
|
||||||
'focus:outline-red-600 outline-red-600': hasError,
|
'focus:outline-red-600 outline-red-600': hasError,
|
||||||
@@ -78,7 +78,7 @@ export default {
|
|||||||
'resize-none': !allowResize,
|
'resize-none': !allowResize,
|
||||||
}"
|
}"
|
||||||
class="block w-full p-3 bg-white border-none rounded-md shadow-sm appearance-none outline outline-1 focus:outline focus:outline-2 text-slate-900 dark:text-slate-100 placeholder:text-slate-400 dark:bg-slate-800"
|
class="block w-full p-3 bg-white border-none rounded-md shadow-sm appearance-none outline outline-1 focus:outline focus:outline-2 text-slate-900 dark:text-slate-100 placeholder:text-slate-400 dark:bg-slate-800"
|
||||||
@input="onInput"
|
@update:model-value="onInput"
|
||||||
@blur="$emit('blur')"
|
@blur="$emit('blur')"
|
||||||
/>
|
/>
|
||||||
</WithLabel>
|
</WithLabel>
|
||||||
|
|||||||
@@ -1,100 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { useDarkMode } from 'widget/composables/useDarkMode';
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'text',
|
|
||||||
},
|
|
||||||
placeholder: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: [String, Number],
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
helpText: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: ['input'],
|
|
||||||
setup() {
|
|
||||||
const { getThemeClass } = useDarkMode();
|
|
||||||
return { getThemeClass };
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
labelClass() {
|
|
||||||
return this.error
|
|
||||||
? `text-red-400 ${this.getThemeClass(
|
|
||||||
'text-black-800',
|
|
||||||
'dark:text-slate-50'
|
|
||||||
)}`
|
|
||||||
: `text-black-800 ${this.getThemeClass(
|
|
||||||
'text-black-800',
|
|
||||||
'dark:text-slate-50'
|
|
||||||
)}`;
|
|
||||||
},
|
|
||||||
isInputDarkOrLightMode() {
|
|
||||||
return `${this.getThemeClass(
|
|
||||||
'bg-white',
|
|
||||||
'dark:bg-slate-600'
|
|
||||||
)} ${this.getThemeClass('text-slate-700', 'dark:text-slate-50')}`;
|
|
||||||
},
|
|
||||||
inputBorderColor() {
|
|
||||||
return `${this.getThemeClass(
|
|
||||||
'border-black-200',
|
|
||||||
'dark:border-black-500'
|
|
||||||
)}`;
|
|
||||||
},
|
|
||||||
inputHasError() {
|
|
||||||
return this.error
|
|
||||||
? `border-red-200 hover:border-red-300 focus:border-red-300 ${this.isInputDarkOrLightMode}`
|
|
||||||
: `hover:border-black-300 focus:border-black-300 ${this.isInputDarkOrLightMode} ${this.inputBorderColor}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onChange(event) {
|
|
||||||
this.$emit('input', event.target.value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<label class="block">
|
|
||||||
<div
|
|
||||||
v-if="label"
|
|
||||||
class="mb-2 text-xs leading-3 font-medium"
|
|
||||||
:class="labelClass"
|
|
||||||
>
|
|
||||||
{{ label }}
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
:type="type"
|
|
||||||
class="border rounded w-full py-2 px-3 leading-tight outline-none"
|
|
||||||
:class="inputHasError"
|
|
||||||
:placeholder="placeholder"
|
|
||||||
:value="value"
|
|
||||||
@change="onChange"
|
|
||||||
/>
|
|
||||||
<div v-if="error" class="text-red-400 mt-2 text-xs leading-3 font-medium">
|
|
||||||
{{ error }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="!error && helpText"
|
|
||||||
class="text-red-400 mt-2 text-xs leading-3 font-medium"
|
|
||||||
>
|
|
||||||
{{ helpText }}
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
</template>
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { useDarkMode } from 'widget/composables/useDarkMode';
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
placeholder: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
type: [String, Number],
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: ['input'],
|
|
||||||
setup() {
|
|
||||||
const { getThemeClass } = useDarkMode();
|
|
||||||
return { getThemeClass };
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
labelClass() {
|
|
||||||
return this.error
|
|
||||||
? `text-red-400 ${this.getThemeClass(
|
|
||||||
'text-black-800',
|
|
||||||
'dark:text-slate-50'
|
|
||||||
)}`
|
|
||||||
: `text-black-800 ${this.getThemeClass(
|
|
||||||
'text-black-800',
|
|
||||||
'dark:text-slate-50'
|
|
||||||
)}`;
|
|
||||||
},
|
|
||||||
isTextAreaDarkOrLightMode() {
|
|
||||||
return `${this.getThemeClass(
|
|
||||||
'bg-white',
|
|
||||||
'dark:bg-slate-600'
|
|
||||||
)} ${this.getThemeClass('text-slate-700', 'dark:text-slate-50')}`;
|
|
||||||
},
|
|
||||||
textAreaBorderColor() {
|
|
||||||
return `${this.getThemeClass(
|
|
||||||
'border-black-200',
|
|
||||||
'dark:border-black-500'
|
|
||||||
)}`;
|
|
||||||
},
|
|
||||||
isTextAreaHasError() {
|
|
||||||
return this.error
|
|
||||||
? `border-red-200 hover:border-red-300 focus:border-red-300 ${this.isTextAreaDarkOrLightMode}`
|
|
||||||
: `hover:border-black-300 focus:border-black-300 ${this.isTextAreaDarkOrLightMode} ${this.textAreaBorderColor}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onChange(event) {
|
|
||||||
this.$emit('input', event.target.value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<label class="block">
|
|
||||||
<div
|
|
||||||
v-if="label"
|
|
||||||
class="mb-2 text-xs font-medium leading-3"
|
|
||||||
:class="labelClass"
|
|
||||||
>
|
|
||||||
{{ label }}
|
|
||||||
</div>
|
|
||||||
<textarea
|
|
||||||
class="w-full px-3 py-2 leading-tight border rounded outline-none resize-none text-slate-700"
|
|
||||||
:class="isTextAreaHasError"
|
|
||||||
:placeholder="placeholder"
|
|
||||||
:value="value"
|
|
||||||
@change="onChange"
|
|
||||||
/>
|
|
||||||
<div v-if="error" class="mt-2 text-xs font-medium leading-3 text-red-400">
|
|
||||||
{{ error }}
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
textarea {
|
|
||||||
min-height: 8rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Reference in New Issue
Block a user