@pequity/squirrel 8.4.3 → 8.4.5

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 (157) hide show
  1. package/README.md +2 -1
  2. package/dist/cjs/chunks/p-alert.js +3 -0
  3. package/dist/cjs/chunks/p-avatar.js +16 -0
  4. package/dist/cjs/chunks/p-btn.js +3 -0
  5. package/dist/cjs/chunks/p-card.js +4 -0
  6. package/dist/cjs/chunks/p-dropdown-select.js +34 -0
  7. package/dist/cjs/chunks/p-input-number.js +32 -0
  8. package/dist/cjs/chunks/p-input-percent.js +13 -2
  9. package/dist/cjs/chunks/p-input.js +28 -0
  10. package/dist/cjs/chunks/p-pagination-info.js +9 -5
  11. package/dist/cjs/chunks/p-pagination.js +23 -13
  12. package/dist/cjs/chunks/p-select-btn.js +2 -1
  13. package/dist/cjs/chunks/p-select.js +33 -0
  14. package/dist/cjs/chunks/p-table-loader.js +20 -0
  15. package/dist/cjs/chunks/p-tabs.js +12 -0
  16. package/dist/cjs/chunks/p-textarea.js +20 -0
  17. package/dist/cjs/index.js +40 -3
  18. package/dist/cjs/p-checkbox.js +8 -1
  19. package/dist/cjs/p-chips.js +17 -1
  20. package/dist/cjs/p-close-btn.js +6 -1
  21. package/dist/cjs/p-drawer.js +90 -2
  22. package/dist/cjs/p-dropdown.js +2 -1
  23. package/dist/cjs/p-icon.js +3 -2
  24. package/dist/cjs/p-input-search.js +13 -1
  25. package/dist/cjs/p-loading.js +1 -1
  26. package/dist/cjs/p-modal.js +82 -2
  27. package/dist/cjs/p-select-pill.js +36 -2
  28. package/dist/cjs/p-skeleton-loader.js +17 -1
  29. package/dist/cjs/p-table-filter-icon.js +4 -1
  30. package/dist/cjs/p-table-header-cell.js +29 -0
  31. package/dist/cjs/p-table-td.js +1 -1
  32. package/dist/cjs/p-toggle.js +22 -1
  33. package/dist/es/chunks/p-alert.js +3 -0
  34. package/dist/es/chunks/p-avatar.js +16 -0
  35. package/dist/es/chunks/p-btn.js +3 -0
  36. package/dist/es/chunks/p-card.js +4 -0
  37. package/dist/es/chunks/p-dropdown-select.js +34 -0
  38. package/dist/es/chunks/p-input-number.js +32 -0
  39. package/dist/es/chunks/p-input-percent.js +13 -2
  40. package/dist/es/chunks/p-input.js +28 -0
  41. package/dist/es/chunks/p-pagination-info.js +9 -5
  42. package/dist/es/chunks/p-pagination.js +24 -14
  43. package/dist/es/chunks/p-select-btn.js +2 -1
  44. package/dist/es/chunks/p-select.js +33 -0
  45. package/dist/es/chunks/p-table-loader.js +20 -0
  46. package/dist/es/chunks/p-tabs.js +12 -0
  47. package/dist/es/chunks/p-textarea.js +20 -0
  48. package/dist/es/index.js +40 -3
  49. package/dist/es/p-checkbox.js +8 -1
  50. package/dist/es/p-chips.js +17 -1
  51. package/dist/es/p-close-btn.js +6 -1
  52. package/dist/es/p-drawer.js +90 -2
  53. package/dist/es/p-dropdown.js +2 -1
  54. package/dist/es/p-icon.js +3 -2
  55. package/dist/es/p-input-search.js +13 -1
  56. package/dist/es/p-loading.js +1 -1
  57. package/dist/es/p-modal.js +82 -2
  58. package/dist/es/p-select-pill.js +36 -2
  59. package/dist/es/p-skeleton-loader.js +17 -1
  60. package/dist/es/p-table-filter-icon.js +4 -1
  61. package/dist/es/p-table-header-cell.js +29 -0
  62. package/dist/es/p-table-td.js +1 -1
  63. package/dist/es/p-toggle.js +22 -1
  64. package/dist/squirrel/components/p-action-bar/p-action-bar.vue.d.ts +15 -3
  65. package/dist/squirrel/components/p-alert/p-alert.vue.d.ts +17 -4
  66. package/dist/squirrel/components/p-avatar/p-avatar.vue.d.ts +36 -1
  67. package/dist/squirrel/components/p-btn/p-btn.vue.d.ts +21 -5
  68. package/dist/squirrel/components/p-card/p-card.vue.d.ts +21 -8
  69. package/dist/squirrel/components/p-checkbox/p-checkbox.vue.d.ts +26 -8
  70. package/dist/squirrel/components/p-chips/p-chips.vue.d.ts +24 -0
  71. package/dist/squirrel/components/p-close-btn/p-close-btn.vue.d.ts +14 -1
  72. package/dist/squirrel/components/p-date-picker/p-date-picker.vue.d.ts +17 -1
  73. package/dist/squirrel/components/p-drawer/p-drawer.vue.d.ts +144 -6
  74. package/dist/squirrel/components/p-dropdown/p-dropdown.vue.d.ts +11 -2
  75. package/dist/squirrel/components/p-dropdown-select/p-dropdown-select.vue.d.ts +70 -2
  76. package/dist/squirrel/components/p-file-upload/p-file-upload.vue.d.ts +71 -7
  77. package/dist/squirrel/components/p-icon/p-icon.types.d.ts +3 -2
  78. package/dist/squirrel/components/p-icon/p-icon.vue.d.ts +5 -1
  79. package/dist/squirrel/components/p-info-icon/p-info-icon.vue.d.ts +12 -5
  80. package/dist/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue.d.ts +28 -8
  81. package/dist/squirrel/components/p-input/p-input.vue.d.ts +74 -9
  82. package/dist/squirrel/components/p-input-number/p-input-number.vue.d.ts +83 -12
  83. package/dist/squirrel/components/p-input-percent/p-input-percent.vue.d.ts +23 -3
  84. package/dist/squirrel/components/p-input-search/p-input-search.vue.d.ts +25 -1
  85. package/dist/squirrel/components/p-link/p-link.vue.d.ts +1 -1
  86. package/dist/squirrel/components/p-loading/p-loading.vue.d.ts +1 -1
  87. package/dist/squirrel/components/p-modal/p-modal.vue.d.ts +186 -16
  88. package/dist/squirrel/components/p-pagination/p-pagination.vue.d.ts +23 -13
  89. package/dist/squirrel/components/p-pagination-info/p-pagination-info.vue.d.ts +17 -9
  90. package/dist/squirrel/components/p-progress-bar/p-progress-bar.vue.d.ts +21 -1
  91. package/dist/squirrel/components/p-ring-loader/p-ring-loader.vue.d.ts +11 -1
  92. package/dist/squirrel/components/p-select/p-select.vue.d.ts +77 -7
  93. package/dist/squirrel/components/p-select-btn/p-select-btn.vue.d.ts +68 -11
  94. package/dist/squirrel/components/p-select-list/p-select-list.vue.d.ts +2 -2
  95. package/dist/squirrel/components/p-select-pill/p-select-pill.vue.d.ts +72 -2
  96. package/dist/squirrel/components/p-skeleton-loader/p-skeleton-loader.vue.d.ts +40 -0
  97. package/dist/squirrel/components/p-steps/p-steps.vue.d.ts +13 -1
  98. package/dist/squirrel/components/p-table/p-table.vue.d.ts +32 -0
  99. package/dist/squirrel/components/p-table-header-cell/p-table-filter-icon.vue.d.ts +7 -1
  100. package/dist/squirrel/components/p-table-header-cell/p-table-header-cell.vue.d.ts +59 -4
  101. package/dist/squirrel/components/p-table-loader/p-table-loader.vue.d.ts +41 -1
  102. package/dist/squirrel/components/p-table-sort/p-table-sort.vue.d.ts +13 -3
  103. package/dist/squirrel/components/p-table-td/p-table-td.vue.d.ts +13 -1
  104. package/dist/squirrel/components/p-tabs/p-tabs.vue.d.ts +34 -3
  105. package/dist/squirrel/components/p-tabs-pills/p-tabs-pills.vue.d.ts +23 -1
  106. package/dist/squirrel/components/p-textarea/p-textarea.vue.d.ts +53 -9
  107. package/dist/squirrel/components/p-toggle/p-toggle.vue.d.ts +51 -4
  108. package/dist/squirrel.css +68 -68
  109. package/package.json +20 -21
  110. package/squirrel/components/p-action-bar/p-action-bar.stories.js +5 -5
  111. package/squirrel/components/p-action-bar/p-action-bar.vue +30 -3
  112. package/squirrel/components/p-alert/p-alert.vue +24 -0
  113. package/squirrel/components/p-avatar/p-avatar.vue +28 -0
  114. package/squirrel/components/p-btn/p-btn.vue +35 -0
  115. package/squirrel/components/p-card/p-card.vue +24 -1
  116. package/squirrel/components/p-checkbox/p-checkbox.vue +23 -1
  117. package/squirrel/components/p-chips/p-chips.vue +24 -0
  118. package/squirrel/components/p-close-btn/p-close-btn.vue +15 -0
  119. package/squirrel/components/p-date-picker/p-date-picker.vue +23 -1
  120. package/squirrel/components/p-drawer/p-drawer.vue +95 -0
  121. package/squirrel/components/p-dropdown/p-dropdown.vue +12 -1
  122. package/squirrel/components/p-dropdown-select/p-dropdown-select.vue +41 -0
  123. package/squirrel/components/p-file-upload/p-file-upload.vue +58 -3
  124. package/squirrel/components/p-icon/p-icon.types.ts +3 -2
  125. package/squirrel/components/p-icon/p-icon.vue +16 -0
  126. package/squirrel/components/p-info-icon/p-info-icon.vue +19 -0
  127. package/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue +32 -0
  128. package/squirrel/components/p-input/p-input.vue +61 -1
  129. package/squirrel/components/p-input-number/p-input-number.vue +78 -1
  130. package/squirrel/components/p-input-percent/p-input-percent.vue +27 -3
  131. package/squirrel/components/p-input-search/p-input-search.vue +30 -2
  132. package/squirrel/components/p-link/p-link.vue +13 -0
  133. package/squirrel/components/p-loading/p-loading.vue +9 -2
  134. package/squirrel/components/p-modal/p-modal.vue +138 -2
  135. package/squirrel/components/p-pagination/p-pagination.vue +28 -8
  136. package/squirrel/components/p-pagination-info/p-pagination-info.vue +16 -4
  137. package/squirrel/components/p-progress-bar/p-progress-bar.vue +31 -4
  138. package/squirrel/components/p-ring-loader/p-ring-loader.vue +17 -0
  139. package/squirrel/components/p-select/p-select.vue +50 -1
  140. package/squirrel/components/p-select-btn/p-select-btn.vue +90 -2
  141. package/squirrel/components/p-select-list/p-select-list.vue +7 -0
  142. package/squirrel/components/p-select-pill/p-select-pill.vue +52 -2
  143. package/squirrel/components/p-skeleton-loader/p-skeleton-loader.vue +24 -0
  144. package/squirrel/components/p-steps/p-steps.vue +25 -0
  145. package/squirrel/components/p-table/p-table.vue +39 -0
  146. package/squirrel/components/p-table-header-cell/p-table-filter-icon.vue +9 -0
  147. package/squirrel/components/p-table-header-cell/p-table-header-cell.vue +36 -0
  148. package/squirrel/components/p-table-loader/p-table-loader.vue +28 -0
  149. package/squirrel/components/p-table-sort/p-table-sort.vue +19 -1
  150. package/squirrel/components/p-table-td/p-table-td.vue +20 -0
  151. package/squirrel/components/p-tabs/p-tabs.stories.js +2 -2
  152. package/squirrel/components/p-tabs/p-tabs.vue +33 -1
  153. package/squirrel/components/p-tabs-pills/p-tabs-pills.vue +33 -0
  154. package/squirrel/components/p-textarea/p-textarea.vue +43 -1
  155. package/squirrel/components/p-toggle/p-toggle.vue +44 -1
  156. package/squirrel/assets/pagination-left-icon.svg +0 -5
  157. package/squirrel/assets/pagination-right-icon.svg +0 -5
