sprintify-ui 0.0.30 → 0.0.31

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.
@@ -27,6 +27,7 @@ declare const messages: {
27
27
  error: string;
28
28
  file_must_be_of_type: string;
29
29
  filters: string;
30
+ go_to_page: string;
30
31
  min_x_characters: string;
31
32
  month: string;
32
33
  next: string;
@@ -34,7 +35,9 @@ declare const messages: {
34
35
  none: string;
35
36
  nothing_found: string;
36
37
  notifications_empty: string;
38
+ of: string;
37
39
  or: string;
40
+ page: string;
38
41
  pagination_detail: string;
39
42
  previous: string;
40
43
  previous_month: string;
@@ -88,6 +91,7 @@ declare const messages: {
88
91
  error: string;
89
92
  file_must_be_of_type: string;
90
93
  filters: string;
94
+ go_to_page: string;
91
95
  min_x_characters: string;
92
96
  month: string;
93
97
  next: string;
@@ -95,7 +99,9 @@ declare const messages: {
95
99
  none: string;
96
100
  nothing_found: string;
97
101
  notifications_empty: string;
102
+ of: string;
98
103
  or: string;
104
+ page: string;
99
105
  pagination_detail: string;
100
106
  previous: string;
101
107
  previous_month: string;
@@ -160,6 +166,7 @@ declare const config: {
160
166
  error: string;
161
167
  file_must_be_of_type: string;
162
168
  filters: string;
169
+ go_to_page: string;
163
170
  min_x_characters: string;
164
171
  month: string;
165
172
  next: string;
@@ -167,7 +174,9 @@ declare const config: {
167
174
  none: string;
168
175
  nothing_found: string;
169
176
  notifications_empty: string;
177
+ of: string;
170
178
  or: string;
179
+ page: string;
171
180
  pagination_detail: string;
172
181
  previous: string;
173
182
  previous_month: string;
@@ -221,6 +230,7 @@ declare const config: {
221
230
  error: string;
222
231
  file_must_be_of_type: string;
223
232
  filters: string;
233
+ go_to_page: string;
224
234
  min_x_characters: string;
225
235
  month: string;
226
236
  next: string;
@@ -228,7 +238,9 @@ declare const config: {
228
238
  none: string;
229
239
  nothing_found: string;
230
240
  notifications_empty: string;
241
+ of: string;
231
242
  or: string;
243
+ page: string;
232
244
  pagination_detail: string;
233
245
  previous: string;
234
246
  previous_month: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sprintify-ui",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
4
4
  "scripts": {
5
5
  "build": "rimraf dist && vue-tsc && vite build",
6
6
  "build-fast": "rimraf dist && vite build",
@@ -8,7 +8,8 @@
8
8
  "docs:build": "vitepress build docs",
9
9
  "docs:serve": "vitepress serve docs",
10
10
  "storybook": "start-storybook -p 6006",
11
- "build-storybook": "build-storybook"
11
+ "build-storybook": "build-storybook",
12
+ "prepack": "npm run build"
12
13
  },
13
14
  "peerDependencies": {
14
15
  "@tailwindcss/aspect-ratio": "^0.4.2",
@@ -25,6 +25,9 @@ const Template = (args) => ({
25
25
  <div style="max-width: 500px;">
26
26
  <BasePagination v-model="modelValue" v-bind="args"></BasePagination>
27
27
  </div>
28
+ <div style="max-width: 250px;">
29
+ <BasePagination v-model="modelValue" v-bind="args"></BasePagination>
30
+ </div>
28
31
  `,
29
32
  });
30
33
 
@@ -1,60 +1,101 @@
1
1
  <template>
2
2
  <nav
3
- v-if="lastPage > 1 || lastPage < modelValue"
3
+ v-show="lastPage > 1 || lastPage < modelValue"
4
4
  ref="paginationNode"
5
- class="flex items-center justify-between border-t border-slate-200"
5
+ class="flex items-start border-t border-slate-200"
6
6
  >
7
- <div class="flex -mt-px w-0 flex-1">
8
- <button
9
- type="button"
10
- :disabled="modelValue == 1"
11
- class="inline-flex items-center border-t-2 border-transparent px-1 py-4 text-sm font-medium text-slate-500 hover:enabled:border-slate-300 hover:enabled:text-slate-700 disabled:cursor-not-allowed disabled:opacity-60"
12
- @click="previous()"
7
+ <div class="flex grow items-center justify-between">
8
+ <div class="-mt-px flex flex-1">
9
+ <button
10
+ type="button"
11
+ :disabled="modelValue == 1"
12
+ class="inline-flex items-center border-t-2 border-transparent px-1 py-4 text-sm font-medium text-slate-500 hover:enabled:border-slate-300 hover:enabled:text-slate-700 disabled:cursor-not-allowed disabled:opacity-60"
13
+ @click="previous()"
14
+ >
15
+ <BaseIcon
16
+ class="mx-2 h-5 w-5 text-slate-400"
17
+ icon="heroicons-solid:chevron-left"
18
+ />
19
+ </button>
20
+ </div>
21
+ <div :class="[mobileLayout ? 'hidden' : '-mt-px flex']">
22
+ <button
23
+ v-for="(i, index) in items"
24
+ :key="i + (index + '')"
25
+ type="button"
26
+ class="inline-flex items-center border-t-2 px-4 py-4 text-sm font-medium"
27
+ :class="[
28
+ i == modelValue ? 'border-primary-500 text-primary-500' : '',
29
+ i != modelValue ? 'border-transparent text-slate-500' : '',
30
+ i != modelValue && isClickable(i)
31
+ ? 'hover:border-slate-300 hover:text-slate-700'
32
+ : '',
33
+ ]"
34
+ @click="onButtonClick(i)"
35
+ >
36
+ {{ i }}
37
+ </button>
38
+ </div>
39
+ <div
40
+ v-if="mobileLayout"
41
+ class="mx-3 flex shrink-0 items-center justify-end"
13
42
  >
14
- <BaseIcon
15
- class="mr-3 h-5 w-5 text-slate-400"
16
- icon="heroicons-solid:arrow-narrow-left"
43
+ <span class="mr-2 text-sm font-normal text-slate-500">
44
+ {{ $t('sui.page') }}
45
+ </span>
46
+ <input
47
+ v-model="manualPageMobile"
48
+ type="number"
49
+ :min="1"
50
+ :max="lastPage"
51
+ :step="1"
52
+ class="rounded border border-slate-300 py-0 px-0.5 pl-1.5"
53
+ @keydown.enter="onManualPageMobileEnter"
54
+ @input="onManualPageMobileInput"
55
+ @blur="setPageFromManualPageMobile"
17
56
  />
18
- {{ $t('sui.previous') }}
19
- </button>
57
+ <span class="ml-2 text-sm font-normal text-slate-500">
58
+ {{ $t('sui.of') }} {{ lastPage }}
59
+ </span>
60
+ </div>
61
+ <div class="-mt-px flex flex-1 justify-end">
62
+ <button
63
+ :disabled="modelValue >= lastPage"
64
+ class="inline-flex items-center border-t-2 border-transparent px-1 py-4 text-sm font-medium text-slate-500 hover:enabled:border-slate-300 hover:enabled:text-slate-700 disabled:cursor-not-allowed disabled:opacity-60"
65
+ @click="next()"
66
+ >
67
+ <BaseIcon
68
+ class="mx-2 h-5 w-5 text-slate-400"
69
+ icon="heroicons-solid:chevron-right"
70
+ />
71
+ </button>
72
+ </div>
20
73
  </div>
21
- <div :class="[mobileLayout ? 'hidden' : 'flex -mt-px']">
22
- <button
23
- v-for="(i, index) in items"
24
- :key="i + (index + '')"
25
- type="button"
26
- class="inline-flex items-center border-t-2 px-4 py-4 text-sm font-medium"
27
- :class="[
28
- i == modelValue ? 'border-primary-500 text-primary-500' : '',
29
- i != modelValue ? 'border-transparent text-slate-500' : '',
30
- i != modelValue && isClickable(i)
31
- ? 'hover:border-slate-300 hover:text-slate-700'
32
- : '',
33
- ]"
34
- @click="onButtonClick(i)"
35
- >
36
- {{ i }}
37
- </button>
38
- </div>
39
- <div class="flex -mt-px w-0 flex-1 justify-end">
40
- <button
41
- :disabled="modelValue >= lastPage"
42
- class="inline-flex items-center border-t-2 border-transparent px-1 py-4 text-sm font-medium text-slate-500 hover:enabled:border-slate-300 hover:enabled:text-slate-700 disabled:cursor-not-allowed disabled:opacity-60"
43
- @click="next()"
44
- >
45
- {{ $t('sui.next') }}
46
- <BaseIcon
47
- class="ml-3 h-5 w-5 text-slate-400"
48
- icon="heroicons-solid:arrow-narrow-right"
49
- />
50
- </button>
74
+ <div
75
+ v-if="!mobileLayout"
76
+ class="mt-3 ml-4 flex shrink-0 items-center justify-end"
77
+ >
78
+ <span class="mr-3 text-sm font-medium text-slate-500">
79
+ {{ $t('sui.go_to_page') }}
80
+ </span>
81
+ <input
82
+ v-model="manualPage"
83
+ type="number"
84
+ :min="1"
85
+ :max="lastPage"
86
+ :step="1"
87
+ class="rounded border border-slate-300 py-0.5 px-0.5 pl-2"
88
+ @keydown.enter="onManualPageEnter"
89
+ @input="onManualPageInput"
90
+ @blur="setPageFromManualPage"
91
+ />
51
92
  </div>
52
93
  </nav>
53
94
  </template>
54
95
 
55
96
  <script lang="ts" setup>
56
97
  import { useResizeObserver } from '@vueuse/core';
57
- import { range } from 'lodash';
98
+ import { debounce, isNumber, range } from 'lodash';
58
99
  import { Ref } from 'vue';
59
100
 
60
101
  const props = defineProps({
@@ -75,18 +116,28 @@ const props = defineProps({
75
116
 
76
117
  const emit = defineEmits(['update:model-value']);
77
118
 
119
+ const manualPage = ref(null) as Ref<null | string | number>;
120
+ const manualPageMobile = ref(props.modelValue) as Ref<null | string | number>;
121
+
122
+ watch(
123
+ () => props.modelValue,
124
+ (value) => {
125
+ manualPageMobile.value = value;
126
+ }
127
+ );
128
+
78
129
  function next() {
79
130
  if (props.modelValue >= props.lastPage) {
80
131
  return;
81
132
  }
82
- emit('update:model-value', props.modelValue + 1);
133
+ updateModalValue(props.modelValue + 1);
83
134
  }
84
135
 
85
136
  function previous() {
86
137
  if (props.modelValue == 1) {
87
138
  return;
88
139
  }
89
- emit('update:model-value', props.modelValue - 1);
140
+ updateModalValue(props.modelValue - 1);
90
141
  }
91
142
 
92
143
  const paginationNode = ref(null) as Ref<null | HTMLElement>;
@@ -163,6 +214,53 @@ function onButtonClick(i: number | string) {
163
214
  if (!isClickable(i)) {
164
215
  return;
165
216
  }
166
- emit('update:model-value', i);
217
+ updateModalValue(i);
218
+ }
219
+
220
+ const onManualPageInput = debounce(() => {
221
+ setPageFromManualPage();
222
+ }, 1000);
223
+
224
+ function onManualPageEnter(e: any) {
225
+ e.preventDefault();
226
+ setPageFromManualPage();
227
+ }
228
+
229
+ function setPageFromManualPage() {
230
+ updateModalValue(manualPage.value);
231
+ nextTick(() => {
232
+ manualPage.value = null;
233
+ });
234
+ }
235
+
236
+ const onManualPageMobileInput = debounce(() => {
237
+ setPageFromManualPageMobile();
238
+ }, 1000);
239
+
240
+ function onManualPageMobileEnter(e: any) {
241
+ e.preventDefault();
242
+ setPageFromManualPageMobile();
243
+ }
244
+
245
+ function setPageFromManualPageMobile() {
246
+ updateModalValue(manualPageMobile.value);
247
+ if (!isValidPage(manualPageMobile.value)) {
248
+ nextTick(() => {
249
+ manualPageMobile.value = props.modelValue;
250
+ });
251
+ }
252
+ }
253
+
254
+ function updateModalValue(newPage: number | string | null | undefined) {
255
+ if (isValidPage(newPage)) {
256
+ emit('update:model-value', newPage);
257
+ }
258
+ }
259
+
260
+ function isValidPage(newPage: number | string | null | undefined) {
261
+ if (isNumber(newPage) && newPage >= 1 && newPage <= props.lastPage) {
262
+ return true;
263
+ }
264
+ return false;
167
265
  }
168
266
  </script>
package/src/lang/en.json CHANGED
@@ -19,6 +19,7 @@
19
19
  "error": "Error",
20
20
  "file_must_be_of_type": "The file must be of type",
21
21
  "filters": "Filters",
22
+ "go_to_page": "Go to ",
22
23
  "min_x_characters": "{x} characters minimum",
23
24
  "month": "Month",
24
25
  "next": "Next",
@@ -26,7 +27,9 @@
26
27
  "none": "None",
27
28
  "nothing_found": "Nothing found",
28
29
  "notifications_empty": "You have no new notifications",
30
+ "of": "of",
29
31
  "or": "or",
32
+ "page": "Page",
30
33
  "pagination_detail": "{page} records of {total}",
31
34
  "previous": "Previous",
32
35
  "previous_month": "Previous month",
package/src/lang/fr.json CHANGED
@@ -19,6 +19,7 @@
19
19
  "error": "Erreur",
20
20
  "file_must_be_of_type": "Le fichier doit être de type",
21
21
  "filters": "Filtres",
22
+ "go_to_page": "Page",
22
23
  "min_x_characters": "{x} caractères minimum",
23
24
  "month": "Mois",
24
25
  "next": "Suivant",
@@ -26,7 +27,9 @@
26
27
  "none": "Aucun",
27
28
  "nothing_found": "Rien n'a été trouvé",
28
29
  "notifications_empty": "Vous n'avez aucune nouvelle notification",
30
+ "of": "de",
29
31
  "or": "ou",
32
+ "page": "Page",
30
33
  "pagination_detail": "{page} items de {total}",
31
34
  "previous": "Précédent",
32
35
  "previous_month": "Mois précédent",