sprintify-ui 0.0.29 → 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.
package/dist/style.css CHANGED
@@ -1,4 +1,4 @@
1
- @charset "UTF-8";.spinner[data-v-945515f9]{animation:rotate-945515f9 1s linear infinite;-webkit-animation:rotate-945515f9 1s linear infinite;-moz-animation:rotate-945515f9 1s linear infinite}@keyframes rotate-945515f9{to{transform:rotate(360deg)}}.path[data-v-945515f9]{stroke-dasharray:170;stroke-dashoffset:20}.th[data-v-6e5812c9]{background-color:rgb(248 250 252 / var(--tw-bg-opacity));position:sticky;top:0px;z-index:1;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(203 213 225 / var(--tw-border-opacity));--tw-bg-opacity: .75;--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}circle[data-v-b63fac0e]{transition:stroke-dashoffset .35s;transform:rotate(-90deg);transform-origin:50% 50%}/*!
1
+ @charset "UTF-8";.spinner[data-v-945515f9]{animation:rotate-945515f9 1s linear infinite;-webkit-animation:rotate-945515f9 1s linear infinite;-moz-animation:rotate-945515f9 1s linear infinite}@keyframes rotate-945515f9{to{transform:rotate(360deg)}}.path[data-v-945515f9]{stroke-dasharray:170;stroke-dashoffset:20}.th[data-v-6e5812c9]{background-color:rgb(248 250 252 / var(--tw-bg-opacity));position:sticky;top:0px;z-index:1;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(203 213 225 / var(--tw-border-opacity));--tw-bg-opacity: .75;--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}circle[data-v-e5ae83e3]{transition:stroke-dashoffset .35s;transform:rotate(-90deg);transform-origin:50% 50%}/*!
2
2
  * Pikaday
3
3
  * Copyright © 2014 David Bushell | BSD & MIT license | https://dbushell.com/
4
4
  */.pika-single{z-index:9999;display:block;position:relative;color:#333;background:#fff;border:1px solid #ccc;border-bottom-color:#bbb;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.pika-single:before,.pika-single:after{content:" ";display:table}.pika-single:after{clear:both}.pika-single.is-hidden{display:none}.pika-single.is-bound{position:absolute;box-shadow:0 5px 15px -5px #00000080}.pika-lendar{float:left;width:240px;margin:8px}.pika-title{position:relative;text-align:center}.pika-label{display:inline-block;position:relative;z-index:9999;overflow:hidden;margin:0;padding:5px 3px;font-size:14px;line-height:20px;font-weight:700;background-color:#fff}.pika-title select{cursor:pointer;position:absolute;z-index:9998;margin:0;left:0;top:5px;opacity:0}.pika-prev,.pika-next{display:block;cursor:pointer;position:relative;outline:none;border:0;padding:0;width:20px;height:30px;text-indent:20px;white-space:nowrap;overflow:hidden;background-color:transparent;background-position:center center;background-repeat:no-repeat;background-size:75% 75%;opacity:.5}.pika-prev:hover,.pika-next:hover{opacity:1}.pika-prev,.is-rtl .pika-next{float:left;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==)}.pika-next,.is-rtl .pika-prev{float:right;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=)}.pika-select{display:inline-block}.pika-table{width:100%;border-collapse:collapse;border-spacing:0;border:0}.pika-table th,.pika-table td{width:14.285714285714286%;padding:0}.pika-table th{color:#999;font-size:12px;line-height:25px;font-weight:700;text-align:center}.pika-button{cursor:pointer;display:block;box-sizing:border-box;-moz-box-sizing:border-box;outline:none;border:0;margin:0;width:100%;padding:5px;color:#666;font-size:12px;line-height:15px;text-align:right;background:#f5f5f5;height:initial}.pika-week{font-size:11px;color:#999}.is-today .pika-button{color:#3af;font-weight:700}.is-selected .pika-button,.has-event .pika-button{color:#fff;font-weight:700;background:#33aaff;box-shadow:inset 0 1px 3px #178fe5;border-radius:3px}.has-event .pika-button{background:#005da9;box-shadow:inset 0 1px 3px #0076c9}.is-disabled .pika-button,.is-inrange .pika-button{background:#D5E9F7}.is-startrange .pika-button{color:#fff;background:#6CB31D;box-shadow:none;border-radius:3px}.is-endrange .pika-button{color:#fff;background:#33aaff;box-shadow:none;border-radius:3px}.is-disabled .pika-button{pointer-events:none;cursor:default;color:#999;opacity:.3}.is-outside-current-month .pika-button{color:#999;opacity:.3}.is-selection-disabled{pointer-events:none;cursor:default}.pika-button:hover,.pika-row.pick-whole-week:hover .pika-button{color:#fff;background:#ff8000;box-shadow:none;border-radius:3px}.pika-table abbr{border-bottom:none;cursor:help}.pikaday-white{--backgroundColor: #ffffff;--textColor: #718096;--currentDateTextColor: #3182ce;--selectedDateBackgroundColor: #3182ce;--selectedDateTextColor: #ffffff;--labelTextColor: #4a5568;--weekDaysTextColor: #a0aec0;font-family:inherit;background-color:var(--backgroundColor);padding:.5rem;z-index:2000;margin:6px 0 0;--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);border-radius:.5rem}.pikaday-white .pika-title{width:100%;text-align:center;display:flex;justify-content:flex-start;margin-bottom:5px}.pikaday-white .pika-prev,.pikaday-white .pika-next{position:absolute;outline:none;padding:0;width:26px;height:26px;top:-1px;display:inline-block;margin-top:0;cursor:pointer;text-indent:-9999px;white-space:nowrap;overflow:hidden;background-color:transparent;background-position:center center;background-repeat:no-repeat;opacity:.7}.pikaday-white .pika-prev:hover,.pikaday-white .pika-next:hover{opacity:1}.pikaday-white .pika-prev{right:30px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23a0aec0'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M15 19l-7-7 7-7'%3E%3C/path%3E%3C/svg%3E")}.pikaday-white .pika-next{right:2px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23a0aec0'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 5l7 7-7 7'%3E%3C/path%3E%3C/svg%3E")}.pika-prev.is-disabled,.pika-next.is-disabled{cursor:default;opacity:.2}.pikaday-white .pika-label{margin-right:.375rem;border-radius:.25rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(203 213 225 / var(--tw-border-opacity));padding:.25rem .5rem;font-size:14px;font-weight:500;line-height:1}.pikaday-white .pika-label{position:relative}.pikaday-white .pika-select-month,.pikaday-white .pika-select-year{width:100%;cursor:pointer;position:absolute;z-index:9998;margin:0;left:0;top:0;opacity:0;padding:0}.pikaday-white table{width:100%;border-collapse:collapse}.pikaday-white table th{width:2em;height:2em;font-weight:400;color:var(--weekDaysTextColor);text-align:center}.pikaday-white table th abbr{text-decoration:none}.pikaday-white table td{padding:1px}.pikaday-white table td button{width:2em;height:2em;text-align:center;border-radius:9999px;background-color:var(--backgroundColor)}.pikaday-white table td button:hover{--tw-bg-opacity: 1;background-color:rgb(226 232 240 / var(--tw-bg-opacity));--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity))}.pikaday-white table td.is-today button{color:var(--currentDateTextColor)}.pikaday-white table td.is-selected button{--tw-bg-opacity: 1;background-color:rgb(99 102 241 / var(--tw-bg-opacity));--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity));font-weight:400}.pikaday-white table td button{color:var(--textColor)}input::-moz-placeholder,textarea::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(148 163 184 / var(--tw-placeholder-opacity))}input::placeholder,textarea::placeholder{--tw-placeholder-opacity: 1;color:rgb(148 163 184 / var(--tw-placeholder-opacity))}
@@ -7,11 +7,11 @@ declare const _default: {
7
7
  color: "gray" | "red" | "orange" | "yellow" | "green" | "blue" | "indigo" | "purple" | "pink";
8
8
  icon: string | undefined;
9
9
  size: "base" | "lg";
10
- contrast: "low" | "high";
10
+ contrast: "high" | "low";
11
11
  }> & Omit<Readonly<import("vue").ExtractPropTypes<{
12
12
  contrast: {
13
13
  default: string;
14
- type: PropType<"low" | "high">;
14
+ type: PropType<"high" | "low">;
15
15
  };
16
16
  color: {
17
17
  default: string;
@@ -42,7 +42,7 @@ declare const _default: {
42
42
  $options: import("vue").ComponentOptionsBase<Readonly<import("vue").ExtractPropTypes<{
43
43
  contrast: {
44
44
  default: string;
45
- type: PropType<"low" | "high">;
45
+ type: PropType<"high" | "low">;
46
46
  };
47
47
  color: {
48
48
  default: string;
@@ -60,7 +60,7 @@ declare const _default: {
60
60
  color: "gray" | "red" | "orange" | "yellow" | "green" | "blue" | "indigo" | "purple" | "pink";
61
61
  icon: string | undefined;
62
62
  size: "base" | "lg";
63
- contrast: "low" | "high";
63
+ contrast: "high" | "low";
64
64
  }, {}, string> & {
65
65
  beforeCreate?: ((() => void) | (() => void)[]) | undefined;
66
66
  created?: ((() => void) | (() => void)[]) | undefined;
@@ -84,7 +84,7 @@ declare const _default: {
84
84
  } & Readonly<import("vue").ExtractPropTypes<{
85
85
  contrast: {
86
86
  default: string;
87
- type: PropType<"low" | "high">;
87
+ type: PropType<"high" | "low">;
88
88
  };
89
89
  color: {
90
90
  default: string;
@@ -105,7 +105,7 @@ declare const _default: {
105
105
  } & import("vue").ComponentOptionsBase<Readonly<import("vue").ExtractPropTypes<{
106
106
  contrast: {
107
107
  default: string;
108
- type: PropType<"low" | "high">;
108
+ type: PropType<"high" | "low">;
109
109
  };
110
110
  color: {
111
111
  default: string;
@@ -123,7 +123,7 @@ declare const _default: {
123
123
  color: "gray" | "red" | "orange" | "yellow" | "green" | "blue" | "indigo" | "purple" | "pink";
124
124
  icon: string | undefined;
125
125
  size: "base" | "lg";
126
- contrast: "low" | "high";
126
+ contrast: "high" | "low";
127
127
  }, {}, string> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
128
128
  $slots: {
129
129
  default: (_: {}) => any;
@@ -15,6 +15,7 @@ declare const _default: import("vue").DefineComponent<{
15
15
  normalizedRadius(): number;
16
16
  circumference(): number;
17
17
  strokeDashoffset(): number;
18
+ fontSize(): number;
18
19
  }, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
19
20
  radius: {
20
21
  default: number;
@@ -44,7 +44,7 @@ import BaseNavbarItemContent from './BaseNavbarItemContent.vue';
44
44
  import BasePagination from './BasePagination.vue';
45
45
  import BasePanel from './BasePanel.vue';
46
46
  import BasePassword from './BasePassword.vue';
47
- import BaseProcessRing from './BaseProcessRing.vue';
47
+ import BaseProgressCircle from './BaseProgressCircle.vue';
48
48
  import BaseReadMore from './BaseReadMore.vue';
49
49
  import BaseSelect from './BaseSelect.vue';
50
50
  import BaseSideNavigation from './BaseSideNavigation.vue';
@@ -64,4 +64,4 @@ import BaseLayoutStacked from './BaseLayoutStacked.vue';
64
64
  import BaseLayoutStackedConfigurable from './BaseLayoutStackedConfigurable.vue';
65
65
  import BaseLayoutSidebar from './BaseLayoutSidebar.vue';
66
66
  import BaseLayoutSidebarConfigurable from './BaseLayoutSidebarConfigurable.vue';
67
- export { BaseActionItem, BaseAlert, BaseApp, BaseAppDialogs, BaseAppNotifications, BaseAutocomplete, BaseAutocompleteFetch, BaseAvatar, BaseBadge, BaseBelongsTo, BaseBoolean, BaseBreadcrumbs, BaseButton, BaseCard, BaseCardRow, BaseCharacterCounter, BaseClipboard, BaseContainer, BaseCounter, BaseDataIterator, BaseDataTable, BaseDatePicker, BaseDateSelect, BaseDescriptionList, BaseDescriptionListItem, BaseDialog, BaseFilePicker, BaseFileUploader, BaseHasMany, BaseIcon, BaseInput, BaseInputLabel, BaseLoadingCover, BaseMediaItem, BaseMediaLibrary, BaseMediaPreview, BaseMenu, BaseMenuItem, BaseModalCenter, BaseModalSide, BaseNavbar, BaseNavbarItem, BaseNavbarItemContent, BasePagination, BasePanel, BasePassword, BaseProcessRing, BaseReadMore, BaseSelect, BaseSideNavigation, BaseSideNavigationItem, BaseSkeleton, BaseSwitch, BaseSystemAlert, BaseTabs, BaseTabItem, BaseTagAutocomplete, BaseTagAutocompleteFetch, BaseTable, BaseTableColumn, BaseTextarea, BaseTextareaAutoresize, BaseLayoutStacked, BaseLayoutStackedConfigurable, BaseLayoutSidebar, BaseLayoutSidebarConfigurable, };
67
+ export { BaseActionItem, BaseAlert, BaseApp, BaseAppDialogs, BaseAppNotifications, BaseAutocomplete, BaseAutocompleteFetch, BaseAvatar, BaseBadge, BaseBelongsTo, BaseBoolean, BaseBreadcrumbs, BaseButton, BaseCard, BaseCardRow, BaseCharacterCounter, BaseClipboard, BaseContainer, BaseCounter, BaseDataIterator, BaseDataTable, BaseDatePicker, BaseDateSelect, BaseDescriptionList, BaseDescriptionListItem, BaseDialog, BaseFilePicker, BaseFileUploader, BaseHasMany, BaseIcon, BaseInput, BaseInputLabel, BaseLoadingCover, BaseMediaItem, BaseMediaLibrary, BaseMediaPreview, BaseMenu, BaseMenuItem, BaseModalCenter, BaseModalSide, BaseNavbar, BaseNavbarItem, BaseNavbarItemContent, BasePagination, BasePanel, BasePassword, BaseProgressCircle, BaseReadMore, BaseSelect, BaseSideNavigation, BaseSideNavigationItem, BaseSkeleton, BaseSwitch, BaseSystemAlert, BaseTabs, BaseTabItem, BaseTagAutocomplete, BaseTagAutocompleteFetch, BaseTable, BaseTableColumn, BaseTextarea, BaseTextareaAutoresize, BaseLayoutStacked, BaseLayoutStackedConfigurable, BaseLayoutSidebar, BaseLayoutSidebarConfigurable, };
@@ -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.29",
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",