@digitalwalletcorp/vue-core 1.3.1 → 1.4.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalwalletcorp/vue-core",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "description": "Basic UI components for Vue 3",
6
6
  "main": "lib/index.cjs",
@@ -19,12 +19,12 @@
19
19
  <template>
20
20
  <section
21
21
  class="dwui-data-table"
22
- :class="{ 'dwui-selectable': props.selectable }"
22
+ :class="{ 'dwui-selectable': settings.selectable }"
23
23
  >
24
24
  <DataTableControls
25
- v-if="props.controls === 'both' || props.controls === 'top'"
25
+ v-if="settings.controls === 'both' || settings.controls === 'top'"
26
26
  v-bind="controlProps"
27
- :pagination="props.pagination === 'both' || props.pagination === 'top'"
27
+ :pagination="settings.pagination === 'both' || settings.pagination === 'top'"
28
28
  @emit:change-page="emit('emit:changePage', $event)"
29
29
  @emit:change-limit="emit('emit:changeLimit', $event)"
30
30
  @emit:download-page="emit('emit:downloadPage')"
@@ -33,14 +33,14 @@
33
33
  <div
34
34
  ref="refContent"
35
35
  class="dwui-data-table-content"
36
- :class="[{ 'dwui-loading': props.loading }, props.contentClass]"
37
- :style="props.contentStyle"
36
+ :class="[{ 'dwui-loading': props.loading }, settings.contentClass]"
37
+ :style="settings.contentStyle"
38
38
  tabindex="-1"
39
39
  @keydown="onKeyDown"
40
40
  >
41
41
  <table
42
- :class="props.tableClass"
43
- :style="props.tableStyle"
42
+ :class="settings.tableClass"
43
+ :style="settings.tableStyle"
44
44
  >
45
45
  <thead ref="refThead">
46
46
  <tr>
@@ -57,8 +57,8 @@
57
57
  <div class="dwui-data-table-header">
58
58
  <span
59
59
  class="dwui-data-table-sort"
60
- :role="props.sortable ? 'button' : undefined"
61
- :tabindex="props.sortable ? 0 : undefined"
60
+ :role="settings.sortable ? 'button' : undefined"
61
+ :tabindex="settings.sortable ? 0 : undefined"
62
62
  @click="onClickSort(header)"
63
63
  @keydown.enter.prevent="onClickSort(header)"
64
64
  @keydown.space.prevent="onClickSort(header)"
@@ -76,7 +76,7 @@
76
76
  </span>
77
77
  </div>
78
78
  <div
79
- v-if="props.resizable && index < innerHeaders.length - 1"
79
+ v-if="settings.resizable && index < innerHeaders.length - 1"
80
80
  class="dwui-data-table-resizer"
81
81
  @pointerdown="onResizeStart($event, index)"
82
82
  @pointermove="onResizing"
@@ -96,7 +96,7 @@
96
96
  :selected-index="selectedIndex"
97
97
  />
98
98
  <tr
99
- v-if="props.dataList.length === 0 && props.showNoData"
99
+ v-if="props.dataList.length === 0 && settings.showNoData"
100
100
  class="dwui-data-table-no-data"
101
101
  >
102
102
  <td :colspan="totalColSize">
@@ -116,9 +116,9 @@
116
116
  </div>
117
117
  </div>
118
118
  <DataTableControls
119
- v-if="props.controls === 'both' || props.controls === 'bottom'"
119
+ v-if="settings.controls === 'both' || settings.controls === 'bottom'"
120
120
  v-bind="controlProps"
121
- :pagination="props.pagination === 'both' || props.pagination === 'bottom'"
121
+ :pagination="settings.pagination === 'both' || settings.pagination === 'bottom'"
122
122
  @emit:change-page="emit('emit:changePage', $event)"
123
123
  @emit:change-limit="emit('emit:changeLimit', $event)"
124
124
  @emit:download-page="emit('emit:downloadPage')"
@@ -128,32 +128,130 @@
128
128
  </template>
129
129
 
130
130
  <script setup lang="ts" generic="T">
