@pequity/squirrel 8.4.4 → 8.5.0
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/README.md +31 -1
- package/dist/cjs/chunks/index.js +530 -179
- package/dist/cjs/chunks/p-alert.js +14 -16
- package/dist/cjs/chunks/p-avatar.js +16 -0
- package/dist/cjs/chunks/p-btn.js +4 -1
- package/dist/cjs/chunks/p-card.js +4 -0
- package/dist/cjs/chunks/p-dropdown-select.js +34 -0
- package/dist/cjs/chunks/p-input-number.js +32 -0
- package/dist/cjs/chunks/p-input-percent.js +15 -4
- package/dist/cjs/chunks/p-input.js +28 -0
- package/dist/cjs/chunks/p-pagination-info.js +9 -5
- package/dist/cjs/chunks/p-pagination.js +23 -13
- package/dist/cjs/chunks/p-select-btn.js +2 -1
- package/dist/cjs/chunks/p-select.js +33 -0
- package/dist/cjs/chunks/p-table-loader.js +20 -0
- package/dist/cjs/chunks/p-tabs.js +12 -0
- package/dist/cjs/chunks/p-textarea.js +20 -0
- package/dist/cjs/index.js +72 -29
- package/dist/cjs/inputClasses.js +3 -3
- package/dist/cjs/p-checkbox.js +8 -1
- package/dist/cjs/p-chips.js +17 -1
- package/dist/cjs/p-close-btn.js +6 -1
- package/dist/cjs/p-drawer.js +90 -2
- package/dist/cjs/p-dropdown.js +2 -1
- package/dist/cjs/p-icon.js +2 -1
- package/dist/cjs/p-input-search.js +13 -1
- package/dist/cjs/p-loading.js +3 -3
- package/dist/cjs/p-modal.js +125 -43
- package/dist/cjs/p-select-pill.js +36 -2
- package/dist/cjs/p-skeleton-loader.js +17 -1
- package/dist/cjs/p-table-filter-icon.js +4 -1
- package/dist/cjs/p-table-header-cell.js +32 -2
- package/dist/cjs/p-table-td.js +1 -1
- package/dist/cjs/p-table.js +2 -0
- package/dist/cjs/p-toggle.js +22 -1
- package/dist/cjs/usePTableHeaderWrap.js +38 -0
- package/dist/es/chunks/index.js +530 -179
- package/dist/es/chunks/p-alert.js +14 -16
- package/dist/es/chunks/p-avatar.js +16 -0
- package/dist/es/chunks/p-btn.js +5 -2
- package/dist/es/chunks/p-card.js +4 -0
- package/dist/es/chunks/p-dropdown-select.js +34 -0
- package/dist/es/chunks/p-input-number.js +32 -0
- package/dist/es/chunks/p-input-percent.js +15 -4
- package/dist/es/chunks/p-input.js +28 -0
- package/dist/es/chunks/p-pagination-info.js +9 -5
- package/dist/es/chunks/p-pagination.js +24 -14
- package/dist/es/chunks/p-select-btn.js +2 -1
- package/dist/es/chunks/p-select.js +33 -0
- package/dist/es/chunks/p-table-loader.js +20 -0
- package/dist/es/chunks/p-tabs.js +12 -0
- package/dist/es/chunks/p-textarea.js +20 -0
- package/dist/es/index.js +77 -34
- package/dist/es/inputClasses.js +4 -4
- package/dist/es/p-checkbox.js +8 -1
- package/dist/es/p-chips.js +17 -1
- package/dist/es/p-close-btn.js +6 -1
- package/dist/es/p-drawer.js +90 -2
- package/dist/es/p-dropdown.js +2 -1
- package/dist/es/p-icon.js +2 -1
- package/dist/es/p-input-search.js +13 -1
- package/dist/es/p-loading.js +3 -3
- package/dist/es/p-modal.js +125 -43
- package/dist/es/p-select-pill.js +36 -2
- package/dist/es/p-skeleton-loader.js +17 -1
- package/dist/es/p-table-filter-icon.js +4 -1
- package/dist/es/p-table-header-cell.js +32 -2
- package/dist/es/p-table-td.js +1 -1
- package/dist/es/p-table.js +2 -0
- package/dist/es/p-toggle.js +22 -1
- package/dist/es/usePTableHeaderWrap.js +38 -0
- package/dist/squirrel/components/p-action-bar/p-action-bar.vue.d.ts +15 -3
- package/dist/squirrel/components/p-alert/p-alert.vue.d.ts +18 -5
- package/dist/squirrel/components/p-avatar/p-avatar.vue.d.ts +36 -1
- package/dist/squirrel/components/p-btn/p-btn.vue.d.ts +21 -5
- package/dist/squirrel/components/p-card/p-card.vue.d.ts +21 -8
- package/dist/squirrel/components/p-checkbox/p-checkbox.vue.d.ts +26 -8
- package/dist/squirrel/components/p-chips/p-chips.vue.d.ts +24 -0
- package/dist/squirrel/components/p-close-btn/p-close-btn.vue.d.ts +14 -1
- package/dist/squirrel/components/p-date-picker/p-date-picker.vue.d.ts +17 -1
- package/dist/squirrel/components/p-drawer/p-drawer.vue.d.ts +153 -15
- package/dist/squirrel/components/p-dropdown/p-dropdown.vue.d.ts +11 -2
- package/dist/squirrel/components/p-dropdown-select/p-dropdown-select.vue.d.ts +70 -2
- package/dist/squirrel/components/p-file-upload/p-file-upload.vue.d.ts +71 -7
- package/dist/squirrel/components/p-icon/p-icon.types.d.ts +1 -0
- package/dist/squirrel/components/p-icon/p-icon.vue.d.ts +5 -1
- package/dist/squirrel/components/p-info-icon/p-info-icon.vue.d.ts +12 -5
- package/dist/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue.d.ts +28 -8
- package/dist/squirrel/components/p-input/p-input.vue.d.ts +74 -9
- package/dist/squirrel/components/p-input-number/p-input-number.vue.d.ts +83 -12
- package/dist/squirrel/components/p-input-percent/p-input-percent.vue.d.ts +23 -3
- package/dist/squirrel/components/p-input-search/p-input-search.vue.d.ts +25 -1
- package/dist/squirrel/components/p-link/p-link.vue.d.ts +1 -1
- package/dist/squirrel/components/p-loading/p-loading.vue.d.ts +1 -1
- package/dist/squirrel/components/p-modal/p-modal.vue.d.ts +190 -16
- package/dist/squirrel/components/p-pagination/p-pagination.vue.d.ts +23 -13
- package/dist/squirrel/components/p-pagination-info/p-pagination-info.vue.d.ts +17 -9
- package/dist/squirrel/components/p-progress-bar/p-progress-bar.vue.d.ts +21 -1
- package/dist/squirrel/components/p-ring-loader/p-ring-loader.vue.d.ts +11 -1
- package/dist/squirrel/components/p-select/p-select.vue.d.ts +77 -7
- package/dist/squirrel/components/p-select-btn/p-select-btn.vue.d.ts +68 -11
- package/dist/squirrel/components/p-select-list/p-select-list.vue.d.ts +2 -2
- package/dist/squirrel/components/p-select-pill/p-select-pill.vue.d.ts +72 -2
- package/dist/squirrel/components/p-skeleton-loader/p-skeleton-loader.vue.d.ts +40 -0
- package/dist/squirrel/components/p-steps/p-steps.vue.d.ts +13 -1
- package/dist/squirrel/components/p-table/p-table.types.d.ts +1 -0
- package/dist/squirrel/components/p-table/p-table.vue.d.ts +33 -1
- package/dist/squirrel/components/p-table/usePTableHeaderWrap.d.ts +4 -0
- package/dist/squirrel/components/p-table-header-cell/p-table-filter-icon.vue.d.ts +7 -1
- package/dist/squirrel/components/p-table-header-cell/p-table-header-cell.vue.d.ts +59 -4
- package/dist/squirrel/components/p-table-loader/p-table-loader.vue.d.ts +41 -1
- package/dist/squirrel/components/p-table-sort/p-table-sort.vue.d.ts +13 -3
- package/dist/squirrel/components/p-table-td/p-table-td.vue.d.ts +13 -1
- package/dist/squirrel/components/p-tabs/p-tabs.vue.d.ts +34 -3
- package/dist/squirrel/components/p-tabs-pills/p-tabs-pills.vue.d.ts +23 -1
- package/dist/squirrel/components/p-textarea/p-textarea.vue.d.ts +53 -9
- package/dist/squirrel/components/p-toggle/p-toggle.vue.d.ts +51 -4
- package/dist/squirrel.css +68 -68
- package/package.json +24 -22
- package/squirrel/components/p-action-bar/p-action-bar.stories.js +5 -5
- package/squirrel/components/p-action-bar/p-action-bar.vue +30 -3
- package/squirrel/components/p-alert/p-alert.spec.js +4 -4
- package/squirrel/components/p-alert/p-alert.stories.js +19 -13
- package/squirrel/components/p-alert/p-alert.vue +33 -11
- package/squirrel/components/p-avatar/p-avatar.vue +28 -0
- package/squirrel/components/p-btn/p-btn.vue +35 -0
- package/squirrel/components/p-card/p-card.vue +24 -1
- package/squirrel/components/p-checkbox/p-checkbox.vue +23 -1
- package/squirrel/components/p-chips/p-chips.vue +24 -0
- package/squirrel/components/p-close-btn/p-close-btn.vue +15 -0
- package/squirrel/components/p-date-picker/p-date-picker.vue +23 -1
- package/squirrel/components/p-drawer/p-drawer.vue +95 -0
- package/squirrel/components/p-dropdown/p-dropdown.vue +12 -1
- package/squirrel/components/p-dropdown-select/p-dropdown-select.vue +41 -0
- package/squirrel/components/p-file-upload/p-file-upload.vue +58 -3
- package/squirrel/components/p-icon/p-icon.types.ts +1 -0
- package/squirrel/components/p-icon/p-icon.vue +16 -0
- package/squirrel/components/p-info-icon/p-info-icon.vue +19 -0
- package/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue +32 -0
- package/squirrel/components/p-input/p-input.vue +61 -1
- package/squirrel/components/p-input-number/p-input-number.vue +78 -1
- package/squirrel/components/p-input-percent/p-input-percent.vue +27 -3
- package/squirrel/components/p-input-search/p-input-search.vue +30 -2
- package/squirrel/components/p-link/p-link.vue +13 -0
- package/squirrel/components/p-loading/p-loading.vue +9 -2
- package/squirrel/components/p-modal/p-modal-basic.spec.js +29 -3
- package/squirrel/components/p-modal/p-modal.vue +182 -35
- package/squirrel/components/p-pagination/p-pagination.vue +28 -8
- package/squirrel/components/p-pagination-info/p-pagination-info.vue +16 -4
- package/squirrel/components/p-progress-bar/p-progress-bar.vue +31 -4
- package/squirrel/components/p-ring-loader/p-ring-loader.vue +17 -0
- package/squirrel/components/p-select/p-select.vue +50 -1
- package/squirrel/components/p-select-btn/p-select-btn.vue +90 -2
- package/squirrel/components/p-select-list/p-select-list.vue +7 -0
- package/squirrel/components/p-select-pill/p-select-pill.vue +52 -2
- package/squirrel/components/p-skeleton-loader/p-skeleton-loader.vue +24 -0
- package/squirrel/components/p-steps/p-steps.vue +25 -0
- package/squirrel/components/p-table/p-table.spec.js +51 -15
- package/squirrel/components/p-table/p-table.types.ts +2 -0
- package/squirrel/components/p-table/p-table.vue +46 -4
- package/squirrel/components/p-table/usePTableHeaderWrap.spec.js +118 -0
- package/squirrel/components/p-table/usePTableHeaderWrap.ts +45 -0
- package/squirrel/components/p-table-header-cell/p-table-filter-icon.vue +9 -0
- package/squirrel/components/p-table-header-cell/p-table-header-cell.spec.js +5 -1
- package/squirrel/components/p-table-header-cell/p-table-header-cell.vue +38 -1
- package/squirrel/components/p-table-loader/p-table-loader.vue +28 -0
- package/squirrel/components/p-table-sort/p-table-sort.vue +19 -1
- package/squirrel/components/p-table-td/p-table-td.vue +20 -0
- package/squirrel/components/p-tabs/p-tabs.stories.js +2 -2
- package/squirrel/components/p-tabs/p-tabs.vue +33 -1
- package/squirrel/components/p-tabs-pills/p-tabs-pills.vue +33 -0
- package/squirrel/components/p-textarea/p-textarea.vue +43 -1
- package/squirrel/components/p-toggle/p-toggle.vue +44 -1
- package/squirrel/assets/pagination-left-icon.svg +0 -5
- package/squirrel/assets/pagination-right-icon.svg +0 -5
|
@@ -40,23 +40,47 @@ import PIcon from '@squirrel/components/p-icon/p-icon.vue';
|
|
|
40
40
|
import PInput from '@squirrel/components/p-input/p-input.vue';
|
|
41
41
|
import { type PropType, ref, useTemplateRef, watch } from 'vue';
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
/**
|
|
44
|
+
* A search input component that provides a specialized input field for search functionality.
|
|
45
|
+
* Features include a search icon prefix, optional enter key icon, clear button,
|
|
46
|
+
* and automatic focus management. Built on top of PInput with search-specific styling
|
|
47
|
+
* and behavior.
|
|
48
|
+
*
|
|
49
|
+
* @displayName PInputSearch
|
|
50
|
+
*/
|
|
45
51
|
defineOptions({
|
|
46
52
|
name: 'PInputSearch',
|
|
47
53
|
inheritAttrs: false,
|
|
48
54
|
});
|
|
49
55
|
|
|
56
|
+
type PInputInstance = InstanceType<typeof PInput>;
|
|
57
|
+
|
|
50
58
|
const emit = defineEmits<{
|
|
59
|
+
/**
|
|
60
|
+
* Emitted when the search query value changes.
|
|
61
|
+
* @param {string} value - The new search query
|
|
62
|
+
*/
|
|
51
63
|
'update:modelValue': [value: string];
|
|
64
|
+
/**
|
|
65
|
+
* Emitted when the enter key is pressed.
|
|
66
|
+
* @param {string} value - The current search query
|
|
67
|
+
*/
|
|
52
68
|
enter: [value: string];
|
|
53
69
|
}>();
|
|
54
70
|
|
|
55
71
|
const props = defineProps({
|
|
72
|
+
/**
|
|
73
|
+
* The search query value (v-model).
|
|
74
|
+
* Controls the input field content and visibility of the clear button.
|
|
75
|
+
*/
|
|
56
76
|
modelValue: {
|
|
57
77
|
type: String,
|
|
58
78
|
default: '',
|
|
59
79
|
},
|
|
80
|
+
/**
|
|
81
|
+
* The size of the search input.
|
|
82
|
+
* Affects the overall dimensions and icon positioning.
|
|
83
|
+
*/
|
|
60
84
|
size: {
|
|
61
85
|
type: String as PropType<Size>,
|
|
62
86
|
default: 'md',
|
|
@@ -64,6 +88,10 @@ const props = defineProps({
|
|
|
64
88
|
return SIZES.includes(value);
|
|
65
89
|
},
|
|
66
90
|
},
|
|
91
|
+
/**
|
|
92
|
+
* Whether to show the enter key icon when the input is focused.
|
|
93
|
+
* Provides visual feedback that pressing enter will trigger a search.
|
|
94
|
+
*/
|
|
67
95
|
showEnterIcon: {
|
|
68
96
|
type: Boolean,
|
|
69
97
|
default: false,
|
|
@@ -12,9 +12,22 @@ import { isExternalLink } from '@squirrel/utils/link';
|
|
|
12
12
|
import { sanitizeUrl } from '@squirrel/utils/sanitization';
|
|
13
13
|
import { RouterLink, type RouterLinkProps } from 'vue-router';
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* A link component that intelligently handles both internal and external links.
|
|
17
|
+
* Automatically detects external URLs and renders them as anchor tags with
|
|
18
|
+
* proper security attributes, while internal links use Vue Router's RouterLink.
|
|
19
|
+
* Supports all RouterLink props for internal navigation.
|
|
20
|
+
*
|
|
21
|
+
* @displayName PLink
|
|
22
|
+
*/
|
|
15
23
|
defineOptions({
|
|
16
24
|
name: 'PLink',
|
|
17
25
|
});
|
|
18
26
|
|
|
27
|
+
/**
|
|
28
|
+
* All props from Vue Router's RouterLink component are supported.
|
|
29
|
+
* The component automatically handles external vs internal link detection
|
|
30
|
+
* and applies appropriate rendering and security measures.
|
|
31
|
+
*/
|
|
19
32
|
defineProps<RouterLinkProps>();
|
|
20
33
|
</script>
|
|
@@ -33,12 +33,19 @@ import { usePLoading } from '@squirrel/components/p-loading/usePLoading';
|
|
|
33
33
|
import { isComponent } from '@squirrel/utils/component';
|
|
34
34
|
import { onBeforeUnmount, ref, toValue, watch } from 'vue';
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
/**
|
|
37
|
+
* A loading component that displays a loading rectangle at the top center of the screen.
|
|
38
|
+
* Shows a customizable content area with smooth animations and dynamic sizing.
|
|
39
|
+
* Supports both text content and component content with automatic dimension calculation.
|
|
40
|
+
*
|
|
41
|
+
* @displayName PLoading
|
|
42
|
+
*/
|
|
38
43
|
defineOptions({
|
|
39
44
|
name: 'PLoading',
|
|
40
45
|
});
|
|
41
46
|
|
|
47
|
+
const textDivClass = `flex h-8 justify-center gap-x-1.5 overflow-hidden whitespace-nowrap px-6 pt-1 text-sm font-semibold text-p-purple-60`;
|
|
48
|
+
|
|
42
49
|
const { show, content, props: componentProps, loadingHide } = usePLoading();
|
|
43
50
|
const dimsReference = ref<HTMLElement | null>(null);
|
|
44
51
|
const width = ref(0);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import PModal from '@squirrel/components/p-modal/p-modal.vue';
|
|
2
|
-
import { waitRAF } from '@tests/vitest.helpers';
|
|
2
|
+
import { waitNT, waitRAF } from '@tests/vitest.helpers';
|
|
3
3
|
import { mount } from '@vue/test-utils';
|
|
4
4
|
|
|
5
5
|
const createWrapperContainer = (componentArgs) => {
|
|
@@ -85,18 +85,44 @@ describe('Modal basic functionality', () => {
|
|
|
85
85
|
await wrapper.setData({ showModal: true });
|
|
86
86
|
|
|
87
87
|
expect(wrapper.find('[data-pm-id]').classes()).toEqual(
|
|
88
|
-
'pm relative flex flex-col rounded-2xl
|
|
88
|
+
'pm relative flex flex-col rounded-2xl cursor-default bg-surface shadow-xl pb-6'.split(' ')
|
|
89
89
|
);
|
|
90
90
|
|
|
91
91
|
wrapper.unmount();
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
+
it('sets the correct base modal class when modal-wrapper slot is used', async () => {
|
|
95
|
+
const wrapper = mount(PModal, {
|
|
96
|
+
attachTo: document.body,
|
|
97
|
+
global: {
|
|
98
|
+
stubs: {
|
|
99
|
+
transition: true,
|
|
100
|
+
teleport: true,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
props: {
|
|
104
|
+
modelValue: true,
|
|
105
|
+
},
|
|
106
|
+
slots: {
|
|
107
|
+
'modal-wrapper': '<div>Modal content goes here...</div>',
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
await waitNT(wrapper.vm);
|
|
112
|
+
|
|
113
|
+
const modalContent = wrapper.find('[data-pm-id]');
|
|
114
|
+
|
|
115
|
+
expect(modalContent.classes()).not.toContain('pb-6');
|
|
116
|
+
|
|
117
|
+
wrapper.unmount();
|
|
118
|
+
});
|
|
119
|
+
|
|
94
120
|
it('passes the modalBaseClass prop to the modal', async () => {
|
|
95
121
|
const wrapper = createWrapperContainer({ modalBaseClass: 'custom-class' });
|
|
96
122
|
|
|
97
123
|
await wrapper.setData({ showModal: true });
|
|
98
124
|
|
|
99
|
-
expect(wrapper.find('[data-pm-id]').classes()).toEqual(['custom-class']);
|
|
125
|
+
expect(wrapper.find('[data-pm-id]').classes()).toEqual(['custom-class', 'pb-6']);
|
|
100
126
|
|
|
101
127
|
wrapper.unmount();
|
|
102
128
|
});
|
|
@@ -29,40 +29,47 @@
|
|
|
29
29
|
@click="overlayClick($event)"
|
|
30
30
|
@keydown="keydown($event)"
|
|
31
31
|
>
|
|
32
|
-
<div
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
<div
|
|
33
|
+
ref="pm"
|
|
34
|
+
:data-pm-id="id"
|
|
35
|
+
:class="[modalBaseClass, modalClass, { 'pb-6': !$slots['modal-wrapper'] }]"
|
|
36
|
+
:style="modalStyle"
|
|
37
|
+
>
|
|
38
|
+
<slot name="modal-wrapper">
|
|
39
|
+
<slot name="title-wrapper">
|
|
40
|
+
<div class="flex pb-4 pl-8 pr-4 pt-4">
|
|
41
|
+
<h3 v-if="title" :id="`${id}-title`" class="mr-auto pt-4 text-xl font-semibold">
|
|
42
|
+
{{ title }}
|
|
43
|
+
</h3>
|
|
44
|
+
<div class="ml-auto">
|
|
45
|
+
<PCloseBtn
|
|
46
|
+
:disabled="disabled"
|
|
47
|
+
:class="{ invisible: !enableClose }"
|
|
48
|
+
:aria-label="closeLabel"
|
|
49
|
+
@click.prevent="close"
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
45
52
|
</div>
|
|
53
|
+
</slot>
|
|
54
|
+
<div v-if="errorMsg" class="mb-4 px-8">
|
|
55
|
+
<PAlert type="error">{{ errorMsg }}</PAlert>
|
|
46
56
|
</div>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
>
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<div v-if="$slots.footer" class="px-8 pt-6">
|
|
64
|
-
<slot name="footer"></slot>
|
|
65
|
-
</div>
|
|
57
|
+
<slot name="content-wrapper">
|
|
58
|
+
<div
|
|
59
|
+
:id="`${id}-content`"
|
|
60
|
+
:class="[
|
|
61
|
+
'relative grow overflow-y-auto overflow-x-hidden px-8',
|
|
62
|
+
{ 'pointer-events-none opacity-50': disabled },
|
|
63
|
+
]"
|
|
64
|
+
>
|
|
65
|
+
<slot></slot>
|
|
66
|
+
</div>
|
|
67
|
+
</slot>
|
|
68
|
+
<slot name="footer-wrapper">
|
|
69
|
+
<div v-if="$slots.footer" class="px-8 pt-6">
|
|
70
|
+
<slot name="footer"></slot>
|
|
71
|
+
</div>
|
|
72
|
+
</slot>
|
|
66
73
|
</slot>
|
|
67
74
|
</div>
|
|
68
75
|
</div>
|
|
@@ -90,99 +97,239 @@ const FOCUSABLE_ELEMENTS =
|
|
|
90
97
|
'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
91
98
|
let animatingZIndex = 0;
|
|
92
99
|
|
|
100
|
+
/**
|
|
101
|
+
* A modal dialog component with advanced features like animations, focus management, and accessibility.
|
|
102
|
+
* Provides a teleported modal interface with backdrop, customizable styling, and lifecycle events.
|
|
103
|
+
* Supports both controlled and uncontrolled modes with proper keyboard navigation.
|
|
104
|
+
*
|
|
105
|
+
* @displayName PModal
|
|
106
|
+
*/
|
|
93
107
|
defineOptions({
|
|
94
108
|
name: 'PModal',
|
|
95
109
|
});
|
|
96
110
|
|
|
111
|
+
defineSlots<{
|
|
112
|
+
/**
|
|
113
|
+
* Default content slot for the modal body.
|
|
114
|
+
*/
|
|
115
|
+
default?: () => unknown;
|
|
116
|
+
/**
|
|
117
|
+
* Custom modal wrapper content.
|
|
118
|
+
*/
|
|
119
|
+
'modal-wrapper'?: () => unknown;
|
|
120
|
+
/**
|
|
121
|
+
* Custom title wrapper content.
|
|
122
|
+
*/
|
|
123
|
+
'title-wrapper'?: () => unknown;
|
|
124
|
+
/**
|
|
125
|
+
* Custom content wrapper.
|
|
126
|
+
*/
|
|
127
|
+
'content-wrapper'?: () => unknown;
|
|
128
|
+
/**
|
|
129
|
+
* Custom footer content.
|
|
130
|
+
*/
|
|
131
|
+
footer?: () => unknown;
|
|
132
|
+
/**
|
|
133
|
+
* Custom footer wrapper.
|
|
134
|
+
*/
|
|
135
|
+
'footer-wrapper'?: () => unknown;
|
|
136
|
+
}>();
|
|
137
|
+
|
|
97
138
|
const emit = defineEmits<{
|
|
139
|
+
/**
|
|
140
|
+
* Emitted before the modal starts opening.
|
|
141
|
+
*/
|
|
98
142
|
'before-open': [];
|
|
143
|
+
/**
|
|
144
|
+
* Emitted when the modal is opening (animation in progress).
|
|
145
|
+
*/
|
|
99
146
|
opening: [];
|
|
147
|
+
/**
|
|
148
|
+
* Emitted when the modal has finished opening.
|
|
149
|
+
*/
|
|
100
150
|
opened: [];
|
|
151
|
+
/**
|
|
152
|
+
* Emitted before the modal starts closing.
|
|
153
|
+
*/
|
|
101
154
|
'before-close': [];
|
|
155
|
+
/**
|
|
156
|
+
* Emitted when the modal is closing (animation in progress).
|
|
157
|
+
*/
|
|
102
158
|
closing: [];
|
|
159
|
+
/**
|
|
160
|
+
* Emitted when the modal has finished closing.
|
|
161
|
+
*/
|
|
103
162
|
closed: [];
|
|
104
|
-
|
|
105
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Emitted when the modal visibility changes (v-model).
|
|
165
|
+
* @param {boolean} value - The new visibility state
|
|
166
|
+
*/
|
|
167
|
+
'update:modelValue': [value: boolean];
|
|
168
|
+
/**
|
|
169
|
+
* Emitted when the backdrop is clicked.
|
|
170
|
+
* @param {MouseEvent} event - The click event
|
|
171
|
+
*/
|
|
172
|
+
'click:overlay': [event: MouseEvent];
|
|
106
173
|
}>();
|
|
107
174
|
|
|
108
175
|
const props = defineProps({
|
|
176
|
+
/**
|
|
177
|
+
* Unique name for the modal when using the modal service.
|
|
178
|
+
* Used for programmatic control of the modal.
|
|
179
|
+
*/
|
|
109
180
|
name: {
|
|
110
181
|
type: String,
|
|
111
182
|
default: '',
|
|
112
183
|
},
|
|
184
|
+
/**
|
|
185
|
+
* Title displayed in the modal header.
|
|
186
|
+
* Used for accessibility and visual identification.
|
|
187
|
+
*/
|
|
113
188
|
title: {
|
|
114
189
|
type: String,
|
|
115
190
|
default: '',
|
|
116
191
|
},
|
|
192
|
+
/**
|
|
193
|
+
* Base z-index for the modal.
|
|
194
|
+
* Higher values ensure the modal appears above other content.
|
|
195
|
+
*/
|
|
117
196
|
baseZindex: {
|
|
118
197
|
type: Number,
|
|
119
198
|
default: 1051,
|
|
120
199
|
},
|
|
200
|
+
/**
|
|
201
|
+
* CSS classes for the backdrop element.
|
|
202
|
+
* Controls the appearance of the modal overlay.
|
|
203
|
+
*/
|
|
121
204
|
bgClass: {
|
|
122
205
|
type: [String, Object, Array] as PropType<StyleValue>,
|
|
123
206
|
default: 'fixed bottom-0 left-0 right-0 top-0 bg-black/20',
|
|
124
207
|
},
|
|
208
|
+
/**
|
|
209
|
+
* CSS classes for the modal wrapper element.
|
|
210
|
+
* Controls the positioning and layout of the modal container.
|
|
211
|
+
*/
|
|
125
212
|
wrapperClass: {
|
|
126
213
|
type: [String, Object, Array] as PropType<StyleValue>,
|
|
127
214
|
default:
|
|
128
215
|
'fixed bottom-0 left-0 right-0 top-0 flex flex-col items-center justify-center overflow-y-auto overflow-x-hidden outline-none',
|
|
129
216
|
},
|
|
217
|
+
/**
|
|
218
|
+
* Base CSS classes for the modal content.
|
|
219
|
+
* Controls the appearance of the modal dialog itself.
|
|
220
|
+
*/
|
|
130
221
|
modalBaseClass: {
|
|
131
222
|
type: [String, Object, Array] as PropType<StyleValue>,
|
|
132
|
-
default: 'pm relative flex flex-col rounded-2xl
|
|
223
|
+
default: 'pm relative flex flex-col rounded-2xl cursor-default bg-surface shadow-xl',
|
|
133
224
|
},
|
|
225
|
+
/**
|
|
226
|
+
* Additional CSS classes for the modal content.
|
|
227
|
+
* Merged with modalBaseClass for custom styling.
|
|
228
|
+
*/
|
|
134
229
|
modalClass: {
|
|
135
230
|
type: [String, Object, Array] as PropType<StyleValue>,
|
|
136
231
|
default: '',
|
|
137
232
|
},
|
|
233
|
+
/**
|
|
234
|
+
* Inline styles for the modal content.
|
|
235
|
+
* Applied directly to the modal element.
|
|
236
|
+
*/
|
|
138
237
|
modalStyle: {
|
|
139
238
|
type: [String, Object, Array] as PropType<StyleValue>,
|
|
140
239
|
default: '',
|
|
141
240
|
},
|
|
241
|
+
/**
|
|
242
|
+
* CSS class for the modal entrance animation.
|
|
243
|
+
* Controls how the modal appears.
|
|
244
|
+
*/
|
|
142
245
|
inClass: {
|
|
143
246
|
type: String,
|
|
144
247
|
default: 'slideInTop',
|
|
145
248
|
},
|
|
249
|
+
/**
|
|
250
|
+
* CSS class for the modal exit animation.
|
|
251
|
+
* Controls how the modal disappears.
|
|
252
|
+
*/
|
|
146
253
|
outClass: {
|
|
147
254
|
type: String,
|
|
148
255
|
default: 'slideOutTop',
|
|
149
256
|
},
|
|
257
|
+
/**
|
|
258
|
+
* CSS class for the backdrop entrance animation.
|
|
259
|
+
* Controls how the backdrop appears.
|
|
260
|
+
*/
|
|
150
261
|
bgInClass: {
|
|
151
262
|
type: String,
|
|
152
263
|
default: 'fadeIn',
|
|
153
264
|
},
|
|
265
|
+
/**
|
|
266
|
+
* CSS class for the backdrop exit animation.
|
|
267
|
+
* Controls how the backdrop disappears.
|
|
268
|
+
*/
|
|
154
269
|
bgOutClass: {
|
|
155
270
|
type: String,
|
|
156
271
|
default: 'fadeOut',
|
|
157
272
|
},
|
|
273
|
+
/**
|
|
274
|
+
* Target element to append the modal to.
|
|
275
|
+
* Usually 'body' for proper z-index stacking.
|
|
276
|
+
*/
|
|
158
277
|
appendTo: {
|
|
159
278
|
type: String,
|
|
160
279
|
default: 'body',
|
|
161
280
|
},
|
|
281
|
+
/**
|
|
282
|
+
* Whether the modal should be mounted immediately.
|
|
283
|
+
* Useful for modals that are always present in the DOM.
|
|
284
|
+
*/
|
|
162
285
|
live: {
|
|
163
286
|
type: Boolean,
|
|
164
287
|
default: false,
|
|
165
288
|
},
|
|
289
|
+
/**
|
|
290
|
+
* Whether the modal can be closed by user interaction.
|
|
291
|
+
* Controls close button visibility and backdrop click behavior.
|
|
292
|
+
*/
|
|
166
293
|
enableClose: {
|
|
167
294
|
type: Boolean,
|
|
168
295
|
default: true,
|
|
169
296
|
},
|
|
297
|
+
/**
|
|
298
|
+
* Controls the visibility of the modal (v-model).
|
|
299
|
+
* Supports two-way binding for modal state.
|
|
300
|
+
*/
|
|
170
301
|
modelValue: {
|
|
171
302
|
type: Boolean,
|
|
172
303
|
default: false,
|
|
173
304
|
},
|
|
305
|
+
/**
|
|
306
|
+
* Accessibility label for the close button.
|
|
307
|
+
* Used by screen readers for better accessibility.
|
|
308
|
+
*/
|
|
174
309
|
closeLabel: {
|
|
175
310
|
type: String,
|
|
176
311
|
default: 'Close',
|
|
177
312
|
},
|
|
313
|
+
/**
|
|
314
|
+
* Whether the modal content is disabled.
|
|
315
|
+
* Prevents user interaction with modal content.
|
|
316
|
+
*/
|
|
178
317
|
disabled: {
|
|
179
318
|
type: Boolean,
|
|
180
319
|
default: false,
|
|
181
320
|
},
|
|
321
|
+
/**
|
|
322
|
+
* Error message to display in the modal.
|
|
323
|
+
* Shows an error alert above the modal content.
|
|
324
|
+
*/
|
|
182
325
|
errorMsg: {
|
|
183
326
|
type: String,
|
|
184
327
|
default: '',
|
|
185
328
|
},
|
|
329
|
+
/**
|
|
330
|
+
* Maximum width of the modal.
|
|
331
|
+
* Controls the responsive behavior of the modal.
|
|
332
|
+
*/
|
|
186
333
|
maxWidth: {
|
|
187
334
|
type: String,
|
|
188
335
|
default: '500px',
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
aria-label="go to the previous page"
|
|
7
7
|
@click="setPage(Number(modelValue) - 1)"
|
|
8
8
|
>
|
|
9
|
-
<
|
|
9
|
+
<PIcon icon="chevron-left" width="24px" />
|
|
10
10
|
</div>
|
|
11
11
|
<div v-for="(page, index) in pages" :key="index" @click="setPage(Number(page))">
|
|
12
12
|
<div class="flex">
|
|
@@ -25,51 +25,71 @@
|
|
|
25
25
|
aria-label="go to the next page"
|
|
26
26
|
@click="setPage(Number(modelValue) + 1)"
|
|
27
27
|
>
|
|
28
|
-
<
|
|
28
|
+
<PIcon icon="chevron-right" width="24px" />
|
|
29
29
|
</div>
|
|
30
30
|
</div>
|
|
31
31
|
</template>
|
|
32
32
|
|
|
33
33
|
<script setup lang="ts">
|
|
34
|
+
import PIcon from '@squirrel/components/p-icon/p-icon.vue';
|
|
34
35
|
import PSkeletonLoader from '@squirrel/components/p-skeleton-loader/p-skeleton-loader.vue';
|
|
35
36
|
import { createPagingRange } from '@squirrel/utils/pagination';
|
|
36
37
|
import { computed, type PropType } from 'vue';
|
|
37
38
|
|
|
39
|
+
/**
|
|
40
|
+
* A pagination component that displays page numbers with navigation controls.
|
|
41
|
+
* Provides a complete pagination interface with previous/next buttons, page numbers,
|
|
42
|
+
* loading states, and ellipsis for large page ranges.
|
|
43
|
+
* Supports customizable page sizes and offset ranges for optimal display.
|
|
44
|
+
*
|
|
45
|
+
* @displayName PPagination
|
|
46
|
+
*/
|
|
38
47
|
defineOptions({ name: 'PPagination' });
|
|
39
48
|
|
|
40
|
-
const emit = defineEmits
|
|
49
|
+
const emit = defineEmits<{
|
|
50
|
+
/**
|
|
51
|
+
* Emitted when the current page changes.
|
|
52
|
+
* @param {number} value - The new page number
|
|
53
|
+
*/
|
|
54
|
+
'update:modelValue': [value: number];
|
|
55
|
+
}>();
|
|
41
56
|
|
|
42
57
|
const props = defineProps({
|
|
43
58
|
/**
|
|
44
|
-
* The current page.
|
|
59
|
+
* The current page number (v-model).
|
|
60
|
+
* Controls which page is visually active and navigable.
|
|
45
61
|
*/
|
|
46
62
|
modelValue: {
|
|
47
63
|
type: Number as PropType<number | null>,
|
|
48
64
|
default: null,
|
|
49
65
|
},
|
|
50
66
|
/**
|
|
51
|
-
* The amount of
|
|
67
|
+
* The total amount of items to paginate through.
|
|
68
|
+
* Used to calculate the total number of pages.
|
|
52
69
|
*/
|
|
53
70
|
count: {
|
|
54
71
|
type: Number,
|
|
55
72
|
default: 0,
|
|
56
73
|
},
|
|
57
74
|
/**
|
|
58
|
-
* The
|
|
75
|
+
* The number of items to display per page.
|
|
76
|
+
* Used to calculate the total number of pages.
|
|
59
77
|
*/
|
|
60
78
|
pageSize: {
|
|
61
79
|
type: Number,
|
|
62
80
|
default: 10,
|
|
63
81
|
},
|
|
64
82
|
/**
|
|
65
|
-
* The
|
|
83
|
+
* The number of pages to show before and after the current page.
|
|
84
|
+
* Controls the range of page numbers displayed around the current page.
|
|
66
85
|
*/
|
|
67
86
|
pageOffset: {
|
|
68
87
|
type: Number,
|
|
69
88
|
default: 2,
|
|
70
89
|
},
|
|
71
90
|
/**
|
|
72
|
-
* Whether the pagination is loading.
|
|
91
|
+
* Whether the pagination is in a loading state.
|
|
92
|
+
* When true, shows a skeleton loader instead of the pagination controls.
|
|
73
93
|
*/
|
|
74
94
|
loading: {
|
|
75
95
|
type: Boolean,
|
|
@@ -10,32 +10,44 @@
|
|
|
10
10
|
import PSkeletonLoader from '@squirrel/components/p-skeleton-loader/p-skeleton-loader.vue';
|
|
11
11
|
import { computed } from 'vue';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* A pagination info component that displays current page information and result counts.
|
|
15
|
+
* Shows the range of items being displayed (e.g., "Showing 1 to 10 of 100 results")
|
|
16
|
+
* and provides a customizable slot for when no results are found.
|
|
17
|
+
* Includes loading state with skeleton loader.
|
|
18
|
+
*
|
|
19
|
+
* @displayName PPaginationInfo
|
|
20
|
+
*/
|
|
13
21
|
defineOptions({ name: 'PPaginationInfo' });
|
|
14
22
|
|
|
15
23
|
const props = defineProps({
|
|
16
24
|
/**
|
|
17
|
-
* The current page.
|
|
25
|
+
* The current page number (1-based).
|
|
26
|
+
* Used to calculate the starting item number in the display range.
|
|
18
27
|
*/
|
|
19
28
|
currentPage: {
|
|
20
29
|
type: Number,
|
|
21
30
|
default: 0,
|
|
22
31
|
},
|
|
23
32
|
/**
|
|
24
|
-
* The
|
|
33
|
+
* The total number of items across all pages.
|
|
34
|
+
* Used to calculate the total count and ending item number.
|
|
25
35
|
*/
|
|
26
36
|
count: {
|
|
27
37
|
type: Number,
|
|
28
38
|
default: 0,
|
|
29
39
|
},
|
|
30
40
|
/**
|
|
31
|
-
* The
|
|
41
|
+
* The number of items displayed per page.
|
|
42
|
+
* Used to calculate the `from` and `to` limits for the current page.
|
|
32
43
|
*/
|
|
33
44
|
pageSize: {
|
|
34
45
|
type: Number,
|
|
35
46
|
default: 0,
|
|
36
47
|
},
|
|
37
48
|
/**
|
|
38
|
-
* Whether the pagination is loading.
|
|
49
|
+
* Whether the pagination data is loading.
|
|
50
|
+
* When true, shows a skeleton loader instead of the info text.
|
|
39
51
|
*/
|
|
40
52
|
loading: {
|
|
41
53
|
type: Boolean,
|
|
@@ -11,20 +11,47 @@
|
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
13
|
<script setup lang="ts">
|
|
14
|
+
/**
|
|
15
|
+
* A progress bar component that displays multiple progress segments with different colors.
|
|
16
|
+
* Each segment represents a portion of the total progress and can have its own color
|
|
17
|
+
* and optional label. Useful for showing complex progress states or multi-part progress.
|
|
18
|
+
*
|
|
19
|
+
* @displayName PProgressBar
|
|
20
|
+
*/
|
|
21
|
+
defineOptions({
|
|
22
|
+
name: 'PProgressBar',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Represents a single progress segment with its value, color, and optional label.
|
|
27
|
+
*/
|
|
14
28
|
export type ProgressItem = {
|
|
29
|
+
/**
|
|
30
|
+
* The numeric value of this progress segment.
|
|
31
|
+
*/
|
|
15
32
|
value: number;
|
|
33
|
+
/**
|
|
34
|
+
* The background color for this progress segment.
|
|
35
|
+
*/
|
|
16
36
|
color: string;
|
|
37
|
+
/**
|
|
38
|
+
* Optional label to display on hover tooltip.
|
|
39
|
+
*/
|
|
17
40
|
label?: string;
|
|
18
41
|
};
|
|
19
42
|
|
|
20
43
|
type Props = {
|
|
44
|
+
/**
|
|
45
|
+
* The total value used to calculate percentage widths.
|
|
46
|
+
* All segment values should sum to this total for accurate representation.
|
|
47
|
+
*/
|
|
21
48
|
total: number;
|
|
49
|
+
/**
|
|
50
|
+
* Array of progress segments to display.
|
|
51
|
+
* Each item represents a portion of the total progress.
|
|
52
|
+
*/
|
|
22
53
|
items: ProgressItem[];
|
|
23
54
|
};
|
|
24
55
|
|
|
25
|
-
defineOptions({
|
|
26
|
-
name: 'PProgressBar',
|
|
27
|
-
});
|
|
28
|
-
|
|
29
56
|
defineProps<Props>();
|
|
30
57
|
</script>
|