@fastkit/vui 0.6.39 → 0.6.40

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 (188) hide show
  1. package/dist/tool/index.js +3 -0
  2. package/dist/tool/vite-plugin.d.ts.map +1 -1
  3. package/dist/vui.cjs.js +180 -5
  4. package/dist/vui.cjs.prod.js +180 -5
  5. package/dist/vui.css +24 -14
  6. package/dist/vui.d.ts +2430 -12
  7. package/dist/vui.esm-bundler.js +180 -7
  8. package/dist/vui.min.css +1 -1
  9. package/dist/vui.min.css.map +1 -1
  10. package/package.json +8 -7
  11. package/src/.DS_Store +0 -0
  12. package/src/assets/.DS_Store +0 -0
  13. package/src/assets/builtins/color-scheme.ts +9 -0
  14. package/src/assets/builtins/media-match.ts +3 -0
  15. package/src/components/.DS_Store +0 -0
  16. package/src/components/VAccordion/VAccordion.scss +2 -0
  17. package/src/components/VAccordion/VAccordion.tsx +5 -0
  18. package/src/components/VAccordion/index.ts +1 -0
  19. package/src/components/VApp/VApp.tsx +17 -0
  20. package/src/components/VApp/index.ts +1 -0
  21. package/src/components/VBreadcrumbs/VBreadcrumbs.scss +61 -0
  22. package/src/components/VBreadcrumbs/VBreadcrumbs.tsx +137 -0
  23. package/src/components/VBreadcrumbs/index.ts +1 -0
  24. package/src/components/VButton/.DS_Store +0 -0
  25. package/src/components/VButton/VButton.scss +137 -0
  26. package/src/components/VButton/VButton.tsx +148 -0
  27. package/src/components/VButton/VButtonGroup.scss +23 -0
  28. package/src/components/VButton/VButtonGroup.tsx +81 -0
  29. package/src/components/VButton/index.ts +2 -0
  30. package/src/components/VCard/VCard.scss +3 -0
  31. package/src/components/VCard/VCard.tsx +20 -0
  32. package/src/components/VCard/VCardActions.scss +10 -0
  33. package/src/components/VCard/VCardActions.tsx +16 -0
  34. package/src/components/VCard/VCardContent.scss +3 -0
  35. package/src/components/VCard/VCardContent.tsx +16 -0
  36. package/src/components/VCard/index.ts +3 -0
  37. package/src/components/VCheckable/VCheckable.scss +103 -0
  38. package/src/components/VCheckable/VCheckable.tsx +60 -0
  39. package/src/components/VCheckable/index.ts +1 -0
  40. package/src/components/VCheckbox/VCheckbox.scss +56 -0
  41. package/src/components/VCheckbox/VCheckbox.tsx +63 -0
  42. package/src/components/VCheckbox/index.ts +1 -0
  43. package/src/components/VCheckboxGroup/.DS_Store +0 -0
  44. package/src/components/VCheckboxGroup/VCheckboxGroup.tsx +11 -0
  45. package/src/components/VCheckboxGroup/index.ts +1 -0
  46. package/src/components/VContentSwitcher/VContentSwitcher.scss +73 -0
  47. package/src/components/VContentSwitcher/VContentSwitcher.tsx +156 -0
  48. package/src/components/VContentSwitcher/index.ts +1 -0
  49. package/src/components/VControlField/VControlField.scss +183 -0
  50. package/src/components/VControlField/VControlField.tsx +152 -0
  51. package/src/components/VControlField/index.ts +1 -0
  52. package/src/components/VDataTable/VDataTable.scss +230 -0
  53. package/src/components/VDataTable/VDataTable.tsx +761 -0
  54. package/src/components/VDataTable/index.ts +1 -0
  55. package/src/components/VDrawerLayout/VDrawerLayout.scss +26 -0
  56. package/src/components/VDrawerLayout/VDrawerLayout.tsx +35 -0
  57. package/src/components/VDrawerLayout/index.ts +1 -0
  58. package/src/components/VForm/VForm.tsx +77 -0
  59. package/src/components/VForm/index.ts +1 -0
  60. package/src/components/VFormControl/VFormControl.scss +59 -0
  61. package/src/components/VFormControl/VFormControl.tsx +85 -0
  62. package/src/components/VFormControl/index.ts +1 -0
  63. package/src/components/VGrid/VGridContainer.scss +4 -0
  64. package/src/components/VGrid/VGridContainer.tsx +191 -0
  65. package/src/components/VGrid/VGridItem.scss +3 -0
  66. package/src/components/VGrid/VGridItem.tsx +110 -0
  67. package/src/components/VGrid/index.ts +2 -0
  68. package/src/components/VGrid/schemes.ts +28 -0
  69. package/src/components/VHero/.DS_Store +0 -0
  70. package/src/components/VHero/VHero.scss +26 -0
  71. package/src/components/VHero/VHero.tsx +52 -0
  72. package/src/components/VHero/index.ts +1 -0
  73. package/src/components/VIcon/VIcon.scss +22 -0
  74. package/src/components/VIcon/VIcon.tsx +110 -0
  75. package/src/components/VIcon/index.ts +1 -0
  76. package/src/components/VListTile/VListTile.scss +71 -0
  77. package/src/components/VListTile/VListTile.tsx +121 -0
  78. package/src/components/VListTile/index.ts +1 -0
  79. package/src/components/VNavigation/VNavigation.scss +12 -0
  80. package/src/components/VNavigation/VNavigation.tsx +79 -0
  81. package/src/components/VNavigation/VNavigationItem.scss +14 -0
  82. package/src/components/VNavigation/VNavigationItem.tsx +252 -0
  83. package/src/components/VNavigation/index.ts +2 -0
  84. package/src/components/VOption/VOption.scss +61 -0
  85. package/src/components/VOption/VOption.tsx +52 -0
  86. package/src/components/VOption/index.ts +1 -0
  87. package/src/components/VOptionGroup/VOptionGroup.scss +3 -0
  88. package/src/components/VOptionGroup/VOptionGroup.tsx +55 -0
  89. package/src/components/VOptionGroup/index.ts +1 -0
  90. package/src/components/VPagination/VPagination.scss +100 -0
  91. package/src/components/VPagination/VPagination.tsx +346 -0
  92. package/src/components/VPagination/index.ts +1 -0
  93. package/src/components/VPaper/VPaper.scss +37 -0
  94. package/src/components/VPaper/VPaper.tsx +78 -0
  95. package/src/components/VPaper/index.ts +1 -0
  96. package/src/components/VRadio/.DS_Store +0 -0
  97. package/src/components/VRadio/VRadio.scss +66 -0
  98. package/src/components/VRadio/VRadio.tsx +56 -0
  99. package/src/components/VRadio/index.ts +1 -0
  100. package/src/components/VRadioGroup/.DS_Store +0 -0
  101. package/src/components/VRadioGroup/VRadioGroup.tsx +10 -0
  102. package/src/components/VRadioGroup/index.ts +1 -0
  103. package/src/components/VSelect/VSelect.scss +78 -0
  104. package/src/components/VSelect/VSelect.tsx +204 -0
  105. package/src/components/VSelect/index.ts +1 -0
  106. package/src/components/VSwitch/VSwitch.scss +125 -0
  107. package/src/components/VSwitch/VSwitch.tsx +66 -0
  108. package/src/components/VSwitch/index.ts +1 -0
  109. package/src/components/VSwitchGroup/.DS_Store +0 -0
  110. package/src/components/VSwitchGroup/VSwitchGroup.tsx +11 -0
  111. package/src/components/VSwitchGroup/index.ts +1 -0
  112. package/src/components/VTabs/.DS_Store +0 -0
  113. package/src/components/VTabs/VTab.scss +73 -0
  114. package/src/components/VTabs/VTab.tsx +88 -0
  115. package/src/components/VTabs/VTabs.scss +49 -0
  116. package/src/components/VTabs/VTabs.tsx +315 -0
  117. package/src/components/VTabs/index.ts +1 -0
  118. package/src/components/VTextCounter/VTextCounter.scss +3 -0
  119. package/src/components/VTextCounter/VTextCounter.tsx +21 -0
  120. package/src/components/VTextCounter/index.ts +1 -0
  121. package/src/components/VTextField/VTextField.scss +45 -0
  122. package/src/components/VTextField/VTextField.tsx +96 -0
  123. package/src/components/VTextField/index.ts +1 -0
  124. package/src/components/VTextarea/VTextarea.scss +41 -0
  125. package/src/components/VTextarea/VTextarea.tsx +93 -0
  126. package/src/components/VTextarea/index.ts +1 -0
  127. package/src/components/VToolbar/.DS_Store +0 -0
  128. package/src/components/VToolbar/VToolbar.scss +26 -0
  129. package/src/components/VToolbar/VToolbar.tsx +44 -0
  130. package/src/components/VToolbar/VToolbarEdge.scss +27 -0
  131. package/src/components/VToolbar/VToolbarEdge.tsx +35 -0
  132. package/src/components/VToolbar/VToolbarMenu.scss +7 -0
  133. package/src/components/VToolbar/VToolbarMenu.tsx +26 -0
  134. package/src/components/VToolbar/VToolbarTitle.scss +22 -0
  135. package/src/components/VToolbar/VToolbarTitle.tsx +25 -0
  136. package/src/components/VToolbar/index.ts +4 -0
  137. package/src/components/VWysiwygEditor/.DS_Store +0 -0
  138. package/src/components/VWysiwygEditor/VWysiwygEditor.scss +60 -0
  139. package/src/components/VWysiwygEditor/VWysiwygEditor.tsx +293 -0
  140. package/src/components/VWysiwygEditor/index.ts +2 -0
  141. package/src/components/VWysiwygEditor/schemes.ts +65 -0
  142. package/src/components/VWysiwygEditor/tools/bullet-list.ts +18 -0
  143. package/src/components/VWysiwygEditor/tools/format-bold.ts +19 -0
  144. package/src/components/VWysiwygEditor/tools/format-italic.ts +18 -0
  145. package/src/components/VWysiwygEditor/tools/format-underline.ts +18 -0
  146. package/src/components/VWysiwygEditor/tools/history.ts +26 -0
  147. package/src/components/VWysiwygEditor/tools/index.ts +8 -0
  148. package/src/components/VWysiwygEditor/tools/link.ts +57 -0
  149. package/src/components/VWysiwygEditor/tools/ordered-list.ts +21 -0
  150. package/src/components/VWysiwygEditor/tools/text-color.ts +14 -0
  151. package/src/components/index.ts +32 -0
  152. package/src/components/kits.ts +1 -0
  153. package/src/components/loading.ts +1 -0
  154. package/src/composables/.DS_Store +0 -0
  155. package/src/composables/control.ts +118 -0
  156. package/src/composables/elevation.ts +34 -0
  157. package/src/composables/form-selector.scss +11 -0
  158. package/src/composables/form-selector.tsx +101 -0
  159. package/src/composables/index.ts +4 -0
  160. package/src/composables/vui.ts +9 -0
  161. package/src/index.ts +10 -0
  162. package/src/injections.ts +61 -0
  163. package/src/logger.ts +7 -0
  164. package/src/plugin.tsx +76 -0
  165. package/src/schemes/control.ts +7 -0
  166. package/src/schemes/elevation.ts +26 -0
  167. package/src/schemes/index.ts +2 -0
  168. package/src/service.tsx +242 -0
  169. package/src/styles/.DS_Store +0 -0
  170. package/src/styles/after-effects/display-flow.scss +346 -0
  171. package/src/styles/after-effects/spacing.scss +155 -0
  172. package/src/styles/after-effects/text.scss +90 -0
  173. package/src/styles/after-effects.scss +3 -0
  174. package/src/styles/base.scss +14 -0
  175. package/src/styles/control.scss +11 -0
  176. package/src/styles/core/functions.scss +62 -0
  177. package/src/styles/core/typo.scss +56 -0
  178. package/src/styles/core.scss +2 -0
  179. package/src/styles/elevation.scss +9 -0
  180. package/src/styles/group.scss +57 -0
  181. package/src/styles/index.scss +9 -0
  182. package/src/styles/transition.scss +11 -0
  183. package/src/styles/typo.scss +11 -0
  184. package/src/styles/variables.scss +320 -0
  185. package/src/styles/wysiwyg.scss +24 -0
  186. package/src/tool/.DS_Store +0 -0
  187. package/src/tool/index.ts +2 -0
  188. package/src/tool/vite-plugin.ts +281 -0
@@ -0,0 +1,761 @@
1
+ import './VDataTable.scss';
2
+
3
+ import {
4
+ defineComponent,
5
+ VNodeChild,
6
+ PropType,
7
+ ref,
8
+ computed,
9
+ onMounted,
10
+ watch,
11
+ CSSProperties,
12
+ VNodeArrayChildren,
13
+ withDirectives,
14
+ Transition,
15
+ } from 'vue';
16
+ import { useVui } from '../../injections';
17
+ import type { VuiService } from '../../service';
18
+ import { VSelect } from '../VSelect';
19
+ import { VPagination } from '../VPagination';
20
+ import { VCheckbox } from '../VCheckbox';
21
+ import { VIcon, resolveRawIconProp } from '../VIcon';
22
+ import { VProgressCircular } from '../loading';
23
+ import { resizeDirectiveArgument } from '@fastkit/vue-utils';
24
+ import { VAppLayoutControl } from '@fastkit/vue-app-layout';
25
+ import { VPaper } from '../VPaper';
26
+
27
+ export type DataTableHeaderAlign = 'left' | 'center' | 'right';
28
+
29
+ const DATA_TABLE_DEFAULTS = {
30
+ itemKey: 'id',
31
+ pageQuery: 'page',
32
+ sortQuery: 'sort',
33
+ orderQuery: 'order',
34
+ limitQuery: 'limit',
35
+ defaultOrder: 'ASC',
36
+ ascQueryValue: 'ASC',
37
+ descQueryValue: 'DESC',
38
+ limits: [5, 10, 20, 50, 100],
39
+ limitDefault: 20,
40
+ contorolThreshold: 10,
41
+ };
42
+
43
+ export type DataTableDefaults = typeof DATA_TABLE_DEFAULTS;
44
+
45
+ export function configureDataTableDefaults(
46
+ defaults: Partial<DataTableDefaults>,
47
+ ) {
48
+ Object.assign(DATA_TABLE_DEFAULTS, defaults);
49
+ if (!defaults.defaultOrder && defaults.ascQueryValue) {
50
+ DATA_TABLE_DEFAULTS.defaultOrder = defaults.ascQueryValue;
51
+ }
52
+ }
53
+
54
+ export interface DataTableItem {
55
+ [key: string]: any;
56
+ }
57
+
58
+ export interface DataTableItemSlotPayload<
59
+ T extends DataTableItem = DataTableItem,
60
+ > {
61
+ key: string;
62
+ item: T;
63
+ /**
64
+ * 選択されている場合true
65
+ */
66
+ selected: boolean;
67
+ }
68
+
69
+ export interface DataTableCellSlotPayload<
70
+ T extends DataTableItem = DataTableItem,
71
+ > {
72
+ vui: VuiService;
73
+ item: T;
74
+ /**
75
+ * 選択されている場合true
76
+ */
77
+ selected: boolean;
78
+ }
79
+
80
+ export interface DataTableHeader {
81
+ key: number | string;
82
+ label?: VNodeChild | ((vui: VuiService) => VNodeChild);
83
+ sortQuery?: string;
84
+ hidden?: boolean;
85
+ align?: DataTableHeaderAlign;
86
+ cell?: (payload: DataTableCellSlotPayload) => VNodeChild;
87
+ }
88
+
89
+ const SELECTABLE_HEADER_SYMBOL = '__selectable_header__';
90
+
91
+ export const VDataTable = defineComponent({
92
+ name: 'VDataTable',
93
+ props: {
94
+ /** 選択中のkeyの配列 */
95
+ modelValue: {
96
+ type: Array as PropType<string[]>,
97
+ default: () => [],
98
+ },
99
+
100
+ itemKey: {
101
+ type: String,
102
+ default: () => DATA_TABLE_DEFAULTS.itemKey,
103
+ },
104
+
105
+ /**
106
+ * ページネーションクエリ名
107
+ */
108
+ pageQuery: {
109
+ type: String,
110
+ default: () => DATA_TABLE_DEFAULTS.pageQuery,
111
+ },
112
+
113
+ /**
114
+ * ソートクエリ名
115
+ */
116
+ sortQuery: {
117
+ type: String,
118
+ default: () => DATA_TABLE_DEFAULTS.sortQuery,
119
+ },
120
+
121
+ /**
122
+ * 表示順クエリ名
123
+ */
124
+ orderQuery: {
125
+ type: String,
126
+ default: () => DATA_TABLE_DEFAULTS.orderQuery,
127
+ },
128
+
129
+ /**
130
+ * リミット件数クエリ名
131
+ */
132
+ limitQuery: {
133
+ type: String,
134
+ default: () => DATA_TABLE_DEFAULTS.limitQuery,
135
+ },
136
+ defaultOrder: {
137
+ type: String,
138
+ default: () => DATA_TABLE_DEFAULTS.defaultOrder,
139
+ },
140
+ ascQueryValue: {
141
+ type: String,
142
+ default: () => DATA_TABLE_DEFAULTS.ascQueryValue,
143
+ },
144
+ descQueryValue: {
145
+ type: String,
146
+ default: () => DATA_TABLE_DEFAULTS.descQueryValue,
147
+ },
148
+ limits: {
149
+ type: Array as PropType<number[]>,
150
+ default: () => DATA_TABLE_DEFAULTS.limits,
151
+ },
152
+ limitDefault: {
153
+ type: Number,
154
+ default: () => DATA_TABLE_DEFAULTS.limitDefault,
155
+ },
156
+ contorolThreshold: {
157
+ type: Number,
158
+ default: () => DATA_TABLE_DEFAULTS.contorolThreshold,
159
+ },
160
+ headers: {
161
+ type: Array as PropType<DataTableHeader[]>,
162
+ required: true,
163
+ },
164
+ items: {
165
+ type: Array as PropType<DataTableItem[]>,
166
+ default: () => [],
167
+ },
168
+ total: {
169
+ type: Number,
170
+ default: 0,
171
+ },
172
+ selectable: Boolean,
173
+ fixedHeader: Boolean,
174
+ maxHeight: [Number, String],
175
+ },
176
+ emits: {
177
+ input: (selecteds: string[]) => true,
178
+ },
179
+ setup(props, ctx) {
180
+ const vui = useVui();
181
+ const bootedRef = ref(false);
182
+ const footerHeightRef = ref(0);
183
+ const internalValues = ref<string[]>(props.modelValue.slice());
184
+ const sortedItemKeysRef = computed(() =>
185
+ props.items.map((item) => item[props.itemKey]),
186
+ );
187
+ const isEmptyRef = computed(() => props.items.length === 0);
188
+ const headersRef = computed<DataTableHeader[]>(() => {
189
+ const { headers, selectable } = props;
190
+ const ret: DataTableHeader[] = [];
191
+ if (selectable) {
192
+ ret.push({
193
+ key: SELECTABLE_HEADER_SYMBOL,
194
+ });
195
+ }
196
+ ret.push(...headers.filter((h) => !h.hidden));
197
+ return ret;
198
+ });
199
+ const classesRef = computed(() => [
200
+ {
201
+ 'v-data-table--fixed-header': props.fixedHeader,
202
+ },
203
+ ]);
204
+
205
+ const layout = VAppLayoutControl.use();
206
+
207
+ const bodyInnerStylesRef = computed<CSSProperties | undefined>(() => {
208
+ if (!bootedRef.value) return;
209
+
210
+ const { fixedHeader, maxHeight } = props;
211
+ const footerHeight = footerHeightRef.value;
212
+
213
+ const _maxHeight = maxHeight || (fixedHeader ? '100%' : maxHeight);
214
+
215
+ if (!_maxHeight) {
216
+ return;
217
+ }
218
+
219
+ return {
220
+ maxHeight: layout.calicurateViewHeight(
221
+ _maxHeight,
222
+ -footerHeight - 100,
223
+ 200,
224
+ ),
225
+ };
226
+ });
227
+
228
+ const defaultOrderQueryRef = computed(() =>
229
+ props.defaultOrder === props.ascQueryValue
230
+ ? props.ascQueryValue
231
+ : props.descQueryValue,
232
+ );
233
+
234
+ const isTransitioningRef = computed(() => {
235
+ return vui.location.isQueryOnlyTransitioning([
236
+ props.pageQuery,
237
+ props.sortQuery,
238
+ props.orderQuery,
239
+ props.limitQuery,
240
+ ]);
241
+ });
242
+
243
+ const pageRef = computed(() =>
244
+ vui.location.getQuery(props.pageQuery, Number, 1),
245
+ );
246
+
247
+ const needShowHeaderControlRef = computed(
248
+ () => props.items.length > props.contorolThreshold,
249
+ );
250
+
251
+ const sortByRef = computed({
252
+ get: () => {
253
+ return vui.location.getQuery(props.sortQuery);
254
+ },
255
+ set(value) {
256
+ vui.location.pushQuery({
257
+ [props.sortQuery]: value || null,
258
+ [props.pageQuery]: 1,
259
+ });
260
+ },
261
+ });
262
+
263
+ const ordersRef = computed(() => [
264
+ props.ascQueryValue,
265
+ props.descQueryValue,
266
+ ]);
267
+
268
+ const usePaigingRef = computed(() => props.limits.length > 0);
269
+
270
+ const orderByRef = computed({
271
+ get: () => {
272
+ const value = vui.location.getQuery(props.orderQuery);
273
+ if (typeof value !== 'string' || !ordersRef.value.includes(value)) {
274
+ return;
275
+ }
276
+ return value;
277
+ },
278
+ set(value) {
279
+ vui.location.pushQuery({
280
+ [props.orderQuery]: value || null,
281
+ [props.pageQuery]: 1,
282
+ });
283
+ },
284
+ });
285
+
286
+ const offsetRef = computed(() => (pageRef.value - 1) * limitRef.value);
287
+
288
+ const limitRef = computed({
289
+ get: () =>
290
+ vui.location.getQuery(props.limitQuery, Number, props.limitDefault),
291
+ set: (value) => {
292
+ const page = Math.floor(offsetRef.value / value) + 1;
293
+ vui.location.pushQuery({
294
+ [props.limitQuery]: value,
295
+ [props.pageQuery]: page,
296
+ });
297
+ },
298
+ });
299
+
300
+ const pageLengthRef = computed(() => {
301
+ const { total } = props;
302
+ const _limit = limitRef.value;
303
+ if (!total) return 0;
304
+ return Math.ceil(total / _limit);
305
+ });
306
+
307
+ const lengthRef = computed(() => props.items.length);
308
+
309
+ const isASCRef = computed(() => orderByRef.value === props.ascQueryValue);
310
+ // const isDESCRef = computed(() => orderByRef.value === props.descQueryValue);
311
+ const sortIconRef = computed(() => {
312
+ let icon = vui.icon('sort');
313
+ if (typeof icon === 'string') {
314
+ const name = icon;
315
+ icon = (gen) => {
316
+ return gen({
317
+ name,
318
+ rotate: isASCRef.value ? 180 : 0,
319
+ });
320
+ };
321
+ }
322
+ return icon;
323
+ });
324
+
325
+ const isIndeterminateRef = computed(() => {
326
+ const { length } = internalValues.value;
327
+ return length > 0 && length < sortedItemKeysRef.value.length;
328
+ });
329
+
330
+ const isAllSelectedRef = computed(
331
+ () => internalValues.value.length === sortedItemKeysRef.value.length,
332
+ );
333
+
334
+ function setSort(settings: { sort?: string; order?: string }) {
335
+ const { sort, order } = settings;
336
+ if (
337
+ (sort === undefined || sortByRef.value === sort) &&
338
+ (order === undefined || orderByRef.value === order)
339
+ )
340
+ return;
341
+
342
+ const queries: { [key: string]: string } = {};
343
+ if (sort) {
344
+ queries[props.sortQuery] = sort as string;
345
+ }
346
+ if (order) {
347
+ queries[props.orderQuery] = order as string;
348
+ }
349
+
350
+ vui.location.pushQuery({
351
+ ...queries,
352
+ [props.pageQuery]: 1,
353
+ });
354
+ }
355
+
356
+ function toggleOrderBy() {
357
+ return setSort({
358
+ order:
359
+ orderByRef.value === props.ascQueryValue
360
+ ? props.descQueryValue
361
+ : props.ascQueryValue,
362
+ });
363
+ }
364
+
365
+ function isSelected(key: string) {
366
+ return internalValues.value.includes(key);
367
+ }
368
+
369
+ function select(key: string) {
370
+ if (!internalValues.value.includes(key)) {
371
+ const values = internalValues.value.slice();
372
+ values.push(key);
373
+ const sortedKeys = sortedItemKeysRef.value;
374
+ values.sort((a, b) => {
375
+ const ai = sortedKeys.indexOf(a);
376
+ const bi = sortedKeys.indexOf(b);
377
+ if (ai < bi) return -1;
378
+ if (ai > bi) return 1;
379
+ return 0;
380
+ });
381
+ internalValues.value = values;
382
+ ctx.emit('input', values);
383
+ }
384
+ }
385
+
386
+ function selectAll() {
387
+ if (!isAllSelectedRef.value) {
388
+ const values = sortedItemKeysRef.value.slice();
389
+ internalValues.value = values;
390
+ ctx.emit('input', values);
391
+ }
392
+ }
393
+
394
+ function deselectAll() {
395
+ if (internalValues.value.length) {
396
+ const values: string[] = [];
397
+ internalValues.value = values;
398
+ ctx.emit('input', values);
399
+ }
400
+ }
401
+
402
+ function deselect(key: string) {
403
+ const values = internalValues.value.slice();
404
+ const index = values.indexOf(key);
405
+ if (index !== -1) {
406
+ values.splice(index, 1);
407
+ internalValues.value = values;
408
+ ctx.emit('input', values);
409
+ }
410
+ }
411
+
412
+ function handleClickSortHeader(header: DataTableHeader, ev: MouseEvent) {
413
+ const { sortQuery } = header;
414
+ if (!sortQuery) return;
415
+ if (sortByRef.value === sortQuery) {
416
+ return toggleOrderBy();
417
+ }
418
+ return setSort({
419
+ sort: sortQuery,
420
+ order: defaultOrderQueryRef.value,
421
+ });
422
+ }
423
+
424
+ function genPagination() {
425
+ return (
426
+ <VPagination
427
+ class="v-data-table__pagination"
428
+ dense
429
+ align="right"
430
+ routeQuery={props.pageQuery}
431
+ modelValue={pageRef.value}
432
+ length={pageLengthRef.value}
433
+ />
434
+ );
435
+ }
436
+
437
+ function genControls() {
438
+ const { total } = props;
439
+ const offset = offsetRef.value;
440
+ const length = lengthRef.value;
441
+
442
+ return (
443
+ <div class="v-data-table__controls">
444
+ <div class="v-data-table__controls__info">
445
+ <small class="v-data-table__controls__info__length">
446
+ 全 {total} 件中 {offset + 1} 件 〜 {offset + length} 件を表示
447
+ </small>
448
+ </div>
449
+ <div class="v-data-table__controls__select-limit">
450
+ <span class="v-data-table__controls__select-limit__prefix">
451
+ 1ページに
452
+ </span>
453
+ <VSelect
454
+ class="v-data-table__controls__select-limit__node"
455
+ size="sm"
456
+ hiddenInfo
457
+ disabled={isTransitioningRef.value}
458
+ items={props.limits.map((limit) => {
459
+ return {
460
+ label: `${limit}件`,
461
+ value: limit,
462
+ };
463
+ })}
464
+ v-model={limitRef.value}
465
+ />
466
+ </div>
467
+ <div class="v-data-table__controls__pagination">
468
+ {genPagination()}
469
+ </div>
470
+ </div>
471
+ );
472
+ }
473
+
474
+ function genTableHeader() {
475
+ const sortBy = sortByRef.value;
476
+ const isIndeterminate = isIndeterminateRef.value;
477
+ const isAllSelected = isAllSelectedRef.value;
478
+ const { defaultOrder, ascQueryValue } = props;
479
+ const usePaiging = usePaigingRef.value;
480
+
481
+ const children = headersRef.value.map((header) => {
482
+ const { label, sortQuery, align, key } = header;
483
+ const headerChildren: VNodeArrayChildren = [];
484
+ if (label != null && typeof label !== 'boolean') {
485
+ let _children = typeof label === 'function' ? label(vui) : label;
486
+ if (
487
+ _children &&
488
+ !Array.isArray(_children) &&
489
+ typeof _children === 'object'
490
+ ) {
491
+ _children = JSON.stringify(_children);
492
+ }
493
+ headerChildren.push(_children);
494
+ }
495
+ if (key === SELECTABLE_HEADER_SYMBOL) {
496
+ headerChildren.push(
497
+ <VCheckbox
498
+ modelValue={isAllSelected}
499
+ indeterminate={isIndeterminate}
500
+ onChange={(ev) => {
501
+ if (isAllSelectedRef.value) {
502
+ deselectAll();
503
+ } else {
504
+ selectAll();
505
+ }
506
+ }}
507
+ />,
508
+ );
509
+ }
510
+ // if (key === DELETOR_HEADER_SYMBOL) {
511
+ // headerChildren.push('削除');
512
+ // }
513
+
514
+ const sortActive = sortBy === sortQuery;
515
+
516
+ if (sortQuery && usePaiging) {
517
+ const isASC = sortActive
518
+ ? isASCRef.value
519
+ : defaultOrder === ascQueryValue;
520
+ headerChildren.unshift(
521
+ <VIcon
522
+ class="v-data-table__table__sort-icon v-data-table__table__sort-icon--empty"
523
+ name="$empty"
524
+ />,
525
+ );
526
+ headerChildren.push(
527
+ resolveRawIconProp(false, sortIconRef.value, {
528
+ class: [
529
+ 'v-data-table__table__sort-icon v-data-table__table__sort-icon--arrow',
530
+ {
531
+ 'v-data-table__table__sort-icon--asc': isASC,
532
+ 'v-data-table__table__sort-icon--desc': !isASC,
533
+ },
534
+ ],
535
+ }),
536
+ // <VIcon
537
+ // class={[
538
+ // 'v-data-table__table__sort-icon v-data-table__table__sort-icon--arrow',
539
+ // {
540
+ // 'v-data-table__table__sort-icon--asc': isASC,
541
+ // 'v-data-table__table__sort-icon--desc': !isASC,
542
+ // },
543
+ // ]}
544
+ // name="mdi-chevron-down"
545
+ // />,
546
+ );
547
+ }
548
+
549
+ const classes = [
550
+ 'v-data-table__table__cell',
551
+ {
552
+ 'v-data-table__table__cell--active': sortActive,
553
+ },
554
+ ];
555
+
556
+ if (align) {
557
+ classes.push(`v-data-table__table__cell--${align}`);
558
+ }
559
+
560
+ return (
561
+ <th
562
+ class={classes}
563
+ key={header.key}
564
+ tabindex={sortQuery && usePaiging ? 0 : undefined}
565
+ onClick={(ev) => {
566
+ if (!sortQuery || !usePaiging) return;
567
+ handleClickSortHeader(header, ev);
568
+ }}>
569
+ <div class="v-data-table__table__cell__tile">{headerChildren}</div>
570
+ </th>
571
+ );
572
+ });
573
+ return (
574
+ <thead class="v-data-table__table__header">
575
+ <tr>{children}</tr>
576
+ </thead>
577
+ );
578
+ }
579
+
580
+ function toggleSelect(key: string) {
581
+ return isSelected(key) ? deselect(key) : select(key);
582
+ }
583
+
584
+ function defaultItemSlot(payload: DataTableItemSlotPayload) {
585
+ const { key, item, selected } = payload;
586
+ const headers = headersRef.value;
587
+ // const { $scopedSlots, $createElement, deletor } = this;
588
+ const children = headers.map((header) => {
589
+ const { cell, align, key: headerKey } = header;
590
+ const cellSlot = cell || ctx.slots.cell;
591
+ let cellChildren: VNodeChild;
592
+ if (cellSlot) {
593
+ const cellPayload: DataTableCellSlotPayload = {
594
+ vui,
595
+ item,
596
+ selected,
597
+ };
598
+ let _children = cellSlot(cellPayload);
599
+ if (
600
+ _children &&
601
+ !Array.isArray(_children) &&
602
+ typeof _children === 'object'
603
+ ) {
604
+ _children = JSON.stringify(_children);
605
+ }
606
+ cellChildren = _children;
607
+ }
608
+
609
+ if (!cellChildren) {
610
+ switch (headerKey) {
611
+ case SELECTABLE_HEADER_SYMBOL: {
612
+ cellChildren = [
613
+ <VCheckbox
614
+ modelValue={selected}
615
+ onChange={(ev) => {
616
+ toggleSelect(key);
617
+ }}
618
+ // checkHandler={(e) => {
619
+ // this.toggleSelect(key as T[K]);
620
+ // }}
621
+ />,
622
+ ];
623
+ break;
624
+ }
625
+ // case DELETOR_HEADER_SYMBOL: {
626
+ // if (deletor) {
627
+ // const onClick = async (event: MouseEvent) => {
628
+ // if (
629
+ // await this.$confirm(`${key}を削除します。よろしいですか?`)
630
+ // ) {
631
+ // this.deletingTargets.push(key);
632
+ // await deletor(item);
633
+ // this.deletingTargets.splice(
634
+ // this.deletingTargets.indexOf(key),
635
+ // 1,
636
+ // );
637
+ // }
638
+ // };
639
+ // cellChildren = [
640
+ // <VBtn
641
+ // icon="trush"
642
+ // onClick={onClick}
643
+ // disabled={this.deletingTargets.includes(key)}
644
+ // />,
645
+ // ];
646
+ // }
647
+ // break;
648
+ // }
649
+ }
650
+ }
651
+
652
+ const classes = align
653
+ ? {
654
+ [`v-data-table__table__cell--${align}`]: true,
655
+ }
656
+ : undefined;
657
+
658
+ return (
659
+ <td class={['v-data-table__table__cell', classes]} key={header.key}>
660
+ {cellChildren}
661
+ </td>
662
+ );
663
+ });
664
+ return (
665
+ <tr
666
+ class={[
667
+ 'v-data-table__table__item',
668
+ {
669
+ 'v-data-table__table__item--selected': selected,
670
+ },
671
+ ]}
672
+ key={key}>
673
+ {children}
674
+ </tr>
675
+ );
676
+ }
677
+
678
+ function genBody() {
679
+ const { items, itemKey } = props;
680
+ const { item: itemSlot = defaultItemSlot } = ctx.slots;
681
+
682
+ const children = items.map((item) => {
683
+ const key = item[itemKey];
684
+ const payload: DataTableItemSlotPayload = {
685
+ key,
686
+ item,
687
+ selected: isSelected(key),
688
+ };
689
+ return itemSlot(payload);
690
+ });
691
+ return <tbody class="v-data-table__table__body">{children}</tbody>;
692
+ }
693
+
694
+ watch(
695
+ () => props.modelValue,
696
+ (modelValue) => {
697
+ internalValues.value = modelValue.slice();
698
+ },
699
+ );
700
+
701
+ watch(
702
+ () => props.items,
703
+ (items) => {
704
+ internalValues.value = internalValues.value.filter((key) => {
705
+ return sortedItemKeysRef.value.includes(key);
706
+ });
707
+ },
708
+ );
709
+
710
+ onMounted(() => {
711
+ bootedRef.value = true;
712
+ });
713
+
714
+ return () => {
715
+ const isEmpty = isEmptyRef.value;
716
+ const usePaiging = usePaigingRef.value;
717
+ return (
718
+ <div class={['v-data-table', classesRef.value]}>
719
+ {!isEmpty && usePaiging && needShowHeaderControlRef.value && (
720
+ <div class="v-data-table__header">{genControls()}</div>
721
+ )}
722
+ <div class="v-data-table__body container-pull">
723
+ {isEmpty ? (
724
+ <div class="v-data-table__empty--message">
725
+ {/* {this.computedEmptyMessage} */}
726
+ </div>
727
+ ) : (
728
+ <VPaper
729
+ class="v-data-table__body__inner"
730
+ style={bodyInnerStylesRef.value}>
731
+ <div class="v-data-table__table-wrapper">
732
+ <table class="v-data-table__table">
733
+ {genTableHeader()}
734
+ {genBody()}
735
+ </table>
736
+ </div>
737
+ </VPaper>
738
+ )}
739
+ <Transition name="fade">
740
+ {isTransitioningRef.value && (
741
+ <div class="v-data-table__loading">
742
+ <VProgressCircular indeterminate />
743
+ </div>
744
+ )}
745
+ </Transition>
746
+ </div>
747
+ {!isEmpty &&
748
+ usePaiging &&
749
+ withDirectives(
750
+ <div class="v-data-table__footer">{genControls()}</div>,
751
+ [
752
+ resizeDirectiveArgument(({ height }) => {
753
+ footerHeightRef.value = height;
754
+ }),
755
+ ],
756
+ )}
757
+ </div>
758
+ );
759
+ };
760
+ },
761
+ });