refactor(client): fix TypeScript errors from MkPageHeader (#9400)
This commit is contained in:
		
							parent
							
								
									e4374aba77
								
							
						
					
					
						commit
						ef1224118c
					
				
					 1 changed files with 20 additions and 17 deletions
				
			
		|  | @ -21,7 +21,7 @@ | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div v-if="!narrow || hideTitle" class="tabs"> | 		<div v-if="!narrow || hideTitle" class="tabs"> | ||||||
| 			<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = el" v-tooltip.noDelay="tab.title" class="tab _button" :class="{ active: tab.key != null && tab.key === props.tab }" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)"> | 			<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = (el as HTMLElement)" v-tooltip.noDelay="tab.title" class="tab _button" :class="{ active: tab.key != null && tab.key === props.tab }" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)"> | ||||||
| 				<i v-if="tab.icon" class="icon" :class="tab.icon"></i> | 				<i v-if="tab.icon" class="icon" :class="tab.icon"></i> | ||||||
| 				<span v-if="!tab.iconOnly" class="title">{{ tab.title }}</span> | 				<span v-if="!tab.iconOnly" class="title">{{ tab.title }}</span> | ||||||
| 			</button> | 			</button> | ||||||
|  | @ -37,34 +37,36 @@ | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
| import { computed, onMounted, onUnmounted, ref, inject, watch, shallowReactive, nextTick, reactive } from 'vue'; | import { onMounted, onUnmounted, ref, inject, watch, nextTick } from 'vue'; | ||||||
| import tinycolor from 'tinycolor2'; | import tinycolor from 'tinycolor2'; | ||||||
| import { popupMenu } from '@/os'; | import { popupMenu } from '@/os'; | ||||||
| import { scrollToTop } from '@/scripts/scroll'; | import { scrollToTop } from '@/scripts/scroll'; | ||||||
| import { i18n } from '@/i18n'; |  | ||||||
| import { globalEvents } from '@/events'; | import { globalEvents } from '@/events'; | ||||||
| import { injectPageMetadata } from '@/scripts/page-metadata'; | import { injectPageMetadata } from '@/scripts/page-metadata'; | ||||||
| import { $i } from '@/account'; | import { $i } from '@/account'; | ||||||
| 
 | 
 | ||||||
| type Tab = { | type Tab = { | ||||||
| 	key?: string | null; | 	key: string; | ||||||
| 	title: string; | 	title: string; | ||||||
| 	icon?: string; | 	icon?: string; | ||||||
| 	iconOnly?: boolean; | 	iconOnly?: boolean; | ||||||
| 	onClick?: (ev: MouseEvent) => void; | 	onClick?: (ev: MouseEvent) => void; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const props = defineProps<{ | const props = withDefaults(defineProps<{ | ||||||
| 	tabs?: Tab[]; | 	tabs?: Tab[]; | ||||||
| 	tab?: string; | 	tab?: string; | ||||||
| 	actions?: { | 	actions?: { | ||||||
| 		text: string; | 		text: string; | ||||||
| 		icon: string; | 		icon: string; | ||||||
|  | 		highlighted?: boolean; | ||||||
| 		handler: (ev: MouseEvent) => void; | 		handler: (ev: MouseEvent) => void; | ||||||
| 	}[]; | 	}[]; | ||||||
| 	thin?: boolean; | 	thin?: boolean; | ||||||
| 	displayMyAvatar?: boolean; | 	displayMyAvatar?: boolean; | ||||||
| }>(); | }>(), { | ||||||
|  | 	tabs: () => ([] as Tab[]) | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| const emit = defineEmits<{ | const emit = defineEmits<{ | ||||||
| 	(ev: 'update:tab', key: string); | 	(ev: 'update:tab', key: string); | ||||||
|  | @ -75,13 +77,12 @@ const metadata = injectPageMetadata(); | ||||||
| const hideTitle = inject('shouldOmitHeaderTitle', false); | const hideTitle = inject('shouldOmitHeaderTitle', false); | ||||||
| const thin_ = props.thin || inject('shouldHeaderThin', false); | const thin_ = props.thin || inject('shouldHeaderThin', false); | ||||||
| 
 | 
 | ||||||
| const el = $ref<HTMLElement | null>(null); | const el = $ref<HTMLElement | undefined>(undefined); | ||||||
| const tabRefs = {}; | const tabRefs: Record<string, HTMLElement | null> = {}; | ||||||
| const tabHighlightEl = $ref<HTMLElement | null>(null); | const tabHighlightEl = $ref<HTMLElement | null>(null); | ||||||
| const bg = ref(null); | const bg = ref<string | undefined>(undefined); | ||||||
| let narrow = $ref(false); | let narrow = $ref(false); | ||||||
| const height = ref(0); | const hasTabs = $computed(() => props.tabs.length > 0); | ||||||
| const hasTabs = $computed(() => props.tabs && props.tabs.length > 0); |  | ||||||
| const hasActions = $computed(() => props.actions && props.actions.length > 0); | const hasActions = $computed(() => props.actions && props.actions.length > 0); | ||||||
| const show = $computed(() => { | const show = $computed(() => { | ||||||
| 	return !hideTitle || hasTabs || hasActions; | 	return !hideTitle || hasTabs || hasActions; | ||||||
|  | @ -100,7 +101,7 @@ const showTabsPopup = (ev: MouseEvent) => { | ||||||
| 			onTabClick(tab, ev); | 			onTabClick(tab, ev); | ||||||
| 		}, | 		}, | ||||||
| 	})); | 	})); | ||||||
| 	popupMenu(menu, ev.currentTarget ?? ev.target); | 	popupMenu(menu, ev.currentTarget! as HTMLElement); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const preventDrag = (ev: TouchEvent) => { | const preventDrag = (ev: TouchEvent) => { | ||||||
|  | @ -108,7 +109,9 @@ const preventDrag = (ev: TouchEvent) => { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const onClick = () => { | const onClick = () => { | ||||||
| 	scrollToTop(el, { behavior: 'smooth' }); | 	if (el) { | ||||||
|  | 		scrollToTop(el as HTMLElement, { behavior: 'smooth' }); | ||||||
|  | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| function onTabMousedown(tab: Tab, ev: MouseEvent): void { | function onTabMousedown(tab: Tab, ev: MouseEvent): void { | ||||||
|  | @ -144,8 +147,8 @@ onMounted(() => { | ||||||
| 
 | 
 | ||||||
| 	watch(() => [props.tab, props.tabs], () => { | 	watch(() => [props.tab, props.tabs], () => { | ||||||
| 		nextTick(() => { | 		nextTick(() => { | ||||||
| 			const tabEl = tabRefs[props.tab]; | 			const tabEl = props.tab ? tabRefs[props.tab] : undefined; | ||||||
| 			if (tabEl && tabHighlightEl) { | 			if (tabEl && tabHighlightEl && tabEl.parentElement) { | ||||||
| 				// offsetWidth や offsetLeft は少数を丸めてしまうため getBoundingClientRect を使う必要がある | 				// offsetWidth や offsetLeft は少数を丸めてしまうため getBoundingClientRect を使う必要がある | ||||||
| 				// https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/offsetWidth#%E5%80%A4 | 				// https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/offsetWidth#%E5%80%A4 | ||||||
| 				const parentRect = tabEl.parentElement.getBoundingClientRect(); | 				const parentRect = tabEl.parentElement.getBoundingClientRect(); | ||||||
|  | @ -161,11 +164,11 @@ onMounted(() => { | ||||||
| 	if (el && el.parentElement) { | 	if (el && el.parentElement) { | ||||||
| 		narrow = el.parentElement.offsetWidth < 500; | 		narrow = el.parentElement.offsetWidth < 500; | ||||||
| 		ro = new ResizeObserver((entries, observer) => { | 		ro = new ResizeObserver((entries, observer) => { | ||||||
| 			if (el.parentElement && document.body.contains(el)) { | 			if (el.parentElement && document.body.contains(el as HTMLElement)) { | ||||||
| 				narrow = el.parentElement.offsetWidth < 500; | 				narrow = el.parentElement.offsetWidth < 500; | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 		ro.observe(el.parentElement); | 		ro.observe(el.parentElement as HTMLElement); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue