renusify 2.5.2 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/components/app/index.vue +74 -22
  2. package/components/app/toast/index.vue +76 -71
  3. package/components/app/toast/toast.vue +62 -44
  4. package/components/avatar/index.vue +207 -84
  5. package/components/button/buttonConfirm.vue +53 -26
  6. package/components/button/buttonGroup.js +0 -2
  7. package/components/button/buttonGroup.vue +310 -62
  8. package/components/button/index.vue +584 -100
  9. package/components/calendar/index.js +0 -2
  10. package/components/calendar/index.vue +326 -262
  11. package/components/calendar/month.vue +64 -55
  12. package/components/calendar/year.vue +30 -25
  13. package/components/card/index.vue +139 -59
  14. package/components/codeEditor/highlightCss.vue +38 -39
  15. package/components/codeEditor/highlightHtml.vue +64 -64
  16. package/components/codeEditor/highlightJs.vue +37 -38
  17. package/components/codeEditor/index.vue +129 -79
  18. package/components/codeEditor/run.vue +225 -39
  19. package/components/codeEditor/useCodeFormatter.js +150 -0
  20. package/components/confirm/index.vue +139 -80
  21. package/components/container/col.vue +5 -4
  22. package/components/container/divider.vue +28 -19
  23. package/components/container/index.vue +34 -15
  24. package/components/container/row.vue +26 -9
  25. package/components/container/spacer.vue +2 -4
  26. package/components/container/style.scss +3 -0
  27. package/components/content/index.vue +49 -32
  28. package/components/cropper/index.vue +401 -244
  29. package/components/float/index.vue +542 -415
  30. package/components/form/addressInput/index.vue +184 -109
  31. package/components/form/camInput/index.vue +370 -244
  32. package/components/form/checkInput/index.vue +138 -71
  33. package/components/form/checkboxInput/index.vue +93 -49
  34. package/components/form/colorInput/Alpha.vue +81 -83
  35. package/components/form/colorInput/Hue.vue +91 -68
  36. package/components/form/colorInput/Preview.vue +43 -47
  37. package/components/form/colorInput/Saturation.vue +101 -86
  38. package/components/form/colorInput/index.vue +71 -39
  39. package/components/form/colorInput/picker.vue +111 -106
  40. package/components/form/colorInput/useColor.js +153 -0
  41. package/components/form/dateInput/index.vue +691 -356
  42. package/components/form/dateInput/month.vue +63 -54
  43. package/components/form/dateInput/year.vue +35 -25
  44. package/components/form/fileInput/index.js +0 -1
  45. package/components/form/fileInput/index.vue +263 -106
  46. package/components/form/fileInput/single.vue +332 -168
  47. package/components/form/groupInput/index.vue +199 -101
  48. package/components/form/index.vue +189 -83
  49. package/components/form/input/index.vue +416 -377
  50. package/components/form/jsonInput/JsonView.vue +54 -56
  51. package/components/form/jsonInput/index.vue +247 -165
  52. package/components/form/maskInput/index.vue +252 -132
  53. package/components/form/numberInput/index.js +0 -1
  54. package/components/form/numberInput/index.vue +226 -117
  55. package/components/form/passwordInput/index.js +2 -1
  56. package/components/form/passwordInput/index.vue +269 -102
  57. package/components/form/radioInput/index.vue +143 -72
  58. package/components/form/rangeInput/index.vue +280 -167
  59. package/components/form/ratingInput/index.vue +57 -57
  60. package/components/form/selectInput/index.js +1 -3
  61. package/components/form/selectInput/index.vue +584 -296
  62. package/components/form/switchInput/index.vue +73 -59
  63. package/components/form/telInput/index.js +0 -1
  64. package/components/form/telInput/index.vue +238 -135
  65. package/components/form/textArea/index.vue +72 -35
  66. package/components/form/textEditor/index.vue +739 -0
  67. package/components/form/{text-editor → textEditor}/style.scss +8 -16
  68. package/components/form/textInput/index.vue +54 -32
  69. package/components/form/timeInput/index.vue +82 -55
  70. package/components/form/timeInput/range.vue +115 -94
  71. package/components/form/timeInput/timepicker.vue +382 -449
  72. package/components/form/uniqueInput/index.vue +105 -48
  73. package/components/form/unitInput/index.vue +139 -84
  74. package/components/formCreator/index.js +0 -1
  75. package/components/formCreator/index.vue +314 -148
  76. package/components/highlight/index.vue +41 -25
  77. package/components/highlight/style.scss +2 -2
  78. package/components/highlight/{mixin.js → useHighlight.js} +181 -160
  79. package/components/icon/index.vue +79 -33
  80. package/components/img/index.vue +250 -147
  81. package/components/img/preview.vue +180 -198
  82. package/components/img/svgImg.vue +42 -39
  83. package/components/index.js +5 -20
  84. package/components/infinite/index.js +3 -3
  85. package/components/infinite/index.vue +290 -66
  86. package/components/map/index.vue +428 -261
  87. package/components/map/route.vue +794 -487
  88. package/components/map/select.vue +118 -58
  89. package/components/menu/index.vue +206 -94
  90. package/components/meta/meta.js +26 -3
  91. package/components/modal/index.vue +382 -156
  92. package/components/notify/index.vue +204 -86
  93. package/components/notify/notification.vue +38 -55
  94. package/components/progress/circle.vue +189 -70
  95. package/components/progress/line.vue +266 -46
  96. package/components/searchBox/index.js +1 -3
  97. package/components/searchBox/index.vue +194 -101
  98. package/components/skeleton/index.vue +45 -20
  99. package/components/slider/index.vue +319 -156
  100. package/components/swiper/index.vue +237 -108
  101. package/components/table/crud/footer.vue +77 -53
  102. package/components/table/crud/header.vue +71 -72
  103. package/components/table/crud/index.vue +629 -399
  104. package/components/table/index.vue +721 -278
  105. package/components/timeAgo/index.vue +145 -96
  106. package/components/tour/index.vue +338 -235
  107. package/components/tree/index.vue +235 -89
  108. package/components/tree/tree-element.vue +106 -106
  109. package/directive/animate/index.js +77 -0
  110. package/directive/clickOutSide/index.js +98 -0
  111. package/directive/drag/index.js +153 -0
  112. package/directive/index.js +11 -13
  113. package/directive/intersect/index.js +263 -0
  114. package/directive/mask/index.js +67 -0
  115. package/directive/parallax/index.js +78 -0
  116. package/directive/ripple/index.js +14 -0
  117. package/directive/scroll/index.js +272 -24
  118. package/directive/sortable/index.js +274 -0
  119. package/directive/title/index.js +75 -0
  120. package/directive/touch/index.js +268 -0
  121. package/index.js +11 -19
  122. package/package.json +5 -2
  123. package/plugins/validation/Validate.js +88 -79
  124. package/scripts/generate-docs.mjs +226 -0
  125. package/scripts/menu.mjs +240 -0
  126. package/scripts/parser.mjs +1086 -0
  127. package/style/_index.scss +7 -0
  128. package/style/app.scss +13 -65
  129. package/style/colors.scss +5 -22
  130. package/style/functions/index.scss +8 -0
  131. package/style/mixins/index.scss +17 -5
  132. package/style/variables/base.scss +155 -178
  133. package/style/variables/color.scss +0 -12
  134. package/style/variables/utilities.scss +0 -180
  135. package/tools/helper.js +0 -8
  136. package/tools/icons.js +7 -2
  137. package/tools/root.js +71 -0
  138. package/components/app/style.scss +0 -41
  139. package/components/app/toast/style.scss +0 -20
  140. package/components/avatar/style.scss +0 -32
  141. package/components/bar/bottomNav.js +0 -1
  142. package/components/bar/bottomNav.vue +0 -28
  143. package/components/bar/bottomNavigationCircle.js +0 -2
  144. package/components/bar/bottomNavigationCircle.vue +0 -99
  145. package/components/bar/scss/bottomNav.scss +0 -67
  146. package/components/bar/scss/toolbar.scss +0 -174
  147. package/components/bar/toolbar/index.js +0 -8
  148. package/components/bar/toolbar/index.vue +0 -35
  149. package/components/bar/toolbar/laptop.vue +0 -33
  150. package/components/bar/toolbar/menuChilds.vue +0 -41
  151. package/components/bar/toolbar/menuLaptop.vue +0 -41
  152. package/components/bar/toolbar/menuMob.vue +0 -39
  153. package/components/bar/toolbar/mixin.js +0 -43
  154. package/components/bar/toolbar/mobile.vue +0 -34
  155. package/components/breadcrumb/bredcrumbItem.vue +0 -39
  156. package/components/breadcrumb/index.js +0 -3
  157. package/components/breadcrumb/index.vue +0 -71
  158. package/components/breadcrumb/style.scss +0 -51
  159. package/components/button/style.scss +0 -411
  160. package/components/card/style.scss +0 -86
  161. package/components/chart/chart.js +0 -1
  162. package/components/chart/chart.vue +0 -69
  163. package/components/chart/worldMap.js +0 -2
  164. package/components/chart/worldMap.vue +0 -1112
  165. package/components/chat/MessageList.vue +0 -163
  166. package/components/chat/chatInput.vue +0 -150
  167. package/components/chat/chatMsg.vue +0 -276
  168. package/components/chat/index.js +0 -11
  169. package/components/chat/index.vue +0 -113
  170. package/components/chip/index.js +0 -3
  171. package/components/chip/index.vue +0 -77
  172. package/components/chip/style.scss +0 -199
  173. package/components/codeEditor/mixin.js +0 -145
  174. package/components/countdown/index.js +0 -1
  175. package/components/countdown/index.vue +0 -105
  176. package/components/form/colorInput/mixin.js +0 -132
  177. package/components/form/fileInput/file.js +0 -148
  178. package/components/form/telInput/assets/flags.png +0 -0
  179. package/components/form/telInput/assets/flags@2x.png +0 -0
  180. package/components/form/text-editor/index.vue +0 -705
  181. package/components/icon/style.scss +0 -17
  182. package/components/infinite/div.js +0 -6
  183. package/components/infinite/div.vue +0 -193
  184. package/components/infinite/page.js +0 -3
  185. package/components/infinite/page.vue +0 -105
  186. package/components/list/index.js +0 -3
  187. package/components/list/index.vue +0 -122
  188. package/components/list/style.scss +0 -66
  189. package/components/message/index.js +0 -4
  190. package/components/message/index.vue +0 -40
  191. package/components/modal/style.scss +0 -146
  192. package/components/nestable/NestableItem.vue +0 -307
  193. package/components/nestable/editable.js +0 -44
  194. package/components/nestable/index.js +0 -1
  195. package/components/nestable/index.vue +0 -226
  196. package/components/nestable/methods.js +0 -416
  197. package/components/progress/style.scss +0 -229
  198. package/components/table/style.scss +0 -338
  199. package/components/tabs/index.js +0 -3
  200. package/components/tabs/index.vue +0 -151
  201. package/components/timeline/index.js +0 -6
  202. package/components/timeline/index.vue +0 -76
  203. package/directive/resize/index.js +0 -30
  204. package/directive/skeleton/index.js +0 -27
  205. package/directive/skeleton/style.scss +0 -37
  206. package/plugins/request/Request.js +0 -68
  207. package/style/animation.scss +0 -94
  208. package/style/style.scss +0 -8
  209. package/tools/rootable.js +0 -75
  210. /package/components/form/{text-editor → textEditor}/index.js +0 -0
  211. /package/components/form/{text-editor → textEditor}/preview.js +0 -0
  212. /package/components/form/{text-editor → textEditor}/preview.vue +0 -0