@@ -10,6 +10,7 @@
10
10
  </div>
11
11
  <div class="relative w-full">
12
12
  <div v-if="!!$slots.prefix || prefixString">
13
+ <!-- Slot for custom prefix content - overrides the prefixString prop -->
13
14
  <slot name="prefix">
14
15
  <div
15
16
  :class="[{ 'absolute left-3 flex items-center': prefixString }, prefixString ? prefixClasses[size] : '']"
@@ -53,30 +54,82 @@ const prefixClasses: Record<Size, string> = {
53
54
  lg: 'text-lg h-12 left-5',
54
55
  };
55
56
 
57
+ /**
58
+ * A specialized input component for numeric values with currency formatting.
59
+ * Provides number-only input with configurable currency display, precision, and formatting options.
60
+ * Supports custom labels, error states, tooltips, and prefix content.
61
+ * Uses vue-currency-input for robust number handling and formatting.
62
+ */
56
63
  defineOptions({
57
64
  name: 'PInputNumber',
58
65
  inheritAttrs: false,
59
66
  });
60
67
 
61
- const emit = defineEmits(['update:modelValue', 'change']);
68
+ const emit = defineEmits<{
69
+ /**
70
+ * Emitted when the numeric value changes.
71
+ * @param {number | null} value - The new numeric value
72
+ */
73
+ 'update:modelValue': [value: number | null];
74
+ /**
75
+ * Emitted when the value changes (includes the new value).
76
+ * @param {number | null} value - The new numeric value
77
+ */
78
+ change: [value: number | null];
79
+ }>();
80
+
81
+ defineSlots<{
82
+ /**
83
+ * Custom label content - overrides the label prop.
84
+ * @param {string} label - The label text
85
+ * @param {string} label-classes - CSS classes for the label
86
+ */
87
+ label?: (props: { label: string; labelClasses: string }) => unknown;
88
+
89
+ /**
90
+ * Custom prefix content - overrides the prefixString prop.
91
+ * Use this slot for custom prefix content instead of the prefixString prop.
92
+ */
93
+ prefix?: () => unknown;
94
+ }>();
62
95
 
