Skip to content

Commit

Permalink
入力欄のあるモーダルが表示されたときに自動でフォーカスするように
Browse files Browse the repository at this point in the history
  • Loading branch information
mehm8128 committed Nov 3, 2023
1 parent 6b1ea3f commit 45a2831
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

<script lang="ts">
import type { Ref } from 'vue'
import { computed, ref } from 'vue'
import { computed, onMounted, ref } from 'vue'
import apis, { buildFilePathForPost, formatResizeError } from '/@/lib/apis'
import useModifierKey from '/@/components/Main/MainView/MessageInput/composables/useModifierKey'
import useTextStampPickerInvoker from '../composables/useTextStampPickerInvoker'
Expand Down Expand Up @@ -172,6 +172,10 @@ const {
addAttachment,
onAddAttachments
} = useAttachmentsEditor(props, text)
onMounted(() => {
textareaComponentRef.value?.textareaAutosizeRef.$el?.focus()
})
</script>

<style lang="scss" module>
Expand Down
16 changes: 13 additions & 3 deletions src/components/Main/MainView/PrimaryViewSidebar/ContentEditor.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<template>
<div :class="$style.container">
<div v-if="isEditingValue && value !== undefined">
<textarea-autosize v-model="value" :class="$style.editor" />
<textarea-autosize
ref="textareaRef"
v-model="value"
:class="$style.editor"
/>
<length-count :val="value" :max-length="maxLength" />
</div>
<div v-else :class="$style.content" :data-is-empty="$boolAttr(isEmpty)">
Expand All @@ -24,7 +28,7 @@
import AIcon from '/@/components/UI/AIcon.vue'
import LengthCount from '/@/components/UI/LengthCount.vue'
import TextareaAutosize from '/@/components/UI/TextareaAutosize.vue'
import { computed } from 'vue'
import { computed, nextTick, ref } from 'vue'
import { countLength } from '/@/lib/basic/string'
import {
useModelSyncer,
Expand All @@ -51,14 +55,20 @@ const emit = defineEmits<{
const value = useModelValueSyncer(props, emit)
const isEditingValue = useModelSyncer(props, emit, 'isEditing')
const textareaRef = ref<InstanceType<typeof TextareaAutosize> | null>(null)
const content = computed(() => {
if (value.value === '') return props.fallbackValue
if (value.value === undefined) return 'ロード中'
return value.value
})
const isEmpty = computed(() => value.value === '' || value.value === undefined)
const onButtonClick = () => {
const onButtonClick = async () => {
isEditingValue.value = !isEditingValue.value
await nextTick()
if (isEditingValue.value) {
textareaRef.value?.focus()
}
}
const isExceeded = computed(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div :class="$style.container">
<div :class="$style.input">
<filter-input v-model="value" on-secondary disable-ime />
<filter-input v-model="value" on-secondary disable-ime focus-on-mount />
</div>
</div>
</template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<navigation-content-container subtitle="ユーザーリスト">
<filter-input v-model="query" on-secondary />
<filter-input v-model="query" on-secondary focus-on-mount />
<div v-if="query.length > 0" :class="$style.list">
<users-element
v-for="user in filteredItems"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
label="チャンネル名"
:class="$style.input"
:max-length="20"
focus-on-mount
/>
<p :class="$style.desc">
実行すると
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
v-model="manageState.name"
label="チャンネル名"
:max-length="20"
focus-on-mount
/>
<form-selector
v-model="manageState.parent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
label="名前"
:class="$style.input"
:max-length="30"
focus-on-mount
/>
<form-text-area
v-model="description.val"
Expand Down
2 changes: 1 addition & 1 deletion src/components/Modal/Common/UsersSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@update:model-value="toggleAll"
/>
</label>
<filter-input v-model="query" :class="$style.search" />
<filter-input v-model="query" :class="$style.search" focus-on-mount />
</div>
<div :class="$style.list">
<label v-for="user in filteredUsers" :key="user.id" :class="$style.user">
Expand Down
1 change: 1 addition & 0 deletions src/components/Modal/GroupCreateModal/GroupCreateModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:class="$style.item"
label="グループ名"
:max-length="30"
focus-on-mount
/>
<form-input
v-model="desc"
Expand Down
12 changes: 10 additions & 2 deletions src/components/UI/FormInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@
<script lang="ts" setup>
import AIcon from '/@/components/UI/AIcon.vue'
import LengthCount from '/@/components/UI/LengthCount.vue'
import { shallowRef } from 'vue'
import { onMounted, shallowRef } from 'vue'
import { randomString } from '/@/lib/basic/randomString'
import useInput from '/@/composables/useInput'
import useShowPassword from '/@/composables/dom/useShowPassword'
import { isTouchDevice } from '/@/lib/dom/browser'
const props = withDefaults(
defineProps<{
Expand All @@ -74,13 +75,15 @@ const props = withDefaults(
step?: string
maxLength?: number
useChangeEvent?: boolean
focusOnMount?: boolean
}>(),
{
type: 'text',
modelValue: '',
onSecondary: false,
placeholder: '',
useChangeEvent: false
useChangeEvent: false,
focusOnMount: false
}
)
Expand Down Expand Up @@ -108,6 +111,11 @@ const id = randomString()
const { isPasswordShown, togglePassword, typeWithShown } =
useShowPassword(props)
onMounted(() => {
if (!props.focusOnMount || isTouchDevice()) return
focus()
})
</script>

<style lang="scss" module>
Expand Down
9 changes: 9 additions & 0 deletions src/components/UI/TextareaAutosize.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ const emit = defineEmits<{
const { value, onInput } = useTextModelSyncer(props, emit)
const textareaEle = ref<HTMLTextAreaElement | null>(null)
const focus = () => {
textareaEle.value?.focus()
}
onMounted(() => {
if (textareaEle.value) {
autosize(textareaEle.value)
Expand All @@ -48,6 +53,10 @@ onBeforeUnmount(() => {
autosize.destroy(textareaEle.value)
}
})
defineExpose({
focus
})
</script>

<style lang="scss" module>
Expand Down

0 comments on commit 45a2831

Please sign in to comment.