@veritree/ui 0.76.1-0 → 0.76.1-2

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/nuxt.js CHANGED
@@ -23,6 +23,7 @@ const components = [
23
23
  'src/components/Tooltip',
24
24
  'src/components/Switch',
25
25
  'src/components/Separator',
26
+ 'src/components/ScrollShadows',
26
27
  ];
27
28
 
28
29
  export default function () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veritree/ui",
3
- "version": "0.76.1-0",
3
+ "version": "0.76.1-2",
4
4
  "description": "veritree ui library",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -15,10 +15,10 @@
15
15
  "release": "np --no-tests --no-2fa"
16
16
  },
17
17
  "dependencies": {
18
- "@floating-ui/dom": "^1.2.0",
18
+ "@floating-ui/dom": "^1.6.5",
19
19
  "@linusborg/vue-simple-portal": "^0.1.5",
20
- "@veritree/icons": "^0.60.0",
21
- "v-calendar": "^2.4.2"
20
+ "@sum.cumo/vue-datepicker": "^4.0.0",
21
+ "@veritree/icons": "^0.62.0"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@babel/eslint-parser": "^7.23.10",
@@ -33,7 +33,7 @@
33
33
  "stylelint-config-prettier": "^9.0.5",
34
34
  "stylelint-config-recommended-vue": "^1.5.0",
35
35
  "stylelint-config-standard": "^36.0.0",
36
- "tailwindcss": "^3.4.1"
36
+ "tailwindcss": "^3.4.3"
37
37
  },
