@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.
Files changed (175) hide show
  1. package/README.md +31 -1
  2. package/dist/cjs/chunks/index.js +530 -179
  3. package/dist/cjs/chunks/p-alert.js +14 -16
  4. package/dist/cjs/chunks/p-avatar.js +16 -0
  5. package/dist/cjs/chunks/p-btn.js +4 -1
  6. package/dist/cjs/chunks/p-card.js +4 -0
  7. package/dist/cjs/chunks/p-dropdown-select.js +34 -0
  8. package/dist/cjs/chunks/p-input-number.js +32 -0
  9. package/dist/cjs/chunks/p-input-percent.js +15 -4
  10. package/dist/cjs/chunks/p-input.js +28 -0
  11. package/dist/cjs/chunks/p-pagination-info.js +9 -5
  12. package/dist/cjs/chunks/p-pagination.js +23 -13
  13. package/dist/cjs/chunks/p-select-btn.js +2 -1
  14. package/dist/cjs/chunks/p-select.js +33 -0
  15. package/dist/cjs/chunks/p-table-loader.js +20 -0
  16. package/dist/cjs/chunks/p-tabs.js +12 -0
  17. package/dist/cjs/chunks/p-textarea.js +20 -0
  18. package/dist/cjs/index.js +72 -29
  19. package/dist/cjs/inputClasses.js +3 -3
  20. package/dist/cjs/p-checkbox.js +8 -1
  21. package/dist/cjs/p-chips.js +17 -1
  22. package/dist/cjs/p-close-btn.js +6 -1
  23. package/dist/cjs/p-drawer.js +90 -2
  24. package/dist/cjs/p-dropdown.js +2 -1
  25. package/dist/cjs/p-icon.js +2 -1
  26. package/dist/cjs/p-input-search.js +13 -1
  27. package/dist/cjs/p-loading.js +3 -3
  28. package/dist/cjs/p-modal.js +125 -43
  29. package/dist/cjs/p-select-pill.js +36 -2
  30. package/dist/cjs/p-skeleton-loader.js +17 -1
  31. package/dist/cjs/p-table-filter-icon.js +4 -1
  32. package/dist/cjs/p-table-header-cell.js +32 -2
  33. package/dist/cjs/p-table-td.js +1 -1
  34. package/dist/cjs/p-table.js +2 -0
  35. package/dist/cjs/p-toggle.js +22 -1
  36. package/dist/cjs/usePTableHeaderWrap.js +38 -0
  37. package/dist/es/chunks/index.js +530 -179
  38. package/dist/es/chunks/p-alert.js +14 -16
  39. package/dist/es/chunks/p-avatar.js +16 -0
  40. package/dist/es/chunks/p-btn.js +5 -2
  41. package/dist/es/chunks/p-card.js +4 -0
  42. package/dist/es/chunks/p-dropdown-select.js +34 -0
  43. package/dist/es/chunks/p-input-number.js +32 -0
  44. package/dist/es/chunks/p-input-percent.js +15 -4
  45. package/dist/es/chunks/p-input.js +28 -0
  46. package/dist/es/chunks/p-pagination-info.js +9 -5
  47. package/dist/es/chunks/p-pagination.js +24 -14
  48. package/dist/es/chunks/p-select-btn.js +2 -1
  49. package/dist/es/chunks/p-select.js +33 -0
  50. package/dist/es/chunks/p-table-loader.js +20 -0
  51. package/dist/es/chunks/p-tabs.js +12 -0
  52. package/dist/es/chunks/p-textarea.js +20 -0
  53. package/dist/es/index.js +77 -34
  54. package/dist/es/inputClasses.js +4 -4
  55. package/dist/es/p-checkbox.js +8 -1
  56. package/dist/es/p-chips.js +17 -1
  57. package/dist/es/p-close-btn.js +6 -1
  58. package/dist/es/p-drawer.js +90 -2
  59. package/dist/es/p-dropdown.js +2 -1
  60. package/dist/es/p-icon.js +2 -1
  61. package/dist/es/p-input-search.js +13 -1
  62. package/dist/es/p-loading.js +3 -3
  63. package/dist/es/p-modal.js +125 -43
  64. package/dist/es/p-select-pill.js +36 -2
  65. package/dist/es/p-skeleton-loader.js +17 -1
  66. package/dist/es/p-table-filter-icon.js +4 -1
  67. package/dist/es/p-table-header-cell.js +32 -2
  68. package/dist/es/p-table-td.js +1 -1
  69. package/dist/es/p-table.js +2 -0
  70. package/dist/es/p-toggle.js +22 -1
  71. package/dist/es/usePTableHeaderWrap.js +38 -0
  72. package/dist/squirrel/components/p-action-bar/p-action-bar.vue.d.ts +15 -3
  73. package/dist/squirrel/components/p-alert/p-alert.vue.d.ts +18 -5
  74. package/dist/squirrel/components/p-avatar/p-avatar.vue.d.ts +36 -1
  75. package/dist/squirrel/components/p-btn/p-btn.vue.d.ts +21 -5
  76. package/dist/squirrel/components/p-card/p-card.vue.d.ts +21 -8
  77. package/dist/squirrel/components/p-checkbox/p-checkbox.vue.d.ts +26 -8
  78. package/dist/squirrel/components/p-chips/p-chips.vue.d.ts +24 -0
  79. package/dist/squirrel/components/p-close-btn/p-close-btn.vue.d.ts +14 -1
  80. package/dist/squirrel/components/p-date-picker/p-date-picker.vue.d.ts +17 -1
  81. package/dist/squirrel/components/p-drawer/p-drawer.vue.d.ts +153 -15
  82. package/dist/squirrel/components/p-dropdown/p-dropdown.vue.d.ts +11 -2
  83. package/dist/squirrel/components/p-dropdown-select/p-dropdown-select.vue.d.ts +70 -2
  84. package/dist/squirrel/components/p-file-upload/p-file-upload.vue.d.ts +71 -7
  85. package/dist/squirrel/components/p-icon/p-icon.types.d.ts +1 -0
  86. package/dist/squirrel/components/p-icon/p-icon.vue.d.ts +5 -1
  87. package/dist/squirrel/components/p-info-icon/p-info-icon.vue.d.ts +12 -5
  88. package/dist/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue.d.ts +28 -8
  89. package/dist/squirrel/components/p-input/p-input.vue.d.ts +74 -9
  90. package/dist/squirrel/components/p-input-number/p-input-number.vue.d.ts +83 -12
  91. package/dist/squirrel/components/p-input-percent/p-input-percent.vue.d.ts +23 -3
  92. package/dist/squirrel/components/p-input-search/p-input-search.vue.d.ts +25 -1
  93. package/dist/squirrel/components/p-link/p-link.vue.d.ts +1 -1
  94. package/dist/squirrel/components/p-loading/p-loading.vue.d.ts +1 -1
  95. package/dist/squirrel/components/p-modal/p-modal.vue.d.ts +190 -16
  96. package/dist/squirrel/components/p-pagination/p-pagination.vue.d.ts +23 -13
  97. package/dist/squirrel/components/p-pagination-info/p-pagination-info.vue.d.ts +17 -9
  98. package/dist/squirrel/components/p-progress-bar/p-progress-bar.vue.d.ts +21 -1
  99. package/dist/squirrel/components/p-ring-loader/p-ring-loader.vue.d.ts +11 -1
  100. package/dist/squirrel/components/p-select/p-select.vue.d.ts +77 -7
  101. package/dist/squirrel/components/p-select-btn/p-select-btn.vue.d.ts +68 -11
  102. package/dist/squirrel/components/p-select-list/p-select-list.vue.d.ts +2 -2
  103. package/dist/squirrel/components/p-select-pill/p-select-pill.vue.d.ts +72 -2
  104. package/dist/squirrel/components/p-skeleton-loader/p-skeleton-loader.vue.d.ts +40 -0
  105. package/dist/squirrel/components/p-steps/p-steps.vue.d.ts +13 -1
  106. package/dist/squirrel/components/p-table/p-table.types.d.ts +1 -0
  107. package/dist/squirrel/components/p-table/p-table.vue.d.ts +33 -1
  108. package/dist/squirrel/components/p-table/usePTableHeaderWrap.d.ts +4 -0
  109. package/dist/squirrel/components/p-table-header-cell/p-table-filter-icon.vue.d.ts +7 -1
  110. package/dist/squirrel/components/p-table-header-cell/p-table-header-cell.vue.d.ts +59 -4
  111. package/dist/squirrel/components/p-table-loader/p-table-loader.vue.d.ts +41 -1
  112. package/dist/squirrel/components/p-table-sort/p-table-sort.vue.d.ts +13 -3
  113. package/dist/squirrel/components/p-table-td/p-table-td.vue.d.ts +13 -1
  114. package/dist/squirrel/components/p-tabs/p-tabs.vue.d.ts +34 -3
  115. package/dist/squirrel/components/p-tabs-pills/p-tabs-pills.vue.d.ts +23 -1
  116. package/dist/squirrel/components/p-textarea/p-textarea.vue.d.ts +53 -9
  117. package/dist/squirrel/components/p-toggle/p-toggle.vue.d.ts +51 -4
  118. package/dist/squirrel.css +68 -68
  119. package/package.json +24 -22
  120. package/squirrel/components/p-action-bar/p-action-bar.stories.js +5 -5
  121. package/squirrel/components/p-action-bar/p-action-bar.vue +30 -3
  122. package/squirrel/components/p-alert/p-alert.spec.js +4 -4
  123. package/squirrel/components/p-alert/p-alert.stories.js +19 -13
  124. package/squirrel/components/p-alert/p-alert.vue +33 -11
  125. package/squirrel/components/p-avatar/p-avatar.vue +28 -0
  126. package/squirrel/components/p-btn/p-btn.vue +35 -0
  127. package/squirrel/components/p-card/p-card.vue +24 -1
  128. package/squirrel/components/p-checkbox/p-checkbox.vue +23 -1
  129. package/squirrel/components/p-chips/p-chips.vue +24 -0
  130. package/squirrel/components/p-close-btn/p-close-btn.vue +15 -0
  131. package/squirrel/components/p-date-picker/p-date-picker.vue +23 -1
  132. package/squirrel/components/p-drawer/p-drawer.vue +95 -0
  133. package/squirrel/components/p-dropdown/p-dropdown.vue +12 -1
  134. package/squirrel/components/p-dropdown-select/p-dropdown-select.vue +41 -0
  135. package/squirrel/components/p-file-upload/p-file-upload.vue +58 -3
  136. package/squirrel/components/p-icon/p-icon.types.ts +1 -0
  137. package/squirrel/components/p-icon/p-icon.vue +16 -0
  138. package/squirrel/components/p-info-icon/p-info-icon.vue +19 -0
  139. package/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue +32 -0
  140. package/squirrel/components/p-input/p-input.vue +61 -1
  141. package/squirrel/components/p-input-number/p-input-number.vue +78 -1
  142. package/squirrel/components/p-input-percent/p-input-percent.vue +27 -3
  143. package/squirrel/components/p-input-search/p-input-search.vue +30 -2
  144. package/squirrel/components/p-link/p-link.vue +13 -0
  145. package/squirrel/components/p-loading/p-loading.vue +9 -2
  146. package/squirrel/components/p-modal/p-modal-basic.spec.js +29 -3
  147. package/squirrel/components/p-modal/p-modal.vue +182 -35
  148. package/squirrel/components/p-pagination/p-pagination.vue +28 -8
  149. package/squirrel/components/p-pagination-info/p-pagination-info.vue +16 -4
  150. package/squirrel/components/p-progress-bar/p-progress-bar.vue +31 -4
  151. package/squirrel/components/p-ring-loader/p-ring-loader.vue +17 -0
  152. package/squirrel/components/p-select/p-select.vue +50 -1
  153. package/squirrel/components/p-select-btn/p-select-btn.vue +90 -2
  154. package/squirrel/components/p-select-list/p-select-list.vue +7 -0
  155. package/squirrel/components/p-select-pill/p-select-pill.vue +52 -2
  156. package/squirrel/components/p-skeleton-loader/p-skeleton-loader.vue +24 -0
  157. package/squirrel/components/p-steps/p-steps.vue +25 -0
  158. package/squirrel/components/p-table/p-table.spec.js +51 -15
  159. package/squirrel/components/p-table/p-table.types.ts +2 -0
  160. package/squirrel/components/p-table/p-table.vue +46 -4
  161. package/squirrel/components/p-table/usePTableHeaderWrap.spec.js +118 -0
  162. package/squirrel/components/p-table/usePTableHeaderWrap.ts +45 -0
  163. package/squirrel/components/p-table-header-cell/p-table-filter-icon.vue +9 -0
  164. package/squirrel/components/p-table-header-cell/p-table-header-cell.spec.js +5 -1
  165. package/squirrel/components/p-table-header-cell/p-table-header-cell.vue +38 -1
  166. package/squirrel/components/p-table-loader/p-table-loader.vue +28 -0
  167. package/squirrel/components/p-table-sort/p-table-sort.vue +19 -1
  168. package/squirrel/components/p-table-td/p-table-td.vue +20 -0
  169. package/squirrel/components/p-tabs/p-tabs.stories.js +2 -2
  170. package/squirrel/components/p-tabs/p-tabs.vue +33 -1
  171. package/squirrel/components/p-tabs-pills/p-tabs-pills.vue +33 -0
  172. package/squirrel/components/p-textarea/p-textarea.vue +43 -1
  173. package/squirrel/components/p-toggle/p-toggle.vue +44 -1
  174. package/squirrel/assets/pagination-left-icon.svg +0 -5
  175. 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
