diff --git a/packages/docs/docs/.vitepress/configs/components.mts b/packages/docs/docs/.vitepress/configs/components.mts
index c260fcacfc..8493f45d8b 100644
--- a/packages/docs/docs/.vitepress/configs/components.mts
+++ b/packages/docs/docs/.vitepress/configs/components.mts
@@ -7,13 +7,11 @@ export const components = {
items: [
{ text: 'MazBtn', link: '/components/maz-btn' },
{ text: 'MazCheckbox', link: '/components/maz-checkbox' },
- { text: 'MazDropzone', link: '/components/maz-dropzone' },
{ text: 'MazInput', link: '/components/maz-input' },
{ text: 'MazInputCode', link: '/components/maz-input-code' },
{ text: 'MazInputNumber', link: '/components/maz-input-number' },
{ text: 'MazInputPrice', link: '/components/maz-input-price' },
{ text: 'MazInputTags', link: '/components/maz-input-tags' },
- { text: 'MazPicker', link: '/components/maz-picker' },
{ text: 'MazPhoneNumberInput', link: '/components/maz-phone-number-input' },
{ text: 'MazRadio', link: '/components/maz-radio' },
{ text: 'MazRadioButtons', link: '/components/maz-radio-buttons' },
@@ -23,6 +21,14 @@ export const components = {
{ text: 'MazTextarea', link: '/components/maz-textarea' },
]
},
+ {
+ text: 'Data',
+ items: [
+ { text: 'MazDropzone', link: '/components/maz-dropzone' },
+ { text: 'MazPicker', link: '/components/maz-picker' },
+ { text: 'MazTable (data-table)', link: '/components/maz-table' },
+ ]
+ },
{
text: 'UI',
items: [
@@ -43,6 +49,7 @@ export const components = {
{ text: 'MazGallery', link: '/components/maz-gallery' },
{ text: 'MazIcon', link: '/components/maz-icon' },
{ text: 'MazLazyImg', link: '/components/maz-lazy-img' },
+ { text: 'MazLoadingBar', link: '/components/maz-loading-bar' },
{ text: 'MazPullToRefresh', link: '/components/maz-pull-to-refresh' },
{ text: 'MazStepper', link: '/components/maz-stepper' },
{ text: 'MazSpinner', link: '/components/maz-spinner' },
diff --git a/packages/docs/docs/components/competitions.ts b/packages/docs/docs/components/competitions.ts
new file mode 100644
index 0000000000..cc7e109689
--- /dev/null
+++ b/packages/docs/docs/components/competitions.ts
@@ -0,0 +1,145 @@
+export const competitions = [
+ {
+ id: '0262672d-7c7a-4d30-866e-edb88b5a5336',
+ name: 'UEFA Champions League',
+ code: 'CL',
+ type: 'CUP',
+ areaName: 'Europe',
+ matchday: 6,
+ logoUrl: 'https://crests.football-data.org/CL.png',
+ groups: 1,
+ index: 1,
+ },
+ {
+ id: '08d15e97-a319-4772-9b82-f1877369b40f',
+ name: 'Premier League',
+ code: 'PL',
+ type: 'LEAGUE',
+ areaName: 'England',
+ matchday: 18,
+ logoUrl: 'https://crests.football-data.org/PL.png',
+ groups: 1,
+ index: 2,
+ },
+ {
+ id: '17e62396-bbcb-42f5-acff-caed11534976',
+ name: 'Serie A',
+ code: 'SA',
+ type: 'LEAGUE',
+ areaName: 'Italy',
+ matchday: 17,
+ logoUrl: 'https://crests.football-data.org/SA.png',
+ groups: 0,
+ index: 3,
+ },
+ {
+ id: '3726264e-ba3a-4a9f-b4a4-8fc33e12747c',
+ name: 'FIFA World Cup',
+ code: 'WC',
+ type: 'CUP',
+ areaName: 'World',
+ matchday: 8,
+ logoUrl: 'https://crests.football-data.org/qatar.png',
+ groups: 1,
+ index: 4,
+ },
+ {
+ id: '555dc3f4-e592-46af-b634-59f07a201f2e',
+ name: 'Primeira Liga',
+ code: 'PPL',
+ type: 'LEAGUE',
+ areaName: 'Portugal',
+ matchday: 15,
+ logoUrl: 'https://crests.football-data.org/PPL.png',
+ groups: 0,
+ index: 5,
+ },
+ {
+ id: '59bbdfa0-86d8-4a74-b701-435747c55a42',
+ name: 'Primera Division',
+ code: 'PD',
+ type: 'LEAGUE',
+ areaName: 'Spain',
+ matchday: 18,
+ logoUrl: 'https://crests.football-data.org/PD.png',
+ groups: 1,
+ index: 6,
+ },
+ {
+ id: '6ae53332-3d27-4781-912d-d9c4e69657f9',
+ name: 'Ligue 1',
+ code: 'FL1',
+ type: 'LEAGUE',
+ areaName: 'France',
+ matchday: 17,
+ logoUrl: 'https://crests.football-data.org/FL1.png',
+ groups: 4,
+ index: 7,
+ },
+ {
+ id: '747c79ee-89c8-436a-b0ea-53f05f180007',
+ name: 'European Championship',
+ code: 'EC',
+ type: 'CUP',
+ areaName: 'Europe',
+ matchday: 1,
+ logoUrl: 'https://crests.football-data.org/EUR.svg',
+ groups: 1,
+ index: 8,
+ },
+ {
+ id: '7a32d897-6b22-4212-8ffe-049ae912c346',
+ name: 'Eredivisie',
+ code: 'DED',
+ type: 'LEAGUE',
+ areaName: 'Netherlands',
+ matchday: 18,
+ logoUrl: 'https://crests.football-data.org/ED.png',
+ groups: 0,
+ index: 9,
+ },
+ {
+ id: 'ab57e2dc-272c-45e6-b13e-57617a13b753',
+ name: 'Championship',
+ code: 'ELC',
+ type: 'LEAGUE',
+ areaName: 'England',
+ matchday: 23,
+ logoUrl: 'https://crests.football-data.org/ELC.png',
+ groups: 0,
+ index: 10,
+ },
+ {
+ id: 'b84e3295-7315-46c7-b979-6d9d784e5460',
+ name: 'Campeonato Brasileiro Série A',
+ code: 'BSA',
+ type: 'LEAGUE',
+ areaName: 'Brazil',
+ matchday: 38,
+ logoUrl: 'https://crests.football-data.org/764.svg',
+ groups: 0,
+ index: 11,
+ },
+ {
+ id: 'cafad3ce-1783-4652-9248-4bcad024dd98',
+ name: 'Copa Libertadores',
+ code: 'CLI',
+ type: 'CUP',
+ areaName: 'South America',
+ matchday: 11,
+ logoUrl: 'https://crests.football-data.org/CLI.svg',
+ groups: 0,
+ index: 12,
+ },
+ {
+ id: 'ed945bea-9a58-450a-8d62-7baa7722b5e7',
+ name: 'Bundesliga',
+ code: 'BL1',
+ type: 'LEAGUE',
+ areaName: 'Germany',
+ matchday: 16,
+ logoUrl: 'https://crests.football-data.org/BL1.png',
+ groups: 0,
+ index: 13,
+ },
+]
diff --git a/packages/docs/docs/components/maz-loading-bar.md b/packages/docs/docs/components/maz-loading-bar.md
new file mode 100644
index 0000000000..a1ca0a0a14
--- /dev/null
+++ b/packages/docs/docs/components/maz-loading-bar.md
@@ -0,0 +1,26 @@
+---
+title: MazLoadingBar
+description: MazLoadingBar is a standalone component
+---
+
+# {{ $frontmatter.title }}
+
+{{ $frontmatter.description }}
+
+
+
+## Basic usage
+
+
+
+```vue
+
+
+
+
+
+```
+
+
diff --git a/packages/docs/docs/components/maz-table.md b/packages/docs/docs/components/maz-table.md
new file mode 100644
index 0000000000..ea612d2dad
--- /dev/null
+++ b/packages/docs/docs/components/maz-table.md
@@ -0,0 +1,441 @@
+---
+title: MazTable
+description: MazTable is designed to be a reusable data table with advanced features. Pagination, Search, Column Sorting, Row Selection, UI options, Loading and Slots.
+---
+
+# {{ $frontmatter.title }}
+
+{{ $frontmatter.description }}
+
+
+
+## Key Features
+
+1. Pagination (prop `pagination`)
+ * The component supports pagination with buttons to go to the first, previous, next, and last page.
+ * You can display only the pagination elements (input and buttons) and make API calls to your server to get elements by using the prop `pagination` with `no-paginate-rows`.
+2. Search (prop `search`): It includes a search feature with a search bar where users can enter a query to filter displayed data. You can choose the column where the search will be activated.
+3. Column Sorting (prop: `sortable`): Columns are sortable, indicated by arrow icons. Sorting can be activated by clicking on the column header.
+4. Row Selection (prop `select-value="key"`): There is a dedicated column for selection with a checkbox for each row. Users can individually or collectively select/deselect rows.
+5. Customizable Page Size: Users can choose the number of items to display per page using a dropdown list.
+6. Loading Indicator (prop `loading`): A loading indicator (MazLoadingBar) is displayed when data is being loaded.
+
+## Available models
+
+* v-model: `(string | boolean | number)[] | undefined` (list of selected key)
+* v-model:search-query: `string | undefined`
+* v-model:page: `number`
+* v-model:page-size: `number`
+
+## Basic usage
+
+You can use MazTable and his child component to build a simple table and enjoy the style.
+
+
+
+
+ 1
+
+
+ John
+
+
+ Doe
+
+
+ 99
+
+
+
+
+ 2
+
+
+ Doe
+
+
+ John
+
+
+ 30
+
+
+
+
+::: details Show code
+
+```vue
+
+
+
+
+ 1
+
+
+ John
+
+
+ Doe
+
+
+ 99
+
+
+
+
+ 2
+
+
+ Doe
+
+
+ John
+
+
+ 30
+
+
+
+
+
+
+```
+
+:::
+
+## Advanced
+
+You can also provide all your data, the table is auto-generated and you can use the features [listed on top](#key-features)
+
+---
+
+`v-model="{{selectedIds ?? 'undefined'}}"`
+
+`v-model:search-query="{{searchQuery ?? 'undefined'}}"`
+
+`v-model:page="{{page ?? 'undefined'}}"`
+
+`v-model:page-size="{{pageSize ?? 'undefined'}}"`
+
+
+
+ {{value}}
+
+
+
+
+ {{value}}
+
+
+
+ {{value}}
+
+
+
+
+
+
+
+::: details Show code
+
+```vue
+
+
+
+ {{value}}
+
+
+
+
+ {{value}}
+
+
+
+ {{value}}
+
+
+
+
+
+
+
+
+
+```
+
+:::
+
+## Loading
+
+
+
+
+ 1
+
+
+ John
+
+
+ Doe
+
+
+ 99
+
+
+
+
+
+
+## Props & Events emitted
+
+## MazTable
+
+
+
+## MazTableCell
+
+
+
+## MazTableRow
+
+
+
+## MazTableTitle
+
+
+
+
diff --git a/packages/lib/components/MazGallery.vue b/packages/lib/components/MazGallery.vue
index b128e095a5..49caabb5c6 100644
--- a/packages/lib/components/MazGallery.vue
+++ b/packages/lib/components/MazGallery.vue
@@ -52,7 +52,7 @@
@@ -60,7 +60,7 @@
+
+
diff --git a/packages/lib/components/MazTable.vue b/packages/lib/components/MazTable.vue
new file mode 100644
index 0000000000..1d53e61551
--- /dev/null
+++ b/packages/lib/components/MazTable.vue
@@ -0,0 +1,816 @@
+
+
+
+
+
+
+
+
+ {{ caption }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ header.label }}
+
+
+
+
+
+
+
+
+ Actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ row[key] }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No results
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/lib/components/MazTableCell.vue b/packages/lib/components/MazTableCell.vue
new file mode 100644
index 0000000000..c4799e182e
--- /dev/null
+++ b/packages/lib/components/MazTableCell.vue
@@ -0,0 +1,42 @@
+
+
+
+ |
+
+
+
+
+
diff --git a/packages/lib/components/MazTableRow.vue b/packages/lib/components/MazTableRow.vue
new file mode 100644
index 0000000000..30aa75356b
--- /dev/null
+++ b/packages/lib/components/MazTableRow.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/lib/components/MazTableTitle.vue b/packages/lib/components/MazTableTitle.vue
new file mode 100644
index 0000000000..94d5eb993f
--- /dev/null
+++ b/packages/lib/components/MazTableTitle.vue
@@ -0,0 +1,42 @@
+
+
+
+ |
+
+
+
+
+
diff --git a/packages/lib/components/index.ts b/packages/lib/components/index.ts
index 870c67341b..bd6fd062d1 100644
--- a/packages/lib/components/index.ts
+++ b/packages/lib/components/index.ts
@@ -35,6 +35,11 @@ export { default as MazSlider } from './MazSlider.vue'
export { default as MazSpinner } from './MazSpinner.vue'
export { default as MazStepper } from './MazStepper.vue'
export { default as MazSwitch } from './MazSwitch.vue'
+export { default as MazTable } from './MazTable.vue'
+export { default as MazTableCell } from './MazTableCell.vue'
+export { default as MazTableRow } from './MazTableRow.vue'
+export { default as MazTableTitle } from './MazTableTitle.vue'
+export { default as MazLoadingBar } from './MazLoadingBar.vue'
export { default as MazTabs } from './MazTabs.vue'
export { default as MazTabsBar } from './MazTabsBar.vue'
export { default as MazTabsContent } from './MazTabsContent.vue'
diff --git a/packages/lib/modules/types/shims-vue.d.ts b/packages/lib/modules/types/shims-vue.d.ts
index 28b0633f27..b6b4f86c6a 100644
--- a/packages/lib/modules/types/shims-vue.d.ts
+++ b/packages/lib/modules/types/shims-vue.d.ts
@@ -1,5 +1,5 @@
-declare module '*.vue' {
- import type { DefineComponent } from 'vue'
- const component: DefineComponent, Record, unknown>
- export default component
-}
+// declare module '*.vue' {
+// import type { DefineComponent } from 'vue'
+// const component: DefineComponent, Record, unknown>
+// export default component
+// }
diff --git a/packages/lib/tests/specs/components/maz-btn.spec.ts b/packages/lib/tests/specs/components/maz-btn.spec.ts
index 4ef59ceea8..d7ee5334a8 100644
--- a/packages/lib/tests/specs/components/maz-btn.spec.ts
+++ b/packages/lib/tests/specs/components/maz-btn.spec.ts
@@ -3,7 +3,7 @@ import { shallowMount } from '@vue/test-utils'
describe('MazBtn', () => {
test('renders the component elements and classes correctly', () => {
- const wrapper = shallowMount(MazBtn)
+ const wrapper = shallowMount(MazBtn, { slots: { default: 'Button Text' } })
expect(wrapper.find('button').exists()).toBe(true)
expect(wrapper.find('.m-btn__icon-left').exists()).toBe(false)
diff --git a/packages/lib/tests/specs/components/maz-loading-bar.spec.ts b/packages/lib/tests/specs/components/maz-loading-bar.spec.ts
new file mode 100644
index 0000000000..0c70caf4df
--- /dev/null
+++ b/packages/lib/tests/specs/components/maz-loading-bar.spec.ts
@@ -0,0 +1,10 @@
+import { mount } from '@vue/test-utils'
+import MazLoadingBar from '@components/MazLoadingBar.vue'
+
+describe('MazLoadingBar', () => {
+ test('renders default color correctly', () => {
+ const wrapper = mount(MazLoadingBar)
+ expect(wrapper.vm.colorCSVariables.alpha).toBe('var(--maz-color-primary-alpha-20)')
+ expect(wrapper.vm.colorCSVariables.main).toBe('var(--maz-color-primary)')
+ })
+})
diff --git a/packages/lib/tests/specs/components/maz-table.spec.ts b/packages/lib/tests/specs/components/maz-table.spec.ts
new file mode 100644
index 0000000000..a9459cf88d
--- /dev/null
+++ b/packages/lib/tests/specs/components/maz-table.spec.ts
@@ -0,0 +1,121 @@
+import { mount } from '@vue/test-utils'
+import MazTable from '@components/MazTable.vue'
+import { MazCheckbox, MazLoadingBar } from '@components/index'
+
+describe('MazTable', () => {
+ test('should render the component', async () => {
+ const wrapper = mount(MazTable, {
+ props: {
+ sortable: true,
+ pagination: true,
+ search: true,
+ selectedKey: 'id',
+ headers: [
+ { label: 'Id', key: 'id' },
+ { label: 'Firstname', key: 'firstname' },
+ { label: 'Lastname', key: 'lastname' },
+ { label: 'Age', key: 'age' },
+ { label: 'City', key: 'city' },
+ ],
+ caption: 'This is a caption',
+ rows: [
+ {
+ id: 1,
+ firstname: 'John',
+ lastname: 'Doe',
+ age: 25,
+ city: 'New York',
+ },
+ {
+ id: 2,
+ firstname: 'Jane',
+ lastname: 'Doe',
+ age: 22,
+ city: 'Paris',
+ },
+ {
+ id: 3,
+ firstname: 'John',
+ lastname: 'Smith',
+ age: 32,
+ city: 'London',
+ },
+ {
+ id: 4,
+ firstname: 'Jane',
+ lastname: 'Smith',
+ age: 28,
+ city: 'Tokyo',
+ },
+ ],
+ },
+ })
+
+ let loadingBar = wrapper.findComponent(MazLoadingBar)
+
+ expect(loadingBar.exists()).toBe(false)
+
+ await wrapper.setProps({ loading: true })
+
+ loadingBar = wrapper.findComponent(MazLoadingBar)
+ expect(loadingBar.isVisible()).toBe(true)
+
+ const checkbox = wrapper.findComponent(MazCheckbox)
+
+ expect(checkbox.exists()).toBe(true)
+
+ wrapper.vm.allSelected = true
+
+ expect(wrapper.emitted('update:model-value')[0]).toStrictEqual([[1, 2, 3, 4]])
+
+ await wrapper.findAll('thead tr th')[3].trigger('click')
+
+ expect(wrapper.vm.rowsFiltered).toStrictEqual([
+ {
+ age: 32,
+ city: 'London',
+ firstname: 'John',
+ id: 3,
+ lastname: 'Smith',
+ selected: true,
+ },
+ {
+ age: 28,
+ city: 'Tokyo',
+ firstname: 'Jane',
+ id: 4,
+ lastname: 'Smith',
+ selected: true,
+ },
+ {
+ age: 25,
+ city: 'New York',
+ firstname: 'John',
+ id: 1,
+ lastname: 'Doe',
+ selected: true,
+ },
+ {
+ age: 22,
+ city: 'Paris',
+ firstname: 'Jane',
+ id: 2,
+ lastname: 'Doe',
+ selected: true,
+ },
+ ])
+
+ wrapper.vm.searchQueryModel = 'Tokyo'
+
+ expect(wrapper.vm.rowsFiltered).toStrictEqual([
+ {
+ age: 28,
+ city: 'Tokyo',
+ firstname: 'Jane',
+ id: 4,
+ lastname: 'Smith',
+ selected: true,
+ },
+ ])
+ })
+})
diff --git a/packages/lib/tests/tsconfig.json b/packages/lib/tests/tsconfig.json
index 0ebe0f2b49..d0462a1a01 100644
--- a/packages/lib/tests/tsconfig.json
+++ b/packages/lib/tests/tsconfig.json
@@ -1,14 +1,13 @@
{
+ "extends": ["./../node_modules/@vue/tsconfig/tsconfig.dom.json"],
"compilerOptions": {
- "types": ["vitest/globals"],
+ "types": ["vitest/globals", "vue"],
"baseUrl": ".",
- "target": "ESNext",
- "moduleResolution": "node",
"paths": {
"@modules/*": ["./../modules/*"],
"@components/*": ["./../components/*"],
"@tests/*": ["./../tests/*"]
}
},
- "include": ["./../types/*", "./**/*", "./../components/**/*", "./../modules/**/*"]
+ "include": ["./../types/*", "**/*", "./../components/**/*", "./../modules/**/*"]
}
diff --git a/packages/lib/vitest.config.mts b/packages/lib/vitest.config.mts
index e758e9beba..82514c4631 100644
--- a/packages/lib/vitest.config.mts
+++ b/packages/lib/vitest.config.mts
@@ -24,7 +24,6 @@ export default defineConfig({
// inline: ['vitest-canvas-mock'],
// },
// },
- // threads: false,
globalSetup: './vitest-global.setup.ts',
environment: 'jsdom',
environmentOptions: {