38
38
  "engines": {
39
39
  "npm": ">=8.0.0",
@@ -2,10 +2,8 @@
2
2
  <VTPopover>
3
3
  <VTPopoverTrigger ref="trigger">
4
4
  <button :class="classComputed" :disabled="disabled" @click.prevent>
5
- <span v-if="valueModel">{{
6
- new Date(valueModel).toISOString().split('T')[0]
7
- }}</span>
8
- <span class="text-gray-500" v-else>yyyy-mm-dd</span>
5
+ <span v-if="valueModel">{{ valueModelFormatted }}</span>
6
+ <span class="text-gray-500" v-else>{{ format }}</span>
9
7
  <span
10
8
  v-if="!iconless"
11
9
  class="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2"
@@ -15,17 +13,24 @@
15
13
  </span>
16
14
  </button>
17
15
  </VTPopoverTrigger>
18
- <VTPopoverContent @hidden="$emit('hidden')" @shown="$emit('shown')">
19
- <DatePicker
16
+ <VTPopoverContent @hidden="$emit('hidden')" @shown="onShown">
17
+ <Datepicker
20
18
  v-model="valueModel"
21
- :min-date="min"
22
- :max-date="max"
23
- :model-config="modelConfig"
24
- :available-dates="availableDates"
25
- color="null"
26
- class="min-w-full"
27
- @dayclick="onDayClick"
28
- />
19
+ :inline="true"
20
+ :initial-view="initialView"
21
+ :minimum-view="minimumView"
22
+ :maximum-view="maximumView"
23
+ :show-edge-dates="showEdgeDates"
24
+ :disabled-dates="disabledDates"
25
+ @input="onInput"
26
+ >
27
+ <template #prevIntervalBtn>
28
+ <IconChevronLeft />
29
+ </template>
30
+ <template #nextIntervalBtn>
31
+ <IconChevronRight />
32
+ </template>
33
+ </Datepicker>
29
34
  </VTPopoverContent>
30
35
  </VTPopover>
31
36
  </template>
@@ -38,7 +43,9 @@ import {
38
43
  import VTPopover from './../Popover/VTPopover.vue';
39
44
  import VTPopoverTrigger from './../Popover/VTPopoverTrigger.vue';
40
45
  import VTPopoverContent from './../Popover/VTPopoverContent.vue';
41
- import DatePicker from 'v-calendar/lib/components/date-picker.umd';
46
+ import Datepicker from '@sum.cumo/vue-datepicker';
47
+ import { IconChevronLeft, IconChevronRight } from '@veritree/icons';
48
+ import { format } from 'date-fns';
42
49
 
43
50
  export default {
44
51
  name: 'VTInputDate',
@@ -46,16 +53,18 @@ export default {
46
53
  mixins: [formControlMixin, formControlStyleMixin],
47
54
 
48
55
  components: {
56
+ Datepicker,
57
+ IconChevronLeft,
58
+ IconChevronRight,
49
59
  VTPopover,
50
60
  VTPopoverTrigger,
51
61
  VTPopoverContent,
52
- DatePicker,
53
62
  },
54
63
 
55
64
  props: {
56
- availableDates: {
57
- type: Object,
58
- default: null,
65
+ format: {
66
+ type: String,
67
+ default: 'YYYY-MM-DD',
59
68
  },
60
69
  min: {
61
70
  type: [String, Date],
@@ -65,17 +74,26 @@ export default {
65
74
  type: [String, Date],
66
75
  default: null,
67
76
  },
77
+ initialView: {
78
+ type: String,
79
+ default: 'day',
80
+ },
81
+ minimumView: {
82
+ type: String,
83
+ default: 'day',
84
+ },
85
+ maximumView: {
86
+ type: String,
87
+ default: 'year',
88
+ },
89
+ showEdgeDates: {
90
+ type: Boolean,
91
+ default: true,
92
+ },
68
93
  iconless: {
69
94
  type: Boolean,
70
95
  default: false,
71
96
  },
72
- modelConfig: {
73
- type: Object,
74
- default: () => ({
75
- type: 'string',
76
- mask: 'YYYY-MM-DD',
77
- }),
78
- },
79
97
  },
80
98
 
81
99
  computed: {
@@ -88,12 +106,311 @@ export default {
88
106
  this.$emit('change', newDate);
89
107
  },
90
108
  },
109
+
110
+ valueModelFormatted() {
111
+ return format(this.value, this.format);
112
+ },
113
+
114
+ disabledDates() {
115
+ return {
116
+ to: this.min,
117
+ from: this.max,
118
+ };
119
+ },
91
120
  },
92
121
 
93
122
  methods: {
94
- onDayClick() {
123
+ onShown() {
124
+ this.$emit('shown');
125
+ this.setFocus();
126
+ },
127
+
128
+ /**
129
+ * Sets the focus on the datepicker element.
130
+ * If there is a selected date, it focuses on that date.
131
+ * If there is no selected date, it focuses on today's date.
132
+ */
133
+ setFocus() {
134
+ const elDatepicker = document.querySelector('.vdp-datepicker');
135
+
136
+ if (!elDatepicker) {
137
+ return;
138
+ }
139
+
140
+ const elSelected = elDatepicker.querySelector('.selected');
141
+
142
+ if (elSelected) {
143
+ elSelected.focus();
144
+ return;
145
+ }
146
+
147
+ const elToday = elDatepicker.querySelector('.today');
148
+
149
+ if (elToday) {
150
+ elToday.focus();
151
+ }
152
+ },
153
+
154
+ onInput() {
95
155
  this.$refs.trigger.cancel();
96
156
  },
97
157
  },
98
158
  };
99
159
  </script>
160
+
161
+ <style>
162
+ .rtl {
163
+ direction: rtl;
164
+ }
165
+
166
+ .vdp-datepicker {
167
+ font-size: 14px;
168
+ }
169
+
170
+ .vdp-datepicker__calendar .today {
171
+ background-color: #f2f2f2;
172
+ }
173
+
174
+ .vdp-datepicker__calendar {
175
+ & button {
176
+ background: inherit;
177
+ text-align: center;
178
+ }
179
+
180
+ & button:disabled {
181
+ color: #ddd;
182
+ }
183
+ }
184
+
185
+ /* header */
186
+ .vdp-datepicker__calendar header {
187
+ display: flex;
188
+
189
+ & button {
190
+ border: none;
191
+ }
192
+
193
+ & button:hover:not(:disabled) {
194
+ background: #f2f2f2;
195
+ }
196
+
197
+ & button.vdp-datepicker__up {
198
+ color: inherit;
199
+ font-weight: 500;
200
+ flex-grow: 1;
201
+ }
202
+
203
+ & .next,
204
+ & .prev {
205
+ border-radius: 50%;
206
+ display: flex;
207
+ align-items: center;
208
+ justify-content: center;
209
+ flex-shrink: 0;
210
+ height: 2rem;
211
+ aspect-ratio: 1 / 1;
212
+ position: relative;
213
+ }
214
+
215
+ & .next .default,
216
+ & .prev .default {
217
+ display: flex;
218
+ text-indent: -10000px;
219
+ }
220
+
221
+ & .next .default:after,
222
+ & .prev .default:after {
223
+ border: 6px solid transparent;
224
+ content: '';
225
+ left: 50%;
226
+ position: absolute;
227
+ top: 50%;
228
+ transform: translateX(-50%) translateY(-50%);
229
+ }
230
+
231
+ & .next.rtl,
232
+ & .prev.rtl {
233
+ transform: rotate(180deg);
234
+ }
235
+
236
+ & .prev .default:after {
237
+ border-right: 10px solid #000;
238
+ margin-left: -5px;
239
+ }
240
+
241
+ & .prev:disabled .default:after {
242
+ border-right: 10px solid #ddd;
243
+ }
244
+
245
+ & .next .default:after {
246
+ border-left: 10px solid #000;
247
+ margin-left: 5px;
248
+ }
249
+
250
+ & .next:disabled .default:after {
251
+ border-left: 10px solid #ddd;
252
+ }
253
+ }
254
+
255
+ /* body (days, months and years) */
256
+ .vdp-datepicker__calendar .picker-cells {
257
+ display: grid;
258
+ list-style: none;
259
+ margin: 0;
260
+ padding: 0;
261
+
262
+ &:has(.cell.day) {
263
+ grid-template-columns: repeat(7, 1fr);
264
+ }
265
+
266
+ &:has(.cell.month),
267
+ &:has(.cell.year) {
268
+ min-height: calc(6 * 2rem);
269
+ grid-template-columns: repeat(3, 1fr);
270
+ }
271
+
272
+ & .cell {
273
+ border: 1px solid transparent;
274
+ }
275
+
276
+ & .cell:not(.selected):focus {
277
+ border-color: #cccccc;
278
+ }
279
+
280
+ & .cell.day {
281
+ border-radius: 50%;
282
+ /* height: 2rem; */
283
+ aspect-ratio: 1 / 1;
284
+ }
285
+ }
286
+
287
+ /* cell states */
288
+ .vdp-datepicker__calendar .cell:not(.blank):not(.disabled).day,
289
+ .vdp-datepicker__calendar .cell:not(.blank):not(.disabled).month,
290
+ .vdp-datepicker__calendar .cell:not(.blank):not(.disabled).year {
291
+ cursor: pointer;
292
+ }
293
+
294
+ .vdp-datepicker__calendar .cell:not(.blank):not(.disabled).day:hover,
295
+ .vdp-datepicker__calendar .cell:not(.blank):not(.disabled).month:hover,
296
+ .vdp-datepicker__calendar .cell:not(.blank):not(.disabled).year:hover {
297
+ border-color: #333;
298
+ }
299
+
300
+ .vdp-datepicker__calendar .cell:not(.blank):not(.disabled).day:focus,
301
+ .vdp-datepicker__calendar .cell:not(.blank):not(.disabled).month:focus,
302
+ .vdp-datepicker__calendar .cell:not(.blank):not(.disabled).year:focus {
303
+ z-index: 1;
304
+ }
305
+
306
+ .vdp-datepicker__calendar .cell.muted {
307
+ color: #ccc;
308
+ }
309
+
310
+ .vdp-datepicker__calendar .cell.selected {
311
+ background: #333;
312
+ color: #fff;
313
+ }
314
+
315
+ .vdp-datepicker__calendar .cell.selected.highlighted,
316
+ .vdp-datepicker__calendar .cell.selected:hover {
317
+ background: #333;
318
+ }
319
+
320
+ .vdp-datepicker__calendar .cell.highlighted {
321
+ background: #cae5ed;
322
+ color: #104756;
323
+ }
324
+
325
+ .vdp-datepicker__calendar .cell.highlighted.disabled {
326
+ color: #accad2;
327
+ }
328
+
329
+ .vdp-datepicker__calendar .cell.muted.disabled:not(.selected) {
330
+ color: #ddd;
331
+ }
332
+
333
+ .vdp-datepicker__calendar .cell.muted.disabled:not(.selected).highlighted {
334
+ color: #accad2;
335
+ }
336
+
337
+ .vdp-datepicker__calendar .day-header {
338
+ display: grid;
339
+ grid-template-columns: repeat(7, 1fr);
340
+
341
+ & span {
342
+ display: flex;
343
+ align-items: center;
344
+ justify-content: center;
345
+ aspect-ratio: 1 / 1;
346
+ height: 2rem;
347
+ color: #767676;
348
+ font-size: 14px;
349
+ white-space: nowrap;
350
+ }
351
+ }
352
+
353
+ /* .vdp-datepicker__calendar .picker-view {
354
+ width: inherit;
355
+ } */
356
+
357
+ .vdp-datepicker__calendar .picker-view .cells-wrapper {
358
+ overflow: hidden;
359
+ position: relative;
360
+ }
361
+
362
+ .vdp-datepicker__calendar .picker-view .cells-wrapper .picker-cells {
363
+ transition: all 0.25s ease-in-out;
364
+ }
365
+
366
+ .vdp-datepicker__calendar .picker-view .slide-right-enter-active {
367
+ top: 0;
368
+ }
369
+
370
+ .vdp-datepicker__calendar .picker-view .slide-right-leave-active {
371
+ position: absolute;
372
+ top: 0;
373
+ }
374
+
375
+ .vdp-datepicker__calendar .picker-view .slide-right-enter {
376
+ transform: translate(100%);
377
+ }
378
+
379
+ .vdp-datepicker__calendar .picker-view .slide-right-leave-to {
380
+ transform: translate(-100%);
381
+ }
382
+
383
+ .vdp-datepicker__calendar .picker-view .slide-left-enter-active {
384
+ top: 0;
385
+ }
386
+
387
+ .vdp-datepicker__calendar .picker-view .slide-left-leave-active {
388
+ position: absolute;
389
+ top: 0;
390
+ }
391
+
392
+ .vdp-datepicker__calendar .picker-view .slide-left-enter {
393
+ transform: translate(-100%);
394
+ }
395
+
396
+ .vdp-datepicker__calendar .picker-view .slide-left-leave-to {
397
+ transform: translate(100%);
398
+ }
399
+
400
+ .view-leave-active {
401
+ position: absolute;
402
+ }
403
+
404
+ .vdp-datepicker__calendar-button,
405
+ .vdp-datepicker__clear-button {
406
+ border: none;
407
+ font-style: normal;
408
+ }
409
+
410
+ .vdp-datepicker__calendar-button.input-group-append,
411
+ .vdp-datepicker__calendar-button.input-group-prepend,
412
+ .vdp-datepicker__clear-button.input-group-append,
413
+ .vdp-datepicker__clear-button.input-group-prepend {
414
+ padding: 0;
415
+ }
416
+ </style>
@@ -0,0 +1,76 @@
1
+ <template>
2
+ <component :is="tag" :class="`scroll-shadows-${orientation}`">
3
+ <slot></slot>
4
+ </component>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'VTScrollShadows',
10
+
11
+ props: {
12
+ tag: {
13
+ type: String,
14
+ default: 'div',
15
+ },
16
+ orientation: {
17
+ type: String,
18
+ default: 'vertical', // horizontal
19
+ },
20
+ },
21
+ };
22
+ </script>
23
+
24
+ <style scoped>
25
+ .scroll-shadows-vertical {
26
+ background:
27
+ /* Shadow Cover TOP */
28
+ linear-gradient(white 30%, rgba(255, 255, 255, 0)) center top,
29
+ /* Shadow Cover BOTTOM */ linear-gradient(rgba(255, 255, 255, 0), white 70%)
30
+ center bottom,
31
+ /* Shadow TOP */
32
+ radial-gradient(
33
+ farthest-side at 50% 0,
34
+ rgba(0, 0, 0, 0.1),
35
+ rgba(0, 0, 0, 0)
36
+ )
37
+ center top,
38
+ /* Shadow BOTTOM */
39
+ radial-gradient(
40
+ farthest-side at 50% 100%,
41
+ rgba(0, 0, 0, 0.1),
42
+ rgba(0, 0, 0, 0)
43
+ )
44
+ center bottom;
45
+
46
+ background-repeat: no-repeat;
47
+ background-size:
48
+ 100% 30px,
49
+ 100% 30px,
50
+ 100% 8px,
51
+ 100% 8px;
52
+ background-attachment: local, local, scroll, scroll;
53
+ }
54
+
55
+ .scroll-shadows-horizontal {
56
+ background:
57
+ linear-gradient(90deg, white 30%, rgba(255, 255, 255, 0)),
58
+ linear-gradient(90deg, rgba(255, 255, 255, 0), white 70%) 0 100%,
59
+ radial-gradient(farthest-side at 0% 50%, rgba(0, 0, 0, 0.2), white),
60
+ radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.2), white) 0 100%;
61
+
62
+ background-repeat: no-repeat;
63
+ background-color: white;
64
+ background-position:
65
+ top left,
66
+ top right,
67
+ top left,
68
+ top right;
69
+ background-size:
70
+ 10px 100%,
71
+ 10px 100%,
72
+ 5px 100%,
73
+ 5px 100%;
74
+ background-attachment: local, local, scroll, scroll;
75
+ }
76
+ </style>