@pequity/squirrel 8.3.2 → 8.3.4
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/index.js +8 -6
- package/dist/es/index.js +8 -6
- package/package.json +4 -4
- package/squirrel/components/p-file-upload/p-file-upload.spec.js +61 -4
- package/squirrel/components/p-file-upload/p-file-upload.vue +5 -1
- package/squirrel/components/p-steps/__snapshots__/p-steps.spec.ts.snap +3 -3
- package/squirrel/components/p-steps/p-steps.spec.ts +4 -1
- package/squirrel/components/p-steps/p-steps.vue +1 -0
package/dist/cjs/index.js
CHANGED
|
@@ -166,7 +166,9 @@ const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({
|
|
|
166
166
|
const file = filesToUpload[i];
|
|
167
167
|
const fileName = file.name || file.url;
|
|
168
168
|
if (res.length + files.value.length >= props.maxNumberOfFiles) {
|
|
169
|
-
|
|
169
|
+
if (!(props.multiple && props.maxNumberOfFiles === 1)) {
|
|
170
|
+
toast.error(`You can only upload a maximum of ${props.maxNumberOfFiles} ${fileWord.value}.`);
|
|
171
|
+
}
|
|
170
172
|
break;
|
|
171
173
|
}
|
|
172
174
|
if (!fileName) {
|
|
@@ -661,7 +663,7 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
|
|
|
661
663
|
}
|
|
662
664
|
});
|
|
663
665
|
const _hoisted_1$2 = { class: "flex items-center gap-2" };
|
|
664
|
-
const _hoisted_2$2 = ["onClick"];
|
|
666
|
+
const _hoisted_2$2 = ["data-state", "onClick"];
|
|
665
667
|
const _hoisted_3$2 = {
|
|
666
668
|
key: 0,
|
|
667
669
|
class: "flex items-center"
|
|
@@ -698,6 +700,7 @@ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
|
|
|
698
700
|
}, [
|
|
699
701
|
vue.createElementVNode("div", {
|
|
700
702
|
class: vue.normalizeClass(["text-nowrap rounded-full border px-4 py-1 text-sm font-semibold", [stepClasses(step, i), { "cursor-pointer": _ctx.clickable && !step.disabled }]]),
|
|
703
|
+
"data-state": step.value === _ctx.activeStep ? "active" : "inactive",
|
|
701
704
|
onClick: ($event) => emit("click:step", step, i)
|
|
702
705
|
}, vue.toDisplayString(step.text || vue.unref(lodashEs.startCase)(String(step.value))), 11, _hoisted_2$2),
|
|
703
706
|
i < _ctx.steps.length - 1 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$2, [
|
|
@@ -869,7 +872,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
|
|
|
869
872
|
ref: (el) => updateThsRefs(el, i),
|
|
870
873
|
key: col.id,
|
|
871
874
|
"data-col-id": col.id
|
|
872
|
-
}, col.thAttrs, {
|
|
875
|
+
}, { ref_for: true }, col.thAttrs, {
|
|
873
876
|
style: col.style,
|
|
874
877
|
class: "bg-surface"
|
|
875
878
|
}), [
|
|
@@ -885,9 +888,8 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
|
|
|
885
888
|
"show-filter-icon": col.filterable || col.sortable,
|
|
886
889
|
"tooltip-text": col.tooltip,
|
|
887
890
|
class: [{ "pl-2": i === 1 && _ctx.isFirstColFixed, "pr-2": i === _ctx.cols.length && _ctx.isLastColFixed }, "grow"],
|
|
888
|
-
"text-color": headerCellTextColor(col)
|
|
889
|
-
|
|
890
|
-
}, col.headerCellAttrs, {
|
|
891
|
+
"text-color": headerCellTextColor(col)
|
|
892
|
+
}, { ref_for: true }, col.headerCellAttrs, {
|
|
891
893
|
onClickFilterIcon: ($event) => _ctx.$emit("click-filter-icon", $event, col)
|
|
892
894
|
}), null, 16, ["text", "filter-active", "show-filter-icon", "tooltip-text", "class", "text-color", "onClickFilterIcon"])
|
|
893
895
|
]),
|
package/dist/es/index.js
CHANGED
|
@@ -166,7 +166,9 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
166
166
|
const file = filesToUpload[i2];
|
|
167
167
|
const fileName = file.name || file.url;
|
|
168
168
|
if (res.length + files.value.length >= props.maxNumberOfFiles) {
|
|
169
|
-
|
|
169
|
+
if (!(props.multiple && props.maxNumberOfFiles === 1)) {
|
|
170
|
+
toast.error(`You can only upload a maximum of ${props.maxNumberOfFiles} ${fileWord.value}.`);
|
|
171
|
+
}
|
|
170
172
|
break;
|
|
171
173
|
}
|
|
172
174
|
if (!fileName) {
|
|
@@ -661,7 +663,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
661
663
|
}
|
|
662
664
|
});
|
|
663
665
|
const _hoisted_1$2 = { class: "flex items-center gap-2" };
|
|
664
|
-
const _hoisted_2$2 = ["onClick"];
|
|
666
|
+
const _hoisted_2$2 = ["data-state", "onClick"];
|
|
665
667
|
const _hoisted_3$2 = {
|
|
666
668
|
key: 0,
|
|
667
669
|
class: "flex items-center"
|
|
@@ -698,6 +700,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
698
700
|
}, [
|
|
699
701
|
createElementVNode("div", {
|
|
700
702
|
class: normalizeClass(["text-nowrap rounded-full border px-4 py-1 text-sm font-semibold", [stepClasses(step, i2), { "cursor-pointer": _ctx.clickable && !step.disabled }]]),
|
|
703
|
+
"data-state": step.value === _ctx.activeStep ? "active" : "inactive",
|
|
701
704
|
onClick: ($event) => emit("click:step", step, i2)
|
|
702
705
|
}, toDisplayString(step.text || unref(startCase)(String(step.value))), 11, _hoisted_2$2),
|
|
703
706
|
i2 < _ctx.steps.length - 1 ? (openBlock(), createElementBlock("div", _hoisted_3$2, [
|
|
@@ -869,7 +872,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
869
872
|
ref: (el) => updateThsRefs(el, i2),
|
|
870
873
|
key: col.id,
|
|
871
874
|
"data-col-id": col.id
|
|
872
|
-
}, col.thAttrs, {
|
|
875
|
+
}, { ref_for: true }, col.thAttrs, {
|
|
873
876
|
style: col.style,
|
|
874
877
|
class: "bg-surface"
|
|
875
878
|
}), [
|
|
@@ -885,9 +888,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
885
888
|
"show-filter-icon": col.filterable || col.sortable,
|
|
886
889
|
"tooltip-text": col.tooltip,
|
|
887
890
|
class: [{ "pl-2": i2 === 1 && _ctx.isFirstColFixed, "pr-2": i2 === _ctx.cols.length && _ctx.isLastColFixed }, "grow"],
|
|
888
|
-
"text-color": headerCellTextColor(col)
|
|
889
|
-
|
|
890
|
-
}, col.headerCellAttrs, {
|
|
891
|
+
"text-color": headerCellTextColor(col)
|
|
892
|
+
}, { ref_for: true }, col.headerCellAttrs, {
|
|
891
893
|
onClickFilterIcon: ($event) => _ctx.$emit("click-filter-icon", $event, col)
|
|
892
894
|
}), null, 16, ["text", "filter-active", "show-filter-icon", "tooltip-text", "class", "text-color", "onClickFilterIcon"])
|
|
893
895
|
]),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pequity/squirrel",
|
|
3
3
|
"description": "Squirrel component library",
|
|
4
|
-
"version": "8.3.
|
|
4
|
+
"version": "8.3.4",
|
|
5
5
|
"packageManager": "pnpm@10.6.4",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@types/node": "^22.15.21",
|
|
72
72
|
"@vitejs/plugin-vue": "^5.2.4",
|
|
73
73
|
"@vitest/coverage-v8": "^3.1.4",
|
|
74
|
-
"@vue/compiler-sfc": "3.5.
|
|
74
|
+
"@vue/compiler-sfc": "3.5.15",
|
|
75
75
|
"@vue/test-utils": "^2.4.6",
|
|
76
76
|
"@vuepic/vue-datepicker": "11.0.2",
|
|
77
77
|
"autoprefixer": "^10.4.21",
|
|
@@ -91,14 +91,14 @@
|
|
|
91
91
|
"resolve-tspaths": "^0.8.23",
|
|
92
92
|
"rimraf": "^6.0.1",
|
|
93
93
|
"sass": "^1.89.0",
|
|
94
|
-
"semantic-release": "^24.2.
|
|
94
|
+
"semantic-release": "^24.2.5",
|
|
95
95
|
"storybook": "^8.6.14",
|
|
96
96
|
"svgo": "^3.3.2",
|
|
97
97
|
"tailwindcss": "^3.4.17",
|
|
98
98
|
"typescript": "5.8.3",
|
|
99
99
|
"vite": "^6.3.5",
|
|
100
100
|
"vitest": "^3.1.4",
|
|
101
|
-
"vue": "3.5.
|
|
101
|
+
"vue": "3.5.15",
|
|
102
102
|
"vue-currency-input": "3.2.1",
|
|
103
103
|
"vue-router": "4.5.1",
|
|
104
104
|
"vue-toastification": "2.0.0-rc.5",
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import PFileUpload from '@squirrel/components/p-file-upload/p-file-upload.vue';
|
|
2
|
+
import { expect } from '@storybook/test';
|
|
2
3
|
import { createWrapperFor } from '@tests/vitest.helpers';
|
|
4
|
+
import { vi } from 'vitest';
|
|
5
|
+
|
|
6
|
+
// Mocking the toastification library
|
|
7
|
+
const toastError = vi.fn();
|
|
8
|
+
|
|
9
|
+
vi.mock('vue-toastification', () => {
|
|
10
|
+
return {
|
|
11
|
+
useToast: () => {
|
|
12
|
+
return {
|
|
13
|
+
error: toastError,
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
});
|
|
3
18
|
|
|
4
|
-
const createFile = () => {
|
|
5
|
-
const file = new File([
|
|
19
|
+
const createFile = (fileName = 'filename') => {
|
|
20
|
+
const file = new File([fileName], `${fileName}.txt`, {
|
|
6
21
|
type: 'text/plain',
|
|
7
|
-
name:
|
|
8
|
-
url:
|
|
22
|
+
name: `${fileName}.txt`,
|
|
23
|
+
url: `https://www.pequity.com/${fileName}.txt`,
|
|
9
24
|
});
|
|
10
25
|
|
|
11
26
|
return file;
|
|
@@ -131,4 +146,46 @@ describe('PFileUpload.vue', () => {
|
|
|
131
146
|
|
|
132
147
|
expect(wrapper.findAll('div.truncate').length).toBe(3);
|
|
133
148
|
});
|
|
149
|
+
|
|
150
|
+
it('shows a toast when maxNumberOfFiles is exceeded', async () => {
|
|
151
|
+
const file1 = createFile('file1');
|
|
152
|
+
const file2 = createFile('file2');
|
|
153
|
+
|
|
154
|
+
const wrapper = createWrapperFor({
|
|
155
|
+
components: { PFileUpload },
|
|
156
|
+
data() {
|
|
157
|
+
return {
|
|
158
|
+
files: [file1, file2],
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
template: `
|
|
162
|
+
<PFileUpload v-model="files" :multiple="true" :max-number-of-files="2" />
|
|
163
|
+
`,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
expect(wrapper.find('div[title="file1.txt"]').exists()).toBe(true);
|
|
167
|
+
expect(wrapper.find('div[title="file2.txt"]').exists()).toBe(true);
|
|
168
|
+
|
|
169
|
+
expect(toastError).toHaveBeenCalledWith('You can only upload a maximum of 2 files.');
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('does not show a toast when multiple is true and maxNumberOfFiles is 1', async () => {
|
|
173
|
+
const file1 = createFile('file1');
|
|
174
|
+
|
|
175
|
+
const wrapper = createWrapperFor({
|
|
176
|
+
components: { PFileUpload },
|
|
177
|
+
data() {
|
|
178
|
+
return {
|
|
179
|
+
files: [file1],
|
|
180
|
+
};
|
|
181
|
+
},
|
|
182
|
+
template: `
|
|
183
|
+
<PFileUpload v-model="files" :multiple="true" :max-number-of-files="1" />
|
|
184
|
+
`,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
expect(wrapper.find('div[title="file1.txt"]').exists()).toBe(true);
|
|
188
|
+
|
|
189
|
+
expect(toastError).not.toHaveBeenCalled();
|
|
190
|
+
});
|
|
134
191
|
});
|
|
@@ -166,7 +166,11 @@ const validateFiles = (filesToUpload: FileUploadFile[]) => {
|
|
|
166
166
|
|
|
167
167
|
// Bail if we reached the max number of files
|
|
168
168
|
if (res.length + files.value.length >= props.maxNumberOfFiles) {
|
|
169
|
-
toast
|
|
169
|
+
// Show a toast - except for the contradictory config (multiple: true with maxNumberOfFiles: 1)
|
|
170
|
+
if (!(props.multiple && props.maxNumberOfFiles === 1)) {
|
|
171
|
+
toast.error(`You can only upload a maximum of ${props.maxNumberOfFiles} ${fileWord.value}.`);
|
|
172
|
+
}
|
|
173
|
+
|
|
170
174
|
break;
|
|
171
175
|
}
|
|
172
176
|
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`PSteps.vue > render tests > renders correctly 1`] = `
|
|
4
4
|
"<div class="flex items-center gap-2">
|
|
5
|
-
<div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold border-p-gray-30 text-p-gray-30">First</div>
|
|
5
|
+
<div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold border-p-gray-30 text-p-gray-30" data-state="inactive">First</div>
|
|
6
6
|
<div class="flex items-center">
|
|
7
7
|
<iconify-icon icon="material-symbols:arrow-right-alt-rounded" class="text-p-gray-30"></iconify-icon>
|
|
8
8
|
</div>
|
|
9
|
-
<div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold border-p-gray-30 text-p-gray-30">Second</div>
|
|
9
|
+
<div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold border-p-gray-30 text-p-gray-30" data-state="inactive">Second</div>
|
|
10
10
|
<div class="flex items-center">
|
|
11
11
|
<iconify-icon icon="material-symbols:arrow-right-alt-rounded" class="text-p-gray-30"></iconify-icon>
|
|
12
12
|
</div>
|
|
13
|
-
<div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold border-p-gray-30 text-p-gray-30">Third</div>
|
|
13
|
+
<div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold border-p-gray-30 text-p-gray-30" data-state="inactive">Third</div>
|
|
14
14
|
<!--v-if-->
|
|
15
15
|
</div>"
|
|
16
16
|
`;
|
|
@@ -37,7 +37,7 @@ describe('PSteps.vue', () => {
|
|
|
37
37
|
expect(stepElements.length).toBe(createSteps().length);
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
it('applies correct classes for current step', () => {
|
|
40
|
+
it('applies correct classes and data-state for current step', () => {
|
|
41
41
|
const wrapper = createWrapper({
|
|
42
42
|
activeStep: 'second',
|
|
43
43
|
});
|
|
@@ -48,17 +48,20 @@ describe('PSteps.vue', () => {
|
|
|
48
48
|
expect(stepElements[0].classes()).toContain('text-nowrap');
|
|
49
49
|
expect(stepElements[0].classes()).toContain('text-p-blue-50');
|
|
50
50
|
expect(stepElements[0].classes()).toContain('border-p-blue-50');
|
|
51
|
+
expect(stepElements[0].attributes('data-state')).toBe('inactive');
|
|
51
52
|
|
|
52
53
|
// Second step should be current (blue background)
|
|
53
54
|
expect(stepElements[1].classes()).toContain('text-nowrap');
|
|
54
55
|
expect(stepElements[1].classes()).toContain('bg-p-blue-50');
|
|
55
56
|
expect(stepElements[1].classes()).toContain('text-surface');
|
|
56
57
|
expect(stepElements[1].classes()).toContain('border-p-blue-50');
|
|
58
|
+
expect(stepElements[1].attributes('data-state')).toBe('active');
|
|
57
59
|
|
|
58
60
|
// Third step should be upcoming (gray)
|
|
59
61
|
expect(stepElements[2].classes()).toContain('text-nowrap');
|
|
60
62
|
expect(stepElements[2].classes()).toContain('text-p-gray-30');
|
|
61
63
|
expect(stepElements[2].classes()).toContain('border-p-gray-30');
|
|
64
|
+
expect(stepElements[2].attributes('data-state')).toBe('inactive');
|
|
62
65
|
});
|
|
63
66
|
|
|
64
67
|
it('displays step titles', () => {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
<div
|
|
5
5
|
class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold"
|
|
6
6
|
:class="[stepClasses(step, i), { 'cursor-pointer': clickable && !step.disabled }]"
|
|
7
|
+
:data-state="step.value === activeStep ? 'active' : 'inactive'"
|
|
7
8
|
@click="emit('click:step', step, i)"
|
|
8
9
|
>
|
|
9
10
|
{{ step.text || startCase(String(step.value)) }}
|