@dcrackel/hematournamentui 1.0.7 → 1.0.20
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/.storybook/preview-head.html +3 -1
- package/dist/HemaTouranmentUI-lib.es.js +26609 -480
- package/dist/HemaTouranmentUI-lib.umd.js +183 -1
- package/dist/style.css +9 -0
- package/package/.eslintrc.js +18 -0
- package/package/.gitattributes +2 -0
- package/package/.prettierignore +1 -0
- package/package/.storybook/main.js +18 -0
- package/package/.storybook/mockRoutes.js +9 -0
- package/package/.storybook/preview-head.html +1 -0
- package/package/.storybook/preview.js +17 -0
- package/package/LICENSE +21 -0
- package/package/README.md +83 -0
- package/package/index.html +12 -0
- package/package/package.json +49 -0
- package/package/postcss.config.js +6 -0
- package/package/prettier.config.js +10 -0
- package/package/src/assets/default-tournament.png +0 -0
- package/package/src/index.js +15 -0
- package/package/src/main.js +2 -0
- package/package/src/mocks/fileMock.js +1 -0
- package/package/src/mocks/tournamentMock.js +34 -0
- package/package/src/stories/Configure.mdx +320 -0
- package/package/tailwind/output.css +1072 -0
- package/package/tailwind/tailwind.css +4 -0
- package/package/tailwind.config.js +25 -0
- package/package/vite.config.js +23 -0
- package/package.json +9 -2
- package/src/assets/select-tournament.png +0 -0
- package/src/index.js +20 -11
- package/src/stories/Atoms/Icon/BaseIcon.stories.js +54 -0
- package/src/stories/Atoms/Icon/BaseIcon.vue +47 -0
- package/src/stories/Atoms/Input/BaseInput.stories.js +28 -0
- package/src/stories/Atoms/Input/BaseInput.test.js +87 -0
- package/src/stories/Atoms/Input/BaseInput.vue +73 -0
- package/src/stories/Atoms/RadioGroup/BaseRadioGroup.stories.js +31 -0
- package/src/stories/Atoms/RadioGroup/BaseRadioGroup.vue +49 -0
- package/src/stories/Atoms/Tag/BaseTag.stories.js +29 -0
- package/src/stories/Atoms/Tag/BaseTag.test.js +42 -0
- package/src/stories/Atoms/Tag/BaseTag.vue +57 -0
- package/src/stories/Atoms/Text/BaseText.stories.js +77 -0
- package/src/stories/Atoms/Text/BaseText.test.js +172 -0
- package/src/stories/Atoms/Text/BaseText.vue +170 -0
- package/src/stories/Molecules/Breadcrumb/Admin/Breadcrumb.stories.js +41 -0
- package/src/stories/Molecules/Breadcrumb/Admin/Breadcrumb.vue +31 -0
- package/src/stories/Molecules/Button/BaseButton.stories.js +76 -0
- package/src/stories/Molecules/Button/BaseButton.test.js +147 -0
- package/src/stories/Molecules/Button/BaseButton.vue +125 -0
- package/src/stories/Molecules/Cards/Detail/TournamentCardDetail.stories.js +33 -0
- package/src/stories/Molecules/Cards/Detail/TournamentCardDetail.vue +38 -0
- package/src/stories/Molecules/Cards/Header/TournamentCardHeader.stories.js +48 -0
- package/src/stories/Molecules/Cards/Header/TournamentCardHeader.vue +40 -0
- package/src/stories/Molecules/Filters/FilterAndSortBar/FilterAndSortBar.stories.js +36 -0
- package/src/stories/Molecules/Filters/FilterAndSortBar/FilterAndSortBar.vue +49 -0
- package/src/stories/Molecules/Filters/FilterUpcomingPast/FilterUpcomingPast.stories.js +32 -0
- package/src/stories/Molecules/Filters/FilterUpcomingPast/FilterUpcomingPast.vue +46 -0
- package/src/stories/Organisms/AddressAutocomplete/AddressAutocomplete.stories.js +25 -0
- package/src/stories/Organisms/AddressAutocomplete/AddressAutocomplete.vue +51 -0
- package/src/stories/Organisms/DatePicker/DatePicker.stories.js +25 -0
- package/src/stories/Organisms/DatePicker/DatePicker.vue +62 -0
- package/src/stories/Organisms/DropDown/DropDownMenu.stories.js +34 -0
- package/src/stories/Organisms/DropDown/DropDownMenu.vue +51 -0
- package/src/stories/Organisms/Grid/GridContainer.stories.js +47 -0
- package/src/stories/Organisms/Grid/GridContainer.vue +108 -0
- package/src/stories/Organisms/ImageCropper/ImageCropper.stories.js +28 -0
- package/src/stories/Organisms/ImageCropper/ImageCropper.vue +86 -0
- package/src/stories/Organisms/TextBoxEditor/TextBoxEditor.stories.js +28 -0
- package/src/stories/Organisms/TextBoxEditor/TextBoxEditor.vue +97 -0
- package/src/stories/Organisms/TournamentCard/TournamentCard.stories.js +37 -0
- package/src/stories/Organisms/TournamentCard/TournamentCard.vue +35 -0
- package/src/stories/Templates/Forms/AddTournamentPageOne/AddTournamentPageOne.stories.js +25 -0
- package/src/stories/Templates/Forms/AddTournamentPageOne/AddTournamentPageOne.vue +136 -0
- package/src/stories/Templates/Menu/Admin/AdminLeftMenu.stories.js +28 -0
- package/src/stories/Templates/Menu/Admin/AdminLeftMenu.vue +57 -0
- package/tailwind/output.css +147 -7
- package/tailwind.config.js +28 -3
- /package/{src → package/src}/stories/Base/Button/BaseButton.stories.js +0 -0
- /package/{src → package/src}/stories/Base/Button/BaseButton.test.js +0 -0
- /package/{src → package/src}/stories/Base/Button/BaseButton.vue +0 -0
- /package/{src → package/src}/stories/Base/Input/BaseInput.stories.js +0 -0
- /package/{src → package/src}/stories/Base/Input/BaseInput.test.js +0 -0
- /package/{src → package/src}/stories/Base/Input/BaseInput.vue +0 -0
- /package/{src → package/src}/stories/Base/Tag/BaseTag.stories.js +0 -0
- /package/{src → package/src}/stories/Base/Tag/BaseTag.test.js +0 -0
- /package/{src → package/src}/stories/Base/Tag/BaseTag.vue +0 -0
- /package/{src → package/src}/stories/Base/Text/BaseText.stories.js +0 -0
- /package/{src → package/src}/stories/Base/Text/BaseText.test.js +0 -0
- /package/{src → package/src}/stories/Base/Text/BaseText.vue +0 -0
- /package/{src → package/src}/stories/Breadcrumb/Admin/Breadcrumb.stories.js +0 -0
- /package/{src → package/src}/stories/Breadcrumb/Admin/Breadcrumb.vue +0 -0
- /package/{src → package/src}/stories/Cards/TournamentCard/Detail/TournamentCardDetail.stories.js +0 -0
- /package/{src → package/src}/stories/Cards/TournamentCard/Detail/TournamentCardDetail.vue +0 -0
- /package/{src → package/src}/stories/Cards/TournamentCard/Header/TournamentCardHeader.stories.js +0 -0
- /package/{src → package/src}/stories/Cards/TournamentCard/Header/TournamentCardHeader.vue +0 -0
- /package/{src → package/src}/stories/Cards/TournamentCard/TournamentCard.stories.js +0 -0
- /package/{src → package/src}/stories/Cards/TournamentCard/TournamentCard.vue +0 -0
- /package/{src → package/src}/stories/Containers/Grid/GridContainer.stories.js +0 -0
- /package/{src → package/src}/stories/Containers/Grid/GridContainer.vue +0 -0
- /package/{src → package/src}/stories/Filters/FilterAndSortBar/FilterAndSortBar.stories.js +0 -0
- /package/{src → package/src}/stories/Filters/FilterAndSortBar/FilterAndSortBar.vue +0 -0
- /package/{src → package/src}/stories/Filters/FilterUpcomingPast/FilterUpcomingPast.stories.js +0 -0
- /package/{src → package/src}/stories/Filters/FilterUpcomingPast/FilterUpcomingPast.vue +0 -0
- /package/{src → package/src}/stories/Menu/Admin/AdminLeftMenu.stories.js +0 -0
- /package/{src → package/src}/stories/Menu/Admin/AdminLeftMenu.vue +0 -0
- /package/{src → package/src}/stories/Menu/DropDown/DropDownMenu.stories.js +0 -0
- /package/{src → package/src}/stories/Menu/DropDown/DropDownMenu.vue +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
export default {
|
|
3
|
+
content: [
|
|
4
|
+
"./index.html",
|
|
5
|
+
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
|
6
|
+
],
|
|
7
|
+
theme: {
|
|
8
|
+
extend: {
|
|
9
|
+
fontFamily: {
|
|
10
|
+
sans: ['Inter', 'system-ui', '-apple-system', 'BlinkMacSystemFont']
|
|
11
|
+
},
|
|
12
|
+
colors: {
|
|
13
|
+
primary: '#141B33',
|
|
14
|
+
primaryHighlight: '#52586C',
|
|
15
|
+
secondary: '#2B324B',
|
|
16
|
+
tertiary: '#F6FAFD',
|
|
17
|
+
quaternary: '#8991AC',
|
|
18
|
+
dropdownSelect: '#D5E4EE',
|
|
19
|
+
neutral: '#FFFFFF',
|
|
20
|
+
bright: '#A0B1EC'
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
plugins: [],
|
|
25
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import vue from '@vitejs/plugin-vue'
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
plugins: [vue()],
|
|
5
|
+
test: {
|
|
6
|
+
environment: "happy-dom",
|
|
7
|
+
},
|
|
8
|
+
build: {
|
|
9
|
+
lib: {
|
|
10
|
+
entry: 'src/index.js', // this will be your entry point file where you export components
|
|
11
|
+
name: 'HemaTournamentUI', // this is the name of your library
|
|
12
|
+
fileName: (format) => `HemaTouranmentUI-lib.${format}.js`
|
|
13
|
+
},
|
|
14
|
+
rollupOptions: {
|
|
15
|
+
external: ['vue'], // add external dependencies here
|
|
16
|
+
output: {
|
|
17
|
+
globals: {
|
|
18
|
+
vue: 'Vue'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
})
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcrackel/hematournamentui",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.20",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/HemaTouranmentUI-lib.umd.js",
|
|
7
7
|
"module": "dist/HemaTouranmentUI-lib.es.js",
|
|
@@ -20,10 +20,17 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@storybook/addon-actions": "^7.4.5",
|
|
23
|
+
"@tiptap/extension-bold": "^2.1.11",
|
|
24
|
+
"@tiptap/starter-kit": "^2.1.11",
|
|
25
|
+
"@tiptap/vue-3": "^2.1.11",
|
|
26
|
+
"@vuepic/vue-datepicker": "^7.1.0",
|
|
23
27
|
"concurrently": "^8.2.1",
|
|
28
|
+
"cropperjs": "^1.6.1",
|
|
24
29
|
"font-awesome": "^4.7.0",
|
|
25
30
|
"happy-dom": "^12.8.0",
|
|
26
|
-
"vue": "^3.3.4"
|
|
31
|
+
"vue": "^3.3.4",
|
|
32
|
+
"vue-avatar-cropper": "^6.0.9",
|
|
33
|
+
"vue-google-autocomplete": "^1.1.4"
|
|
27
34
|
},
|
|
28
35
|
"devDependencies": {
|
|
29
36
|
"@storybook/addon-docs": "^7.4.5",
|
|
Binary file
|
package/src/index.js
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
export { default as
|
|
2
|
-
export { default as
|
|
3
|
-
export { default as
|
|
4
|
-
export { default as
|
|
1
|
+
export { default as BaseIcon } from './stories/Atoms/Icon/BaseIcon.vue';
|
|
2
|
+
export { default as BaseInput } from './stories/Atoms/Input/BaseInput.vue';
|
|
3
|
+
export { default as BaseRaioGroup } from './stories/Atoms/RadioGroup/BaseRadioGroup.vue';
|
|
4
|
+
export { default as BaseTag } from './stories/Atoms/Tag/BaseTag.vue';
|
|
5
|
+
export { default as BaseText } from './stories/Atoms/Text/BaseText.vue';
|
|
5
6
|
|
|
6
|
-
export { default as
|
|
7
|
-
export { default as
|
|
8
|
-
export { default as
|
|
7
|
+
export { default as Breadcrumb } from './stories/Molecules/Breadcrumb/Admin/Breadcrumb.vue';
|
|
8
|
+
export { default as BaseButton } from './stories/Molecules/Button/BaseButton.vue';
|
|
9
|
+
export { default as TournamentCardDetails } from './stories/Molecules/Cards/Detail/TournamentCardDetail.vue';
|
|
10
|
+
export { default as TournamentCardHeader } from './stories/Molecules/Cards/Header/TournamentCardHeader.vue';
|
|
11
|
+
export { default as FilterAndSortBar } from './stories/Molecules/Filters/FilterAndSortBar/FilterAndSortBar.vue';
|
|
12
|
+
export { default as FilterUpcomingPast } from './stories/Molecules/Filters/FilterUpcomingPast/FilterUpcomingPast.vue';
|
|
9
13
|
|
|
10
|
-
export { default as
|
|
14
|
+
export { default as AddressAutocomplete } from './stories/Organisms/AddressAutocomplete/AddressAutocomplete.vue';
|
|
15
|
+
export { default as DatePicker } from './stories/Organisms/DatePicker/DatePicker.vue';
|
|
16
|
+
export { default as DropDown } from './stories/Organisms/DropDown/DropDownMenu.vue';
|
|
17
|
+
export { default as ImageCropper } from './stories/Organisms/ImageCropper/ImageCropper.vue';
|
|
18
|
+
export { default as TextBoxEditor } from './stories/Organisms/TextBoxEditor/TextBoxEditor.vue';
|
|
19
|
+
export { default as TournamentCard } from './stories/Organisms/TournamentCard/TournamentCard.vue';
|
|
11
20
|
|
|
12
|
-
export { default as
|
|
13
|
-
export { default as
|
|
14
|
-
export { default as
|
|
21
|
+
export { default as AddTournamentPageOne } from './stories/Templates/Forms/AddTournamentPageOne/AddTournamentPageOne.vue';
|
|
22
|
+
// export { default as AddTournamentPageTwo } from './stories/Templates/Forms/AddTournamentPageTwo/AddTournamentPageTwo.vue';
|
|
23
|
+
export { default as AdminLeftMenu } from './stories/Templates/Menu/Admin/AdminLeftMenu.vue';
|
|
15
24
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import BaseIcon from './BaseIcon.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Atoms/BaseIcon',
|
|
5
|
+
component: BaseIcon,
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
argTypes: {
|
|
8
|
+
iconName: {
|
|
9
|
+
control: {
|
|
10
|
+
type: 'text',
|
|
11
|
+
defaultValue: 'fa-check'
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
style: {
|
|
15
|
+
control: {
|
|
16
|
+
type: 'select'
|
|
17
|
+
},
|
|
18
|
+
options: ['fa-solid', 'fa-regular', 'fa-solid', 'fa-light', 'fa-thing'],
|
|
19
|
+
defaultValue: 'solid'
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
control: {
|
|
23
|
+
type: 'select'
|
|
24
|
+
},
|
|
25
|
+
options: ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'],
|
|
26
|
+
defaultValue: 'sm'
|
|
27
|
+
},
|
|
28
|
+
color: {
|
|
29
|
+
control: {
|
|
30
|
+
type: 'text'
|
|
31
|
+
},
|
|
32
|
+
options: ['primary', 'secondary', 'tertiary', 'neutral', 'bright'],
|
|
33
|
+
defaultValue: 'primary'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const BasicPrimary = {
|
|
39
|
+
args: {
|
|
40
|
+
iconName: 'fa-face-smile',
|
|
41
|
+
size: 'sm',
|
|
42
|
+
color: 'primary',
|
|
43
|
+
style: 'fa-solid'
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const RegularAndBright = {
|
|
48
|
+
args: {
|
|
49
|
+
iconName: 'fa-face-smile',
|
|
50
|
+
size: 'lg',
|
|
51
|
+
color: 'bright',
|
|
52
|
+
style: 'fa-regular'
|
|
53
|
+
}
|
|
54
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<i :class="computedIconClass"></i>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script>
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
name: 'BaseIcon',
|
|
9
|
+
props: {
|
|
10
|
+
iconName: {
|
|
11
|
+
type: String,
|
|
12
|
+
required: true
|
|
13
|
+
},
|
|
14
|
+
style: {
|
|
15
|
+
type: String,
|
|
16
|
+
default: 'fa-solid',
|
|
17
|
+
validator: function (value) {
|
|
18
|
+
return ['fa-solid', 'fa-regular', 'fa-solid', 'fa-light', 'fa-thing'].indexOf(value) !== -1;
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
type: String,
|
|
23
|
+
validator: function (value) {
|
|
24
|
+
return ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'].indexOf(value) !== -1;
|
|
25
|
+
},
|
|
26
|
+
default: 'sm'
|
|
27
|
+
},
|
|
28
|
+
color: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: 'primary'
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
computed: {
|
|
34
|
+
computedIconClass() {
|
|
35
|
+
return [
|
|
36
|
+
this.style,
|
|
37
|
+
this.iconName,
|
|
38
|
+
`text-${this.size}`,
|
|
39
|
+
this.colorClass
|
|
40
|
+
];
|
|
41
|
+
},
|
|
42
|
+
colorClass() {
|
|
43
|
+
return `text-${this.color}`;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
</script>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import BaseInput from './BaseInput.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Atoms/BaseInput',
|
|
5
|
+
component: BaseInput,
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
argTypes: {
|
|
8
|
+
placeholder: { control: 'text' },
|
|
9
|
+
value: { control: 'text' }
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Template = args => ({
|
|
14
|
+
components: { BaseInput },
|
|
15
|
+
props: Object.keys(args),
|
|
16
|
+
methods: {
|
|
17
|
+
onValueUpdate(newValue) {
|
|
18
|
+
console.log('Value updated:', newValue);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const Default = {
|
|
24
|
+
args: {
|
|
25
|
+
placeholder: 'Enter text...',
|
|
26
|
+
value: ''
|
|
27
|
+
}
|
|
28
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import BaseInput from './BaseInput.vue';
|
|
2
|
+
import { mount } from "@vue/test-utils";
|
|
3
|
+
import { describe, expect, test, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
describe('BaseInput.vue', () => {
|
|
6
|
+
|
|
7
|
+
it('renders with default props', () => {
|
|
8
|
+
const wrapper = mount(BaseInput);
|
|
9
|
+
const inputElement = wrapper.find('input');
|
|
10
|
+
|
|
11
|
+
expect(inputElement.attributes('placeholder')).toBe('');
|
|
12
|
+
expect(wrapper.vm.internalValue).toBe('');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('initializes with the correct value prop', () => {
|
|
16
|
+
const initialValue = 'Hello, World!';
|
|
17
|
+
const wrapper = mount(BaseInput, {
|
|
18
|
+
props: {
|
|
19
|
+
value: initialValue
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(wrapper.vm.internalValue).toBe(initialValue);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('updates internalValue when value prop changes', async () => {
|
|
27
|
+
const wrapper = mount(BaseInput);
|
|
28
|
+
await wrapper.setProps({ value: 'New Value' });
|
|
29
|
+
|
|
30
|
+
expect(wrapper.vm.internalValue).toBe('New Value');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('emits update:value with a delay upon input', async () => {
|
|
34
|
+
const wrapper = mount(BaseInput);
|
|
35
|
+
const inputElement = wrapper.find('input');
|
|
36
|
+
|
|
37
|
+
await inputElement.setValue('Test Input');
|
|
38
|
+
|
|
39
|
+
// TODO: Handle timer-related functionality with vitest
|
|
40
|
+
await new Promise(resolve => setTimeout(resolve, 350));
|
|
41
|
+
|
|
42
|
+
expect(wrapper.emitted('update:value')).toBeTruthy();
|
|
43
|
+
expect(wrapper.emitted('update:value')[0]).toEqual(['Test Input']);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('applies formInput styles when type is formInput', () => {
|
|
47
|
+
const wrapper = mount(BaseInput, {
|
|
48
|
+
props: {
|
|
49
|
+
type: 'formInput',
|
|
50
|
+
invalid: false
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
const inputElement = wrapper.find('input');
|
|
54
|
+
expect(inputElement.classes()).toContain('border');
|
|
55
|
+
expect(inputElement.classes()).toContain('rounded-lg');
|
|
56
|
+
expect(inputElement.classes()).toContain('text-secondary');
|
|
57
|
+
expect(inputElement.classes()).toContain('placeholder:text-xs');
|
|
58
|
+
expect(inputElement.classes()).toContain('text-sm');
|
|
59
|
+
expect(inputElement.classes()).toContain('p-2');
|
|
60
|
+
expect(inputElement.classes()).toContain('w-full');
|
|
61
|
+
expect(inputElement.classes()).toContain('border-dropdownSelect');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('applies border-alarm class when invalid is true', () => {
|
|
65
|
+
const wrapper = mount(BaseInput, {
|
|
66
|
+
props: {
|
|
67
|
+
type: 'formInput',
|
|
68
|
+
invalid: true
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
const inputElement = wrapper.find('input');
|
|
72
|
+
expect(inputElement.classes()).toContain('border-alarm');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('does not apply border-alarm class when invalid is false', () => {
|
|
76
|
+
const wrapper = mount(BaseInput, {
|
|
77
|
+
props: {
|
|
78
|
+
type: 'formInput',
|
|
79
|
+
invalid: false
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const inputElement = wrapper.find('input');
|
|
83
|
+
expect(inputElement.classes()).not.toContain('border-alarm');
|
|
84
|
+
expect(inputElement.classes()).toContain('border-dropdownSelect');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<input
|
|
3
|
+
:class="baseClasses"
|
|
4
|
+
:placeholder="placeholder"
|
|
5
|
+
v-model="internalValue"
|
|
6
|
+
@input="onInput"
|
|
7
|
+
/>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
import { ref, watch, computed } from 'vue';
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
name: 'BaseInput',
|
|
15
|
+
props: {
|
|
16
|
+
placeholder: {
|
|
17
|
+
type: String,
|
|
18
|
+
default: ''
|
|
19
|
+
},
|
|
20
|
+
value: {
|
|
21
|
+
type: String,
|
|
22
|
+
default: ''
|
|
23
|
+
},
|
|
24
|
+
type: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: 'borderless',
|
|
27
|
+
validator: function (value) {
|
|
28
|
+
return ['formInput', 'borderless'].indexOf(value) !== -1;
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
invalid: {
|
|
32
|
+
type: Boolean,
|
|
33
|
+
default: false
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
setup(props, { emit }) {
|
|
37
|
+
const internalValue = ref(props.value);
|
|
38
|
+
const timeout = ref(null);
|
|
39
|
+
|
|
40
|
+
watch(() => props.value, newValue => {
|
|
41
|
+
internalValue.value = newValue;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const baseClasses = computed(() => {
|
|
45
|
+
let baseClasses = 'appearance-none focus:outline-none';
|
|
46
|
+
|
|
47
|
+
switch (props.type) {
|
|
48
|
+
case 'borderless':
|
|
49
|
+
baseClasses += ' w-full text-sm';
|
|
50
|
+
break;
|
|
51
|
+
case 'formInput':
|
|
52
|
+
baseClasses += ' border rounded-lg text-secondary placeholder:text-xs text-sm p-2 w-full';
|
|
53
|
+
props.invalid ? baseClasses += ' border-alarm' : baseClasses += ' border border-dropdownSelect';
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
return baseClasses;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const onInput = () => {
|
|
60
|
+
clearTimeout(timeout.value);
|
|
61
|
+
timeout.value = setTimeout(() => {
|
|
62
|
+
emit('update:value', internalValue.value);
|
|
63
|
+
}, 300);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
internalValue,
|
|
68
|
+
baseClasses,
|
|
69
|
+
onInput
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
</script>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import BaseRadioGroup from './BaseRadioGroup.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Atoms/BaseRadioGroup',
|
|
5
|
+
component: BaseRadioGroup,
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
argTypes: {
|
|
8
|
+
items: {
|
|
9
|
+
control: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const Template = (args) => ({
|
|
17
|
+
components: { BaseRadioGroup },
|
|
18
|
+
setup() {
|
|
19
|
+
return { args };
|
|
20
|
+
},
|
|
21
|
+
template: '<BaseRadioGroup v-bind="args" />',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const Default = Template.bind({});
|
|
25
|
+
Default.args = {
|
|
26
|
+
items: [
|
|
27
|
+
{ label: 'Option 1', value: 'opt1', description: 'Description for Item1' },
|
|
28
|
+
{ label: 'Option 2', value: 'opt2', description: 'Description for Item2' },
|
|
29
|
+
{ label: 'Option 2', value: 'opt2', description: 'Description for Item3' },
|
|
30
|
+
]
|
|
31
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="text-xl" role="radiogroup">
|
|
3
|
+
<div
|
|
4
|
+
class="flex flex-row p-4 text-quaternary rounded-lg mb-2 shadow border hover:bg-tertiary"
|
|
5
|
+
v-for="(item, index) in items"
|
|
6
|
+
:key="index"
|
|
7
|
+
:class="[selectedIndex === index ? ' bg-tertiary' : ' bg-white', invalid ? ' border-alarm' : ' border-dropdownSelect']"
|
|
8
|
+
@click="selectItem(index)"
|
|
9
|
+
role="radio"
|
|
10
|
+
:aria-checked="selectedIndex === index ? 'true' : 'false'"
|
|
11
|
+
tabindex="0"
|
|
12
|
+
@keydown.enter.prevent="selectItem(index)"
|
|
13
|
+
>
|
|
14
|
+
<i :class="[selectedIndex === index ? 'fa-circle-dot text-quaternary ' : 'fa-circle ' ]" class="fa-regular pr-4 pt-2" ></i>
|
|
15
|
+
<div class="flex flex-col">
|
|
16
|
+
<p :class="[selectedIndex === index ? 'text-quaternary ' : '' ]" class="font-bold text-sm">{{ item.label }}</p>
|
|
17
|
+
<p :class="[selectedIndex === index ? 'text-quaternary ' : '' ]" class="text-sm">{{ item.description }}</p>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script>
|
|
24
|
+
export default {
|
|
25
|
+
name: 'BaseRadioGroup',
|
|
26
|
+
props: {
|
|
27
|
+
invalid: {
|
|
28
|
+
type: Boolean,
|
|
29
|
+
default: false,
|
|
30
|
+
},
|
|
31
|
+
items: {
|
|
32
|
+
type: Array,
|
|
33
|
+
required: true,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
data() {
|
|
37
|
+
return {
|
|
38
|
+
selectedIndex: null,
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
methods: {
|
|
42
|
+
selectItem(index) {
|
|
43
|
+
this.selectedIndex = index;
|
|
44
|
+
this.$emit('update:value', this.items[index].value);
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
</script>
|
|
49
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import BaseTag from './BaseTag.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Atoms/BaseTag',
|
|
5
|
+
component: BaseTag,
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
argTypes: {
|
|
8
|
+
label: {
|
|
9
|
+
control: {
|
|
10
|
+
type: 'text',
|
|
11
|
+
defaultValue: 'Default Label'
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
backgroundColor: {
|
|
15
|
+
control: {
|
|
16
|
+
type: 'select'
|
|
17
|
+
},
|
|
18
|
+
options: ['primary', 'secondary', 'tertiary', 'neutral', 'bright'],
|
|
19
|
+
defaultValue: 'primary'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const Basic = {
|
|
25
|
+
args: {
|
|
26
|
+
label: 'default tag',
|
|
27
|
+
backgroundColor: 'primary'
|
|
28
|
+
}
|
|
29
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import BaseTag from './BaseTag.vue';
|
|
2
|
+
import { mount } from "@vue/test-utils";
|
|
3
|
+
import { describe, expect, test, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
describe('base-tag.vue', () => {
|
|
6
|
+
|
|
7
|
+
it('renders with default classes and primary background color', () => {
|
|
8
|
+
const wrapper = mount(BaseTag, {
|
|
9
|
+
props: { label: 'Test Tag' }
|
|
10
|
+
});
|
|
11
|
+
const tagElement = wrapper.find('div');
|
|
12
|
+
|
|
13
|
+
expect(tagElement.classes()).toContain('cursor-pointer');
|
|
14
|
+
expect(tagElement.classes()).toContain('bg-primary');
|
|
15
|
+
expect(tagElement.text()).toBe('Test Tag');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('renders with specified background color classes', () => {
|
|
19
|
+
const backgrounds = ['primary', 'secondary', 'tertiary', 'neutral', 'bright'];
|
|
20
|
+
|
|
21
|
+
backgrounds.forEach(async (bg) => {
|
|
22
|
+
const wrapper = mount(BaseTag, {
|
|
23
|
+
props: { label: 'Test Tag', backgroundColor: bg }
|
|
24
|
+
});
|
|
25
|
+
const tagElement = wrapper.find('div');
|
|
26
|
+
|
|
27
|
+
expect(tagElement.classes()).toContain(`bg-${bg}`);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('renders with primary background color for unknown values', () => {
|
|
32
|
+
const wrapper = mount(BaseTag, {
|
|
33
|
+
props: { label: 'Test Tag', backgroundColor: 'unknown' }
|
|
34
|
+
});
|
|
35
|
+
const tagElement = wrapper.find('div');
|
|
36
|
+
|
|
37
|
+
expect(tagElement.classes()).toContain('bg-primary');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="classes">{{ label }}</div>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script>
|
|
6
|
+
import { computed, reactive } from 'vue';
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
name: 'base-tag',
|
|
10
|
+
|
|
11
|
+
props: {
|
|
12
|
+
label: {
|
|
13
|
+
type: String,
|
|
14
|
+
required: true
|
|
15
|
+
},
|
|
16
|
+
backgroundColor: {
|
|
17
|
+
type: String,
|
|
18
|
+
validator: function (value) {
|
|
19
|
+
return ['primary', 'secondary', 'tertiary', 'neutral', 'bright'].indexOf(value) !== -1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
setup(props) {
|
|
25
|
+
props = reactive(props);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
classes: computed(() => {
|
|
29
|
+
let baseClasses = 'cursor-pointer inline-block py-1 px-3 my-2 ml-3 text-xs font-normal rounded-full text-neutral';
|
|
30
|
+
|
|
31
|
+
switch (props.backgroundColor) {
|
|
32
|
+
case 'primary':
|
|
33
|
+
baseClasses += ' bg-primary';
|
|
34
|
+
break;
|
|
35
|
+
case 'secondary':
|
|
36
|
+
baseClasses += ' bg-secondary';
|
|
37
|
+
break;
|
|
38
|
+
case 'tertiary':
|
|
39
|
+
baseClasses += ' bg-tertiary';
|
|
40
|
+
break;
|
|
41
|
+
case 'neutral':
|
|
42
|
+
baseClasses += ' bg-neutral';
|
|
43
|
+
break;
|
|
44
|
+
case 'bright':
|
|
45
|
+
baseClasses += ' bg-bright';
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
baseClasses += ' bg-primary';
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return baseClasses;
|
|
53
|
+
})
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
</script>
|