@ouestfrance/sipa-bms-ui 8.16.0 → 8.18.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.
Files changed (35) hide show
  1. package/dist/components/navigation/BmsTabs.vue.d.ts +6 -1
  2. package/dist/components/navigation/UiTab.vue.d.ts +5 -4
  3. package/dist/components/navigation/UiTabs.vue.d.ts +21 -0
  4. package/dist/components/table/BmsTable.vue.d.ts +3 -1
  5. package/dist/components/table/UiBmsTable.vue.d.ts +1 -1
  6. package/dist/helpers/tab.helper.d.ts +2 -0
  7. package/dist/helpers/table.helper.d.ts +1 -0
  8. package/dist/models/tab.model.d.ts +5 -0
  9. package/dist/models/table.model.d.ts +2 -1
  10. package/dist/sipa-bms-ui.css +70 -69
  11. package/dist/sipa-bms-ui.es.js +380 -294
  12. package/dist/sipa-bms-ui.es.js.map +1 -1
  13. package/dist/sipa-bms-ui.umd.js +388 -301
  14. package/dist/sipa-bms-ui.umd.js.map +1 -1
  15. package/package.json +1 -1
  16. package/src/components/layout/BmsFloatingWindow.vue +1 -0
  17. package/src/components/navigation/BmsTabs.stories.js +58 -4
  18. package/src/components/navigation/BmsTabs.vue +53 -33
  19. package/src/components/navigation/UiTab.stories.js +5 -5
  20. package/src/components/navigation/UiTab.vue +15 -20
  21. package/src/components/navigation/UiTabs.stories.js +34 -0
  22. package/src/components/navigation/UiTabs.vue +76 -0
  23. package/src/components/table/BmsTable.stories.js +47 -0
  24. package/src/components/table/BmsTable.vue +22 -3
  25. package/src/components/table/UiBmsTable.spec.ts +47 -3
  26. package/src/components/table/UiBmsTable.stories.js +43 -0
  27. package/src/components/table/UiBmsTable.vue +51 -91
  28. package/src/components/table/UiBmsTableRow.vue +18 -3
  29. package/src/documentation/principles.mdx +73 -7
  30. package/src/helpers/tab.helper.ts +3 -0
  31. package/src/helpers/table.helper.ts +19 -0
  32. package/src/models/tab.model.ts +6 -0
  33. package/src/models/table.model.ts +1 -0
  34. package/src/showroom/pages/server-table.vue +1 -4
  35. package/src/showroom/pages/table.vue +3 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouestfrance/sipa-bms-ui",
3
- "version": "8.16.0",
3
+ "version": "8.18.0",
4
4
  "author": "Ouest-France BMS",
5
5
  "license": "ISC",
