Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit f6d2ee3

Browse files
committed
feat(DataTable): add items per page global settings
1 parent 6289afd commit f6d2ee3

File tree

8 files changed

+152
-44
lines changed

8 files changed

+152
-44
lines changed

.eslintrc-auto-import.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@
334334
"ExtractDefaultPropTypes": true,
335335
"ExtractPropTypes": true,
336336
"ExtractPublicPropTypes": true,
337-
"useClipboardItems": true
337+
"useClipboardItems": true,
338+
"TableSymbol": true,
339+
"createTableDefaults": true,
340+
"useTable": true
338341
}
339342
}

README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ import '@fontsource/roboto/latin.css';
2727
To use the library you must install the library plugin:
2828

2929
```typescript
30-
import { RuiPlugin } from "@rotki/ui-library-compat";
30+
import { createRui } from "@rotki/ui-library-compat";
3131

3232
...
33-
Vue.use(RuiPlugin, options);
33+
const RuiPlugin = createRui(options)
34+
Vue.use(RuiPlugin);
3435
```
3536

3637
### Using the components
@@ -71,11 +72,15 @@ switchThemeScheme(ThemeMode.dark);
7172

7273
You need to specify which icons you want to enable, when installing the RuiPlugin.
7374
```typescript
74-
import { Ri4kFill, Ri4kLine, RuiPlugin } from '@rotki/ui-library-compat';
75-
76-
Vue.use(RuiPlugin, {
77-
icons: [Ri4kFill, Ri4kLine]
78-
});
75+
import { Ri4kFill, Ri4kLine, RuiPlugin, createRui } from '@rotki/ui-library-compat';
76+
a
77+
const RuiPlugin = createRui({
78+
theme: {
79+
icons: [Ri4kFill, Ri4kLine]
80+
}
81+
})
82+
83+
Vue.use(RuiPlugin);
7984
```
8085

