fix display:none

This commit is contained in:
samunohito 2024-01-30 09:53:47 +09:00
parent b2c8548c67
commit ad03ef03da
4 changed files with 101 additions and 18 deletions

View File

@ -50,7 +50,7 @@
</template>
<script setup lang="ts">
import { computed, defineAsyncComponent, nextTick, ref, shallowRef, toRefs, watch } from 'vue';
import { computed, defineAsyncComponent, nextTick, onMounted, onUnmounted, ref, shallowRef, toRefs, watch } from 'vue';
import { GridEventEmitter, Size } from '@/components/grid/grid.js';
import { useTooltip } from '@/scripts/use-tooltip.js';
import * as os from '@/os.js';
@ -144,6 +144,10 @@ function onInputText(ev: Event) {
editingValue.value = (ev.target as HTMLInputElement).value;
}
function onForceRefreshContentSize() {
emitContentSizeChanged();
}
function registerOutsideMouseDown() {
unregisterOutsideMouseDown();
addEventListener('mousedown', onOutsideMouseDown);
@ -223,6 +227,14 @@ useTooltip(rootEl, (showing) => {
}, {}, 'closed');
});
onMounted(() => {
bus.value.on('forceRefreshContentSize', onForceRefreshContentSize);
});
onUnmounted(() => {
bus.value.off('forceRefreshContentSize', onForceRefreshContentSize);
});
</script>
<style module lang="scss">

View File

