11<script setup>
2+ import { computed , onMounted , ref } from " vue" ;
23import Shape from " ./Shape.vue" ;
34
45const 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({
1118const { backgroundColor: thbg , color: thc , outline: tho } = props .config .th ;
1219const { 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 : 3 px ; gap : 3 px " >
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 : 5 px ; justify-content : flex-end ; width : 100 % ; padding-right : 3 px ; " >
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 : 3 px ; gap : 3 px " >
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 : 5 px ; justify-content : flex-end ; width : 100 % ; padding-right : 3 px ; " >
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 >
0 commit comments