@@ -4,7 +4,7 @@
4
4
  :class="{
5
5
  [`${$r.prefix}table`]:true,
6
6
  'table-editable':editable,
7
- 'table-bordered':borderd,
7
+ 'table-bordered':bordered,
8
8
  'row-thin':thin,
9
9
  'table-fixed-header':fixedHeader,
10
10
  'table-sortable':sortable,
@@ -20,11 +20,13 @@
20
20
  </span>
21
21
  </div>
22
22
  <div class="table-wrapper">
23
- <div ref="table" class="table-container">
23
+ <div ref="tableRef" class="table-container">
24
24
  <r-progress-line v-if="loading" color="color-two"></r-progress-line>
25
25
  <table>
26
26
  <thead>
27
27
  <tr>
28
+ <!-- @slot Slot for custom header rendering
29
+ @binding {Array} header - Table header configuration -->
28
30
  <slot name="header" v-bind:header="th">
29
31
  <th v-for="(item,key) in th" :key="key"
30
32
  :class="{'color-info-text':sortKey===item.value}"
@@ -40,18 +42,27 @@
40
42
  <template v-for="(item,key) in lists" :key="gen_key(item)||key">
41
43
  <template v-if="true">
42
44
  <tr :key="`${gen_key(item)||key}- f`">