131
- import { computed, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue';
132
- import type { StyleValue } from 'vue';
131
+ import { computed, inject, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue';
132
+ import type { ClassValue, StyleValue } from 'vue';
133
133
  import { SvgPointingTriangle } from '@digitalwalletcorp/vue-svg-icons';
134
134
  import DataTableControls from '@/internal/data-table-controls.vue';
135
135
  import { compareValues, getValueByPath, resolveLabel, stringifyValue } from '@/internal/data-table-value';
136
- import type { DataTableEmits, DataTableHeader, DataTableLabels, DataTableProps, DataTableResolvedLabels, DataTableSlots, DataTableSortContext } from '@/types/data-table';
136
+ import { vueCoreOptionsKey } from '@/helpers/vue-core-options';
137
+ import type { DataTableOptions } from '@/helpers/vue-core-options';
138
+ import type { DataTableControlsPlacement, DataTableHeader, DataTableLabels, DataTableResolvedLabels, DataTableSortContext, DataTableSortMode } from '@/types/data-table';
137
139
 
138
- const props = withDefaults(defineProps<DataTableProps<T>>(), {
140
+ /**
141
+ * DataTable の props
142
+ */
143
+ export interface Props<T = unknown> {
144
+ /** 表示している行のデータ。スロットで描画する行と同じ順に並んでいること */
145
+ dataList: T[];
146
+ /** ヘッダ。id は一意であること */
147
+ headers: DataTableHeader<T>[];
148
+ /** 読み込み中。true の間は行を描画せず読み込み中の表示を出す */
149
+ loading?: boolean;
150
+ /** 総件数。未指定なら dataList の件数 */
151
+ totalCount?: number;
152
+ /** 現在ページ(1起点) */
153
+ current?: number;
154
+ /** 1ページあたりの表示件数 */
155
+ limit?: number;
156
+ /** 1ページあたりの表示件数の上限 */
157
+ maxLimit?: number;
158
+ /** ページネーションに並べるページ番号の最大数 */
159
+ maxPagination?: number;
160
+ /** 行をクリックで選択できるか */
161
+ selectable?: boolean;
162
+ /** コントロールを出す位置 */
163
+ controls?: DataTableControlsPlacement;
164
+ /** ページネーションを出す位置。controls が無い側には出ない */
165
+ pagination?: DataTableControlsPlacement;
166
+ /** ページダウンロードボタンを表示するか */
167
+ showDownloadPage?: boolean;
168
+ /** 全件ダウンロードボタンを表示するか */
169
+ showDownloadAll?: boolean;
170
+ /** 総件数を表示するか */
171
+ showTotal?: boolean;
172
+ /** 1ページあたりの表示件数の入力を表示するか */
173
+ showLimit?: boolean;
174
+ /** ページネーションにページ番号の選択を表示するか */
175
+ showPageSelect?: boolean;
176
+ /** dataList が空のときにデータが無い旨の行を表示するか */
177
+ showNoData?: boolean;
178
+ /** ヘッダの境界のドラッグで列幅を変えられるか */
179
+ resizable?: boolean;
180
+ /** ヘッダのクリックでソートできるか */
181
+ sortable?: boolean;
182
+ /** ソートの方式。未指定なら remote */
183
+ sortMode?: DataTableSortMode;
184
+ /** テーブルをスクロールする領域に付ける class */
185
+ contentClass?: ClassValue;
186
+ /** テーブルをスクロールする領域に付ける style */
187
+ contentStyle?: StyleValue;
188
+ /** table に付ける class */
189
+ tableClass?: ClassValue;
190
+ /** table に付ける style */
191
+ tableStyle?: StyleValue;
192
+ /** 表示する文言。未指定の項目は英語 */
193
+ labels?: DataTableLabels;
194
+ /** 総件数の整形。未指定なら en-US の桁区切り。SSR とクライアントで同じ文字列を返すこと */
195
+ formatTotalCount?: (count: number) => string;
196
+ }
197
+
198
+ /**
199
+ * DataTable が発行するイベント
200
+ */
201
+ export interface Emits<T = unknown> {
202
+ /** 選択が変わった。クリックでの選択・解除、カーソルキーでの移動、読み込み完了時の解除で発行する。解除は undefined と -1 */
203
+ (e: 'emit:selectRow', value: T | undefined, index: number): void;
204
+ /** ソートの条件が変わった。sortMode に関わらず発行する */
205
+ (e: 'emit:changeSort', context: DataTableSortContext): void;
206
+ (e: 'emit:updateHeader', headers: DataTableHeader<T>[]): void;
207
+ (e: 'emit:dblclickRow', value: T, index: number): void;
208
+ (e: 'emit:changeLimit', limit: number): void;
209
+ (e: 'emit:changePage', page: number): void;
210
+ (e: 'emit:downloadPage'): void;
211
+ (e: 'emit:downloadAll'): void;
212
+ }
213
+
214
+ /**
215
+ * DataTable のスロット
216
+ */
217
+ export interface Slots<T = unknown> {
218
+ /** 行。tr を rows と同じ順に並べ、tr の click で clickRow(row, index) を呼ぶ */
219
+ default?(props: {
220
+ /** 表示する行。sortMode が page のときはソートした順、それ以外は dataList そのもの */
221
+ rows: T[];
222
+ /** 行を選択する。選択している行なら選択を解除する */
223
+ clickRow: (row: T, index: number) => void;
224
+ /** 行を選択してダブルクリックを通知する */
225
+ dblclickRow: (row: T, index: number) => void;
226
+ /** 行のインデックスから、ページをまたいだ1起点の行番号を返す */
227
+ rowNumber: (index: number) => number;
228
+ /** 選択している行のインデックス。選択していなければ -1 */
229
+ selectedIndex: number;
230
+ }): unknown;
231
+ /** 読み込み中の表示。未指定なら既定のスピナー */
232
+ loading?(): unknown;
233
+ }
234
+
235
+ // 設定の props は未指定を undefined のまま受け、vueCoreOptionsKey の値とライブラリ既定で埋める(boolean が false にならないよう既定を明示する)
236
+ const props = withDefaults(defineProps<Props<T>>(), {
139
237
  loading: false,
140
238
  totalCount: undefined,
141
239
  current: 1,
142
240
  limit: 100,
143
- maxLimit: 9999,
144
- maxPagination: 7,
145
- selectable: true,
146
- controls: 'both',
147
- pagination: 'both',
148
- showDownloadPage: true,
149
- showDownloadAll: true,
150
- showTotal: true,
151
- showLimit: true,
152
- showPageSelect: false,
153
- showNoData: true,
154
- resizable: true,
155
- sortable: true,
156
- sortMode: 'remote',
241
+ maxLimit: undefined,
242
+ maxPagination: undefined,
243
+ selectable: undefined,
244
+ controls: undefined,
245
+ pagination: undefined,
246
+ showDownloadPage: undefined,
247
+ showDownloadAll: undefined,
248
+ showTotal: undefined,
249
+ showLimit: undefined,
250
+ showPageSelect: undefined,
251
+ showNoData: undefined,
252
+ resizable: undefined,
253
+ sortable: undefined,
254
+ sortMode: undefined,
157
255
  formatTotalCount: undefined,
158
256
  contentClass: undefined,
159
257
  contentStyle: undefined,
@@ -162,9 +260,11 @@ const props = withDefaults(defineProps<DataTableProps<T>>(), {
162
260
  labels: undefined
163
261
  });
164
262
 
165
- const emit = defineEmits<DataTableEmits<T>>();
263
+ const emit = defineEmits<Emits<T>>();
166
264
 
167
- defineSlots<DataTableSlots<T>>();
265
+ defineSlots<Slots<T>>();
266
+
267
+ const appOptions = inject(vueCoreOptionsKey, {});
168
268
 
169
269
  const refContent = ref<HTMLDivElement>();
170
270
  const refThead = ref<HTMLTableSectionElement>();
@@ -186,6 +286,45 @@ const innerHeaders = computed((): DataTableHeader<T>[] => {
186
286
  return props.headers.map(header => widths.value[header.id] == null ? header : { ...header, width: widths.value[header.id] });
187
287
  });
188
288
 
289
+ /** 設定のライブラリ既定。labels は項目ごとに合わせるため別に持つ */
290
+ const DEFAULT_SETTINGS: Omit<DataTableOptions, 'labels'> = {
291
+ maxLimit: 9999,
292
+ maxPagination: 7,
293
+ selectable: true,
294
+ controls: 'both',
295
+ pagination: 'both',
296
+ showDownloadPage: true,
297
+ showDownloadAll: true,
298
+ showTotal: true,
299
+ showLimit: true,
300
+ showPageSelect: false,
301
+ showNoData: true,
302
+ resizable: true,
303
+ sortable: true,
304
+ sortMode: 'remote',
305
+ contentClass: undefined,
306
+ contentStyle: undefined,
307
+ tableClass: undefined,
308
+ tableStyle: undefined,
309
+ formatTotalCount: undefined
310
+ };
311
+
312
+ type OptionalSettingKey = 'contentClass' | 'contentStyle' | 'tableClass' | 'tableStyle' | 'formatTotalCount';
313
+ type DataTableSettings = Required<Omit<DataTableOptions, 'labels' | OptionalSettingKey>> & Pick<DataTableOptions, OptionalSettingKey>;
314
+
315
+ /** 設定。props、vueCoreOptionsKey の dataTable、ライブラリ既定の順に、指定のあるものを使う */
316
+ const settings = computed((): DataTableSettings => {
317
+ const resolved = { ...DEFAULT_SETTINGS } as DataTableSettings;
318
+ for (const source of [appOptions.dataTable ?? {}, props]) {
319
+ for (const key of Object.keys(DEFAULT_SETTINGS) as (keyof typeof DEFAULT_SETTINGS)[]) {
320
+ if (source[key] !== undefined) {
321
+ Object.assign(resolved, { [key]: source[key] });
322
+ }
323
+ }
324
+ }
325
+ return resolved;
326
+ });
327
+
189
328
  const labels = computed((): DataTableResolvedLabels => {
190
329
  const merged: Required<DataTableLabels> = {
191
330
  totalCount: 'Total',
@@ -201,6 +340,7 @@ const labels = computed((): DataTableResolvedLabels => {
201
340
  nextPages: 'Next pages',
202
341
  nextPage: 'Next page',
203
342
  lastPage: 'Last page',
343
+ ...appOptions.dataTable?.labels,
204
344
  ...props.labels
205
345
  };
206
346
  const resolved = {} as DataTableResolvedLabels;
@@ -212,22 +352,22 @@ const labels = computed((): DataTableResolvedLabels => {
212
352
  });
213
353
 
214
354
  const limit = computed((): number => {
215
- return Math.min(props.limit, props.maxLimit);
355
+ return Math.min(props.limit, settings.value.maxLimit);
216
356
  });
217
357
 
218
358
  const controlProps = computed(() => {
219
359
  return {
220
- showTotal: props.showTotal,
221
- showLimit: props.showLimit,
222
- showPageSelect: props.showPageSelect,
223
- showDownloadPage: props.showDownloadPage,
224
- showDownloadAll: props.showDownloadAll,
360
+ showTotal: settings.value.showTotal,
361
+ showLimit: settings.value.showLimit,
362
+ showPageSelect: settings.value.showPageSelect,
363
+ showDownloadPage: settings.value.showDownloadPage,
364
+ showDownloadAll: settings.value.showDownloadAll,
225
365
  current: props.current,
226
366
  limit: limit.value,
227
- maxLimit: props.maxLimit,
228
- maxPagination: props.maxPagination,
367
+ maxLimit: settings.value.maxLimit,
368
+ maxPagination: settings.value.maxPagination,
229
369
  totalCount: props.totalCount ?? props.dataList.length,
230
- formatTotalCount: props.formatTotalCount,
370
+ formatTotalCount: settings.value.formatTotalCount,
231
371
  labels: labels.value
232
372
  };
233
373
  });
@@ -237,7 +377,7 @@ const selectedRow = shallowRef<T | undefined>(undefined);
237
377
 
238
378
  /** 表示する行。ページ内ソート中は dataList を並べ替えたコピー、それ以外は dataList そのもの */
239
379
  const rows = computed((): T[] => {
240
- const header = props.sortMode === 'page' ? props.headers.find(header => header.id === sortKey.value) : undefined;
380
+ const header = settings.value.sortMode === 'page' ? props.headers.find(header => header.id === sortKey.value) : undefined;
241
381
  if (!header) {
242
382
  return props.dataList;
243
383
  }
@@ -293,7 +433,7 @@ const ariaSort = (id: string): 'ascending' | 'descending' | undefined => {
293
433
  };
294
434
 
295
435
  const caretDirection = (id: string): 'up' | 'down' | undefined => {
296
- if (!props.sortable || sortKey.value !== id) {
436
+ if (!settings.value.sortable || sortKey.value !== id) {
297
437
  return undefined;
298
438
  }
299
439
  return descending.value ? 'down' : 'up';
@@ -356,7 +496,7 @@ const select = (row: T | undefined, index: number): void => {
356
496
  * 行を選択する。選択している行なら選択を解除する
357
497
  */
358
498
  const clickRow = (row: T, index: number): void => {
359
- if (!props.selectable) {
499
+ if (!settings.value.selectable) {
360
500
  return;
361
501
  }
362
502
  if (index === selectedIndex.value) {
@@ -395,7 +535,7 @@ const onKeyDown = (event: KeyboardEvent): void => {
395
535
  };
396
536
 
397
537
  const onClickSort = (header: DataTableHeader<T>): void => {
398
- if (!props.sortable || props.dataList.length === 0) {
538
+ if (!settings.value.sortable || props.dataList.length === 0) {
399
539
  return;
400
540
  }
401
541
  descending.value = sortKey.value === header.id ? !descending.value : false;
@@ -410,7 +550,7 @@ const onClickSort = (header: DataTableHeader<T>): void => {
410
550
  * 列幅の変更を始める。すべての列の幅を今の表示幅で固定してから変更する
411
551
  */
412
552
  const onResizeStart = (event: PointerEvent, index: number): void => {
413
- if (!props.resizable) {
553
+ if (!settings.value.resizable) {
414
554
  return;
415
555
  }
416
556
  event.preventDefault();
@@ -478,7 +618,7 @@ watch(() => props.loading, (newValue, oldValue) => {
478
618
  // 読み込みが終わったら、前のデータに対する選択は引き継がない。
479
619
  // ページ内ソートも同様だが、remote のソート条件は再取得後も有効なので保つ
480
620
  if (oldValue && !newValue) {
481
- if (props.sortMode === 'page') {
621
+ if (settings.value.sortMode === 'page') {
482
622
  sortKey.value = '';
483
623
  descending.value = false;
484
624
  }
@@ -0,0 +1,20 @@
1
+ import type { InjectionKey } from 'vue';
2
+ import type { Props } from '@/data-table.vue';
3
+
4
+ /**
5
+ * DataTable のアプリ既定の設定。vueCoreOptionsKey の dataTable で渡す。
6
+ * props のうちデータと表示の状態を除いた項目を持ち、DataTable の props に同じ名前の指定があればそちらが優先される
7
+ */
8
+ export type DataTableOptions = Partial<Omit<Props, 'dataList' | 'headers' | 'loading' | 'totalCount' | 'current' | 'limit'>>;
9
+
10
+ /** アプリ全体の設定 */
11
+ export type VueCoreOptions = {
12
+ /** DataTable のアプリ既定の設定 */
13
+ dataTable?: DataTableOptions;
14
+ };
15
+
16
+ /**
17
+ * アプリ全体の設定を provide/inject するためのキー
18
+ * provide は任意。画面の上位または app.provide で使う
19
+ */
20
+ export const vueCoreOptionsKey: InjectionKey<VueCoreOptions> = Symbol('dwui-vue-core-options');
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ export * from '@/components';
2
2
  export type { Props as AccordionFieldsetProps, Slots as AccordionFieldsetSlots } from '@/accordion-fieldset.vue';
3
3
  export type { Props as AccordionSectionProps, Slots as AccordionSectionSlots } from '@/accordion-section.vue';
4
4
  export type { Props as CopyButtonProps, Emits as CopyButtonEmits, Slots as CopyButtonSlots } from '@/copy-button.vue';
5
+ export type { Props as DataTableProps, Emits as DataTableEmits, Slots as DataTableSlots } from '@/data-table.vue';
5
6
  export type { Props as DarkModeSelectorProps, Emits as DarkModeSelectorEmits, Slots as DarkModeSelectorSlots } from '@/dark-mode-selector.vue';
6
7
  export type { Props as HelpButtonProps, Emits as HelpButtonEmits, Slots as HelpButtonSlots } from '@/help-button.vue';
7
8
  export type { Props as HelpPopperProps, Emits as HelpPopperEmits, Slots as HelpPopperSlots } from '@/help-popper.vue';
@@ -18,7 +19,7 @@ export type { Props as TabContentProps, Slots as TabContentSlots } from '@/tab-c
18
19
  export type { Props as TabGroupProps, Slots as TabGroupSlots } from '@/tab-group.vue';
19
20
  export type { Props as WarningPopperProps, Emits as WarningPopperEmits, Slots as WarningPopperSlots } from '@/warning-popper.vue';
20
21
  export { headersToCsvColumns, rowToCsvColumns } from '@/helpers/data-table-csv';
21
- export type { DataTableControlsPlacement, DataTableCsvColumn, DataTableEmits, DataTableHeader, DataTableLabels, DataTableProps, DataTableResolvedLabels, DataTableSlots, DataTableSortContext, DataTableSortMode, DataTableValueType } from '@/types/data-table';
22
+ export type { DataTableControlsPlacement, DataTableCsvColumn, DataTableHeader, DataTableLabels, DataTableResolvedLabels, DataTableSortContext, DataTableSortMode, DataTableValueType } from '@/types/data-table';
22
23
  export { closeAllFloatingComponents, showFloatingComponent, showFloatingMessage, useFloatingComponent } from '@/helpers/show-floating-component';
23
24
  export type { FloatingComponentContentProps, FloatingComponentHandle, ShowFloatingComponentOptions, ShowFloatingMessageOptions } from '@/helpers/show-floating-component';
24
25
  export { showConfirmationDialog, showErrorDialog, showInformationDialog, showModalDialog, showWarningDialog } from '@/helpers/show-modal-dialog';
@@ -34,4 +35,6 @@ export type { SnackbarDirection, SnackbarPlacement } from '@/internal/snackbar-i
34
35
  export type { LabelPreset } from '@/types/label-preset';
35
36
  export type { MovableWindowContentProps, MovableWindowDragMode, MovableWindowHandle } from '@/types/movable-window';
36
37
  export type { TabContentStatus } from '@/internal/tab-group-context';
38
+ export { vueCoreOptionsKey } from '@/helpers/vue-core-options';
39
+ export type { DataTableOptions, VueCoreOptions } from '@/helpers/vue-core-options';
37
40
  export type { PopoverPlacement } from '@/internal/anchored-position';
@@ -1,5 +1,3 @@
1
- import type { ClassValue, StyleValue } from 'vue';
2
-
3
1
  /** 列の値の型。ソートの比較方法を決める */
4
2
  export type DataTableValueType = 'boolean' | 'string' | 'number' | 'object';
5
3
 
@@ -90,101 +88,6 @@ export interface DataTableLabels {
90
88
  /** 関数を評価した後の文言 */
91
89
  export type DataTableResolvedLabels = Record<keyof DataTableLabels, string>;
92
90
 
93
- /**
94
- * DataTable の props
95
- */
96
- export interface DataTableProps<T = unknown> {
97
- /** 表示している行のデータ。スロットで描画する行と同じ順に並んでいること */
98
- dataList: T[];
99
- /** ヘッダ。id は一意であること */
100
- headers: DataTableHeader<T>[];
101
- /** 読み込み中。true の間は行を描画せず読み込み中の表示を出す */
102
- loading?: boolean;
103
- /** 総件数。未指定なら dataList の件数 */
104
- totalCount?: number;
105
- /** 現在ページ(1起点) */
106
- current?: number;
107
- /** 1ページあたりの表示件数 */
108
- limit?: number;
109
- /** 1ページあたりの表示件数の上限 */
110
- maxLimit?: number;
111
- /** ページネーションに並べるページ番号の最大数 */
112
- maxPagination?: number;
113
- /** 行をクリックで選択できるか */
114
- selectable?: boolean;
115
- /** コントロールを出す位置 */
116
- controls?: DataTableControlsPlacement;
117
- /** ページネーションを出す位置。controls が無い側には出ない */
118
- pagination?: DataTableControlsPlacement;
119
- /** ページダウンロードボタンを表示するか */
120
- showDownloadPage?: boolean;
121
- /** 全件ダウンロードボタンを表示するか */
122
- showDownloadAll?: boolean;
123
- /** 総件数を表示するか */
124
- showTotal?: boolean;
125
- /** 1ページあたりの表示件数の入力を表示するか */
126
- showLimit?: boolean;
127
- /** ページネーションにページ番号の選択を表示するか */
128
- showPageSelect?: boolean;
129
- /** dataList が空のときにデータが無い旨の行を表示するか */
130
- showNoData?: boolean;
131
- /** ヘッダの境界のドラッグで列幅を変えられるか */
132
- resizable?: boolean;
133
- /** ヘッダのクリックでソートできるか */
134
- sortable?: boolean;
135
- /** ソートの方式。未指定なら remote */
136
- sortMode?: DataTableSortMode;
137
- /** テーブルをスクロールする領域に付ける class */
138
- contentClass?: ClassValue;
139
- /** テーブルをスクロールする領域に付ける style */
140
- contentStyle?: StyleValue;
141
- /** table に付ける class */
142
- tableClass?: ClassValue;
143
- /** table に付ける style */
144
- tableStyle?: StyleValue;
145
- /** 表示する文言。未指定の項目は英語 */
146
- labels?: DataTableLabels;
147
- /** 総件数の整形。未指定なら en-US の桁区切り。SSR とクライアントで同じ文字列を返すこと */
148
- formatTotalCount?: (count: number) => string;
149
- }
150
-
151
- /**
152
- * DataTable が発行するイベント
153
- */
154
- export interface DataTableEmits<T = unknown> {
155
- /** 選択が変わった。クリックでの選択・解除、カーソルキーでの移動、読み込み完了時の解除で発行する。解除は undefined と -1 */
156
- (e: 'emit:selectRow', value: T | undefined, index: number): void;
157
- /** ソートの条件が変わった。sortMode に関わらず発行する */
158
- (e: 'emit:changeSort', context: DataTableSortContext): void;
159
- (e: 'emit:updateHeader', headers: DataTableHeader<T>[]): void;
160
- (e: 'emit:dblclickRow', value: T, index: number): void;
161
- (e: 'emit:changeLimit', limit: number): void;
162
- (e: 'emit:changePage', page: number): void;
163
- (e: 'emit:downloadPage'): void;
164
- (e: 'emit:downloadAll'): void;
165
- }
166
-
167
- /**
168
- * DataTable のスロット
169
- */
170
- export interface DataTableSlots<T = unknown> {
171
- /** 行。tr を rows と同じ順に並べ、tr の click で clickRow(row, index) を呼ぶ */
172
- default?(props: {
173
- /** 表示する行。sortMode が page のときはソートした順、それ以外は dataList そのもの */
174
- rows: T[];
175
- /** 行を選択する。選択している行なら選択を解除する */
176
- clickRow: (row: T, index: number) => void;
177
- /** 行を選択してダブルクリックを通知する */
178
- dblclickRow: (row: T, index: number) => void;
179
- /** 行のインデックスから、ページをまたいだ1起点の行番号を返す */
180
- rowNumber: (index: number) => number;
181
- /** 選択している行のインデックス。選択していなければ -1 */
182
- selectedIndex: number;
183
- }): unknown;
184
- /** 読み込み中の表示。未指定なら既定のスピナー */
185
- loading?(): unknown;
186
- }
187
-
188
91
  /**
189
92
  * ソートの状態
190
93
  */