@ -36,7 +36,7 @@
</template>
<script setup lang="ts">
import { computed, ref, toRefs, watch } from 'vue';
import { computed, nextTick, onMounted, ref, toRefs, watch } from 'vue';
import {
CellValueChangedEvent,
ColumnSetting,
@ -71,7 +71,21 @@ const emit = defineEmits<{
(ev: 'change:cellValue', event: CellValueChangedEvent): void;
}>();
/**
* grid -> 各子コンポーネントのイベント経路を担う{@link GridEventEmitter}
* 子コンポーネント -> gridのイベントでは原則使用せず{@link emit}を使用する
*/
const bus = new GridEventEmitter();
/**
* テーブルコンポーネントのリサイズイベントを監視するための{@link ResizeObserver}
* 表示切替を検知しサイズの再計算要求を発行するために使用するマウント時にコンテンツが表示されていない場合初手のサイズの自動計算が正常に働かないため
*
* {@link setTimeout}を経由している理由は{@link onResize}の中でサイズ再計算要求サイズ変更が発生するとループとみなされ
* ResizeObserver loop completed with undelivered notifications.という警告が発生するため状態管理してるので実際にはループしない
*
* @see {@link onResize}
*/
const resizeObserver = new ResizeObserver((entries) => setTimeout(() => onResize(entries)));
const { gridSetting, columnSettings, data } = toRefs(props);
@ -122,14 +136,44 @@ watch(columnSettings, refreshColumnsSetting);
watch(data, refreshData);
if (_DEV_) {
watch(state, (value) => {
console.log(`state: ${value}`);
watch(state, (value, oldValue) => {
console.log(`[grid][state] ${oldValue} -> ${value}`);
});
}
function onResize(entries: ResizeObserverEntry[]) {
if (entries.length !== 1 || entries[0].target !== rootEl.value) {
return;
}
const contentRect = entries[0].contentRect;
if (_DEV_) {
console.log(`[grid][resize] contentRect: ${contentRect.width}x${contentRect.height}`);
}
switch (state.value) {
case 'hidden': {
if (contentRect.width > 0 && contentRect.height > 0) {
state.value = 'normal';
//
unSelectionRange();
bus.emit('forceRefreshContentSize');
}
break;
}
default: {
if (contentRect.width === 0 || contentRect.height === 0) {
state.value = 'hidden';
}
break;
}
}
}
function onKeyDown(ev: KeyboardEvent) {
if (_DEV_) {
console.log('[Grid]', `ctrl: ${ev.ctrlKey}, shift: ${ev.shiftKey}, code: ${ev.code}`);
console.log(`[grid][key] ctrl: ${ev.ctrlKey}, shift: ${ev.shiftKey}, code: ${ev.code}`);
}
switch (state.value) {
@ -482,7 +526,7 @@ function onChangeCellValue(sender: GridCell, newValue: CellValue) {
function onChangeCellContentSize(sender: GridCell, contentSize: Size) {
cells.value[sender.address.row][sender.address.col].contentSize = contentSize;
if (sender.column.setting.width === 'auto') {
largestCellWidth(sender.column);
calcLargestCellWidth(sender.column);
}
}
@ -519,7 +563,7 @@ function onHeaderCellChangeContentSize(sender: GridColumn, newSize: Size) {
case 'normal': {
columns.value[sender.index].contentSize = newSize;
if (sender.setting.width === 'auto') {
largestCellWidth(sender);
calcLargestCellWidth(sender);
}
break;
}
@ -529,13 +573,13 @@ function onHeaderCellChangeContentSize(sender: GridColumn, newSize: Size) {
function onHeaderCellWidthLargest(sender: GridColumn) {
switch (state.value) {
case 'normal': {
largestCellWidth(sender);
calcLargestCellWidth(sender);
break;
}
}
}
function largestCellWidth(column: GridColumn) {
function calcLargestCellWidth(column: GridColumn) {
const _cells = cells.value;
const largestColumnWidth = columns.value[column.index].contentSize.width;
@ -548,7 +592,9 @@ function largestCellWidth(column: GridColumn) {
)
: 0;
console.log(`largestCellWidth: ${largestColumnWidth}, ${largestCellWidth}`);
if (_DEV_) {
console.log(`[grid][calc-largest] idx:${column.setting.bindTo}, col:${largestColumnWidth}, cell:${largestCellWidth}`);
}
column.width = `${Math.max(largestColumnWidth, largestCellWidth)}px`;
}
@ -800,9 +846,21 @@ function unregisterMouseUp() {
removeEventListener('mouseup', onMouseUp);
}
onMounted(() => {
refreshColumnsSetting();
refreshData();
if (rootEl.value) {
resizeObserver.observe(rootEl.value);
// hidden
// resizehidden
const bounds = rootEl.value.getBoundingClientRect();
if (bounds.width === 0 || bounds.height === 0) {
state.value = 'hidden';
}
}
});
</script>
<style module lang="scss">
@ -812,7 +870,6 @@ $borderRadius: var(--radius);
.grid {
overflow: scroll;
table-layout: fixed;
width: fit-content;
user-select: none;
}

View File

@ -22,7 +22,7 @@
</template>
<script setup lang="ts">
import { computed, nextTick, ref, toRefs, watch } from 'vue';
import { computed, nextTick, onMounted, onUnmounted, ref, toRefs, watch } from 'vue';
import { GridColumn, GridEventEmitter, Size } from '@/components/grid/grid.js';
const emit = defineEmits<{
@ -51,7 +51,7 @@ const text = computed(() => {
watch(column, () => {
//
nextTick(updateContentSize);
nextTick(emitContentSizeChanged);
}, { immediate: true });
function onHandleDoubleClick(ev: MouseEvent) {
@ -111,6 +111,10 @@ function onHandleMouseUp(ev: MouseEvent) {
}
}
function onForceRefreshContentSize() {
emitContentSizeChanged();
}
function registerHandleMouseMove() {
unregisterHandleMouseMove();
addEventListener('mousemove', onHandleMouseMove);
@ -129,7 +133,7 @@ function unregisterHandleMouseUp() {
removeEventListener('mouseup', onHandleMouseUp);
}
function updateContentSize() {
function emitContentSizeChanged() {
const clientWidth = contentEl.value?.clientWidth ?? 0;
const clientHeight = contentEl.value?.clientHeight ?? 0;
emit('change:contentSize', column.value, {
@ -139,6 +143,14 @@ function updateContentSize() {
});
}
onMounted(() => {
bus.value.on('forceRefreshContentSize', onForceRefreshContentSize);
});
onUnmounted(() => {
bus.value.off('forceRefreshContentSize', onForceRefreshContentSize);
});
</script>
<style module lang="scss">

View File

@ -8,7 +8,7 @@ export type GridSetting = {
export type DataSource = Record<string, CellValue>;
export type GridState = 'normal' | 'cellSelecting' | 'cellEditing' | 'colResizing' | 'colSelecting' | 'rowSelecting'
export type GridState = 'normal' | 'cellSelecting' | 'cellEditing' | 'colResizing' | 'colSelecting' | 'rowSelecting' | 'hidden'
export type Size = {
width: number;
@ -47,5 +47,7 @@ export type CellValueChangedEvent = {
value: CellValue;
}
export class GridEventEmitter extends EventEmitter<{}> {
export class GridEventEmitter extends EventEmitter<{
'forceRefreshContentSize': void;
}> {
}