45
+ <!-- Slot for custom row rendering
46
+ @binding {*} item - Row data item
47
+ @binding {Function} open - Function to toggle row expansion
48
+ @binding {Number|null} opened - Currently opened row index
49
+ @binding {Function} show - Function to check if expand button should be shown
50
+ @binding {Array} th - Table header configuration -->
43
51
  <slot :key="key" :item="item" :open="open" :opened="opened" :show="show" :th="th"
44
52
  name="row">
45
53
  <td v-for="(value,k) in th" :key="`${key}- ${k}`">
54
+ <!-- Dynamic slot for individual cell content, named 'td-[value.value]'
55
+ @binding {*} item - Row data item
56
+ @binding {Object} value - Column configuration -->
46
57
  <slot :item="item" :value="value" :name="'td-'+value.value">
47
- <div>
48
- <r-btn v-if="show(k)"
49
- icon text @click.prevent="open(key)">
50
- <r-icon v-if="opened!==key" v-html="$r.icons.plus"></r-icon>
51
- <r-icon v-else v-html="$r.icons.minus"></r-icon>
52
- </r-btn>
53
- {{ item[value.value] }}
54
- </div>
58
+ <div>
59
+ <r-btn v-if="show(k)"
60
+ icon text @click.prevent="open(key)">
61
+ <r-icon v-if="opened!==key" v-html="$r.icons.plus"></r-icon>
62
+ <r-icon v-else v-html="$r.icons.minus"></r-icon>
63
+ </r-btn>
64
+ {{ item[value.value] }}
65
+ </div>
55
66
  </slot>
56
67
  </td>
57
68
  </slot>
@@ -98,311 +109,743 @@
98
109
  </r-modal>
99
110
  </template>
100
111
 
