Skip to content

Commit

Permalink
[atable] modal z-sorting (#240)
Browse files Browse the repository at this point in the history
* changed amodal to calculate the cell position based on cell and row sizes. Amodal position changed from fixed to absolute

* amodal row height calculation gets the height of rows instead of assuming they are all the same height

* fix: use offsets to determine relative heights/widths

* moved border-top styling from arow to acell

---------

Co-authored-by: Rohan Bansal <[email protected]>
  • Loading branch information
crabinak and Rohan Bansal authored Feb 17, 2025
1 parent 7dc141d commit 8cccf4b
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 35 deletions.
4 changes: 3 additions & 1 deletion atable/src/components/ACell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,12 @@ const showModal = () => {
state.modal.visible = true
state.modal.colIndex = colIndex
state.modal.rowIndex = rowIndex
// TODO: typing refs somehow resolves to unref'd value; probably a bug in API Extractor?
// TODO: typing refs somehow resolves to unref'd value; probably a bug in TS?
state.modal.left = left
state.modal.bottom = bottom
state.modal.width = width
state.modal.height = height
state.modal.cell = cellRef.value
if (typeof column.modalComponent === 'function') {
state.modal.component = column.modalComponent({ table: state.table, row, column })
Expand Down Expand Up @@ -201,6 +202,7 @@ const updateCellData = (payload: Event) => {
order: 1;
white-space: nowrap;
max-width: 40ch;
border-top: 1px solid var(--sc-row-border-color);
}
.atable-cell a {
color: var(--sc-cell-text-color);
Expand Down
1 change: 0 additions & 1 deletion atable/src/components/ARow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ if (addNavigation) {
@import url('@stonecrop/themes/default.css');
.atable-row {
border-top: 1px solid var(--sc-row-border-color);
display: flex;
background-color: white;
}
Expand Down
6 changes: 3 additions & 3 deletions atable/src/components/ATable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ defineExpose({ store })
.sticky-index {
position: sticky;
left: 0px;
z-index: 1;
z-index: 10;
order: 0;
}
Expand All @@ -185,15 +185,14 @@ td.sticky-column,
th.sticky-index,
td.sticky-index {
position: sticky;
z-index: 1;
z-index: 10;
order: 0;
background: white;
}
.sticky-column-edge,
.atable th.sticky-column-edge {
border-right: 1px solid var(--sc-row-border-color);
border-right-width: 1px;
}
</style>

Expand All @@ -209,6 +208,7 @@ td.sticky-index {
box-sizing: border-box;
table-layout: auto;
width: auto;
overflow: clip;
/* border-left:4px solid var(--sc-form-border); */
}
.atable th {
Expand Down
46 changes: 19 additions & 27 deletions atable/src/components/ATableModal.vue
Original file line number Diff line number Diff line change
@@ -1,61 +1,53 @@
<template>
<div class="amodal" ref="amodal" tabindex="-1" @click="handleInput" @input="handleInput" :style="amodalStyles">
<div class="amodal" ref="amodal" tabindex="-1" @click.stop @input.stop :style="amodalStyles">
<slot />
</div>
</template>

<script setup lang="ts">
import { useElementBounding, useWindowScroll } from '@vueuse/core'
import { useElementBounding } from '@vueuse/core'
import { useTemplateRef, computed } from 'vue'
import { createTableStore } from '../stores/table'
const { store } = defineProps<{ store: ReturnType<typeof createTableStore> }>()
const amodalRef = useTemplateRef('amodal')
const { width, height } = useElementBounding(amodalRef)
const { y: scrollY } = useWindowScroll()
const { width: modalWidth, height: modalHeight } = useElementBounding(amodalRef)
const amodalStyles = computed(() => {
if (!(store.modal.height && store.modal.width && store.modal.left && store.modal.bottom)) return
const body = document.body
const html = document.documentElement
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
const table = store.modal.cell?.closest('table')!
const maxHeight = table.offsetHeight || 0
const maxWidth = table.offsetWidth || 0
const maxHeight = Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight
)
const maxWidth = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth)
// Get the Y position of the cell clicked by getting the cumulative height of prior rows + the header (if present)
let modalY = store.modal.cell?.offsetTop || 0
const headerHeight = table.querySelector('thead')?.offsetHeight || 0
modalY += headerHeight
// if the modal will overflow the bottom of the table, remove modal and cell heights from the Y position
modalY = modalY + modalHeight.value < maxHeight ? modalY : modalY - (modalHeight.value + store.modal.height)
const modalY =
store.modal.bottom + height.value + scrollY.value <= maxHeight
? store.modal.bottom
: store.modal.bottom - height.value - store.modal.height
const modalX =
store.modal.left + width.value <= maxWidth ? store.modal.left : store.modal.left - (width.value - store.modal.width)
// Get the X position of the cell clicked by getting the cumulative width of prior cells within the row
let modalX = store.modal.cell?.offsetLeft || 0
// if the modal will overflow the right of the table, remove modal and cell widths from the X position
modalX = modalX + modalWidth.value <= maxWidth ? modalX : modalX - (modalWidth.value - store.modal.width)
return {
left: `${modalX}px`,
top: `${modalY}px`,
}
})
const handleInput = (event: Event) => {
event.stopPropagation()
}
</script>

<style>
@import url('@stonecrop/themes/default.css');
.amodal {
position: fixed;
position: absolute;
background-color: var(--sc-row-color-zebra-dark);
z-index: 1000;
z-index: 5;
}
</style>
2 changes: 1 addition & 1 deletion atable/src/stores/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export const createTableStore = (initData: {
const config = ref(initData.config || {})
const table = ref(initData.table || createTableObject())
const display = ref(createDisplayObject(initData.display))
const modal = ref(initData.modal || { visible: false })
const modal = ref<TableModal>(initData.modal || { visible: false })
const updates = ref<Record<string, string>>({})

// getters
Expand Down
1 change: 1 addition & 0 deletions atable/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export type TableRow = {
*/
export type TableModal = {
bottom?: ReturnType<typeof useElementBounding>['bottom']
cell?: HTMLTableCellElement | null
colIndex?: number
event?: string
height?: ReturnType<typeof useElementBounding>['height']
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@stonecrop/atable",
"comment": "amodal uses cell and row sizes to calculate position",
"type": "patch"
}
],
"packageName": "@stonecrop/atable"
}
7 changes: 7 additions & 0 deletions common/reviews/api/atable.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ rowModified?: boolean | undefined;
}[]>;
modal: Ref< {
bottom?: number | undefined;
cell?: (HTMLTableCellElement | null) | undefined;
colIndex?: number | undefined;
event?: string | undefined;
height?: number | undefined;
Expand All @@ -125,6 +126,7 @@ component?: string | undefined;
componentProps?: Record<string, any> | undefined;
}, TableModal | {
bottom?: number | undefined;
cell?: (HTMLTableCellElement | null) | undefined;
colIndex?: number | undefined;
event?: string | undefined;
height?: number | undefined;
Expand Down Expand Up @@ -219,6 +221,7 @@ rowModified?: boolean | undefined;
}[]>;
modal: Ref< {
bottom?: number | undefined;
cell?: (HTMLTableCellElement | null) | undefined;
colIndex?: number | undefined;
event?: string | undefined;
height?: number | undefined;
Expand All @@ -231,6 +234,7 @@ component?: string | undefined;
componentProps?: Record<string, any> | undefined;
}, TableModal | {
bottom?: number | undefined;
cell?: (HTMLTableCellElement | null) | undefined;
colIndex?: number | undefined;
event?: string | undefined;
height?: number | undefined;
Expand Down Expand Up @@ -325,6 +329,7 @@ rowModified?: boolean | undefined;
}[]>;
modal: Ref< {
bottom?: number | undefined;
cell?: (HTMLTableCellElement | null) | undefined;
colIndex?: number | undefined;
event?: string | undefined;
height?: number | undefined;
Expand All @@ -337,6 +342,7 @@ component?: string | undefined;
componentProps?: Record<string, any> | undefined;
}, TableModal | {
bottom?: number | undefined;
cell?: (HTMLTableCellElement | null) | undefined;
colIndex?: number | undefined;
event?: string | undefined;
height?: number | undefined;
Expand Down Expand Up @@ -416,6 +422,7 @@ export type TableDisplay = {
// @public
export type TableModal = {
bottom?: ReturnType<typeof useElementBounding>['bottom'];
cell?: HTMLTableCellElement | null;
colIndex?: number;
event?: string;
height?: ReturnType<typeof useElementBounding>['height'];
Expand Down
Loading

0 comments on commit 8cccf4b

Please sign in to comment.