6
6
  "scripts": {
@@ -55,6 +55,7 @@ const open = defineModel<boolean>({
55
55
  display: grid;
56
56
  grid-template-rows: auto 1fr;
57
57
  box-shadow: 0px 8px 8px 0px rgba(0, 0, 0, 0.25);
58
+ z-index: var(--bms-z-index-modal);
58
59
 
59
60
  &__header {
60
61
  display: flex;
@@ -1,4 +1,5 @@
1
1
  import BmsTabs from '@/components/navigation/BmsTabs.vue';
2
+ import { vueRouter } from 'storybook-vue3-router';
2
3
 
3
4
  export default {
4
5
  title: 'Composants/navigation/Tabs',
@@ -6,6 +7,21 @@ export default {
6
7
  argTypes: {
7
8
  items: {},
8
9
  },
10
+ decorators: [
11
+ vueRouter([
12
+ {
13
+ name: 'titi',
14
+ path: '/titi',
15
+ },
16
+ {
17
+ path: '/',
18
+ },
19
+ {
20
+ name: 'toto',
21
+ path: '/toto',
22
+ },
23
+ ]),
24
+ ],
9
25
  };
10
26
 
11
27
  const Template = (args) => ({
@@ -20,11 +36,49 @@ const Template = (args) => ({
20
36
  `,
21
37
  });
22
38
 
23
- export const Primary = Template.bind({});
24
- Primary.args = {
39
+ export const Default = Template.bind({});
40
+ Default.args = {
41
+ title: 'Title',
42
+ tabs: [{ name: 'Titi', id: 'titi' }, { name: 'Toto' }],
43
+ };
44
+ export const WithSelectedTabId = Template.bind({});
45
+ WithSelectedTabId.args = {
46
+ title: 'Title',
47
+ initialTabId: 'Toto',
48
+ tabs: [
49
+ { name: 'Titi', id: 'titi' },
50
+ { name: 'Tata' },
51
+ { name: 'Toto' },
52
+ { name: 'Tutu' },
53
+ ],
54
+ };
55
+
56
+ export const WithRouterEngine = Template.bind({});
57
+ WithRouterEngine.args = {
58
+ title: 'Title',
59
+ initialTabId: 'titi',
60
+ tabs: [
61
+ { name: 'Titi', routeName: 'titi', id: 'titi' },
62
+ { name: 'Toto', routePath: '/toto' },
63
+ ],
64
+ };
65
+
66
+ export const WithError = Template.bind({});
67
+ WithError.args = {
68
+ title: 'Title',
69
+ initialTabId: 'titi',
70
+ tabs: [
71
+ { name: 'Titi', routeName: 'titi', id: 'titi' },
72
+ { name: 'Toto', routePath: '/toto', error: true },
73
+ ],
74
+ };
75
+
76
+ export const WithDisabled = Template.bind({});
77
+ WithDisabled.args = {
25
78
  title: 'Title',
79
+ initialTabId: 'titi',
26
80
  tabs: [
27
- { name: 'Titi', routePath: 'titi' },
28
- { name: 'Toto', routePath: 'toto' },
81
+ { name: 'Titi', routeName: 'titi', id: 'titi' },
82
+ { name: 'Toto', routePath: '/toto', disabled: true },
29
83
  ],
30
84
  };
@@ -1,46 +1,66 @@
1
1
  <template>
2
- <div class="tabs-header">
3
- <div class="tabs-title">
4
- <h3>{{ title }}</h3>
5
- </div>
6
- <UiTab
7
- v-for="tab in tabs"
8
- :key="tab.name"
9
- :tab="tab"
10
- :current-route="currentRoute"
11
- />
12
- </div>
2
+ <UiTabs
3
+ :title="title"
4
+ :tabs="tabs"
5
+ :initial-tab-id="selectedTabId"
6
+ @click="$emits('click', $event)"
7
+ >
8
+ <template v-if="needRouterEngine" #router="{ tab }">
9
+ <router-link class="tab" :to="getTabTarget(tab)">{{
10
+ tab.name
11
+ }}</router-link>
12
+ </template>
13
+ </UiTabs>
13
14
  </template>
14
15
 
15
16
  <script setup lang="ts">
16
- import { useRouter } from 'vue-router';
17
17
  import { Tab } from '@/models/tab.model';
18
- import UiTab from './UiTab.vue';
18
+ import UiTabs from './UiTabs.vue';
19
+ import { computed, ComputedRef, onMounted, ref, watch } from 'vue';
20
+ import { RouteLocation, useRouter } from 'vue-router';
21
+ import { getTabId } from '@/helpers/tab.helper';
19
22
 
20
23
  const { currentRoute } = useRouter();
21
24
 
22
- defineProps<{ title: string; tabs: Tab[] }>();
23
- </script>
25
+ const props = defineProps<{
26
+ title: string;
27
+ tabs: Tab[];
28
+ initialTabId?: string;
29
+ }>();
24
30
 
25
- <style lang="scss" scoped>
26
- .tabs-header {
27
- display: flex;
28
- align-items: center;
29
- border-bottom: 1px solid var(--bms-grey-25);
30
- box-sizing: border-box;
31
+ const getTabTarget = (tab: Tab) => {
32
+ return tab.routePath ? { path: tab.routePath } : { name: tab.routeName };
33
+ };
31
34
 
32
- .tabs-title {
33
- margin-right: auto;
34
- margin-bottom: 16px;
35
+ const $emits = defineEmits<{
36
+ (e: 'click', tab: Tab): void;
37
+ }>();
35
38
 
36
- h3 {
37
- margin: 0;
38
- }
39
- }
39
+ const needRouterEngine = computed(() => {
40
+ return (
41
+ !!props.tabs &&
42
+ !!props.tabs[0] &&
43
+ !!(props.tabs[0].routePath || props.tabs[0].routeName)
44
+ );
45
+ });
40
46
 
41
- a {
42
- position: relative;
43
- top: 1px;
47
+ const selectedTabId: ComputedRef<string | null> = computed(() => {
48
+ if (needRouterEngine.value) {
49
+ const selectedTab =
50
+ props.tabs.find((t) => isTabSelected(t, currentRoute.value)) || null;
51
+ return selectedTab ? getTabId(selectedTab) : null;
52
+ } else if (props.initialTabId) {
53
+ return props.initialTabId;
54
+ } else {
55
+ return null;
44
56
  }
45
- }
46
- </style>
57
+ });
58
+
59
+ const isTabSelected = (tab: Tab, currentRoute: RouteLocation) =>
60
+ tab.routePath
61
+ ? currentRoute.path.includes(tab.routePath)
62
+ : tab.routeName
63
+ ? !!currentRoute.name &&
64
+ (currentRoute.name as string).includes(tab.routeName)
65
+ : false;
66
+ </script>
@@ -30,31 +30,31 @@ const Template = (args) => ({
30
30
 
31
31
  export const Default = Template.bind({});
32
32
  Default.args = {
33
- currentRoute: { path: 'toto' },
33
+ selectedTabId: 'toto',
34
34
  tab: { name: 'Titi', routePath: 'titi' },
35
35
  };
36
36
 
37
37
  export const Active = Template.bind({});
38
38
  Active.args = {
39
- currentRoute: { path: 'titi-subRoute' },
39
+ selectedTabId: 'Titi',
40
40
  tab: { name: 'Titi', routePath: 'titi' },
41
41
  };
42
42
 
43
43
  export const Disabled = Template.bind({});
44
44
  Disabled.args = {
45
- currentRoute: { path: 'toto' },
45
+ selectedTabId: 'toto',
46
46
  tab: { name: 'Titi', routePath: 'titi', disabled: true },
47
47
  };
48
48
 
49
49
  export const Error = Template.bind({});
50
50
  Error.args = {
51
- currentRoute: { path: 'toto' },
51
+ selectedTabId: 'toto',
52
52
  tab: { name: 'Titi', routePath: 'titi', error: true },
53
53
  };
54
54
 
55
55
  export const Hover = Template.bind({});
56
56
  Hover.args = {
57
- currentRoute: { path: 'toto' },
57
+ selectedTabId: 'toto',
58
58
  tab: { name: 'Titi', routePath: 'titi' },
59
59
  };
60
60
  Hover.play = async ({ canvasElement }) => {
@@ -1,40 +1,30 @@
1
1
  <template>
2
- <router-link
3
- :to="tabTarget"
2
+ <span
4
3
  data-testid="tab"
5
4
  class="tab"
6
5
  :class="{ active: isTabSelected, error: tab.error, disabled: tab.disabled }"
7
6
  >
8
- <slot>{{ tab.name }}</slot>
9
- </router-link>
7
+ <slot name="router" :tab="tab">{{ tab.name }}</slot>
8
+ </span>
10
9
  </template>
11
10
 
12
11
  <script lang="ts" setup>
13
12
  import { Tab } from '@/models/tab.model';
14
- import { ComputedRef, computed } from 'vue';
15
- import { RouteLocation, RouteLocationRaw } from 'vue-router';
13
+ import { computed, ComputedRef } from 'vue';
14
+ import { getTabId } from '@/helpers/tab.helper';
16
15
 
17
16
  const props = withDefaults(
18
17
  defineProps<{
19
- currentRoute: RouteLocation;
18
+ selectedTabId: string | null;
20
19
  tab: Tab;
21
20
  }>(),
22
21
  {},
23
22
  );
24
23
 
25
- const isTabSelected: ComputedRef<boolean> = computed(() =>
26
- props.tab.routePath
27
- ? props.currentRoute.path.includes(props.tab.routePath)
28
- : props.tab.routeName
29
- ? !!props.currentRoute.name &&
30
- (props.currentRoute.name as string).includes(props.tab.routeName)
31
- : false,
32
- );
24
+ const tabId = computed(() => getTabId(props.tab));
33
25
 
34
- const tabTarget: ComputedRef<RouteLocationRaw> = computed(() =>
35
- props.tab.routePath
36
- ? { path: props.tab.routePath }
37
- : { name: props.tab.routeName },
26
+ const isTabSelected: ComputedRef<boolean> = computed(
27
+ () => (tabId.value && tabId.value === props.selectedTabId) || false,
38
28
  );
39
29
  </script>
40
30
 
@@ -47,10 +37,15 @@ const tabTarget: ComputedRef<RouteLocationRaw> = computed(() =>
47
37
  text-decoration: none;
48
38
  border-bottom: 4px solid var(--tab-border-color);
49
39
  padding: 0 8px 16px 8px;
50
-
40
+ cursor: pointer;
41
+ :deep(a) {
42
+ color: var(--tab-color);
43
+ text-decoration: none;
44
+ }
51
45
  &:hover,
52
46
  &__hover {
53
47
  --tab-border-color: var(--bms-main-50);
48
+ text-decoration: none;
54
49
  }
55
50
 
56
51
  &.active {
@@ -0,0 +1,34 @@
1
+ import UiTabs from '@/components/navigation/UiTabs.vue';
2
+ import template from '@/documentation/template_field_dependency.mdx';
3
+
4
+ export default {
5
+ parameters: {
6
+ docs: {
7
+ page: template,
8
+ },
9
+ },
10
+ title: 'Composants/navigation/UiTabs',
11
+ component: UiTabs,
12
+ argTypes: {
13
+ items: {},
14
+ },
15
+ tags: ['technical'],
16
+ };
17
+
18
+ const Template = (args) => ({
19
+ components: {
20
+ UiTabs,
21
+ },
22
+ setup() {
23
+ return { args };
24
+ },
25
+ template: `
26
+ <UiTabs v-bind="args" />
27
+ `,
28
+ });
29
+
30
+ export const Primary = Template.bind({});
31
+ Primary.args = {
32
+ title: 'Title',
33
+ tabs: [{ name: 'Titi', id: 'titi' }, { name: 'Toto' }],
34
+ };
@@ -0,0 +1,76 @@
1
+ <template>
2
+ <div class="tabs-header">
3
+ <div class="tabs-title">
4
+ <h3>{{ title }}</h3>
5
+ </div>
6
+ <UiTab
7
+ v-for="tab in tabs"
8
+ :key="getTabId(tab)"
9
+ :selectedTabId="selectedTabId"
10
+ :tab="tab"
11
+ @click="onTabClick(tab)"
12
+ >
13
+ <template #router="{ tab }"><slot name="router" :tab="tab" /></template>
14
+ </UiTab>
15
+ </div>
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ import { Tab } from '@/models/tab.model';
20
+ import UiTab from './UiTab.vue';
21
+ import { computed, ComputedRef, onMounted, ref, watch } from 'vue';
22
+ import { getTabId } from '@/helpers/tab.helper';
23
+
24
+ const props = defineProps<{
25
+ title: string;
26
+ tabs: Tab[];
27
+ initialTabId?: string | null;
28
+ }>();
29
+
30
+ const selectedTabId = ref<string | null>(null);
31
+
32
+ onMounted(() => {
33
+ selectedTabId.value = props.initialTabId || null;
34
+ });
35
+
36
+ watch(
37
+ () => props.initialTabId,
38
+ () => {
39
+ selectedTabId.value = props.initialTabId || null;
40
+ },
41
+ );
42
+
43
+ const $emits = defineEmits<{
44
+ (e: 'click', value: any): void;
45
+ }>();
46
+
47
+ const onTabClick = (tab: Tab) => {
48
+ if (getTabId(tab) !== selectedTabId.value) {
49
+ $emits('click', tab);
50
+ selectedTabId.value = getTabId(tab);
51
+ }
52
+ };
53
+ </script>
54
+
55
+ <style lang="scss" scoped>
56
+ .tabs-header {
57
+ display: flex;
58
+ align-items: center;
59
+ border-bottom: 1px solid var(--bms-grey-25);
60
+ box-sizing: border-box;
61
+
62
+ .tabs-title {
63
+ margin-right: auto;
64
+ margin-bottom: 16px;
65
+
66
+ h3 {
67
+ margin: 0;
68
+ }
69
+ }
70
+
71
+ span {
72
+ position: relative;
73
+ top: 1px;
74
+ }
75
+ }
76
+ </style>
@@ -10,6 +10,12 @@ export default {
10
10
  disableSearch: {
11
11
  control: { type: 'boolean' },
12
12
  },
13
+ selectMode: {
14
+ options: ['single', 'default'],
15
+ },
16
+ mode: {
17
+ options: ['normal', 'dense'],
18
+ },
13
19
  loading: {
14
20
  control: { type: 'boolean' },
15
21
  },
@@ -751,6 +757,47 @@ Selected.args = {
751
757
  selectable: true,
752
758
  };
753
759
 
760
+ export const SingleSelected = Template.bind({});
761
+ SingleSelected.args = {
762
+ headers: [
763
+ {
764
+ label: 'Column 1',
765
+ key: 'col1',
766
+ align: 'start',
767
+ },
768
+ {
769
+ label: 'Column 2',
770
+ key: 'col2',
771
+ align: 'center',
772
+ },
773
+ {
774
+ label: 'Column 3',
775
+ key: 'col3',
776
+ align: 'end',
777
+ },
778
+ ],
779
+ items: [
780
+ {
781
+ col1: 'Value1',
782
+ col2: 'Value2',
783
+ col3: 'Value3',
784
+ },
785
+ {
786
+ col1: 'Value4',
787
+ col2: 'Value5',
788
+ col3: 'Value6',
789
+ },
790
+ ],
791
+ selectedItems: [
792
+ {
793
+ col1: 'Value1',
794
+ col2: 'Value2',
795
+ col3: 'Value3',
796
+ },
797
+ ],
798
+ selectable: true,
799
+ selectMode: 'single',
800
+ };
754
801
  const TemplateWithSelectAction = (args) => ({
755
802
  components: {
756
803
  BmsTable,
@@ -6,7 +6,14 @@ import UiFilterButton from '@/components/table/UiFilterButton.vue';
6
6
  import { usePagination } from '@/composables/pagination.composable';
7
7
  import { useSearch } from '@/composables/search.composable';
8
8
  import { useSort } from '@/composables/sort.composable';
9
- import { Filter, SavedFilter, Sort, SortValue, TableHeader } from '@/models';
9
+ import {
10
+ Filter,
11
+ SavedFilter,
12
+ SelectMode,
13
+ Sort,
14
+ SortValue,
15
+ TableHeader,
16
+ } from '@/models';
10
17
  import { computed, Ref, ref, watch, watchEffect } from 'vue';
11
18
  import BmsTableFilters from './BmsTableFilters.vue';
12
19
  import BmsSearch from '../form/BmsSearch.vue';
@@ -34,6 +41,7 @@ interface UiTableProps {
34
41
  defaultSort?: Sort;
35
42
  selectable?: boolean;
36
43
  selectableDisabled?: boolean;
44
+ selectMode?: SelectMode.DEFAULT | SelectMode.SINGLE;
37
45
  }
38
46
 
39
47
  const props = withDefaults(defineProps<UiTableProps>(), {
@@ -51,6 +59,7 @@ const props = withDefaults(defineProps<UiTableProps>(), {
51
59
  }),
52
60
  selectable: false,
53
61
  selectableDisabled: false,
62
+ selectMode: SelectMode.DEFAULT,
54
63
  });
55
64
 
56
65
  const {
@@ -212,9 +221,18 @@ const onClickHeader = (header: TableHeader) => {
212
221
  changeSort(header);
213
222
  };
214
223
 
224
+ const elementsAndChildElements = computed(() => {
225
+ const childElements = items.value
226
+ .map((item) => item.childElement)
227
+ .filter((childElement) => !!childElement);
228
+ return [...items.value, ...childElements];
229
+ });
230
+
215
231
  const onSelectAll = () => {
216
- selectedItems.value = items.value;
232
+ selectedItems.value = elementsAndChildElements.value;
217
233
  };
234
+
235
+ const totalSize = computed(() => elementsAndChildElements.value.length);
218
236
  </script>
219
237
 
220
238
  <template>
@@ -228,7 +246,8 @@ const onSelectAll = () => {
228
246
  :sort="sort"
229
247
  :selectable="selectable"
230
248
  :selectableDisabled="selectableDisabled"
231
- :totalSize="items.length"
249
+ :totalSize="totalSize"
250
+ :selectMode="selectMode"
232
251
  @clickHeader="onClickHeader"
233
252
  @selectAll="onSelectAll"
234
253
  >
@@ -2,9 +2,8 @@ import UiBmsTable from '@/components/table/UiBmsTable.vue';
2
2
  import { field } from '@/plugins/field';
3
3
  import { mount, MountingOptions } from '@vue/test-utils';
4
4
  import UiBmsInputCheckbox from '../form/UiBmsInputCheckbox.vue';
5
- import BmsAlert from '../feedback/BmsAlert.vue';
6
- import { wrap } from 'lodash';
7
5
  import { SelectMode } from '@/models';
6
+ import BmsInputRadio from '../form/BmsInputRadio.vue';
8
7
 
9
8
  const intersectionObserverMock = () => ({
10
9
  observe: () => null,
@@ -40,13 +39,21 @@ const factory = (options: MountingOptions<any, {}> = {}) => {
40
39
  } as any);
41
40
  return {
42
41
  wrapper,
42
+ selectedMessage: () => wrapper.findAll('.bms-table__selected')[0],
43
+
44
+ getAllCheckboxes: () => wrapper.findAllComponents(UiBmsInputCheckbox),
43
45
  getAllCheckedCheckboxes: () =>
44
46
  wrapper
45
47
  .findAllComponents(UiBmsInputCheckbox)
46
48
  .filter((checkbox) => checkbox.props('modelValue') === true),
47
49
  getTableCheckbox: () => wrapper.findAllComponents(UiBmsInputCheckbox)[0],
48
50
  getFirstRowCheckbox: () => wrapper.findAllComponents(UiBmsInputCheckbox)[1],
49
- selectedMessage: () => wrapper.findAll('.bms-table__selected')[0],
51
+
52
+ getAllCheckedRadio: () =>
53
+ wrapper
54
+ .findAllComponents(BmsInputRadio)
55
+ .filter((checkbox) => checkbox.props('modelValue') === true),
56
+ getAllRadio: () => wrapper.findAllComponents(BmsInputRadio),
50
57
  };
51
58
  };
52
59
  describe('UiBmsTable', () => {
@@ -369,5 +376,42 @@ describe('UiBmsTable', () => {
369
376
  'Vous avez sélectionné la totalité des 2 éléments.',
370
377
  );
371
378
  });
379
+ it('should display readio if in selectMode SINGLE', async () => {
380
+ const { getAllRadio, getAllCheckboxes } = factory({
381
+ props: {
382
+ headers,
383
+ items,
384
+ totalSize: 2,
385
+ selectable: true,
386
+ selectMode: SelectMode.SINGLE,
387
+ selectedItems: [items[0]],
388
+ },
389
+ });
390
+
391
+ expect(getAllRadio().length).toEqual(2);
392
+ expect(getAllCheckboxes().length).toEqual(0);
393
+ });
394
+ it('should unselect previous selection if in selectMode SINGLE', async () => {
395
+ const { getAllRadio } = factory({
396
+ props: {
397
+ headers,
398
+ items,
399
+ totalSize: 2,
400
+ selectable: true,
401
+ selectMode: SelectMode.SINGLE,
402
+ selectedItems: [items[0]],
403
+ },
404
+ });
405
+ const firstRadio = getAllRadio()[0];
406
+ const secondRadio = getAllRadio()[1];
407
+
408
+ expect(firstRadio.props('modelValue')).toBeTruthy();
409
+ expect(secondRadio.props('modelValue')).toBeFalsy();
410
+
411
+ await secondRadio.get('input').setValue(items[1]);
412
+
413
+ expect(secondRadio.props('modelValue')).toBeTruthy();
414
+ expect(firstRadio.props('modelValue')).toBeFalsy();
415
+ });
372
416
  });
373
417
  });
@@ -559,6 +559,49 @@ SelectedWithMaxSelected.args = {
559
559
  maxSelectedSize: 1,
560
560
  };
561
561
 
562
+ export const SingleSelect = Template.bind({});
563
+ SingleSelect.args = {
564
+ headers: [
565
+ {
566
+ label: 'Column 1',
567
+ key: 'col1',
568
+ align: 'start',
569
+ },
570
+ {
571
+ label: 'Column 2',
572
+ key: 'col2',
573
+ align: 'center',
574
+ },
575
+ {
576
+ label: 'Column 3',
577
+ key: 'col3',
578
+ align: 'end',
579
+ },
580
+ ],
581
+ items: [
582
+ {
583
+ col1: 'Value1',
584
+ col2: 'Value2',
585
+ col3: 'Value3',
586
+ },
587
+ {
588
+ col1: 'Value4',
589
+ col2: 'Value5',
590
+ col3: 'Value6',
591
+ },
592
+ ],
593
+ selectedItems: [
594
+ {
595
+ col1: 'Value1',
596
+ col2: 'Value2',
597
+ col3: 'Value3',
598
+ },
599
+ ],
600
+ selectable: true,
601
+ selectMode: 'single',
602
+ totalSize: 2,
603
+ };
604
+
562
605
  export const AllSelected = Template.bind({});
563
606
  AllSelected.args = {
564
607
  headers: [