@pequity/squirrel 5.4.1 → 5.4.3
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/dist/cjs/chunks/p-action-bar.js +10 -11
- package/dist/cjs/chunks/p-date-picker.js +108 -0
- package/dist/cjs/chunks/p-dropdown-select.js +7 -8
- package/dist/cjs/chunks/p-inline-date-picker.js +112 -0
- package/dist/cjs/chunks/p-input-percent.js +3 -5
- package/dist/cjs/chunks/p-pagination-info.js +1 -1
- package/dist/cjs/chunks/p-pagination.js +12 -16
- package/dist/cjs/index.js +55 -53
- package/dist/cjs/p-btn.js +8 -5
- package/dist/cjs/p-chips.js +3 -5
- package/dist/cjs/p-date-picker.js +2 -138
- package/dist/cjs/p-info-icon.js +1 -3
- package/dist/cjs/p-inline-date-picker.js +2 -143
- package/dist/cjs/p-table-td.js +3 -5
- package/dist/es/chunks/p-action-bar.js +10 -11
- package/dist/es/chunks/p-date-picker.js +109 -0
- package/dist/es/chunks/p-dropdown-select.js +7 -8
- package/dist/es/chunks/p-inline-date-picker.js +113 -0
- package/dist/es/chunks/p-input-percent.js +3 -5
- package/dist/es/chunks/p-pagination-info.js +1 -1
- package/dist/es/chunks/p-pagination.js +12 -16
- package/dist/es/index.js +104 -102
- package/dist/es/p-btn.js +8 -5
- package/dist/es/p-chips.js +4 -6
- package/dist/es/p-date-picker.js +2 -138
- package/dist/es/p-info-icon.js +2 -4
- package/dist/es/p-inline-date-picker.js +2 -143
- package/dist/es/p-table-td.js +4 -6
- package/dist/squirrel/components/p-action-bar/p-action-bar.vue.d.ts +5 -14
- package/dist/squirrel/components/p-alert/p-alert.vue.d.ts +4 -4
- package/dist/squirrel/components/p-avatar/p-avatar.vue.d.ts +5 -5
- package/dist/squirrel/components/p-btn/p-btn.vue.d.ts +40 -5
- package/dist/squirrel/components/p-card/p-card.vue.d.ts +4 -4
- package/dist/squirrel/components/p-checkbox/p-checkbox.vue.d.ts +5 -5
- package/dist/squirrel/components/p-chips/p-chips.vue.d.ts +5 -5
- package/dist/squirrel/components/p-close-btn/p-close-btn.vue.d.ts +4 -4
- package/dist/squirrel/components/p-date-picker/p-date-picker.vue.d.ts +35 -128
- package/dist/squirrel/components/p-drawer/p-drawer.vue.d.ts +37 -5
- package/dist/squirrel/components/p-dropdown/p-dropdown.vue.d.ts +5 -5
- package/dist/squirrel/components/p-dropdown-select/p-dropdown-select.vue.d.ts +128 -29
- package/dist/squirrel/components/p-file-upload/p-file-upload.vue.d.ts +5 -5
- package/dist/squirrel/components/p-icon/p-icon.vue.d.ts +1 -10
- package/dist/squirrel/components/p-info-icon/p-info-icon.vue.d.ts +2 -23
- package/dist/squirrel/components/p-input/p-input.vue.d.ts +9 -9
- package/dist/squirrel/components/p-input-number/p-input-number.vue.d.ts +40 -10
- package/dist/squirrel/components/p-input-percent/p-input-percent.vue.d.ts +5 -5
- package/dist/squirrel/components/p-input-search/p-input-search.vue.d.ts +121 -5
- package/dist/squirrel/components/p-link/p-link.vue.d.ts +1 -10
- package/dist/squirrel/components/p-loading/p-loading.vue.d.ts +1 -1
- package/dist/squirrel/components/p-modal/p-modal.vue.d.ts +5 -5
- package/dist/squirrel/components/p-pagination/p-pagination.vue.d.ts +5 -5
- package/dist/squirrel/components/p-pagination-info/p-pagination-info.vue.d.ts +4 -4
- package/dist/squirrel/components/p-progress-bar/p-progress-bar.vue.d.ts +3 -3
- package/dist/squirrel/components/p-ring-loader/p-ring-loader.vue.d.ts +4 -4
- package/dist/squirrel/components/p-select/p-select.vue.d.ts +5 -5
- package/dist/squirrel/components/p-select-btn/p-select-btn.vue.d.ts +4 -45
- package/dist/squirrel/components/p-select-list/p-select-list.vue.d.ts +143 -29
- package/dist/squirrel/components/p-select-list/useSelectList.d.ts +4 -4
- package/dist/squirrel/components/p-select-pill/p-select-pill.vue.d.ts +5 -5
- package/dist/squirrel/components/p-skeleton-loader/p-skeleton-loader.vue.d.ts +4 -4
- package/dist/squirrel/components/p-table/p-table.vue.d.ts +10 -47
- package/dist/squirrel/components/p-table/usePTableColResize.d.ts +4 -4
- package/dist/squirrel/components/p-table/usePTableRowVirtualizer.d.ts +10 -4
- package/dist/squirrel/components/p-table-header-cell/p-table-filter-icon.vue.d.ts +4 -4
- package/dist/squirrel/components/p-table-header-cell/p-table-header-cell.vue.d.ts +48 -5
- package/dist/squirrel/components/p-table-loader/p-table-loader.vue.d.ts +4 -4
- package/dist/squirrel/components/p-table-sort/p-table-sort.vue.d.ts +5 -5
- package/dist/squirrel/components/p-table-td/p-table-td.vue.d.ts +2 -25
- package/dist/squirrel/components/p-tabs/p-tabs.vue.d.ts +5 -5
- package/dist/squirrel/components/p-textarea/p-textarea.vue.d.ts +9 -9
- package/dist/squirrel/components/p-toggle/p-toggle.vue.d.ts +9 -9
- package/dist/squirrel/composables/useInputClasses.d.ts +1 -1
- package/dist/squirrel/utils/inputClassesMixin.d.ts +4 -4
- package/package.json +25 -25
- package/squirrel/components/p-btn/p-btn.spec.js +33 -4
- package/squirrel/components/p-btn/p-btn.vue +5 -2
- package/squirrel/components/p-date-picker/p-date-picker.vue +79 -86
- package/squirrel/components/p-inline-date-picker/p-inline-date-picker.spec.js +12 -14
- package/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue +87 -99
- package/squirrel/components/p-select-list/p-select-list.spec.js +26 -0
- package/squirrel/components/p-select-list/p-select-list.vue +8 -1
- package/dist/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue.d.ts +0 -154
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type StyleValue } from 'vue';
|
|
2
|
-
declare const _default: import("vue").DefineComponent<{
|
|
2
|
+
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
3
3
|
modelValue: {
|
|
4
4
|
type: (StringConstructor | NumberConstructor)[];
|
|
5
5
|
default: string;
|
|
@@ -16,14 +16,14 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
16
16
|
type: BooleanConstructor;
|
|
17
17
|
default: boolean;
|
|
18
18
|
};
|
|
19
|
-
}
|
|
19
|
+
}>, {}, {}, {
|
|
20
20
|
attrs(): {
|
|
21
21
|
[x: string]: unknown;
|
|
22
22
|
};
|
|
23
23
|
style(): StyleValue;
|
|
24
24
|
}, {
|
|
25
25
|
updateValue(e: Event): void;
|
|
26
|
-
}, import("vue").DefineComponent<{
|
|
26
|
+
}, import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
27
27
|
size: {
|
|
28
28
|
type: import("vue").PropType<import("../../index.js").InputSize>;
|
|
29
29
|
default: string;
|
|
@@ -41,7 +41,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
41
41
|
type: BooleanConstructor;
|
|
42
42
|
default: boolean;
|
|
43
43
|
};
|
|
44
|
-
}
|
|
44
|
+
}>, {}, {
|
|
45
45
|
errorMsgClasses: string;
|
|
46
46
|
}, {
|
|
47
47
|
inputClasses(): string;
|
|
@@ -66,12 +66,12 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
66
66
|
type: BooleanConstructor;
|
|
67
67
|
default: boolean;
|
|
68
68
|
};
|
|
69
|
-
}
|
|
69
|
+
}>> & Readonly<{}>, {
|
|
70
70
|
size: "sm" | "lg" | "md";
|
|
71
71
|
rounded: boolean;
|
|
72
72
|
required: boolean;
|
|
73
73
|
errorMsg: string;
|
|
74
|
-
}, {}>, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
74
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
75
75
|
modelValue: {
|
|
76
76
|
type: (StringConstructor | NumberConstructor)[];
|
|
77
77
|
default: string;
|
|
@@ -88,12 +88,12 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
88
88
|
type: BooleanConstructor;
|
|
89
89
|
default: boolean;
|
|
90
90
|
};
|
|
91
|
-
}>> & {
|
|
91
|
+
}>> & Readonly<{
|
|
92
92
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
93
|
-
}
|
|
93
|
+
}>, {
|
|
94
94
|
label: string;
|
|
95
95
|
required: boolean;
|
|
96
96
|
modelValue: string | number;
|
|
97
97
|
errorMsg: string;
|
|
98
|
-
}, {}>;
|
|
98
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
99
99
|
export default _default;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type StyleValue } from 'vue';
|
|
2
|
-
declare const _default: import("vue").DefineComponent<{
|
|
2
|
+
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
3
3
|
modelValue: {
|
|
4
4
|
type: BooleanConstructor;
|
|
5
5
|
default: boolean;
|
|
@@ -16,7 +16,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
16
16
|
type: BooleanConstructor;
|
|
17
17
|
default: boolean;
|
|
18
18
|
};
|
|
19
|
-
}
|
|
19
|
+
}>, {}, {}, {
|
|
20
20
|
toggleClasses(): string;
|
|
21
21
|
toggleLabelClasses(): string;
|
|
22
22
|
attrs(): {
|
|
@@ -25,7 +25,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
25
25
|
style(): StyleValue;
|
|
26
26
|
}, {
|
|
27
27
|
change(e: Event): void;
|
|
28
|
-
}, import("vue").DefineComponent<{
|
|
28
|
+
}, import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
29
29
|
size: {
|
|
30
30
|
type: import("vue").PropType<import("../../index.js").InputSize>;
|
|
31
31
|
default: string;
|
|
@@ -43,7 +43,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
43
43
|
type: BooleanConstructor;
|
|
44
44
|
default: boolean;
|
|
45
45
|
};
|
|
46
|
-
}
|
|
46
|
+
}>, {}, {
|
|
47
47
|
errorMsgClasses: string;
|
|
48
48
|
}, {
|
|
49
49
|
inputClasses(): string;
|
|
@@ -68,12 +68,12 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
68
68
|
type: BooleanConstructor;
|
|
69
69
|
default: boolean;
|
|
70
70
|
};
|
|
71
|
-
}
|
|
71
|
+
}>> & Readonly<{}>, {
|
|
72
72
|
size: "sm" | "lg" | "md";
|
|
73
73
|
rounded: boolean;
|
|
74
74
|
required: boolean;
|
|
75
75
|
errorMsg: string;
|
|
76
|
-
}, {}>, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
76
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
77
77
|
modelValue: {
|
|
78
78
|
type: BooleanConstructor;
|
|
79
79
|
default: boolean;
|
|
@@ -90,12 +90,12 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
90
90
|
type: BooleanConstructor;
|
|
91
91
|
default: boolean;
|
|
92
92
|
};
|
|
93
|
-
}>> & {
|
|
93
|
+
}>> & Readonly<{
|
|
94
94
|
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
95
|
-
}
|
|
95
|
+
}>, {
|
|
96
96
|
label: string;
|
|
97
97
|
required: boolean;
|
|
98
98
|
modelValue: boolean;
|
|
99
99
|
errorMsg: string;
|
|
100
|
-
}, {}>;
|
|
100
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
101
101
|
export default _default;
|
|
@@ -12,6 +12,6 @@ export declare function useInputClasses(props: Partial<Props>): {
|
|
|
12
12
|
labelClasses: import("vue").ComputedRef<string>;
|
|
13
13
|
selectClasses: import("vue").ComputedRef<string>;
|
|
14
14
|
textareaClasses: import("vue").ComputedRef<string>;
|
|
15
|
-
errorMsgClasses: import("vue").Ref<string>;
|
|
15
|
+
errorMsgClasses: import("vue").Ref<string, string>;
|
|
16
16
|
};
|
|
17
17
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type InputSize } from './inputClassesShared';
|
|
2
2
|
import { type PropType } from 'vue';
|
|
3
|
-
declare const _default: import("vue").DefineComponent<{
|
|
3
|
+
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
4
|
size: {
|
|
5
5
|
type: PropType<InputSize>;
|
|
6
6
|
default: string;
|
|
@@ -18,7 +18,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
18
18
|
type: BooleanConstructor;
|
|
19
19
|
default: boolean;
|
|
20
20
|
};
|
|
21
|
-
}
|
|
21
|
+
}>, {}, {
|
|
22
22
|
errorMsgClasses: string;
|
|
23
23
|
}, {
|
|
24
24
|
inputClasses(): string;
|
|
@@ -43,10 +43,10 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
43
43
|
type: BooleanConstructor;
|
|
44
44
|
default: boolean;
|
|
45
45
|
};
|
|
46
|
-
}
|
|
46
|
+
}>> & Readonly<{}>, {
|
|
47
47
|
size: "sm" | "lg" | "md";
|
|
48
48
|
rounded: boolean;
|
|
49
49
|
required: boolean;
|
|
50
50
|
errorMsg: string;
|
|
51
|
-
}, {}>;
|
|
51
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
52
52
|
export default _default;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pequity/squirrel",
|
|
3
3
|
"description": "Squirrel component library",
|
|
4
|
-
"version": "5.4.
|
|
5
|
-
"packageManager": "pnpm@9.
|
|
4
|
+
"version": "5.4.3",
|
|
5
|
+
"packageManager": "pnpm@9.12.1",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"preinstall": "npx only-allow pnpm",
|
|
@@ -53,33 +53,33 @@
|
|
|
53
53
|
"@commitlint/cli": "^19.5.0",
|
|
54
54
|
"@commitlint/config-conventional": "^19.5.0",
|
|
55
55
|
"@pequity/eslint-config": "^0.0.13",
|
|
56
|
-
"@playwright/test": "^1.
|
|
56
|
+
"@playwright/test": "^1.48.0",
|
|
57
57
|
"@popperjs/core": "2.11.8",
|
|
58
58
|
"@semantic-release/changelog": "^6.0.3",
|
|
59
59
|
"@semantic-release/git": "^10.0.1",
|
|
60
|
-
"@storybook/addon-a11y": "^8.3.
|
|
61
|
-
"@storybook/addon-actions": "^8.3.
|
|
62
|
-
"@storybook/addon-essentials": "^8.3.
|
|
63
|
-
"@storybook/addon-interactions": "^8.3.
|
|
64
|
-
"@storybook/addon-links": "^8.3.
|
|
65
|
-
"@storybook/blocks": "^8.3.
|
|
66
|
-
"@storybook/manager-api": "^8.3.
|
|
67
|
-
"@storybook/test": "^8.3.
|
|
60
|
+
"@storybook/addon-a11y": "^8.3.5",
|
|
61
|
+
"@storybook/addon-actions": "^8.3.5",
|
|
62
|
+
"@storybook/addon-essentials": "^8.3.5",
|
|
63
|
+
"@storybook/addon-interactions": "^8.3.5",
|
|
64
|
+
"@storybook/addon-links": "^8.3.5",
|
|
65
|
+
"@storybook/blocks": "^8.3.5",
|
|
66
|
+
"@storybook/manager-api": "^8.3.5",
|
|
67
|
+
"@storybook/test": "^8.3.5",
|
|
68
68
|
"@storybook/test-runner": "^0.19.1",
|
|
69
|
-
"@storybook/theming": "^8.3.
|
|
70
|
-
"@storybook/vue3": "^8.3.
|
|
71
|
-
"@storybook/vue3-vite": "^8.3.
|
|
69
|
+
"@storybook/theming": "^8.3.5",
|
|
70
|
+
"@storybook/vue3": "^8.3.5",
|
|
71
|
+
"@storybook/vue3-vite": "^8.3.5",
|
|
72
72
|
"@tanstack/vue-virtual": "3.10.8",
|
|
73
73
|
"@types/jsdom": "^21.1.7",
|
|
74
74
|
"@types/lodash-es": "^4.17.12",
|
|
75
|
-
"@types/node": "^22.7.
|
|
75
|
+
"@types/node": "^22.7.5",
|
|
76
76
|
"@vitejs/plugin-vue": "^5.1.4",
|
|
77
|
-
"@vitest/coverage-v8": "^2.1.
|
|
78
|
-
"@vue/compiler-sfc": "3.
|
|
77
|
+
"@vitest/coverage-v8": "^2.1.3",
|
|
78
|
+
"@vue/compiler-sfc": "3.5.12",
|
|
79
79
|
"@vue/test-utils": "^2.4.6",
|
|
80
80
|
"autoprefixer": "^10.4.20",
|
|
81
81
|
"dayjs": "1.11.13",
|
|
82
|
-
"eslint": "^8.57.
|
|
82
|
+
"eslint": "^8.57.1",
|
|
83
83
|
"eslint-plugin-storybook": "^0.9.0",
|
|
84
84
|
"floating-vue": "5.2.2",
|
|
85
85
|
"glob": "^11.0.0",
|
|
@@ -94,16 +94,16 @@
|
|
|
94
94
|
"prettier-plugin-tailwindcss": "^0.6.8",
|
|
95
95
|
"resolve-tspaths": "^0.8.22",
|
|
96
96
|
"rimraf": "^6.0.1",
|
|
97
|
-
"sass": "^1.79.
|
|
97
|
+
"sass": "^1.79.5",
|
|
98
98
|
"semantic-release": "^24.1.2",
|
|
99
|
-
"storybook": "^8.3.
|
|
99
|
+
"storybook": "^8.3.5",
|
|
100
100
|
"svgo": "^3.3.2",
|
|
101
|
-
"tailwindcss": "^3.4.
|
|
102
|
-
"typescript": "5.6.
|
|
101
|
+
"tailwindcss": "^3.4.14",
|
|
102
|
+
"typescript": "5.6.3",
|
|
103
103
|
"v-calendar": "3.1.2",
|
|
104
|
-
"vite": "^5.4.
|
|
105
|
-
"vitest": "^2.1.
|
|
106
|
-
"vue": "3.
|
|
104
|
+
"vite": "^5.4.9",
|
|
105
|
+
"vitest": "^2.1.3",
|
|
106
|
+
"vue": "3.5.12",
|
|
107
107
|
"vue-currency-input": "3.1.0",
|
|
108
108
|
"vue-router": "4.4.5",
|
|
109
109
|
"vue-toastification": "2.0.0-rc.5",
|
|
@@ -14,6 +14,18 @@ const ELEMENTS_MAP = {
|
|
|
14
14
|
section: { name: 'home', params: { id: 1 } },
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
const DEFAULT_CLASSES_ARRAY = [
|
|
18
|
+
'relative',
|
|
19
|
+
'inline-block',
|
|
20
|
+
'outline-none',
|
|
21
|
+
'disabled:opacity-50',
|
|
22
|
+
'disabled:cursor-default',
|
|
23
|
+
'disabled:pointer-events-none',
|
|
24
|
+
'aria-disabled:opacity-50',
|
|
25
|
+
'aria-disabled:cursor-default',
|
|
26
|
+
'aria-disabled:pointer-events-none',
|
|
27
|
+
];
|
|
28
|
+
|
|
17
29
|
describe('PBtn.vue', () => {
|
|
18
30
|
Object.keys(ELEMENTS_MAP).forEach((el) => {
|
|
19
31
|
const to = ELEMENTS_MAP[el];
|
|
@@ -66,6 +78,7 @@ describe('PBtn.vue', () => {
|
|
|
66
78
|
const element = await wrapper.find(el);
|
|
67
79
|
|
|
68
80
|
expect(classes.every((c) => element.classes().includes(c))).toBe(true);
|
|
81
|
+
expect(DEFAULT_CLASSES_ARRAY.every((c) => element.classes().includes(c))).toBe(true);
|
|
69
82
|
});
|
|
70
83
|
});
|
|
71
84
|
|
|
@@ -81,26 +94,42 @@ describe('PBtn.vue', () => {
|
|
|
81
94
|
expect(button.text()).toContain(`This is a button`);
|
|
82
95
|
});
|
|
83
96
|
|
|
84
|
-
it(
|
|
97
|
+
it.each([
|
|
98
|
+
['button', undefined],
|
|
99
|
+
['a', 'https://pequity.com/'],
|
|
100
|
+
['a', { name: 'home', params: { id: 1 } }],
|
|
101
|
+
])('gets disabled when the element is a %s and points to %s', async (el, to) => {
|
|
85
102
|
const wrapper = createWrapperFor(PBtn, {
|
|
103
|
+
props: {
|
|
104
|
+
to,
|
|
105
|
+
},
|
|
86
106
|
attrs: {
|
|
87
107
|
disabled: true,
|
|
88
108
|
},
|
|
109
|
+
global: {
|
|
110
|
+
stubs: { RouterLink: { template: '<a class="router-link-stub"><slot /></a>' } },
|
|
111
|
+
},
|
|
89
112
|
});
|
|
90
113
|
|
|
91
|
-
const button = await wrapper.find(
|
|
114
|
+
const button = await wrapper.find(el);
|
|
92
115
|
|
|
93
116
|
await button.trigger('click');
|
|
94
117
|
|
|
95
|
-
|
|
118
|
+
if (el === 'button') {
|
|
119
|
+
expect(wrapper.emitted().click).toBeFalsy();
|
|
120
|
+
}
|
|
96
121
|
expect(button.attributes()).toHaveProperty('disabled');
|
|
122
|
+
expect(button.attributes()['aria-disabled']).toBe('true');
|
|
97
123
|
|
|
98
124
|
await wrapper.setProps({ disabled: false });
|
|
99
125
|
|
|
100
126
|
await button.trigger('click');
|
|
101
127
|
|
|
102
|
-
|
|
128
|
+
if (el === 'button') {
|
|
129
|
+
expect(wrapper.emitted().click[0][0] instanceof MouseEvent).toBe(true);
|
|
130
|
+
}
|
|
103
131
|
expect(button.attributes()).not.toHaveProperty('disabled');
|
|
132
|
+
expect(button.attributes()['aria-disabled']).toBe('false');
|
|
104
133
|
});
|
|
105
134
|
|
|
106
135
|
it('has a loading state', async () => {
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
:href="sanitizeUrl(to)"
|
|
6
6
|
target="_blank"
|
|
7
7
|
:class="classes"
|
|
8
|
+
:disabled="!!$attrs.disabled ? true : null"
|
|
9
|
+
:aria-disabled="!!$attrs.disabled"
|
|
8
10
|
>
|
|
9
11
|
<slot></slot>
|
|
10
12
|
</a>
|
|
@@ -16,7 +18,8 @@
|
|
|
16
18
|
:aria-selected="selected"
|
|
17
19
|
:class="classes"
|
|
18
20
|
v-bind="$attrs"
|
|
19
|
-
:disabled="
|
|
21
|
+
:disabled="!!$attrs.disabled || loading ? true : null"
|
|
22
|
+
:aria-disabled="$attrs.disabled"
|
|
20
23
|
>
|
|
21
24
|
<div :class="{ invisible: loading }"><slot></slot></div>
|
|
22
25
|
<PRingLoader
|
|
@@ -57,7 +60,7 @@ type ButtonNativeType = (typeof BUTTON_NATIVE_TYPES)[number];
|
|
|
57
60
|
type ButtonTypeKeys = keyof typeof BUTTON_TYPES;
|
|
58
61
|
type ButtonType = (typeof BUTTON_TYPES)[ButtonTypeKeys];
|
|
59
62
|
|
|
60
|
-
const DEFAULT_CLASSES = `relative inline-block outline-none disabled:opacity-50 disabled:cursor-default disabled:pointer-events-none`;
|
|
63
|
+
const DEFAULT_CLASSES = `relative inline-block outline-none disabled:opacity-50 disabled:cursor-default disabled:pointer-events-none aria-disabled:opacity-50 aria-disabled:cursor-default aria-disabled:pointer-events-none`;
|
|
61
64
|
|
|
62
65
|
type ButtonClass = {
|
|
63
66
|
[key in ButtonType]: string;
|
|
@@ -15,10 +15,9 @@
|
|
|
15
15
|
:timezone="timezone"
|
|
16
16
|
>
|
|
17
17
|
<template #default="{ inputValue, inputEvents }">
|
|
18
|
-
<
|
|
19
|
-
:class="[inputClasses, { 'cursor-pointer': !attrs.disabled }]"
|
|
18
|
+
<PInput
|
|
20
19
|
:value="inputValue"
|
|
21
|
-
v-bind="
|
|
20
|
+
v-bind="attrsWithoutClassAndStyle"
|
|
22
21
|
:placeholder="displayPlaceholder"
|
|
23
22
|
v-on="inputEvents"
|
|
24
23
|
/>
|
|
@@ -28,12 +27,18 @@
|
|
|
28
27
|
</div>
|
|
29
28
|
</template>
|
|
30
29
|
|
|
31
|
-
<script lang="ts">
|
|
30
|
+
<script setup lang="ts">
|
|
31
|
+
import PInput from '@squirrel/components/p-input/p-input.vue';
|
|
32
32
|
import dayjs from 'dayjs';
|
|
33
|
-
import inputClassesMixin from '@squirrel/utils/inputClassesMixin';
|
|
34
33
|
import { DatePicker } from 'v-calendar';
|
|
35
|
-
import { type
|
|
34
|
+
import { type StyleValue, computed, nextTick, ref, useAttrs, watch } from 'vue';
|
|
36
35
|
import { isDate, isString } from 'lodash-es';
|
|
36
|
+
import { useInputClasses } from '@squirrel/composables/useInputClasses';
|
|
37
|
+
|
|
38
|
+
defineOptions({
|
|
39
|
+
name: 'PDatePicker',
|
|
40
|
+
inheritAttrs: false,
|
|
41
|
+
});
|
|
37
42
|
|
|
38
43
|
// The type of the select attribute is defined in node_modules/v-calendar/dist/types/src/utils/attribute.d.ts
|
|
39
44
|
// but there was no way to import it, so as a workaround we cast the selectAttribute as `any`.
|
|
@@ -47,87 +52,75 @@ const DEFAULT_MASKS = {
|
|
|
47
52
|
data: 'YYYY-MM-DD',
|
|
48
53
|
};
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
type: String as PropType<string | null | undefined>,
|
|
60
|
-
default: '',
|
|
61
|
-
},
|
|
62
|
-
label: {
|
|
63
|
-
type: String,
|
|
64
|
-
default: '',
|
|
65
|
-
},
|
|
66
|
-
errorMsg: {
|
|
67
|
-
type: String,
|
|
68
|
-
default: '',
|
|
69
|
-
},
|
|
70
|
-
required: {
|
|
71
|
-
type: Boolean,
|
|
72
|
-
default: false,
|
|
73
|
-
},
|
|
74
|
-
minDate: {
|
|
75
|
-
type: Date,
|
|
76
|
-
default: null,
|
|
77
|
-
},
|
|
78
|
-
maxDate: {
|
|
79
|
-
type: Date,
|
|
80
|
-
default: null,
|
|
81
|
-
},
|
|
82
|
-
timezone: {
|
|
83
|
-
type: String,
|
|
84
|
-
default: '',
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
emits: ['update:modelValue'],
|
|
88
|
-
data() {
|
|
89
|
-
return {
|
|
90
|
-
// innerValue is a Date object
|
|
91
|
-
innerValue: null as Date | null,
|
|
92
|
-
stopWatch: false,
|
|
93
|
-
selectAttribute,
|
|
94
|
-
};
|
|
95
|
-
},
|
|
96
|
-
computed: {
|
|
97
|
-
displayPlaceholder(): string {
|
|
98
|
-
return isString(this.$attrs.placeholder) ? this.$attrs.placeholder : this.masks.input;
|
|
99
|
-
},
|
|
100
|
-
masks() {
|
|
101
|
-
return Object.assign(DEFAULT_MASKS, this.$attrs.masks);
|
|
102
|
-
},
|
|
103
|
-
attrs() {
|
|
104
|
-
const { class: classes, style, ...rest } = this.$attrs;
|
|
55
|
+
type Props = {
|
|
56
|
+
modelValue?: string | null;
|
|
57
|
+
label?: string;
|
|
58
|
+
errorMsg?: string;
|
|
59
|
+
required?: boolean;
|
|
60
|
+
minDate?: Date | null;
|
|
61
|
+
maxDate?: Date | null;
|
|
62
|
+
timezone?: string;
|
|
63
|
+
};
|
|
105
64
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
65
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
66
|
+
modelValue: '',
|
|
67
|
+
label: '',
|
|
68
|
+
errorMsg: '',
|
|
69
|
+
required: false,
|
|
70
|
+
minDate: null,
|
|
71
|
+
maxDate: null,
|
|
72
|
+
timezone: '',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const emit = defineEmits<{
|
|
76
|
+
'update:modelValue': [value: string | null];
|
|
77
|
+
}>();
|
|
78
|
+
|
|
79
|
+
// Data
|
|
80
|
+
const { labelClasses, errorMsgClasses } = useInputClasses(props);
|
|
81
|
+
const attrs = useAttrs();
|
|
82
|
+
// innerValue is a Date object
|
|
83
|
+
const innerValue = ref<Date | null>(null);
|
|
84
|
+
const stopWatch = ref(false);
|
|
85
|
+
|
|
86
|
+
// Computed
|
|
87
|
+
const masks = computed(() => {
|
|
88
|
+
return Object.assign(DEFAULT_MASKS, attrs.masks);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const displayPlaceholder = computed(() => {
|
|
92
|
+
return isString(attrs.placeholder) ? attrs.placeholder : masks.value.input;
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const attrsWithoutClassAndStyle = computed(() => {
|
|
96
|
+
const { class: classes, style, ...rest } = attrs;
|
|
97
|
+
|
|
98
|
+
return rest;
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const style = computed(() => {
|
|
102
|
+
return attrs.style as StyleValue;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Watch
|
|
106
|
+
watch(
|
|
107
|
+
() => props.modelValue,
|
|
108
|
+
(nV) => {
|
|
109
|
+
if (!stopWatch.value) {
|
|
110
|
+
innerValue.value = nV ? dayjs(nV, masks.value.data).toDate() : null;
|
|
111
|
+
}
|
|
131
112
|
},
|
|
113
|
+
{ immediate: true }
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
watch(innerValue, (nV) => {
|
|
117
|
+
// We're emitting back a formatted String (value) or null in case we have an invalid date
|
|
118
|
+
const toEmit = isDate(nV) && nV.toString() !== 'Invalid Date' ? dayjs(nV).format(masks.value.data) : null;
|
|
119
|
+
// Stop watching when updating the value by clicking in the datepicker, in order to prevent double-emit.
|
|
120
|
+
stopWatch.value = true;
|
|
121
|
+
emit('update:modelValue', toEmit);
|
|
122
|
+
nextTick(() => {
|
|
123
|
+
stopWatch.value = false;
|
|
124
|
+
});
|
|
132
125
|
});
|
|
133
126
|
</script>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import PInlineDatePicker from '@squirrel/components/p-inline-date-picker/p-inline-date-picker.vue';
|
|
2
|
+
import { DatePicker } from 'v-calendar';
|
|
2
3
|
import { createWrapperFor } from '@tests/vitest.helpers';
|
|
3
4
|
|
|
4
5
|
const createWrapper = (props) => {
|
|
@@ -20,17 +21,17 @@ describe('PInlineDatePicker.vue', () => {
|
|
|
20
21
|
it('renders a datepicker', () => {
|
|
21
22
|
const wrapper = createWrapper();
|
|
22
23
|
|
|
23
|
-
const datePicker = wrapper.findComponent(
|
|
24
|
+
const datePicker = wrapper.findComponent(DatePicker);
|
|
24
25
|
|
|
25
|
-
expect(datePicker.props()).
|
|
26
|
+
expect(datePicker.props()).toMatchObject({
|
|
26
27
|
modelValue: null,
|
|
27
28
|
selectAttribute: { highlight: { class: 'bg-primary', contentClass: 'text-white' } },
|
|
28
29
|
minDate: null,
|
|
29
30
|
maxDate: null,
|
|
30
31
|
masks: { input: 'DD-MMM-YYYY', data: 'YYYY-MM-DD' },
|
|
31
|
-
style: {},
|
|
32
32
|
timezone: '',
|
|
33
33
|
});
|
|
34
|
+
|
|
34
35
|
expect(wrapper.find('label').exists()).toBe(false);
|
|
35
36
|
expect(wrapper.find('div.text-xs.text-on-error.mt-1').isVisible()).toBe(false);
|
|
36
37
|
});
|
|
@@ -43,7 +44,7 @@ describe('PInlineDatePicker.vue', () => {
|
|
|
43
44
|
timezone: 'UTC',
|
|
44
45
|
});
|
|
45
46
|
|
|
46
|
-
const datePicker = wrapper.findComponent(
|
|
47
|
+
const datePicker = wrapper.findComponent(DatePicker);
|
|
47
48
|
|
|
48
49
|
expect(datePicker.props().modelValue).toEqual(new Date('2024-05-19'));
|
|
49
50
|
expect(datePicker.props().minDate).toEqual(new Date('2024-05-01'));
|
|
@@ -77,7 +78,6 @@ describe('PInlineDatePicker.vue', () => {
|
|
|
77
78
|
|
|
78
79
|
expect(wrapper.props().required).toBe(true);
|
|
79
80
|
});
|
|
80
|
-
|
|
81
81
|
it('passes listeners to the datepicker', () => {
|
|
82
82
|
// Since DatePicker emits are not defined on PInlineDatePicker we need to Spy on console.warn and mock the implementation to suppress the warning:
|
|
83
83
|
// [Vue warn]: Component emitted event "update:view" but it is neither declared in the emits option nor as an "onUpdate:view" prop.
|
|
@@ -100,7 +100,7 @@ describe('PInlineDatePicker.vue', () => {
|
|
|
100
100
|
},
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
-
const datePicker = wrapper.findComponent(
|
|
103
|
+
const datePicker = wrapper.findComponent(DatePicker);
|
|
104
104
|
|
|
105
105
|
datePicker.vm.$emit('update:view');
|
|
106
106
|
|
|
@@ -112,9 +112,9 @@ describe('PInlineDatePicker.vue', () => {
|
|
|
112
112
|
it('sets the disabled state correctly', () => {
|
|
113
113
|
const wrapper = createWrapper({ label: 'test datepicker', disabled: true });
|
|
114
114
|
|
|
115
|
-
const
|
|
115
|
+
const datePickerDiv = wrapper.find('.vc-container');
|
|
116
116
|
|
|
117
|
-
expect(['pointer-events-none', 'opacity-70'].every((c) =>
|
|
117
|
+
expect(['pointer-events-none', 'opacity-70'].every((c) => datePickerDiv.classes().includes(c))).toBe(true);
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
it(`updates the value when a day is clicked`, async () => {
|
|
@@ -128,7 +128,7 @@ describe('PInlineDatePicker.vue', () => {
|
|
|
128
128
|
},
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
const datePicker = wrapper.findComponent(
|
|
131
|
+
const datePicker = wrapper.findComponent(DatePicker);
|
|
132
132
|
|
|
133
133
|
datePicker.vm.$emit('dayclick', { id: '2024-09-02' });
|
|
134
134
|
|
|
@@ -138,7 +138,7 @@ describe('PInlineDatePicker.vue', () => {
|
|
|
138
138
|
it(`updates the datepicker value when modelValue is changed`, async () => {
|
|
139
139
|
const wrapper = createWrapper({ modelValue: '2024-09-01' });
|
|
140
140
|
|
|
141
|
-
const datePicker = wrapper.findComponent(
|
|
141
|
+
const datePicker = wrapper.findComponent(DatePicker);
|
|
142
142
|
datePicker.vm.move = vi.fn();
|
|
143
143
|
|
|
144
144
|
expect(datePicker.props().modelValue).toEqual(new Date('2024-09-01'));
|
|
@@ -156,11 +156,9 @@ describe('PInlineDatePicker.vue', () => {
|
|
|
156
156
|
});
|
|
157
157
|
|
|
158
158
|
expect(wrapper.attributes()['data-has-error']).toBeDefined();
|
|
159
|
-
const
|
|
159
|
+
const datePickerDiv = wrapper.find('.vc-container');
|
|
160
160
|
|
|
161
|
-
expect(
|
|
162
|
-
border: '1px solid var(--color-on-error)',
|
|
163
|
-
});
|
|
161
|
+
expect(datePickerDiv.element.style.border).toBe('1px solid #f0453c');
|
|
164
162
|
const errorDiv = wrapper.find('div.text-xs.text-on-error.mt-1');
|
|
165
163
|
expect(errorDiv.isVisible()).toBe(true);
|
|
166
164
|
expect(errorDiv.text()).toBe('datepicker has error');
|