63
96
  const props = defineProps({
97
+ /**
98
+ * The current numeric value of the input (v-model).
99
+ * Supports two-way binding for form inputs.
100
+ */
64
101
  modelValue: {
65
102
  type: [Number, String] as PropType<number | string | null | undefined>,
66
103
  default: null,
67
104
  },
105
+ /**
106
+ * Text label for the input field.
107
+ * If not provided, you can use the label slot instead.
108
+ */
68
109
  label: {
69
110
  type: String,
70
111
  default: '',
71
112
  },
113
+ /**
114
+ * Error message to display below the input.
115
+ * When provided, the input will show error styling.
116
+ */
72
117
  errorMsg: {
73
118
  type: String,
74
119
  default: '',
75
120
  },
121
+ /**
122
+ * Whether the input is required.
123
+ * Adds required attribute and visual indicator.
124
+ */
76
125
  required: {
77
126
  type: Boolean,
78
127
  default: false,
79
128
  },
129
+ /**
130
+ * The size of the input - affects padding, font size, and spacing.
131
+ * Valid values: 'sm', 'md', 'lg'
132
+ */
80
133
  size: {
81
134
  type: String as PropType<Size>,
82
135
  default: 'md',
@@ -84,14 +137,26 @@ const props = defineProps({
84
137
  return SIZES.includes(value);
85
138
  },
86
139
  },
140
+ /**
141
+ * Whether to select all text when the input receives focus.
142
+ * Provides better UX for number input fields.
143
+ */
87
144
  selectOnClick: {
88
145
  type: Boolean,
89
146
  default: true,
90
147
  },
148
+ /**
149
+ * Text for the info tooltip displayed next to the label.
150
+ * Uses PInfoIcon component for consistent tooltip styling.
151
+ */
91
152
  tooltipText: {
92
153
  type: String,
93
154
  default: '',
94
155
  },
156
+ /**
157
+ * String to display as prefix in the input field.
158
+ * Can be overridden by the prefix slot for custom content.
159
+ */
95
160
  prefixString: {
96
161
  type: String,
97
162
  default: '',
@@ -155,9 +220,21 @@ const style = computed(() => {
155
220
  return attrs.style as StyleValue;
156
221
  });
157
222
 
223
+ /**
224
+ * Handles focus event on the input field.
225
+ * Selects all text if selectOnClick is enabled.
226
+ * @param {void} - No parameters
227
+ * @returns {void}
228
+ */
158
229
  const focus = () => {
159
230
  props.selectOnClick && inputRef.value.select();
160
231
  };
161
232
 
233
+ /**
234
+ * Programmatically sets the numeric value of the input.
235
+ * Useful for external control of the input value.
236
+ * @param {number | null} value - The numeric value to set
237
+ * @returns {void}
238
+ */
162
239
  defineExpose({ setValue });
163
240
  </script>
@@ -11,6 +11,7 @@
11
11
  <script setup lang="ts">
12
12
  import { type Size } from '@squirrel/components/p-btn/p-btn.types';
13
13
  import PInputNumber from '@squirrel/components/p-input-number/p-input-number.vue';
14
+ import { toNumberOrNull } from '@squirrel/utils/number';
14
15
  import { isNumber } from 'lodash-es';
15
16
  import { computed, type PropType } from 'vue';
16
17
 
@@ -20,25 +21,48 @@ const prefixClasses: Record<Size, string> = {
20
21
  lg: 'text-lg h-12 left-5',
21
22
  };
22
23
 
24
+ /**
25
+ * A percentage input component that wraps PInputNumber with automatic decimal conversion.
26
+ * Displays values as percentages (multiplied by 100) while storing the actual decimal value.
27
+ * Provides a consistent interface for percentage inputs with proper formatting and validation.
28
+ *
29
+ * @displayName PInputPercent
30
+ */
23
31
  defineOptions({
24
32
  name: 'PInputPercent',
25
33
  });
26
34
 
27
35
  const props = defineProps({
36
+ /**
37
+ * The current value (v-model).
38
+ * Stored as a decimal (0.5 = 50%) but displayed as a percentage.
39
+ * Supports two-way binding for form inputs.
40
+ */
28
41
  modelValue: {
29
42
  type: [Number, String] as PropType<number | string | null | undefined>,
30
43
  default: null,
31
44
  },
45
+ /**
46
+ * The size of the input field.
47
+ * Valid values: 'sm', 'md', 'lg'
48
+ * @values sm, md, lg
49
+ */
32
50
  size: {
33
51
  type: String as PropType<Size>,
34
52
  default: 'md',
35
53
  },
36
54
  });
37
55
 
38
- const emit = defineEmits(['update:modelValue']);
56
+ const emit = defineEmits<{
57
+ /**
58
+ * Emitted when the percentage value changes.
59
+ * @param {number | null} value - The new decimal value
60
+ */
61
+ 'update:modelValue': [value: number | null];
62
+ }>();
39
63
 
40
64
  const convertedValue = computed({
41
- get: () => (isNumber(props.modelValue) ? props.modelValue * 100 : props.modelValue),
42
- set: (nV) => emit('update:modelValue', isNumber(nV) ? nV / 100 : nV),
65
+ get: () => (isNumber(props.modelValue) ? props.modelValue * 100 : toNumberOrNull(props.modelValue)),
66
+ set: (nV) => emit('update:modelValue', isNumber(nV) ? nV / 100 : toNumberOrNull(nV)),
43
67
  });
44
68
  </script>
@@ -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);
@@ -90,99 +90,235 @@ const FOCUSABLE_ELEMENTS =
90
90
  'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex]:not([tabindex="-1"])';
91
91
  let animatingZIndex = 0;
92
92
 
93
+ /**
94
+ * A modal dialog component with advanced features like animations, focus management, and accessibility.
95
+ * Provides a teleported modal interface with backdrop, customizable styling, and lifecycle events.
96
+ * Supports both controlled and uncontrolled modes with proper keyboard navigation.
97
+ *
98
+ * @displayName PModal
99
+ */
93
100
  defineOptions({
94
101
  name: 'PModal',
95
102
  });
96
103
 
104
+ defineSlots<{
105
+ /**
106
+ * Default content slot for the modal body.
107
+ */
108
+ default?: () => unknown;
109
+ /**
110
+ * Custom title wrapper content.
111
+ */
112
+ 'title-wrapper'?: () => unknown;
113
+ /**
114
+ * Custom content wrapper.
115
+ */
116
+ 'content-wrapper'?: () => unknown;
117
+ /**
118
+ * Custom footer content.
119
+ */
120
+ footer?: () => unknown;
121
+ /**
122
+ * Custom footer wrapper.
123
+ */
124
+ 'footer-wrapper'?: () => unknown;
125
+ }>();
126
+
97
127
  const emit = defineEmits<{
128
+ /**
129
+ * Emitted before the modal starts opening.
130
+ */
98
131
  'before-open': [];
132
+ /**
133
+ * Emitted when the modal is opening (animation in progress).
134
+ */
99
135
  opening: [];
136
+ /**
137
+ * Emitted when the modal has finished opening.
138
+ */
100
139
  opened: [];
140
+ /**
141
+ * Emitted before the modal starts closing.
142
+ */
101
143
  'before-close': [];
144
+ /**
145
+ * Emitted when the modal is closing (animation in progress).
146
+ */
102
147
  closing: [];
148
+ /**
149
+ * Emitted when the modal has finished closing.
150
+ */
103
151
  closed: [];
104
- 'update:modelValue': [boolean];
105
- 'click:overlay': [MouseEvent];
152
+ /**
153
+ * Emitted when the modal visibility changes (v-model).
154
+ * @param {boolean} value - The new visibility state
155
+ */
156
+ 'update:modelValue': [value: boolean];
157
+ /**
158
+ * Emitted when the backdrop is clicked.
159
+ * @param {MouseEvent} event - The click event
160
+ */
161
+ 'click:overlay': [event: MouseEvent];
106
162
  }>();
107
163
 
108
164
  const props = defineProps({
165
+ /**
166
+ * Unique name for the modal when using the modal service.
167
+ * Used for programmatic control of the modal.
168
+ */
109
169
  name: {
110
170
  type: String,
111
171
  default: '',
112
172
  },
173
+ /**
174
+ * Title displayed in the modal header.
175
+ * Used for accessibility and visual identification.
176
+ */
113
177
  title: {
114
178
  type: String,
115
179
  default: '',
116
180
  },
181
+ /**
182
+ * Base z-index for the modal.
183
+ * Higher values ensure the modal appears above other content.
184
+ */
117
185
  baseZindex: {
118
186
  type: Number,
119
187
  default: 1051,
120
188
  },
189
+ /**
190
+ * CSS classes for the backdrop element.
191
+ * Controls the appearance of the modal overlay.
192
+ */
121
193
  bgClass: {
122
194
  type: [String, Object, Array] as PropType<StyleValue>,
123
195
  default: 'fixed bottom-0 left-0 right-0 top-0 bg-black/20',
124
196
  },
197
+ /**
198
+ * CSS classes for the modal wrapper element.
199
+ * Controls the positioning and layout of the modal container.
200
+ */
125
201
  wrapperClass: {
126
202
  type: [String, Object, Array] as PropType<StyleValue>,
127
203
  default:
128
204
  '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
205
  },
206
+ /**
207
+ * Base CSS classes for the modal content.
208
+ * Controls the appearance of the modal dialog itself.
209
+ */
130
210
  modalBaseClass: {
131
211
  type: [String, Object, Array] as PropType<StyleValue>,
132
212
  default: 'pm relative flex flex-col rounded-2xl pb-6 cursor-default bg-surface shadow-xl',
133
213
  },
214
+ /**
215
+ * Additional CSS classes for the modal content.
216
+ * Merged with modalBaseClass for custom styling.
217
+ */
134
218
  modalClass: {
135
219
  type: [String, Object, Array] as PropType<StyleValue>,
136
220
  default: '',
137
221
  },
222
+ /**
223
+ * Inline styles for the modal content.
224
+ * Applied directly to the modal element.
225
+ */
138
226
  modalStyle: {
139
227
  type: [String, Object, Array] as PropType<StyleValue>,
140
228
  default: '',
141
229
  },
230
+ /**
231
+ * CSS class for the modal entrance animation.
232
+ * Controls how the modal appears.
233
+ */
142
234
  inClass: {
143
235
  type: String,
144
236
  default: 'slideInTop',
145
237
  },
238
+ /**
239
+ * CSS class for the modal exit animation.
240
+ * Controls how the modal disappears.
241
+ */
146
242
  outClass: {
147
243
  type: String,
148
244
  default: 'slideOutTop',
149
245
  },
246
+ /**
247
+ * CSS class for the backdrop entrance animation.
248
+ * Controls how the backdrop appears.
249
+ */
150
250
  bgInClass: {
151
251
  type: String,
152
252
  default: 'fadeIn',
153
253
  },
254
+ /**
255
+ * CSS class for the backdrop exit animation.
256
+ * Controls how the backdrop disappears.
257
+ */
154
258
  bgOutClass: {
155
259
  type: String,
156
260
  default: 'fadeOut',
157
261
  },
262
+ /**
263
+ * Target element to append the modal to.
264
+ * Usually 'body' for proper z-index stacking.
265
+ */
158
266
  appendTo: {
159
267
  type: String,
160
268
  default: 'body',
161
269
  },
270
+ /**
271
+ * Whether the modal should be mounted immediately.
272
+ * Useful for modals that are always present in the DOM.
273
+ */
162
274
  live: {
163
275
  type: Boolean,
164
276
  default: false,
165
277
  },
278
+ /**
279
+ * Whether the modal can be closed by user interaction.
280
+ * Controls close button visibility and backdrop click behavior.
281
+ */
166
282
  enableClose: {
167
283
  type: Boolean,
168
284
  default: true,
169
285
  },
286
+ /**
287
+ * Controls the visibility of the modal (v-model).
288
+ * Supports two-way binding for modal state.
289
+ */
170
290
  modelValue: {
171
291
  type: Boolean,
172
292
  default: false,
173
293
  },
294
+ /**
295
+ * Accessibility label for the close button.
296
+ * Used by screen readers for better accessibility.
297
+ */
174
298
  closeLabel: {
175
299
  type: String,
176
300
  default: 'Close',
177
301
  },
302
+ /**
303
+ * Whether the modal content is disabled.
304
+ * Prevents user interaction with modal content.
305
+ */
178
306
  disabled: {
179
307
  type: Boolean,
180
308
  default: false,
181
309
  },
310
+ /**
311
+ * Error message to display in the modal.
312
+ * Shows an error alert above the modal content.
313
+ */
182
314
  errorMsg: {
183
315
  type: String,
184
316
  default: '',
185
317
  },
318
+ /**
319
+ * Maximum width of the modal.
320
+ * Controls the responsive behavior of the modal.
321
+ */
186
322
  maxWidth: {
187
323
  type: String,
188
324
  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,