- type PInputInstance = InstanceType<typeof PInput>;
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
- 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`;
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 pb-6 cursor-default bg-surface shadow-xl'.split(' ')
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 ref="pm" :data-pm-id="id" :class="[modalBaseClass, modalClass]" :style="modalStyle">
33
- <slot name="title-wrapper">
34
- <div class="flex pb-4 pl-8 pr-4 pt-4">
35
- <h3 v-if="title" :id="`${id}-title`" class="mr-auto pt-4 text-xl font-semibold">
36
- {{ title }}
37
- </h3>
38
- <div class="ml-auto">
39
- <PCloseBtn
40
- :disabled="disabled"
41
- :class="{ invisible: !enableClose }"
42
- :aria-label="closeLabel"
43
- @click.prevent="close"
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
- </slot>
48
- <div v-if="errorMsg" class="mb-4 px-8">
49
- <PAlert type="error">{{ errorMsg }}</PAlert>
50
- </div>
51
- <slot name="content-wrapper">
52
- <div
53
- :id="`${id}-content`"
54
- :class="[
55
- 'relative grow overflow-y-auto overflow-x-hidden px-8',
56
- { 'pointer-events-none opacity-50': disabled },
57
- ]"
58
- >
59
- <slot></slot>
60
- </div>
61
- </slot>
62
- <slot name="footer-wrapper">
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
- 'update:modelValue': [boolean];
105
- 'click:overlay': [MouseEvent];
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 pb-6 cursor-default bg-surface shadow-xl',
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
- <img src="@squirrel/assets/pagination-left-icon.svg" />
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
- <img src="@squirrel/assets/pagination-right-icon.svg" />
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(['update:modelValue']);
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 data pagination should iterate through.
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 amount of data to be displayed at 1 page. Used to calculate the length of pagination.
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 amount of pages to be displayed before and after the current page.
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 amount of data pagination iterates through.
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 amount of data to be displayed at 1 page. Used to calculate the `from` and `to` limits.
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>