Skip to content

Commit 0e6998c

Browse files
committed
Improved table layout and responsiveness
1 parent 6780fb4 commit 0e6998c

15 files changed

+269
-60
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vue-data-ui",
33
"private": false,
4-
"version": "1.9.70",
4+
"version": "1.9.71",
55
"type": "module",
66
"description": "A user-empowering data visualization Vue components library",
77
"keywords": [

src/atoms/DataTable.vue

Lines changed: 113 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
<script setup>
2+
import { computed, onMounted, ref } from "vue";
23
import Shape from "./Shape.vue";
34
45
const props = defineProps({
6+
colNames: {
7+
type: Array,
8+
default() {
9+
return []
10+
}
11+
},
512
head: Array,
613
body: Array,
714
title: String,
@@ -11,61 +18,121 @@ const props = defineProps({
1118
const { backgroundColor:thbg, color:thc, outline:tho } = props.config.th;
1219
const { backgroundColor:tdbg, color:tdc, outline:tdo } = props.config.td;
1320
21+
const breakpoint = computed(() => {
22+
return props.config.breakpoint
23+
})
24+
25+
const tableContainer = ref(null)
26+
const isResponsive = ref(false)
27+
28+
onMounted(() => {
29+
const observer = new ResizeObserver((entries) => {
30+
entries.forEach(entry => {
31+
isResponsive.value = entry.contentRect.width < breakpoint.value;
32+
})
33+
})
34+
if(tableContainer.value) {
35+
observer.observe(tableContainer.value)
36+
}
37+
38+
})
39+
1440
</script>
1541

1642
<template>
17-
<table data-cy="vue-data-ui-table-data" class="vue-ui-data-table">
18-
<thead>
19-
<tr>
20-
<th :style="{backgroundColor: thbg, color: thc, outline: tho}" :colspan="head.length">
21-
{{ title }}
22-
</th>
23-
</tr>
24-
<tr>
25-
<th :style="{backgroundColor: thbg, color: thc, outline: tho}" v-for="(th, i) in head" :key="`th_${i}`">
26-
<div style="display: flex; align-items:center; justify-content:center; justify-content:flex-end;padding-right: 3px; gap:3px">
27-
<svg height="12" width="12" v-if="th.color" viewBox="0 0 20 20" style="background: none;">
28-
<circle cx="10" cy="10" r="10" :fill="th.color"/>
29-
</svg>
30-
<slot name="th" :th="th"/>
31-
</div>
32-
</th>
33-
</tr>
34-
</thead>
35-
36-
<tbody>
37-
<tr v-for="(tr, i) in body">
38-
<td v-for="(td, j) in tr" :style="{backgroundColor: tdbg, color: tdc, outline: tdo}">
39-
<div style="display: flex; align-items:center; gap: 5px; justify-content:flex-end; width:100%; padding-right:3px;">
40-
<svg height="12" width="12" v-if="td.color" viewBox="0 0 20 20" style="background: none;overflow: visible">
41-
<Shape
42-
:plot="{ x: 10, y: 10 }"
43-
:color="td.color"
44-
:radius="9"
45-
:shape="config.shape || 'circle'"
46-
/>
47-
</svg>
48-
<slot name="td" :td="td"></slot>
49-
</div>
50-
</td>
51-
</tr>
52-
</tbody>
53-
</table>
43+
<div ref="tableContainer" style="width: 100%; container-type: inline-size;" :class="{'vue-ui-responsive': isResponsive}">
44+
<table data-cy="vue-data-ui-table-data" class="vue-ui-data-table">
45+
<caption :style="{backgroundColor: thbg, color: thc, outline: tho}">
46+
{{ title }}
47+
</caption>
48+
<thead>
49+
<tr>
50+
<th :style="{backgroundColor: thbg, color: thc, outline: tho}" v-for="(th, i) in head" :key="`th_${i}`">
51+
<div style="display: flex; align-items:center; justify-content:center; justify-content:flex-end;padding-right: 3px; gap:3px">
52+
<svg height="12" width="12" v-if="th.color" viewBox="0 0 20 20" style="background: none;">
53+
<circle cx="10" cy="10" r="10" :fill="th.color"/>
54+
</svg>
55+
<slot name="th" :th="th"/>
56+
</div>
57+
</th>
58+
</tr>
59+
</thead>
60+
61+
<tbody>
62+
<tr v-for="(tr, i) in body">
63+
<td role="" v-for="(td, j) in tr" :data-cell="colNames[j]" :style="{backgroundColor: tdbg, color: tdc, outline: tdo}">
64+
<div style="display: flex; align-items:center; gap: 5px; justify-content:flex-end; width:100%; padding-right:3px;">
65+
<svg height="12" width="12" v-if="td.color" viewBox="0 0 20 20" style="background: none;overflow: visible">
66+
<Shape
67+
:plot="{ x: 10, y: 10 }"
68+
:color="td.color"
69+
:radius="9"
70+
:shape="config.shape || 'circle'"
71+
/>
72+
</svg>
73+
<slot name="td" :td="td"></slot>
74+
</div>
75+
</td>
76+
</tr>
77+
</tbody>
78+
</table>
79+
</div>
5480
</template>
5581

56-
<style scoped>
57-
table.vue-ui-data-table {
58-
width: 100%;
59-
border-collapse:collapse;
60-
}
61-
.vue-ui-data-table td {
62-
padding-right: 6px;
63-
font-variant-numeric: tabular-nums;
64-
}
82+
<style scoped lang="scss">
6583
.vue-ui-data-table th {
6684
position: sticky;
6785
top:0;
6886
font-weight: 400;
6987
user-select: none;
7088
}
89+
90+
table {
91+
width: 100%;
92+
padding: 1rem;
93+
border-collapse:collapse;
94+
}
95+
96+
caption,
97+
th,
98+
td {
99+
padding: 0.5rem;
100+
font-variant-numeric: tabular-nums;
101+
}
102+
103+
caption {
104+
font-size: 1.3rem;
105+
font-weight: 700;
106+
}
107+
108+
.vue-ui-responsive {
109+
th {
110+
display: none;
111+
}
112+
td {
113+
display: grid;
114+
gap: 0.5rem;
115+
grid-template-columns: repeat(2, 1fr);
116+
padding: 0.5rem 1rem;
117+
outline: none !important;
118+
text-align: left;
119+
}
120+
tr {
121+
outline: 1px solid #CCCCCC;
122+
}
123+
124+
td:first-child {
125+
padding-top: 1rem;
126+
}
127+
128+
td:last-child {
129+
padding-bottom: 1rem;
130+
}
131+
132+
td::before {
133+
content: attr(data-cell) ": ";
134+
font-weight: 700;
135+
text-transform: capitalize;
136+
}
137+
}
71138
</style>

src/components/vue-ui-donut-evolution.cy.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
import VueUiDonutEvolution from './vue-ui-donut-evolution.vue'
22

3+
4+
35
describe('<VueUiDonutEvolution />', () => {
46
beforeEach(function () {
7+
const stub = cy.stub()
8+
Cypress.on('uncaught:exception', (err, runnable) => {
9+
if (err.message.includes('ResizeObserver')) {
10+
stub()
11+
return false
12+
}
13+
})
514
cy.fixture('donut-evolution.json').as('fixture');
615
cy.viewport(400, 400);
716
cy.get('@fixture').then((fixture) => {

src/components/vue-ui-donut-evolution.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,10 +349,15 @@ const table = computed(() => {
349349
backgroundColor: donutEvolutionConfig.value.table.td.backgroundColor,
350350
color: donutEvolutionConfig.value.table.td.color,
351351
outline: donutEvolutionConfig.value.table.td.outline
352-
}
352+
},
353+
breakpoint: donutEvolutionConfig.value.table.responsiveBreakpoint
353354
}
354355
355-
return { head, body, config };
356+
const colNames = [
357+
donutEvolutionConfig.value.table.columnNames.period
358+
].concat(convertedDataset.value.filter(ds => !segregated.value.includes(ds.uid)).map(ds => ds.name)).concat(donutEvolutionConfig.value.table.columnNames.total)
359+
360+
return { head, body, config, colNames };
356361
});
357362
358363
function getData() {
@@ -773,6 +778,7 @@ defineExpose({
773778
774779
<DataTable
775780
v-if="mutableConfig.showTable"
781+
:colNames="table.colNames"
776782
:head="table.head"
777783
:body="table.body"
778784
:config="table.config"

src/components/vue-ui-donut.cy.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import VueUiDonut from './vue-ui-donut.vue';
22

33
describe('<VueUiDonut />', () => {
44
beforeEach(function () {
5+
const stub = cy.stub()
6+
Cypress.on('uncaught:exception', (err, runnable) => {
7+
if (err.message.includes('ResizeObserver')) {
8+
stub()
9+
return false
10+
}
11+
})
512
cy.fixture('donut.json').as('fixture');
613
cy.viewport(1000, 1100);
714
});

src/components/vue-ui-donut.vue

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,18 @@ const dataTable = computed(() => {
283283
backgroundColor: donutConfig.value.table.td.backgroundColor,
284284
color: donutConfig.value.table.td.color,
285285
outline: donutConfig.value.table.td.outline
286-
}
286+
},
287+
breakpoint: donutConfig.value.table.responsiveBreakpoint
287288
}
288289
290+
const colNames = [
291+
donutConfig.value.table.columnNames.series,
292+
donutConfig.value.table.columnNames.value,
293+
donutConfig.value.table.columnNames.percentage
294+
]
295+
289296
return {
297+
colNames,
290298
head,
291299
body,
292300
config
@@ -608,6 +616,7 @@ defineExpose({
608616
<!-- DATA TABLE -->
609617
<DataTable
610618
v-if="mutableConfig.showTable"
619+
:colNames="dataTable.colNames"
611620
:head="dataTable.head"
612621
:body="dataTable.body"
613622
:config="dataTable.config"

src/components/vue-ui-molecule.vue

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,21 @@ const dataTable = computed(() => {
384384
backgroundColor: moleculeConfig.value.table.td.backgroundColor,
385385
color: moleculeConfig.value.table.td.color,
386386
outline: moleculeConfig.value.table.td.outline
387-
}
387+
},
388+
breakpoint: moleculeConfig.value.table.responsiveBreakpoint
388389
}
389390
391+
const colNames = [
392+
moleculeConfig.value.table.translations.nodeName,
393+
moleculeConfig.value.table.translations.details,
394+
moleculeConfig.value.table.translations.parentNode
395+
]
396+
390397
return {
391398
head,
392399
body,
393-
config
400+
config,
401+
colNames
394402
}
395403
});
396404
@@ -535,6 +543,7 @@ defineExpose({
535543

536544
<DataTable
537545
v-if="mutableConfig.showTable"
546+
:colNames="dataTable.colNames"
538547
:head="dataTable.head"
539548
:body="dataTable.body"
540549
:config="dataTable.config"

src/components/vue-ui-mood-radar.vue

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,21 @@ const dataTable = computed(() => {
223223
backgroundColor: radarConfig.value.table.td.backgroundColor,
224224
color: radarConfig.value.table.td.color,
225225
outline: radarConfig.value.table.td.outline
226-
}
226+
},
227+
breakpoint: radarConfig.value.table.responsiveBreakpoint
227228
}
228229
230+
const colNames = [
231+
radarConfig.value.table.columnNames.series,
232+
radarConfig.value.table.columnNames.value,
233+
radarConfig.value.table.columnNames.percentage
234+
]
235+
229236
return {
230237
head,
231238
body,
232-
config
239+
config,
240+
colNames
233241
}
234242
});
235243
@@ -436,6 +444,7 @@ defineExpose({
436444
<!-- DATA TABLE -->
437445
<DataTable
438446
v-if="mutableConfig.showTable"
447+
:colNames="dataTable.colNames"
439448
:head="dataTable.head"
440449
:body="dataTable.body"
441450
:config="dataTable.config"

src/components/vue-ui-rings.cy.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ import VueUiRings from './vue-ui-rings.vue'
33
describe('<VueUiRings />', () => {
44

55
beforeEach(function() {
6+
const stub = cy.stub()
7+
Cypress.on('uncaught:exception', (err, runnable) => {
8+
if (err.message.includes('ResizeObserver')) {
9+
stub()
10+
return false
11+
}
12+
})
613
cy.fixture('rings.json').as('fixture');
714
cy.viewport(600, 800);
815
});

0 commit comments

Comments
 (0)