101
- <script>
102
- import './style.scss'
103
-
104
- export default {
105
- name: 'r-table',
106
- props: {
107
- transition: {
108
- type: String,
109
- default: 'table-row'
110
- },
111
- keyItem: [String, Function],
112
- thin: Boolean,
113
- responsive: Boolean,
114
- translate: Boolean,
115
- editable: Boolean,
116
- stripped: Boolean,
117
- borderd: Boolean,
118
- sortable: Object,
119
- fixedHeader: Boolean,
120
- fixedFirstColumn: Boolean,
121
- headers: Array,
122
- items: Array
112
+ <script setup>
113
+ import {ref, computed, watch, onMounted, nextTick, inject} from 'vue'
114
+
115
+ /**
116
+ * @example // Table usage
117
+ * <template>
118
+ * <r-table
119
+ * :transition="transition"
120
+ * :key-Item="keyItem"
121
+ * :thin="thin"
122
+ * :responsive="responsive"
123
+ * :translate="translate"
124
+ * :editable="editable"
125
+ * :stripped="stripped"
126
+ * :bordered="bordered"
127
+ * :sortable="sortable"
128
+ * :fixed-Header="fixedHeader"
129
+ * :fixed-First-Column="fixedFirstColumn"
130
+ * :headers="headers"
131
+ * :items="items"
132
+ * ></r-table>
133
+ * </template>
134
+ *
135
+ * <script>
136
+ * import { ref } from 'vue'
137
+ *
138
+ * const transition = ref('table-row')
139
+ * const keyItem = ref(null)
140
+ * const thin = ref(false)
141
+ * const responsive = ref(false)
142
+ * const translate = ref(false)
143
+ * const editable = ref(true)
144
+ * const stripped = ref(true)
145
+ * const borderd = ref(false)
146
+ *
147
+ * const sortable = ref({
148
+ * id: true,
149
+ * name: true,
150
+ * age: false,
151
+ * skill: 'vuejs'
152
+ * })
153
+ *
154
+ * const fixedHeader = ref(false)
155
+ * const fixedFirstColumn = ref(false)
156
+ *
157
+ * const headers = ref([
158
+ * { text: 'id', value: 'id' },
159
+ * { text: 'name', value: 'name' },
160
+ * { text: 'lastname', value: 'lastname' },
161
+ * { text: 'age', value: 'age' },
162
+ * { text: 'skill', value: 'skill' }
163
+ * ])
164
+ *
165
+ * const items = ref([
166
+ * { id: 1, name: 'Smko', lastname: 'Bzd', age: 29, skill: { vuejs: 20, python: 25 } },
167
+ * { id: 2, name: 'Noah', lastname: 'Ava', age: 23, skill: { vuejs: 18, python: 32 } },
168
+ * { id: 3, name: 'James', lastname: 'Barr', age: 18, skill: { vuejs: 45, python: 25 } },
169
+ * { id: 4, name: 'William', lastname: 'Emma', age: 30, skill: { vuejs: 30, python: 50 } },
170
+ * { id: 5, name: 'Liam', lastname: 'Emma', age: 53, skill: { vuejs: 15, python: 20 } }
171
+ * ])
172
+ * <//script>
173
+ *
174
+ * */
175
+ const props = defineProps({
176
+ /**
177
+ * CSS transition name for table rows
178
+ * @type {String}
179
+ * @default 'table-row'
180
+ */
181
+ transition: {
182
+ type: String,
183
+ default: 'table-row'
123
184
  },
124
- data() {
125
- return {
126
- key: 0,
127
- showTable: true,
128
- opened: null,
129
- sortKey: null,
130
- sortAsc: true,
131
- showModal: false,
132
- loading: false,
133
- eventsHandler: null,
134
- hidden_col: {},
135
- hidden: {},
136
- cols: []
185
+ /**
186
+ * Key property or function to generate unique row keys
187
+ * @type {String|Function}
188
+ */
189
+ keyItem: [String, Function],
190
+ /**
191
+ * Applies thin row styling
192
+ * @type {Boolean}
193
+ */
194
+ thin: Boolean,
195
+ /**
196
+ * Enables responsive column hiding on small screens
197
+ * @type {Boolean}
198
+ */
199
+ responsive: Boolean,
200
+ /**
201
+ * Enables text translation for header texts
202
+ * @type {Boolean}
203
+ */
204
+ translate: Boolean,
205
+ /**
206
+ * Enables column configuration editing
207
+ * @type {Boolean}
208
+ */
209
+ editable: Boolean,
210
+ /**
211
+ * Applies stripped row styling
212
+ * @type {Boolean}
213
+ */
214
+ stripped: Boolean,
215
+ /**
216
+ * Applies bordered styling
217
+ * @type {Boolean}
218
+ */
219
+ bordered: Boolean,
220
+ /**
221
+ * Sorting configuration object mapping column values to sortable keys
222
+ * @type {Object}
223
+ */
224
+ sortable: Object,
225
+ /**
226
+ * Enables fixed header
227
+ * @type {Boolean}
228
+ */
229
+ fixedHeader: Boolean,
230
+ /**
231
+ * Enables fixed first column
232
+ * @type {Boolean}
233
+ */
234
+ fixedFirstColumn: Boolean,
235
+ /**
236
+ * Array of header configuration objects
237
+ * @type {Array}
238
+ */
239
+ headers: Array,
240
+ /**
241
+ * Array of data items for table rows
242
+ * @type {Array}
243
+ */
244
+ items: Array
245
+ })
246
+
247
+ const emit = defineEmits([
248
+ /**
249
+ * Emitted when table sorting changes
250
+ * @param {Object} sort - Sorting information
251
+ * @param {String} sort.key - Column key being sorted
252
+ * @param {Boolean} sort.asc - Whether sorting is ascending
253
+ */
254
+ 'sort'
255
+ ])
256
+
257
+ const {$helper, $storage} = inject('renusify')
258
+
259
+ const key = ref(0)
260
+ const opened = ref(null)
261
+ const sortKey = ref(null)
262
+ const sortAsc = ref(true)
263
+ const showModal = ref(false)
264
+ const loading = ref(false)
265
+ const hidden_col = ref({})
266
+ const hidden = ref({})
267
+ const cols = ref([])
268
+
269
+ const tableRef = ref(null)
270
+
271
+ const priority = computed(() => {
272
+ const res = {}
273
+ th.value.forEach((item) => {
274
+ if (item && $helper.ifHas(item, false, 'option', 'priority') !== false) {
275
+ res[item.value] = item.option.priority
276
+ } else {
277
+ res[item.value] = 0
137
278
  }
138
- },
139
- watch: {
140
- items: {
141
- immediate: true,
142
- handler() {
143
- setTimeout(() => {
144
- this.setup()
145
- }, 100)
146
- },
279
+ })
280
+ return res
281
+ })
282
+
283
+ const lists = computed(() => {
284
+ if (!props.items) return []
285
+
286
+ let res = [...props.items]
287
+
288
+ if (res.length > 0 && props.sortable && sortKey.value && props.sortable[sortKey.value]) {
289
+ return res.sort(dynamicSort(sortKey.value, sortAsc.value, props.sortable[sortKey.value]))
290
+ }
291
+ return res
292
+ })
293
+
294
+ const th = computed(() => {
295
+ const res = []
296
+ const list = cols.value.length > 0 ? cols.value : th_all.value
297
+
298
+ list.forEach((item) => {
299
+ if (item && !(item.value in hidden.value) && !(item.value in hidden_col.value)) {
300
+ res.push(item)
147
301
  }
148
- },
149
- computed: {
150
- priority() {
151
- let res = {}
152
- this.th.forEach((item) => {
153
- if (this.$helper.ifHas(item, false, 'option', 'priority') !== false) {
154
- res[item.value] = item['option']['priority']
155
- } else {
156
- res[item.value] = 0
157
- }
158
- })
302
+ })
303
+ return res
304
+ })
159
305
 
160
- return res
161
- },
162
- lists() {
163
- let res = this.items
306
+ const th_all = computed(() => {
307
+ const res = []
164
308
 
165
- if (res && this.sortable && this.sortable[this.sortKey]) {
166
- return res.sort(this.dynamicSort(this.sortKey, this.sortAsc, this.sortable[this.sortKey]))
309
+ if (props.headers && props.headers.length > 0) {
310
+ props.headers.forEach((item) => {
311
+ if (item) {
312
+ res.push(item)
167
313
  }
168
- return res
169
- },
170
- th() {
171
- let res = []
172
- let list = this.cols.length > 0 ? this.cols : this.th_all
173
- list.forEach((item) => {
174
- if (item && !(item.value in this.hidden) && !(item.value in this.hidden_col)) {
175
- res.push(item)
176
- }
177
- })
178
- return res
179
- },
180
- th_all() {
181
- let res = []
182
- if (this.headers) {
183
- this.headers.forEach((item) => {
184
- if (item) {
185
- res.push(item)
186
- }
187
- })
188
- } else {
189
- for (let name in this.items[0]) {
190
- if (this.$helper.hasKey(this.items[0], name)) {
191
- res.push({text: name, value: name})
192
- }
193
- }
314
+ })
315
+ } else if (props.items && props.items.length > 0) {
316
+ for (let name in props.items[0]) {
317
+ if ($helper.hasKey(props.items[0], name)) {
318
+ res.push({text: name, value: name})
194
319
  }
195
- return res
196
- },
197
- hash_key() {
198
- let r = ''
199
- this.th_all.forEach((item) => {
200
- if (item) {
201
- r += item.value
202
- }
203
- })
204
- return this.$helper.hash(r)
205
320
  }
206
- },
207
- methods: {
208
- check_hidden() {
209
- const d = this.$storage.get('table_' + this.hash_key)
210
- if (d) {
211
- let res = {}
212
- d.forEach((item) => {
213
- if (item && item.show === false) {
214
- res[item.value] = true
215
- }
216
- })
217
- this.hidden_col = res
218
- this.cols = d
321
+ }
322
+
323
+ return res
324
+ })
325
+
326
+ const hash_key = computed(() => {
327
+ let r = ''
328
+ th_all.value.forEach((item) => {
329
+ if (item) {
330
+ r += item.value
331
+ }
332
+ })
333
+ return $helper.hash(r)
334
+ })
335
+
336
+ // Methods
337
+ const check_hidden = () => {
338
+ const d = $storage.get('table_' + hash_key.value)
339
+ if (d) {
340
+ const res = {}
341
+ d.forEach((item) => {
342
+ if (item && item.show === false) {
343
+ res[item.value] = true
219
344
  }
345
+ })
346
+ hidden_col.value = res
347
+ cols.value = d
348
+ }
349
+ }
220
350
 
221
- },
222
- store_db(data) {
223
- this.$storage.set('table_' + this.hash_key, data)
224
- this.key++
225
- this.check_hidden()
226
- if (this.responsive) {
227
- this.build()
351
+ const store_db = (data) => {
352
+ $storage.set('table_' + hash_key.value, data)
353
+ key.value++
354
+ check_hidden()
355
+ if (props.responsive) {
356
+ build()
357
+ }
358
+ }
359
+
360
+ const open_modal = () => {
361
+ const d = $storage.get('table_' + hash_key.value)
362
+ if (d) {
363
+ cols.value = []
364
+ d.forEach((item) => {
365
+ if (item) {
366
+ cols.value.push(item)
228
367
  }
229
- },
230
- open_modal() {
231
- const d = this.$storage.get('table_' + this.hash_key)
232
- if (d) {
233
- this.cols = []
234
- d.forEach((item) => {
235
- if (item) {
236
- this.cols.push(item)
237
- }
238
- })
239
- } else {
240
- this.cols = []
241
- this.th_all.forEach((item) => {
242
- if (item) {
243
- this.cols.push({text: item.text, value: item.value, show: true})
244
- }
245
- })
368
+ })
369
+ } else {
370
+ cols.value = []
371
+ th_all.value.forEach((item) => {
372
+ if (item) {
373
+ cols.value.push({text: item.text, value: item.value, show: true})
246
374
  }
375
+ })
376
+ }
377
+
378
+ showModal.value = true
379
+ }
380
+
381
+ const gen_key = (item) => {
382
+ if (!props.keyItem) return null
383
+
384
+ if (typeof props.keyItem === 'string') {
385
+ return item[props.keyItem]
386
+ }
387
+
388
+ if (typeof props.keyItem === 'function') {
389
+ return props.keyItem(item)
390
+ }
247
391
 
248
- this.showModal = true
249
- },
250
- gen_key(item) {
251
- if (!this.keyItem) {
252
- return false
392
+ return null
393
+ }
394
+
395
+ const open = (rowKey) => {
396
+ if (opened.value === rowKey) {
397
+ opened.value = null
398
+ } else {
399
+ opened.value = rowKey
400
+ }
401
+ }
402
+
403
+ const show = (k) => {
404
+ if (Object.keys(hidden.value).length === 0) {
405
+ return false
406
+ }
407
+
408
+ if (Array.isArray(th.value) && k === 0) {
409
+ return true
410
+ }
411
+
412
+ const keys = Object.keys(th.value)
413
+ return keys[0] === k.toString()
414
+ }
415
+
416
+ const setup = () => {
417
+ if (props.editable) {
418
+ check_hidden()
419
+ const s = $storage.get('table_sort')
420
+ if (s && hash_key.value in s) {
421
+ sortKey.value = s[hash_key.value][0]
422
+ sortAsc.value = s[hash_key.value][1]
423
+ }
424
+ }
425
+
426
+ if (props.responsive) {
427
+ build()
428
+ }
429
+ }
430
+
431
+ const build = () => {
432
+ if (!tableRef.value) return
433
+
434
+ opened.value = null
435
+ hidden.value = {}
436
+
437
+ nextTick(() => {
438
+ const table = tableRef.value.querySelector('table')
439
+ if (!table) return
440
+
441
+ const all_th = table.querySelectorAll('th') || []
442
+ const th_w = []
443
+
444
+ all_th.forEach((th) => {
445
+ if (th) {
446
+ th_w.push(th.clientWidth)
253
447
  }
254
- if (typeof this.keyItem === 'string') {
255
- return item[this.keyItem]
448
+ })
449
+
450
+ const thn_w = {}
451
+ let i = 0
452
+ for (let name in priority.value) {
453
+ if ($helper.hasKey(priority.value, name)) {
454
+ thn_w[name] = th_w[i]
455
+ i++
256
456
  }
257
- return this.keyItem(item)
258
- },
259
- open(key) {
260
- if (this.opened === key) {
261
- this.opened = null
262
- } else {
263
- this.opened = key
457
+ }
458
+
459
+ if (tableRef.value.clientWidth < table.clientWidth) {
460
+ const [show, hide] = extractor(tableRef.value.clientWidth, table.clientWidth, thn_w, priority.value)
461
+ hidden.value = hide
462
+ }
463
+ })
464
+ }
465
+
466
+ const extractor = (width, table_w, th, priority, removed = 0, hide = {}) => {
467
+ if (table_w > width + removed) {
468
+ const name = remove_one(priority)
469
+ hide[name] = true
470
+ const newPriority = {...priority}
471
+ delete newPriority[name]
472
+ return extractor(width, table_w, th, newPriority, removed + th[name], hide)
473
+ }
474
+ return [priority, hide]
475
+ }
476
+
477
+ const remove_one = (priority) => {
478
+ const res = []
479
+ for (let name in priority) {
480
+ if ($helper.hasKey(priority, name)) {
481
+ res.push({name: name, value: priority[name]})
482
+ }
483
+ }
484
+
485
+ res.sort((a, b) => {
486
+ return a.value - b.value
487
+ })
488
+
489
+ return res[0]?.name
490
+ }
491
+
492
+ const getText = (key) => {
493
+ if (Array.isArray(props.headers)) {
494
+ const header = props.headers.find(item => item.value === key)
495
+ return header?.text || key
496
+ }
497
+ return key
498
+ }
499
+
500
+ const sorting = (name) => {
501
+ if (props.sortable && props.sortable[name]) {
502
+ loading.value = true
503
+
504
+ setTimeout(() => {
505
+ loading.value = false
506
+ }, 500)
507
+
508
+ if (sortKey.value === name) {
509
+ sortAsc.value = !sortAsc.value
510
+ } else {
511
+ sortKey.value = name
512
+ sortAsc.value = true
513
+ }
514
+
515
+ if (props.editable) {
516
+ let t = $storage.get('table_sort') || {}
517
+ t[hash_key.value] = [name, sortAsc.value]
518
+ $storage.set('table_sort', t)
519
+ }
520
+
521
+ emit('sort', {key: name, asc: sortAsc.value})
522
+ }
523
+ }
524
+
525
+ const dynamicSort = (property, sortAsc, sortable_key = undefined) => {
526
+ let sortOrder = sortAsc ? 1 : -1
527
+
528
+ return function (a, b) {
529
+ let result = 0
530
+
531
+ if (a[property] !== undefined && b[property] !== undefined) {
532
+ let av = a[property]
533
+ let bv = b[property]
534
+
535
+ if (sortable_key && av && bv &&
536
+ av[sortable_key] !== undefined &&
537
+ bv[sortable_key] !== undefined) {
538
+ av = av[sortable_key]
539
+ bv = bv[sortable_key]
264
540
  }
265
- },
266
- show(k) {
267
- if (this.$helper.size(this.hidden) === 0) {
268
- return false
541
+
542
+ if (av < bv) {
543
+ result = -1
544
+ } else if (av > bv) {
545
+ result = 1
269
546
  }
270
- if (this.$helper.isArray(this.th) && k === 0) {
271
- return true
547
+ } else if (a[property] === undefined && b[property] !== undefined) {
548
+ result = -1
549
+ } else if (a[property] !== undefined && b[property] === undefined) {
550
+ result = 1
551
+ }
552
+
553
+ return result * sortOrder
554
+ }
555
+ }
556
+
557
+
558
+ onMounted(() => {
559
+ setup()
560
+ })
561
+
562
+ watch(() => props.items, () => {
563
+ setTimeout(() => {
564
+ setup()
565
+ }, 100)
566
+ }, {immediate: true})
567
+
568
+ </script>
569
+ <style lang="scss">
570
+ @use "sass:map";
571
+ @use "../../style" as *;
572
+
573
+ $data-table-thin-header-height: 38px !default;
574
+ $data-table-thin-row-height: 32px !default;
575
+ $data-table-regular-row-height: 42px !default;
576
+ $data-table-regular-header-height: 38px !default;
577
+
578
+ .#{$prefix}table {
579
+ position: relative;
580
+
581
+ .table-wrapper {
582
+ background-color: var(--color-sheet-container-lowest);
583
+ color: var(--color-on-sheet);
584
+ }
585
+
586
+ .table-svg-path {
587
+ fill: var(--color-sheet);
588
+ }
589
+
590
+ .table-editable-icon {
591
+ background-color: var(--color-sheet);
592
+ color: var(--color-on-sheet);
593
+ }
594
+
595
+ &.table-fixed-header {
596
+ thead th {
597
+ box-shadow: inset 0 -2px var(--color-border)
598
+ }
599
+ }
600
+
601
+ thead {
602
+ tr {
603
+ &:last-child th {
604
+ border-bottom: 1px solid var(--color-border)
272
605
  }
273
- const l = Object.keys(this.th)
274
- return l[0] === k;
275
-
276
- },
277
- setup() {
278
- if (this.editable) {
279
- this.check_hidden()
280
- const s = this.$storage.get('table_sort')
281
- if (s && this.hash_key in s) {
282
- this.sortKey = s[this.hash_key][0]
283
- this.sortAsc = s[this.hash_key][1]
284
- }
606
+
607
+ th {
608
+ background-color: var(--color-sheet);
609
+ color: var(--color-on-sheet)
285
610
  }
286
- if (this.responsive) {
287
- this.build()
611
+ }
612
+ }
613
+
614
+ &.table-fixed-first-columns {
615
+ tr {
616
+ th:first-child {
617
+ background: var(--color-sheet);
618
+ color: var(--color-on-sheet)
288
619
  }
289
- },
290
- build() {
291
- let el = this.$refs.table
292
- if (!el) {
293
- return
620
+
621
+ td:first-child {
622
+ background: var(--color-sheet);
623
+ color: var(--color-on-sheet)
294
624
  }
295
- this.opened = null
296
- this.hidden = {}
297
- setTimeout(() => {
298
- let table = el.querySelector('table')
299
- let all_th = table.querySelectorAll('th') || []
300
- let th_w = []
301
- all_th.forEach((th) => {
302
- if (th) {
303
- th_w.push(th.clientWidth)
304
- }
305
- })
306
- let thn_w = {}
307
- let i = 0
308
- for (let name in this.priority) {
309
- if (this.$helper.hasKey(this.priority, name)) {
310
- thn_w[name] = th_w[i]
311
- i++
312
- }
625
+
626
+ &:hover {
627
+ td:first-child {
628
+ background: var(--color-sheet-container);
629
+ color: var(--color-on-sheet)
313
630
  }
314
- if (el.clientWidth < table.clientWidth) {
315
- const [show, hide] = this.extractor(el.clientWidth, table.clientWidth, thn_w, this.priority)
316
- this.hidden = hide
631
+ }
632
+ }
633
+ }
634
+
635
+ &.table-stripped {
636
+ tbody {
637
+ tr:nth-child(2n):not(:hover) {
638
+ td {
639
+ background: var(--color-sheet-container-low)
317
640
  }
318
- }, 10)
641
+ }
642
+ }
643
+ }
319
644
 
320
- },
321
- extractor(width, table_w, th, priority, removed = 0, hide = {}) {
645
+ tbody {
646
+ tr {
647
+ &:active {
648
+ background: var(--color-sheet-container)
649
+ }
322
650
 
323
- if (table_w > width + removed) {
324
- const name = this.remove_one(priority)
325
- hide[name] = true
326
- delete priority[name]
327
- return this.extractor(width, table_w, th, priority, removed + th[name], hide)
651
+ &:hover {
652
+ background: var(--color-sheet-container)
328
653
  }
329
- return [priority, hide]
330
-
331
- },
332
- remove_one(priority) {
333
- let res = []
334
- for (let name in priority) {
335
- if (this.$helper.hasKey(priority, name)) {
336
- res.push({'name': name, 'value': priority[name]})
337
- }
654
+ }
655
+
656
+ tr:not(:last-child) {
657
+ td {
658
+ border-bottom: 1px solid var(--color-border)
338
659
  }
339
- res = res.sort((a, b) => {
340
- return a['value'] - b['value']
341
- })
342
- return res[0]['name']
343
-
344
- },
345
- getText(key) {
346
- if (this.$helper.isArray(this.headers)) {
347
- const lng = this.headers.length
348
- for (let i = 0; i < lng; i++) {
349
- const item = this.headers[i]
350
- if (item.value === key) {
351
- return item.text
660
+ }
661
+ }
662
+
663
+ &.table-bordered .table-wrapper {
664
+ border: 1px solid var(--color-border);
665
+ border-collapse: collapse;
666
+ }
667
+
668
+ .table-wrapper {
669
+ border-radius: map.get($borders, 'lg');
670
+ overflow: hidden;
671
+ }
672
+
673
+ table {
674
+ width: 100%;
675
+ border-spacing: 0;
676
+ border-collapse: collapse;
677
+ }
678
+
679
+ td, th {
680
+ padding: 0 16px;
681
+ @include ltr() {
682
+ text-align: left
683
+ }
684
+ @include rtl() {
685
+ text-align: right
686
+ }
687
+ }
688
+
689
+ th {
690
+ user-select: none;
691
+ font-size: 14px;
692
+ font-weight: bold;
693
+ height: $data-table-regular-header-height;
694
+
695
+ }
696
+
697
+ td {
698
+ font-size: 14px;
699
+ font-weight: normal;
700
+ height: $data-table-regular-row-height;
701
+ }
702
+
703
+ &.row-thin {
704
+ th {
705
+ font-size: 12px;
706
+ height: $data-table-thin-header-height;
707
+
708
+ }
709
+
710
+ td {
711
+ font-size: 12px;
712
+ height: $data-table-thin-row-height
713
+ }
714
+ }
715
+
716
+ .table-container {
717
+ overflow-x: auto
718
+ }
719
+
720
+ &.table-fixed-header {
721
+ .table-container {
722
+ overflow-y: auto;
723
+ max-height: 85vh;
724
+ }
725
+
726
+ thead {
727
+ th {
728
+ border-bottom: 0px !important;
729
+ position: sticky;
730
+ top: 0;
731
+ z-index: 2;
732
+
733
+ tr:nth-child(2) {
734
+ th {
735
+ top: $data-table-regular-header-height
352
736
  }
353
737
  }
738
+ }
739
+ }
740
+ }
354
741
 
355
- } else {
356
- return key
742
+ &.table-fixed-first-columns {
743
+ tr {
744
+ position: relative;
745
+
746
+ th:first-child {
747
+ min-width: 300px !important;
748
+ position: sticky;
749
+ width: 300px;
750
+ @include rtl() {
751
+ right: 0;
752
+ }
753
+ @include ltr() {
754
+ left: 0;
755
+ }
756
+ z-index: map.get($z-index, 'medium');
357
757
  }
358
- },
359
- sorting(name) {
360
- if (this.sortable && this.sortable[name]) {
361
- this.loading = true
362
- setTimeout(() => {
363
- this.loading = false
364
- }, 500)
365
- if (this.sortKey === name) {
366
- this.sortAsc = !this.sortAsc
367
- } else {
368
- this.sortKey = name
369
- this.sortAsc = true
758
+
759
+ td:first-child {
760
+ position: sticky;
761
+ width: 300px;
762
+ @include rtl() {
763
+ right: 0;
370
764
  }
371
- if (this.editable) {
372
- let t = this.$storage.get('table_sort')
373
- if (!t) {
374
- t = {}
375
- }
376
- t[this.hash_key] = [name, this.sortAsc]
377
- this.$storage.set('table_sort', t)
765
+ @include ltr() {
766
+ left: 0;
378
767
  }
768
+ height: auto;
769
+ z-index: map.get($z-index, 'low');
379
770
  }
380
- },
381
- dynamicSort(property, sortAsc, sortable_key = undefined) {
382
- let sortOrder = 1
383
- if (!sortAsc) {
384
- sortOrder = -1
771
+ }
772
+ }
773
+
774
+ &.table-sortable {
775
+ th {
776
+ &:hover {
777
+ cursor: pointer;
385
778
  }
386
- const that = this
387
- return function (a, b) {
388
- let result = -1
389
- if (a[property] !== undefined && b[property] !== undefined) {
390
- let av = a[property]
391
- let bv = b[property]
392
- if (av[sortable_key] !== undefined && bv[sortable_key] !== undefined) {
393
- av = av[sortable_key]
394
- bv = bv[sortable_key]
395
- }
396
- result = (av < bv) ? -1 : (av > bv) ? 1 : 0
397
- } else if (a[property] === undefined && b[property] !== undefined) {
398
- result = -1
399
- } else if (a[property] !== undefined && b[property] === undefined) {
400
- result = 1
401
- }
779
+ }
780
+ }
402
781
 
403
- return result * sortOrder
782
+ &.table-editable {
783
+ .table-editable-icon {
784
+ cursor: pointer;
785
+ border-radius: 20px 20px 0 0;
786
+ border: none;
787
+ min-width: 25px !important;
788
+ padding-top: 8px;
789
+ height: 30px !important;
790
+ }
791
+
792
+ .table-wrapper {
793
+ @include rtl() {
794
+ border-top-left-radius: 0;
795
+ }
796
+ @include ltr() {
797
+ border-top-right-radius: 0;
404
798
  }
405
799
  }
800
+
801
+ .table-svg {
802
+ @include ltr() {
803
+ transform: rotateY(180deg);
804
+ }
805
+ }
806
+ }
807
+
808
+ .sort-desc {
809
+ transform: rotate(180deg) !important;
810
+ }
811
+
812
+ tr, td, td > * {
813
+ transition: height .4s ease-in-out;
814
+ }
815
+
816
+ td > * {
817
+ overflow-y: hidden;
818
+ overflow-x: auto;
819
+ }
820
+
821
+ .tr-hidden {
822
+ overflow: hidden;
823
+ }
824
+
825
+ .table-row-enter-active, .table-row-leave-active {
826
+ transition: height .3s linear;
827
+ line-height: 0;
828
+ }
829
+
830
+ .table-row-enter-from {
831
+ td {
832
+ height: 0;
833
+ line-height: 0;
834
+ overflow: hidden;
835
+ }
836
+ }
837
+
838
+ .table-row-leave-to {
839
+ td {
840
+ height: 0;
841
+ line-height: 0;
842
+ overflow: hidden;
843
+
844
+ }
845
+ }
846
+
847
+ .table-row-move {
848
+ transition: transform .3s ease-in-out;
406
849
  }
407
850
  }
408
- </script>
851
+ </style>