8186
```vue

example/src/main.ts

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import '@/assets/main.css';
22
import '@rotki/ui-library-compat/style.css';
33
import '@fontsource/roboto/latin.css';
44

5-
import { PiniaVuePlugin, createPinia, setActivePinia } from 'pinia';
5+
import {
6+
PiniaVuePlugin,
7+
createPinia,
8+
setActivePinia,
9+
storeToRefs,
10+
} from 'pinia';
611
import {
712
RiAddFill,
813
RiAlertLine,
@@ -24,44 +29,58 @@ import {
2429
RiMoonLine,
2530
RiStarFill,
2631
RiSunLine,
27-
RuiPlugin,
32+
createRui,
2833
} from '@rotki/ui-library-compat';
2934
import Vue from 'vue';
3035
import App from '@/App.vue';
3136
import router from '@/router';
37+
import { useCounterStore } from '@/stores/counter';
3238

3339
Vue.use(PiniaVuePlugin);
34-
Vue.use(RuiPlugin, {
35-
icons: [
36-
RiMoonLine,
37-
RiStarFill,
38-
RiSunLine,
39-
RiMacbookLine,
40-
RiArrowLeftLine,
41-
RiArrowRightLine,
42-
RiAddFill,
43-
RiAlertLine,
44-
RiAlignCenter,
45-
RiAlignLeft,
46-
RiAlignRight,
47-
RiAlignJustify,
48-
RiCheckboxCircleLine,
49-
RiCloseFill,
50-
RiInformationLine,
51-
RiErrorWarningLine,
52-
RiArrowLeftSLine,
53-
RiArrowRightSLine,
54-
RiArrowUpSLine,
55-
RiArrowDownSLine,
56-
],
57-
});
58-
5940
const pinia = createPinia();
6041
setActivePinia(pinia);
6142

43+
const { itemsPerPage } = storeToRefs(useCounterStore());
44+
45+
const RuiPlugin = createRui({
46+
theme: {
47+
icons: [
48+
RiMoonLine,
49+
RiStarFill,
50+
RiSunLine,
51+
RiMacbookLine,
52+
RiArrowLeftLine,
53+
RiArrowRightLine,
54+
RiAddFill,
55+
RiAlertLine,
56+
RiAlignCenter,
57+
RiAlignLeft,
58+
RiAlignRight,
59+
RiAlignJustify,
60+
RiCheckboxCircleLine,
61+
RiCloseFill,
62+
RiInformationLine,
63+
RiErrorWarningLine,
64+
RiArrowLeftSLine,
65+
RiArrowRightSLine,
66+
RiArrowUpSLine,
67+
RiArrowDownSLine,
68+
],
69+
},
70+
defaults: {
71+
table: {
72+
itemsPerPage,
73+
},
74+
},
75+
});
76+
Vue.use(RuiPlugin);
77+
6278
new Vue({
6379
// @ts-ignore
6480
pinia,
6581
router,
82+
setup() {
83+
RuiPlugin.setupProvide();
84+
},
6685
render: (h) => h(App),
6786
}).$mount('#app');

example/src/stores/counter.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ export const useCounterStore = defineStore('counter', () => {
99
count.value++;
1010
}
1111

12-
return { count, doubleCount, increment };
12+
const itemsPerPage = ref(15);
13+
14+
return { count, doubleCount, increment, itemsPerPage };
1315
});

src/components/tables/DataTable.spec.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ import { describe, expect, it } from 'vitest';
22
import { mount } from '@vue/test-utils';
33
import DataTable, { type TableColumn } from '@/components/tables/DataTable.vue';
44

5-
const createWrapper = (options?: any) => mount(DataTable, options);
5+
const createWrapper = (options?: any) =>
6+
mount(DataTable, {
7+
...options,
8+
provide: {
9+
[TableSymbol.valueOf()]: {
10+
itemsPerPage: ref(10),
11+
globalItemsPerPage: get(false),
12+
},
13+
},
14+
});
615

716
describe('DataTable', () => {
817
const data = [

src/components/tables/DataTable.vue

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ export interface Props {
122122
* should add zebra-striping to the table row
123123
*/
124124
striped?: boolean;
125+
/**
126+
* Affects how the items per page work across the app.
127+
* When true, changing the items per page setting in one table will affect other tables.
128+
*/
129+
globalItemsPerPage?: boolean;
125130
}
126131
127132
defineOptions({
@@ -145,6 +150,7 @@ const props = withDefaults(defineProps<Props>(), {
145150
rounded: 'md',
146151
hideDefaultFooter: false,
147152
striped: false,
153+
globalItemsPerPage: undefined,
148154
});
149155
150156
const emit = defineEmits<{
@@ -170,6 +176,13 @@ const {
170176
} = toRefs(props);
171177
172178
const css = useCssModule();
179+
const tableDefaults = useTable();
180+
const globalItemsPerPageSettings = computed(() => {
181+
if (props.globalItemsPerPage !== undefined) {
182+
return props.globalItemsPerPage;
183+
}
184+
return get(tableDefaults.globalItemsPerPage);
185+
});
173186
174187
/**
175188
* Prepare the columns from props or generate using first item in the list
@@ -198,6 +211,15 @@ const internalPaginationState: Ref<TablePaginationData | undefined> = ref();
198211
199212
watchImmediate(pagination, (pagination) => {
200213
set(internalPaginationState, pagination);
214+
if (pagination?.limit && get(globalItemsPerPageSettings)) {
215+
set(tableDefaults.itemsPerPage, pagination.limit);
216+
}
217+
});
218+
219+
watchImmediate(tableDefaults.itemsPerPage, (itemsPerPage) => {
220+
if (get(globalItemsPerPageSettings)) {
221+
emit('update:pagination', { ...get(paginationData), limit: itemsPerPage });
222+
}
201223
});
202224
203225
/**

src/composables/defaults/table.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { type InjectionKey, type Ref } from 'vue';
2+
import { type MaybeRef } from '@vueuse/shared';
3+
4+
export interface TableOptions {
5+
itemsPerPage: Ref<number>;
6+
globalItemsPerPage: MaybeRef<boolean>;
7+
}
8+
9+
export const TableSymbol: InjectionKey<TableOptions> = Symbol.for('rui:table');
10+
11+
export const createTableDefaults = (options?: TableOptions): TableOptions => ({
12+
itemsPerPage: ref(10),
13+
globalItemsPerPage: false,
14+
...options,
15+
});
16+
17+
export const useTable = () => {
18+
const options = inject(TableSymbol);
19+
20+
if (!options) {
21+
throw new Error('Could not find rui table options injection');
22+
}
23+
24+
return options;
25+
};

src/index.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
/* eslint-disable max-lines,import/max-dependencies */
2-
import Vue, { type VueConstructor } from 'vue';
2+
import Vue, { type VueConstructor, provide } from 'vue';
33
import { isClient } from '@vueuse/core';
44
import { StepperState } from '@/types/stepper';
55
import { createTeleport } from '@/components/overlays/teleport-container';
6+
import {
7+
type TableOptions,
8+
TableSymbol,
9+
createTableDefaults,
10+
} from '@/composables/defaults/table';
611
import type { InitThemeOptions } from '@/types/theme';
712
import '@/style.scss';
813

@@ -23,6 +28,13 @@ export * from '@/components';
2328

2429
export { StepperState };
2530

31+
export interface RuiOptions {
32+
theme?: InitThemeOptions;
33+
defaults?: {
34+
table?: TableOptions;
35+
};
36+
}
37+
2638
const installTeleport = () => {
2739
if (!isClient) {
2840
return;
@@ -36,11 +48,22 @@ const installTeleport = () => {
3648
});
3749
};
3850

39-
export const RuiPlugin = {
40-
install: (app: VueConstructor, options?: InitThemeOptions) => {
51+
export function createRui(options: RuiOptions = {}) {
52+
const { theme } = options;
53+
const install = (_app: VueConstructor) => {
4154
const { registerIcons } = useIcons();
42-
registerIcons(options?.icons || []);
43-
useRotkiTheme().init({ ...options });
55+
registerIcons(theme?.icons || []);
56+
useRotkiTheme().init({ ...theme });
4457
installTeleport();
45-
},
46-
};
58+
};
59+
60+
const setupProvide = () => {
61+
const tableDefaults = createTableDefaults(options.defaults?.table);
62+
provide(TableSymbol, tableDefaults);
63+
};
64+
65+
return {
66+
install,
67+
setupProvide,
68+
};
69+
}

0 commit comments

Comments
 (0)