diff --git a/packages/frontend/src/components/MkSelect.vue b/packages/frontend/src/components/MkSelect.vue
index 63625dc125..eeadd49936 100644
--- a/packages/frontend/src/components/MkSelect.vue
+++ b/packages/frontend/src/components/MkSelect.vue
@@ -16,9 +16,8 @@ SPDX-License-Identifier: AGPL-3.0-only
@keydown.space.enter="show"
>
-
+ {{ currentValueText ?? '' }}
+
+
+
+
-
- {{ i18n.ts.save }}
@@ -44,9 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
import { onMounted, nextTick, ref, watch, computed, toRefs, VNode, useSlots, VNodeChild } from 'vue';
import { useInterval } from '@@/js/use-interval.js';
import type { MenuItem } from '@/types/menu.js';
-import MkButton from '@/components/MkButton.vue';
import * as os from '@/os.js';
-import { i18n } from '@/i18n.js';
const props = defineProps<{
modelValue: string | number | null;
@@ -56,25 +53,20 @@ const props = defineProps<{
placeholder?: string;
autofocus?: boolean;
inline?: boolean;
- manualSave?: boolean;
small?: boolean;
large?: boolean;
}>();
const emit = defineEmits<{
- (ev: 'changeByUser', value: string | number | null): void;
(ev: 'update:modelValue', value: string | number | null): void;
}>();
const slots = useSlots();
const { modelValue, autofocus } = toRefs(props);
-const v = ref(modelValue.value);
const focused = ref(false);
const opening = ref(false);
-const changed = ref(false);
-const invalid = ref(false);
-const filled = computed(() => v.value !== '' && v.value != null);
+const currentValueText = ref(null);
const inputEl = ref(null);
const prefixEl = ref(null);
const suffixEl = ref(null);
@@ -85,26 +77,6 @@ const height =
36;
const focus = () => container.value?.focus();
-const onInput = (ev) => {
- changed.value = true;
-};
-
-const updated = () => {
- changed.value = false;
- emit('update:modelValue', v.value);
-};
-
-watch(modelValue, newValue => {
- v.value = newValue;
-});
-
-watch(v, () => {
- if (!props.manualSave) {
- updated();
- }
-
- invalid.value = inputEl.value?.validity.badInput ?? true;
-});
// このコンポーネントが作成された時、非表示状態である場合がある
// 非表示状態だと要素の幅などは0になってしまうので、定期的に計算する
@@ -134,6 +106,31 @@ onMounted(() => {
});
});
+watch(modelValue, () => {
+ const scanOptions = (options: VNodeChild[]) => {
+ for (const vnode of options) {
+ if (typeof vnode !== 'object' || vnode === null || Array.isArray(vnode)) continue;
+ if (vnode.type === 'optgroup') {
+ const optgroup = vnode;
+ if (Array.isArray(optgroup.children)) scanOptions(optgroup.children);
+ } else if (Array.isArray(vnode.children)) { // 何故かフラグメントになってくることがある
+ const fragment = vnode;
+ if (Array.isArray(fragment.children)) scanOptions(fragment.children);
+ } else if (vnode.props == null) { // v-if で条件が false のときにこうなる
+ // nop?
+ } else {
+ const option = vnode;
+ if (option.props?.value === modelValue.value) {
+ currentValueText.value = option.children as string;
+ break;
+ }
+ }
+ }
+ };
+
+ scanOptions(slots.default!());
+}, { immediate: true });
+
function show() {
if (opening.value) return;
focus();
@@ -146,11 +143,9 @@ function show() {
const pushOption = (option: VNode) => {
menu.push({
text: option.children as string,
- active: computed(() => v.value === option.props?.value),
+ active: computed(() => modelValue.value === option.props?.value),
action: () => {
- v.value = option.props?.value;
- changed.value = true;
- emit('changeByUser', v.value);
+ emit('update:modelValue', option.props?.value);
},
});
};
@@ -248,7 +243,8 @@ function show() {
.inputCore {
appearance: none;
-webkit-appearance: none;
- display: block;
+ display: flex;
+ align-items: center;
height: v-bind("height + 'px'");
width: 100%;
margin: 0;