its_ui_vite 1.0.14 → 1.0.16
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/README.md +2 -0
- package/package.json +1 -1
- package/src/assets/js/helpers.js +10 -6
- package/src/components/CCheckbox.vue +26 -2
- package/src/components/CDatepicker.vue +62 -14
- package/src/components/CScroll.vue +4 -2
- package/src/components/CSelect.vue +17 -1
- package/src/components/CTooltip.vue +18 -2
- package/src/pages/index.vue +11 -2
package/README.md
CHANGED
|
@@ -140,6 +140,7 @@ slots: ['customIcon' <!-- есть дефольное значение -->]
|
|
|
140
140
|
min?: string,
|
|
141
141
|
width?: string,
|
|
142
142
|
isOpen?: boolean,
|
|
143
|
+
isTooltip?: boolean,
|
|
143
144
|
modelValue?: any,
|
|
144
145
|
}
|
|
145
146
|
|
|
@@ -152,6 +153,7 @@ slots: ['customIcon' <!-- есть дефольное значение -->]
|
|
|
152
153
|
{
|
|
153
154
|
position?: 'top' | 'top_left' | 'top_right' | 'bottom' | 'bottom_left' | 'bottom_right',
|
|
154
155
|
interactive?: Boolean,
|
|
156
|
+
disabled?: boolean,
|
|
155
157
|
}
|
|
156
158
|
|
|
157
159
|
slots: ['icon' <!-- есть дефольное значение -->, 'content']
|
package/package.json
CHANGED
package/src/assets/js/helpers.js
CHANGED
|
@@ -59,6 +59,8 @@ export function addTracingElement(target, moveFn = () => {}) {
|
|
|
59
59
|
let timer
|
|
60
60
|
let debounceTimer
|
|
61
61
|
|
|
62
|
+
const handlesEvents = ['mousemove', 'wheel', 'load', 'fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'msfullscreenchange']
|
|
63
|
+
|
|
62
64
|
function isVisible(position) {
|
|
63
65
|
if (!position) return false
|
|
64
66
|
|
|
@@ -108,16 +110,18 @@ export function addTracingElement(target, moveFn = () => {}) {
|
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
function addListeners() {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
handlesEvents.forEach((eventName) => {
|
|
114
|
+
const handleRoot = eventName === 'load' ? window : document.body
|
|
115
|
+
handleRoot.addEventListener(eventName, targetMoveHandler)
|
|
116
|
+
})
|
|
114
117
|
targetMoveHandler()
|
|
115
118
|
}
|
|
116
119
|
|
|
117
120
|
function removeListeners() {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
handlesEvents.forEach((eventName) => {
|
|
122
|
+
const handleRoot = eventName === 'load' ? window : document.body
|
|
123
|
+
handleRoot.removeEventListener(eventName, targetMoveHandler)
|
|
124
|
+
})
|
|
121
125
|
}
|
|
122
126
|
|
|
123
127
|
return {
|
|
@@ -100,11 +100,36 @@ const isRadio = props.variant === 'radio'
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
&.radio {
|
|
103
|
+
.c-checkbox__inp:checked:not(:disabled) ~ .c-checkbox__checkmark {
|
|
104
|
+
&::before {
|
|
105
|
+
display: flex;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
103
109
|
.c-checkbox__checkmark {
|
|
104
110
|
border-radius: 50%;
|
|
105
111
|
|
|
112
|
+
&::before {
|
|
113
|
+
content: '';
|
|
114
|
+
position: absolute;
|
|
115
|
+
z-index: 1;
|
|
116
|
+
|
|
117
|
+
left: 50%;
|
|
118
|
+
top: 50%;
|
|
119
|
+
transform: translate(-50%, -50%);
|
|
120
|
+
|
|
121
|
+
display: none;
|
|
122
|
+
|
|
123
|
+
width: 10px;
|
|
124
|
+
height: 10px;
|
|
125
|
+
|
|
126
|
+
border-radius: 50%;
|
|
127
|
+
|
|
128
|
+
background: var(--white);
|
|
129
|
+
}
|
|
130
|
+
|
|
106
131
|
&::after{
|
|
107
|
-
background: var(--green-light)
|
|
132
|
+
background: var(--green-light);
|
|
108
133
|
}
|
|
109
134
|
}
|
|
110
135
|
}
|
|
@@ -129,7 +154,6 @@ const isRadio = props.variant === 'radio'
|
|
|
129
154
|
border-radius: var(--size);
|
|
130
155
|
|
|
131
156
|
background: var(--black-dark);
|
|
132
|
-
|
|
133
157
|
|
|
134
158
|
&::after {
|
|
135
159
|
position: absolute;
|
|
@@ -18,7 +18,17 @@
|
|
|
18
18
|
:disabled="true"
|
|
19
19
|
>
|
|
20
20
|
<template #customIcon>
|
|
21
|
-
<
|
|
21
|
+
<CTooltip
|
|
22
|
+
v-if="isTooltip"
|
|
23
|
+
>
|
|
24
|
+
<template #icon>
|
|
25
|
+
<CIcon :name="{'calendar-month-outline': true}" :size="24" />
|
|
26
|
+
</template>
|
|
27
|
+
<template #content>
|
|
28
|
+
<slot></slot>
|
|
29
|
+
</template>
|
|
30
|
+
</CTooltip>
|
|
31
|
+
<CIcon v-else :name="{'calendar-month-outline': true}" :size="24" />
|
|
22
32
|
</template>
|
|
23
33
|
</CInput>
|
|
24
34
|
</div>
|
|
@@ -50,7 +60,7 @@
|
|
|
50
60
|
@blur="isOpenTime = false"
|
|
51
61
|
/>
|
|
52
62
|
</div>
|
|
53
|
-
<Teleport to="
|
|
63
|
+
<Teleport :to="teleportTo">
|
|
54
64
|
<div
|
|
55
65
|
class="c-datepicker__hours_list-wrap"
|
|
56
66
|
ref="timeContent"
|
|
@@ -66,7 +76,11 @@
|
|
|
66
76
|
<button
|
|
67
77
|
v-for="item in hoursOptions"
|
|
68
78
|
:key="item.value"
|
|
69
|
-
:class="['c-datepicker__hours_btn', {
|
|
79
|
+
:class="['c-datepicker__hours_btn', {
|
|
80
|
+
disable: isDisableTime('hour', item.value),
|
|
81
|
+
active: item.text === modelHour
|
|
82
|
+
}]"
|
|
83
|
+
|
|
70
84
|
@click="setTime('hour', item.text)"
|
|
71
85
|
>
|
|
72
86
|
{{ item.text }}
|
|
@@ -77,7 +91,11 @@
|
|
|
77
91
|
<button
|
|
78
92
|
v-for="item in minuteOptions"
|
|
79
93
|
:key="item.value"
|
|
80
|
-
:class="['c-datepicker__hours_btn', {
|
|
94
|
+
:class="['c-datepicker__hours_btn', {
|
|
95
|
+
disable: isDisableTime('minute', item.value),
|
|
96
|
+
active: item.text === modelMinute
|
|
97
|
+
}]"
|
|
98
|
+
|
|
81
99
|
@click="setTime('minute', item.text)"
|
|
82
100
|
>
|
|
83
101
|
{{ item.text }}
|
|
@@ -89,7 +107,7 @@
|
|
|
89
107
|
</Teleport>
|
|
90
108
|
</div>
|
|
91
109
|
|
|
92
|
-
<Teleport to="
|
|
110
|
+
<Teleport :to="teleportTo">
|
|
93
111
|
<div
|
|
94
112
|
:style="pickerContentStyle"
|
|
95
113
|
:class="['c-datepicker__content_wrap', { open: isOpenPicker }]"
|
|
@@ -178,6 +196,7 @@ import CSelect from './CSelect.vue';
|
|
|
178
196
|
import CInput from './CInput.vue';
|
|
179
197
|
import CButton from './CButton.vue';
|
|
180
198
|
import CScroll from './CScroll.vue';
|
|
199
|
+
import CTooltip from './CTooltip.vue';
|
|
181
200
|
|
|
182
201
|
import { addTracingElement } from '../assets/js/helpers';
|
|
183
202
|
import { computed, ref, watch, onMounted, onUnmounted, Teleport } from 'vue';
|
|
@@ -190,6 +209,7 @@ type TProps = {
|
|
|
190
209
|
width?: string,
|
|
191
210
|
isOpen?: boolean,
|
|
192
211
|
modelValue?: any,
|
|
212
|
+
isTooltip?: boolean,
|
|
193
213
|
}
|
|
194
214
|
|
|
195
215
|
const props = withDefaults(defineProps<TProps>(), {
|
|
@@ -253,6 +273,10 @@ let timeStyle = ref({
|
|
|
253
273
|
height: '34px'
|
|
254
274
|
});
|
|
255
275
|
|
|
276
|
+
let teleportTo = ref<Element | 'body'>('body');
|
|
277
|
+
|
|
278
|
+
const fullscreenEvents = ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'msfullscreenchange'];
|
|
279
|
+
|
|
256
280
|
const TracingElement = addTracingElement(root, handlePicker);
|
|
257
281
|
const TracingTime = addTracingElement(time, handleTime);
|
|
258
282
|
|
|
@@ -283,13 +307,21 @@ onMounted(() => {
|
|
|
283
307
|
TracingTime.addListeners();
|
|
284
308
|
document.body.addEventListener('click', handleClickPicker);
|
|
285
309
|
document.body.addEventListener('click', handleClickTime);
|
|
310
|
+
|
|
311
|
+
fullscreenEvents.forEach((eventName) => {
|
|
312
|
+
document.addEventListener(eventName, setTeleportTo);
|
|
313
|
+
});
|
|
286
314
|
});
|
|
287
315
|
|
|
288
316
|
onUnmounted(() => {
|
|
289
317
|
TracingElement.removeListeners();
|
|
290
318
|
TracingTime.removeListeners();
|
|
291
|
-
document.body.removeEventListener('click', handleClickPicker)
|
|
319
|
+
document.body.removeEventListener('click', handleClickPicker);
|
|
292
320
|
document.body.removeEventListener('click', handleClickTime);
|
|
321
|
+
|
|
322
|
+
fullscreenEvents.forEach((eventName) => {
|
|
323
|
+
document.removeEventListener(eventName, setTeleportTo);
|
|
324
|
+
});
|
|
293
325
|
});
|
|
294
326
|
|
|
295
327
|
const emit = defineEmits<{
|
|
@@ -483,6 +515,10 @@ function handleTime(positionInfo?: any) {
|
|
|
483
515
|
isOpenTime.value = false;
|
|
484
516
|
}
|
|
485
517
|
|
|
518
|
+
function setTeleportTo() {
|
|
519
|
+
teleportTo.value = document.fullscreenElement || 'body';
|
|
520
|
+
}
|
|
521
|
+
|
|
486
522
|
function setPickerContentPosition() {
|
|
487
523
|
const windowHeight = window.innerHeight;
|
|
488
524
|
const inputHeight = root.value.clientHeight;
|
|
@@ -543,15 +579,10 @@ function isDisableDay(ISO: string): boolean {
|
|
|
543
579
|
function setTime(name: 'hour' | 'minute', value: string) {
|
|
544
580
|
const numValue = value.replace(/[^0-9]/g, '');
|
|
545
581
|
|
|
546
|
-
|
|
547
|
-
let max = 59;
|
|
582
|
+
const format = name === 'hour' ? 'HH' : 'mm';
|
|
548
583
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
552
|
-
if (name === 'minute') {
|
|
553
|
-
max = 59;
|
|
554
|
-
}
|
|
584
|
+
let min = props?.min ? +DateTime.fromISO(props?.min)?.toFormat(format) : 0;
|
|
585
|
+
let max = props?.max ? +DateTime.fromISO(props?.max)?.toFormat(format) : (name === 'hour' ? 23 : 59);
|
|
555
586
|
|
|
556
587
|
const validValue = Math.min(Math.max(min, +numValue), max);
|
|
557
588
|
const strValue = getTimeStr(validValue);
|
|
@@ -570,6 +601,15 @@ function getTimeStr(value: number) {
|
|
|
570
601
|
return `0${value}`.match(/.{2}$/)?.[0] || '00'
|
|
571
602
|
}
|
|
572
603
|
|
|
604
|
+
function isDisableTime(name: 'hour' | 'minute', value: number) {
|
|
605
|
+
const format = name === 'hour' ? 'HH' : 'mm';
|
|
606
|
+
|
|
607
|
+
const max = props?.max ? +DateTime.fromISO(props?.max)?.toFormat(format) : 99;
|
|
608
|
+
const min = props?.min ? +DateTime.fromISO(props?.min)?.toFormat(format) : -1;
|
|
609
|
+
|
|
610
|
+
return max < value || min > value
|
|
611
|
+
}
|
|
612
|
+
|
|
573
613
|
function setIsOpen(value: boolean) {
|
|
574
614
|
isOpenPicker.value = value;
|
|
575
615
|
setOldDate(value);
|
|
@@ -699,6 +739,9 @@ $timeWidth: 54px;
|
|
|
699
739
|
|
|
700
740
|
.c-input__custom-icon {
|
|
701
741
|
opacity: 1;
|
|
742
|
+
pointer-events: all;
|
|
743
|
+
|
|
744
|
+
z-index: 1;
|
|
702
745
|
|
|
703
746
|
svg path {
|
|
704
747
|
transition: var(--transition);
|
|
@@ -871,6 +914,11 @@ $timeWidth: 54px;
|
|
|
871
914
|
&:hover {
|
|
872
915
|
color: var(--green-light);
|
|
873
916
|
}
|
|
917
|
+
|
|
918
|
+
&.disable {
|
|
919
|
+
opacity: 0.6;
|
|
920
|
+
pointer-events: none;
|
|
921
|
+
}
|
|
874
922
|
}
|
|
875
923
|
}
|
|
876
924
|
}
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
:options="{
|
|
4
4
|
scrollYMarginOffset
|
|
5
5
|
}"
|
|
6
|
+
ref="root"
|
|
6
7
|
:class="['c-scroll', CClasses.scrollContainer]"
|
|
8
|
+
@ps-y-reach-end="handleMaxScroll"
|
|
7
9
|
>
|
|
8
10
|
<div class="c-scroll__content">
|
|
9
11
|
<slot><div class=""></div></slot>
|
|
@@ -26,7 +28,7 @@ export default {
|
|
|
26
28
|
data() {
|
|
27
29
|
return {
|
|
28
30
|
scrollYMarginOffset: 0,
|
|
29
|
-
CClasses
|
|
31
|
+
CClasses,
|
|
30
32
|
}
|
|
31
33
|
},
|
|
32
34
|
|
|
@@ -40,7 +42,7 @@ export default {
|
|
|
40
42
|
|
|
41
43
|
methods: {
|
|
42
44
|
handleMaxScroll(direction) {
|
|
43
|
-
|
|
45
|
+
this.$refs.root.ps.update();
|
|
44
46
|
}
|
|
45
47
|
},
|
|
46
48
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
</slot>
|
|
21
21
|
</template>
|
|
22
22
|
</CInput>
|
|
23
|
-
<Teleport to="
|
|
23
|
+
<Teleport :to="teleportTo">
|
|
24
24
|
<div
|
|
25
25
|
:data-c-select-id="selectId"
|
|
26
26
|
:style="listStyle"
|
|
@@ -145,6 +145,8 @@ let findValue = ref(''),
|
|
|
145
145
|
activeOptions = ref(new Set<TOption>()),
|
|
146
146
|
oldActiveOptions = ref(new Set<TOption>())
|
|
147
147
|
|
|
148
|
+
let teleportTo = ref<Element | 'body'>('body')
|
|
149
|
+
|
|
148
150
|
let listStyle = ref({
|
|
149
151
|
left: '0px',
|
|
150
152
|
top: '0px',
|
|
@@ -165,6 +167,8 @@ const classes = {
|
|
|
165
167
|
fixedContainer: 'c-select__fixed-container',
|
|
166
168
|
}
|
|
167
169
|
|
|
170
|
+
const fullscreenEvents = ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'msfullscreenchange']
|
|
171
|
+
|
|
168
172
|
const TracingElement = addTracingElement(root, handleMove)
|
|
169
173
|
|
|
170
174
|
const text = computed(() => {
|
|
@@ -252,11 +256,19 @@ onMounted(() => {
|
|
|
252
256
|
TracingElement.addListeners()
|
|
253
257
|
document.body.addEventListener('click', handleClick)
|
|
254
258
|
if (!isMultiple.value && props.autocomplete) debounceEvent(props.options[0]);
|
|
259
|
+
|
|
260
|
+
fullscreenEvents.forEach((eventName) => {
|
|
261
|
+
document.addEventListener(eventName, setTeleportTo)
|
|
262
|
+
})
|
|
255
263
|
})
|
|
256
264
|
|
|
257
265
|
onUnmounted(() => {
|
|
258
266
|
TracingElement.removeListeners()
|
|
259
267
|
document.body.removeEventListener('click', handleClick)
|
|
268
|
+
|
|
269
|
+
fullscreenEvents.forEach((eventName) => {
|
|
270
|
+
document.removeEventListener(eventName, setTeleportTo)
|
|
271
|
+
})
|
|
260
272
|
})
|
|
261
273
|
|
|
262
274
|
function handleMove(positionInfo?: any) {
|
|
@@ -271,6 +283,10 @@ function handleMove(positionInfo?: any) {
|
|
|
271
283
|
isOpen.value = false
|
|
272
284
|
}
|
|
273
285
|
|
|
286
|
+
function setTeleportTo() {
|
|
287
|
+
teleportTo.value = document.fullscreenElement || 'body'
|
|
288
|
+
}
|
|
289
|
+
|
|
274
290
|
const handleOption: TDebounceEvent = function(option, evt) {
|
|
275
291
|
if (isSelectAll.value && evt) setAllOption(evt)
|
|
276
292
|
setOption(option, evt);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<CIcons iconId="question" />
|
|
6
6
|
</slot>
|
|
7
7
|
</div>
|
|
8
|
-
<Teleport to="
|
|
8
|
+
<Teleport v-if="!disabled" :to="teleportTo">
|
|
9
9
|
<div
|
|
10
10
|
:class="[classes.fixedContainer, position, {interactive: false}, {open: isOpen.click || isOpen.hover}]"
|
|
11
11
|
:style="tooltipPosition"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
</template>
|
|
23
23
|
|
|
24
24
|
<script setup lang="ts">
|
|
25
|
-
import { ref, onMounted, onUnmounted, Teleport } from 'vue'
|
|
25
|
+
import { ref, onMounted, onUnmounted, Teleport, computed } from 'vue'
|
|
26
26
|
|
|
27
27
|
import CIcons from './CIcons/index.vue'
|
|
28
28
|
import { addTracingElement } from '../assets/js/helpers'
|
|
@@ -30,11 +30,13 @@ import { addTracingElement } from '../assets/js/helpers'
|
|
|
30
30
|
type TProps = {
|
|
31
31
|
position?: 'top' | 'top_left' | 'top_right' | 'bottom' | 'bottom_left' | 'bottom_right' | 'right' | 'left',
|
|
32
32
|
interactive?: boolean,
|
|
33
|
+
disabled?: boolean,
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
const props = withDefaults(defineProps<TProps>(), {
|
|
36
37
|
position: 'top',
|
|
37
38
|
interactive: true,
|
|
39
|
+
disabled: false,
|
|
38
40
|
});
|
|
39
41
|
|
|
40
42
|
let icon = ref()
|
|
@@ -43,6 +45,8 @@ let isOpen = ref({
|
|
|
43
45
|
hover: false,
|
|
44
46
|
})
|
|
45
47
|
|
|
48
|
+
let teleportTo = ref<Element | 'body'>('body')
|
|
49
|
+
|
|
46
50
|
let tooltipPosition = ref({
|
|
47
51
|
left: '0px',
|
|
48
52
|
top: '0px',
|
|
@@ -57,16 +61,24 @@ const classes = {
|
|
|
57
61
|
fixedContainer: 'c-tooltip__fixed-container'
|
|
58
62
|
}
|
|
59
63
|
|
|
64
|
+
const fullscreenEvents = ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'msfullscreenchange'];
|
|
65
|
+
|
|
60
66
|
const TracingElement = addTracingElement(icon, handleMove)
|
|
61
67
|
|
|
62
68
|
onMounted(() => {
|
|
63
69
|
addListener()
|
|
64
70
|
TracingElement.addListeners()
|
|
71
|
+
fullscreenEvents.forEach((eventName) => {
|
|
72
|
+
document.addEventListener(eventName, setTeleportTo)
|
|
73
|
+
})
|
|
65
74
|
})
|
|
66
75
|
|
|
67
76
|
onUnmounted(() => {
|
|
68
77
|
removeListener()
|
|
69
78
|
TracingElement.removeListeners()
|
|
79
|
+
fullscreenEvents.forEach((eventName) => {
|
|
80
|
+
document.removeEventListener(eventName, setTeleportTo)
|
|
81
|
+
})
|
|
70
82
|
})
|
|
71
83
|
|
|
72
84
|
function handleMove(positionInfo?: any) {
|
|
@@ -80,6 +92,10 @@ function handleMove(positionInfo?: any) {
|
|
|
80
92
|
isOpen.value.click = false
|
|
81
93
|
}
|
|
82
94
|
|
|
95
|
+
function setTeleportTo() {
|
|
96
|
+
teleportTo.value = document.fullscreenElement || 'body'
|
|
97
|
+
}
|
|
98
|
+
|
|
83
99
|
function handleMouseover(evt: MouseEvent){
|
|
84
100
|
const target = (evt.target as HTMLElement);
|
|
85
101
|
const tooltipTarget = target.closest(`.${classes.icon}`)
|
package/src/pages/index.vue
CHANGED
|
@@ -656,7 +656,9 @@
|
|
|
656
656
|
<!-- col -->
|
|
657
657
|
<div class="table__col checkboxes">
|
|
658
658
|
<div class="table__item">
|
|
659
|
-
<CDatepicker @change_cdatepicker="(e) => console.log(e)"
|
|
659
|
+
<CDatepicker :is-tooltip="true" @change_cdatepicker="(e) => console.log(e)">
|
|
660
|
+
text
|
|
661
|
+
</CDatepicker>
|
|
660
662
|
</div>
|
|
661
663
|
</div>
|
|
662
664
|
<!-- ./col -->
|
|
@@ -824,7 +826,13 @@
|
|
|
824
826
|
<!-- col -->
|
|
825
827
|
<div class="table__col">
|
|
826
828
|
<div class="table__item">
|
|
827
|
-
<
|
|
829
|
+
<CCheckbox v-model="isDisabledTooltip">
|
|
830
|
+
is disabled tooltip: {{ isDisabledTooltip }}
|
|
831
|
+
</CCheckbox>
|
|
832
|
+
</div>
|
|
833
|
+
|
|
834
|
+
<div class="table__item">
|
|
835
|
+
<CTooltip :disabled="isDisabledTooltip" style="white-space: nowrap;">
|
|
828
836
|
<template #content>
|
|
829
837
|
Text helper
|
|
830
838
|
</template>
|
|
@@ -1004,6 +1012,7 @@ export default {
|
|
|
1004
1012
|
|
|
1005
1013
|
isToggleTabs: true,
|
|
1006
1014
|
selectIsOpen: false,
|
|
1015
|
+
isDisabledTooltip: false,
|
|
1007
1016
|
|
|
1008
1017
|
option: [
|
|
1009
1018
|
{
|