mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-11 09:42:15 +01:00
fix focus state for dropdowns, fix taborder for timerange select in timetracker and timeentryrows
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import TimeRangeSelector from '@/packages/ui/src/Input/TimeRangeSelector.vue';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
import parse from 'parse-duration';
|
||||
@@ -28,8 +28,8 @@ function pauseLiveTimerUpdate(event: FocusEvent) {
|
||||
|
||||
function onTimeEntryEnterPress() {
|
||||
updateTimerAndStartLiveTimerUpdate();
|
||||
const activeElement = document.activeElement as HTMLElement;
|
||||
activeElement?.blur();
|
||||
//const activeElement = document.activeElement as HTMLElement;
|
||||
// activeElement?.blur();
|
||||
}
|
||||
|
||||
const currentTime = computed({
|
||||
@@ -111,6 +111,7 @@ function isHHMM(value: string): boolean {
|
||||
function parseHHMM(value: string): string[] | null {
|
||||
return value.match(HHMMtimeRegex);
|
||||
}
|
||||
|
||||
const temporaryCustomTimerEntry = ref<string>('');
|
||||
|
||||
async function updateTimeRange(newStart: string) {
|
||||
@@ -132,11 +133,31 @@ const startTime = computed(() => {
|
||||
return dayjs().utc().format();
|
||||
});
|
||||
const inputField = ref<HTMLInputElement | null>(null);
|
||||
watch(open, (isOpen) => {
|
||||
if (!isOpen) {
|
||||
inputField.value?.focus();
|
||||
|
||||
const timeRangeSelector = ref<HTMLElement | null>(null);
|
||||
|
||||
function openModalOnTab(e: FocusEvent) {
|
||||
// check if the source is inside the dropdown
|
||||
const source = e.relatedTarget as HTMLElement;
|
||||
if (source && window.document.body.contains(source)) {
|
||||
open.value = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function focusNextElement(e: KeyboardEvent) {
|
||||
if (open.value) {
|
||||
e.preventDefault();
|
||||
const focusableElement = timeRangeSelector.value?.querySelector<HTMLElement>(
|
||||
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
||||
);
|
||||
focusableElement?.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function closeAndFocusInput() {
|
||||
inputField.value?.focus();
|
||||
open.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -150,20 +171,26 @@ watch(open, (isOpen) => {
|
||||
<input
|
||||
placeholder="00:00:00"
|
||||
@focus="pauseLiveTimerUpdate"
|
||||
@focusin="openModalOnTab"
|
||||
@keydown.exact.tab="focusNextElement"
|
||||
@keydown.exact.shift.tab="open = false"
|
||||
ref="inputField"
|
||||
data-testid="time_entry_time"
|
||||
@blur="updateTimerAndStartLiveTimerUpdate"
|
||||
@keydown.enter="onTimeEntryEnterPress"
|
||||
v-model="currentTime"
|
||||
class="w-[110px] lg:w-[130px] h-full text-white py-2.5 rounded-r-lg text-center px-4 text-base lg:text-lg font-bold bg-card-background border-none placeholder-muted focus:ring-0 transition"
|
||||
class="w-[110px] lg:w-[130px] h-full text-white py-2.5 rounded-lg border-border-secondary border text-center px-4 text-base lg:text-lg font-bold bg-card-background border-none placeholder-muted focus:ring-0 transition"
|
||||
type="text" />
|
||||
</template>
|
||||
<template #content>
|
||||
<TimeRangeSelector
|
||||
@changed="updateTimeRange"
|
||||
:start="startTime"
|
||||
:end="null">
|
||||
</TimeRangeSelector>
|
||||
<div ref="timeRangeSelector">
|
||||
<TimeRangeSelector
|
||||
@changed="updateTimeRange"
|
||||
@close="closeAndFocusInput"
|
||||
:start="startTime"
|
||||
:end="null">
|
||||
</TimeRangeSelector>
|
||||
</div>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user