n8n/packages/design-system/src/components/N8nSelect/Select.vue
Mutasem Aldmour 60da5bb7ec
refactor(design-system): replace functional components (#3802)
* update creator item

* update warning tooltip

* update badge and trigger icon

* update action box

* update avatar component

* update badge

* update heading component

* update icon component

* update link component

* update menu

* update route component

* fix avatar bug

* fix avatar bug

* update input component

* update select

* update input

* update tags component

* update spinner

* update square button

* update tag component

* update text component

* add danger color

* add vue.extend

* add human readable names

* add human readable name

* revert button changes

* update name

* revert name

* update classes

* delete unused component

* redo name change

* rename

* rename back

* rename back

* update snapshots
2022-08-05 15:03:24 +02:00

182 lines
3.1 KiB
Vue

<template>
<div :class="{'n8n-select': true, [$style.container]: true, [$style.withPrepend]: !!$slots.prepend}">
<div v-if="$slots.prepend" :class="$style.prepend">
<slot name="prepend" />
</div>
<el-select
v-bind="$props"
:value="value"
:size="computedSize"
:class="$style[classes]"
:popper-class="popperClass"
v-on="$listeners"
ref="innerSelect"
>
<template #prefix>
<slot name="prefix" />
</template>
<template #suffix>
<slot name="suffix" />
</template>
<template #default>
<slot></slot>
</template>
</el-select>
</div>
</template>
<script lang="ts">
import ElSelect from 'element-ui/lib/select';
import Vue from 'vue';
interface IProps {
size?: string;
limitPopperWidth?: string;
popperClass?: string;
}
export default Vue.extend({
name: 'n8n-select',
components: {
ElSelect,
},
props: {
value: {
},
size: {
type: String,
default: 'large',
validator: (value: string): boolean =>
['mini', 'small', 'medium', 'large', 'xlarge'].includes(value),
},
placeholder: {
type: String,
},
disabled: {
type: Boolean,
},
filterable: {
type: Boolean,
},
defaultFirstOption: {
type: Boolean,
},
multiple: {
type: Boolean,
},
filterMethod: {
type: Function,
},
loading: {
type: Boolean,
},
loadingText: {
type: String,
},
popperClass: {
type: String,
},
popperAppendToBody: {
type: Boolean,
},
limitPopperWidth: {
type: Boolean,
},
noDataText: {
type: String,
},
},
computed: {
computedSize(): string | undefined {
if (this.size === 'xlarge') {
return undefined;
}
return this.size;
},
classes(): string {
if (this.size === 'xlarge') {
return 'xlarge';
}
return '';
},
popperClasses(): string {
let classes = this.popperClass || '';
if (this.limitPopperWidth) {
classes = `${classes} ${this.$style.limitPopperWidth}`;
}
return classes;
},
},
methods: {
focus() {
const input = this.$refs.innerSelect;
if (input) {
input.focus();
}
},
blur() {
const input = this.$refs.innerSelect;
if (input) {
input.blur();
}
},
focusOnInput() {
const select = (this.$refs.innerSelect) as (Vue | undefined);
if (select) {
const input = select.$refs.input;
if (input) {
input.focus();
}
}
},
},
});
</script>
<style lang="scss" module>
.xlarge {
--input-font-size: var(--font-size-m);
input {
height: 48px;
}
}
.limitPopperWidth {
width: 0;
li > span {
text-overflow: ellipsis;
overflow-x: hidden;
}
}
.container {
display: inline-flex;
width: 100%;
}
.withPrepend {
input {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
.prepend {
font-size: var(--font-size-2xs);
border: var(--border-base);
border-right: none;
display: flex;
align-items: center;
padding: 0 var(--spacing-3xs);
background-color: var(--color-background-light);
border-bottom-left-radius: var(--input-border-radius, var(--border-radius-base));
border-top-left-radius: var(--input-border-radius, var(--border-radius-base));
color: var(--color-text-base);
white-space: nowrap;
}
</style>