summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/components/form/input.vue2
-rw-r--r--src/client/components/form/select.vue65
-rw-r--r--src/client/components/form/textarea.vue2
-rw-r--r--src/client/components/ui/menu.vue5
-rw-r--r--src/client/components/ui/popup-menu.vue6
-rw-r--r--src/client/os.ts7
6 files changed, 75 insertions, 12 deletions
diff --git a/src/client/components/form/input.vue b/src/client/components/form/input.vue
index d7b6f77519..591eda9ed5 100644
--- a/src/client/components/form/input.vue
+++ b/src/client/components/form/input.vue
@@ -33,7 +33,7 @@
<script lang="ts">
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
-import MkButton from '../ui/button.vue';
+import MkButton from '@client/components/ui/button.vue';
import { debounce } from 'throttle-debounce';
export default defineComponent({
diff --git a/src/client/components/form/select.vue b/src/client/components/form/select.vue
index 257e2cc990..30ccfd312b 100644
--- a/src/client/components/form/select.vue
+++ b/src/client/components/form/select.vue
@@ -1,9 +1,9 @@
<template>
<div class="vblkjoeq">
<div class="label" @click="focus"><slot name="label"></slot></div>
- <div class="input" :class="{ inline, disabled, focused }">
+ <div class="input" :class="{ inline, disabled, focused }" @click.prevent="onClick" ref="container">
<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
- <select ref="inputEl"
+ <select class="select" ref="inputEl"
v-model="v"
:disabled="disabled"
:required="required"
@@ -25,7 +25,8 @@
<script lang="ts">
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
-import MkButton from '../ui/button.vue';
+import MkButton from '@client/components/ui/button.vue';
+import * as os from '@client/os';
export default defineComponent({
components: {
@@ -81,6 +82,7 @@ export default defineComponent({
const inputEl = ref(null);
const prefixEl = ref(null);
const suffixEl = ref(null);
+ const container = ref(null);
const focus = () => inputEl.value.focus();
const onInput = (ev) => {
@@ -132,6 +134,47 @@ export default defineComponent({
});
});
+ const onClick = (ev: MouseEvent) => {
+ focused.value = true;
+
+ const menu = [];
+ let options = context.slots.default();
+
+ for (const optionOrOptgroup of options) {
+ if (optionOrOptgroup.type === 'optgroup') {
+ const optgroup = optionOrOptgroup;
+ menu.push({
+ type: 'label',
+ text: optgroup.props.label,
+ });
+ for (const option of optgroup.children) {
+ menu.push({
+ text: option.children,
+ active: v.value === option.props.value,
+ action: () => {
+ v.value = option.props.value;
+ },
+ });
+ }
+ } else {
+ const option = optionOrOptgroup;
+ menu.push({
+ text: option.children,
+ active: v.value === option.props.value,
+ action: () => {
+ v.value = option.props.value;
+ },
+ });
+ }
+ }
+
+ os.popupMenu(menu, container.value, {
+ width: container.value.offsetWidth,
+ }).then(() => {
+ focused.value = false;
+ });
+ };
+
return {
v,
focused,
@@ -141,8 +184,10 @@ export default defineComponent({
inputEl,
prefixEl,
suffixEl,
+ container,
focus,
onInput,
+ onClick,
updated,
};
},
@@ -174,8 +219,15 @@ export default defineComponent({
> .input {
$height: 42px;
position: relative;
+ cursor: pointer;
- > select {
+ &:hover {
+ > .select {
+ border-color: var(--inputBorderHover);
+ }
+ }
+
+ > .select {
appearance: none;
-webkit-appearance: none;
display: block;
@@ -195,10 +247,7 @@ export default defineComponent({
box-sizing: border-box;
cursor: pointer;
transition: border-color 0.1s ease-out;
-
- &:hover {
- border-color: var(--inputBorderHover);
- }
+ pointer-events: none;
}
> .prefix,
diff --git a/src/client/components/form/textarea.vue b/src/client/components/form/textarea.vue
index 50be69f930..048e9032df 100644
--- a/src/client/components/form/textarea.vue
+++ b/src/client/components/form/textarea.vue
@@ -26,7 +26,7 @@
<script lang="ts">
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
-import MkButton from '../ui/button.vue';
+import MkButton from '@client/components/ui/button.vue';
import { debounce } from 'throttle-debounce';
export default defineComponent({
diff --git a/src/client/components/ui/menu.vue b/src/client/components/ui/menu.vue
index da24d90170..aaef527f1a 100644
--- a/src/client/components/ui/menu.vue
+++ b/src/client/components/ui/menu.vue
@@ -1,5 +1,6 @@
<template>
<div class="rrevdjwt" :class="{ center: align === 'center' }"
+ :style="{ width: width ? width + 'px' : null }"
ref="items"
@contextmenu.self="e => e.preventDefault()"
v-hotkey="keymap"
@@ -59,6 +60,10 @@ export default defineComponent({
type: String,
requried: false
},
+ width: {
+ type: Number,
+ required: false
+ },
},
emits: ['close'],
data() {
diff --git a/src/client/components/ui/popup-menu.vue b/src/client/components/ui/popup-menu.vue
index 23f7c89f3b..3ff4c658b1 100644
--- a/src/client/components/ui/popup-menu.vue
+++ b/src/client/components/ui/popup-menu.vue
@@ -1,6 +1,6 @@
<template>
<MkPopup ref="popup" :src="src" @closed="$emit('closed')">
- <MkMenu :items="items" :align="align" @close="$refs.popup.close()" class="_popup _shadow"/>
+ <MkMenu :items="items" :align="align" :width="width" @close="$refs.popup.close()" class="_popup _shadow"/>
</MkPopup>
</template>
@@ -24,6 +24,10 @@ export default defineComponent({
type: String,
required: false
},
+ width: {
+ type: Number,
+ required: false
+ },
viaKeyboard: {
type: Boolean,
required: false
diff --git a/src/client/os.ts b/src/client/os.ts
index 7ae774dd92..743d2d131f 100644
--- a/src/client/os.ts
+++ b/src/client/os.ts
@@ -372,12 +372,17 @@ export async function openEmojiPicker(src?: HTMLElement, opts, initialTextarea:
});
}
-export function popupMenu(items: any[] | Ref<any[]>, src?: HTMLElement, options?: { align?: string; viaKeyboard?: boolean }) {
+export function popupMenu(items: any[] | Ref<any[]>, src?: HTMLElement, options?: {
+ align?: string;
+ width?: number;
+ viaKeyboard?: boolean;
+}) {
return new Promise((resolve, reject) => {
let dispose;
popup(import('@client/components/ui/popup-menu.vue'), {
items,
src,
+ width: options?.width,
align: options?.align,
viaKeyboard: options?.viaKeyboard
}, {