fu-kit 0.7.2 → 1.0.1
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/LICENCE.txt +20 -20
- package/README.md +21 -21
- package/package.json +44 -42
- package/src/components/UiButton.vue +202 -169
- package/src/components/UiButtonLink.vue +74 -74
- package/src/components/UiButtonRoute.vue +79 -0
- package/src/components/UiCheck.vue +206 -206
- package/src/components/UiCodeInput.vue +47 -36
- package/src/components/UiCopy.vue +88 -88
- package/src/components/UiDropdown.vue +109 -109
- package/src/components/UiDropdownItem.vue +66 -66
- package/src/components/UiIcon.vue +29 -29
- package/src/components/UiIconProvider.vue +511 -32
- package/src/components/UiImg.vue +72 -0
- package/src/components/UiModal.vue +103 -103
- package/src/components/UiSelectX.vue +312 -312
- package/src/components/UiSidebar.vue +118 -118
- package/src/components/UiText.vue +121 -121
- package/src/components/UiTextarea.vue +117 -117
- package/src/entry.js +23 -21
- package/src/scss-kit/colors.scss +2 -3
- package/src/scss-kit/media.scss +3 -3
- package/src/scss-kit/pal_dark.scss +6 -6
- package/src/scss-kit/pal_fu.scss +8 -8
- package/src/scss-kit/pal_light.scss +6 -6
- package/src/scss-kit/typo.scss +39 -39
- package/src/scss-kit/typo_default.scss +4 -2
- package/src/scss-kit/ui.scss +49 -49
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
:key="'char' + i"
|
|
21
21
|
:class="{
|
|
22
22
|
'_select': i - 1 >= selection.from && i - 1 < selection.to && selection.from !== selection.to,
|
|
23
|
-
'_cursor': i
|
|
23
|
+
'_cursor': i === selection.to,
|
|
24
|
+
'_cursor_0': selection.from === 0 && selection.to === 0 && i === 1,
|
|
24
25
|
}"
|
|
25
26
|
class="code-input_char"
|
|
26
27
|
>
|
|
@@ -31,37 +32,30 @@
|
|
|
31
32
|
</template>
|
|
32
33
|
|
|
33
34
|
<script>
|
|
34
|
-
import { computed,
|
|
35
|
+
import { computed, reactive, ref } from 'vue'
|
|
35
36
|
|
|
36
37
|
export default {
|
|
37
38
|
name: 'ui-code-input',
|
|
38
39
|
props: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
},
|
|
42
|
-
length: {
|
|
43
|
-
type: Number,
|
|
44
|
-
default: 6,
|
|
45
|
-
},
|
|
40
|
+
type: { type: String, default: 'text' },
|
|
41
|
+
modelValue: { type: String },
|
|
42
|
+
length: { type: Number, default: 4 },
|
|
46
43
|
},
|
|
47
44
|
setup (props, { emit }) {
|
|
48
45
|
const selection = reactive({ from: 0, to: 0 })
|
|
49
46
|
const inp = ref(null)
|
|
50
47
|
|
|
51
48
|
const selectionUpdate = (e) => {
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
requestAnimationFrame(() => {
|
|
50
|
+
selection.from = e.target.selectionStart
|
|
51
|
+
selection.to = e.target.selectionEnd
|
|
52
|
+
})
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
const handleInput = (e) =>
|
|
57
|
-
emit('update:modelValue', e.target.value)
|
|
58
|
-
}
|
|
55
|
+
const handleInput = (e) => emit('update:modelValue', e.target.value)
|
|
59
56
|
|
|
60
57
|
const chars = computed(() => (props.modelValue).split(''))
|
|
61
58
|
|
|
62
|
-
onMounted(() => { })
|
|
63
|
-
onBeforeUnmount(() => { })
|
|
64
|
-
|
|
65
59
|
return { chars, selection, selectionUpdate, inp, handleInput }
|
|
66
60
|
},
|
|
67
61
|
}
|
|
@@ -69,10 +63,8 @@ export default {
|
|
|
69
63
|
|
|
70
64
|
<style lang="scss" scoped>
|
|
71
65
|
.code-input {
|
|
72
|
-
--charbox-width: 34px;
|
|
73
|
-
--chabox-height: 48px;
|
|
74
|
-
|
|
75
66
|
display: flex;
|
|
67
|
+
height: var(--ui-lt-h);
|
|
76
68
|
|
|
77
69
|
&_wrapper {
|
|
78
70
|
position: relative;
|
|
@@ -84,36 +76,50 @@ export default {
|
|
|
84
76
|
}
|
|
85
77
|
|
|
86
78
|
&_inp {
|
|
87
|
-
|
|
79
|
+
--extra-indent: calc((var(--ui-lt-h) + #{spacing(200)}));
|
|
80
|
+
|
|
88
81
|
position: absolute;
|
|
89
|
-
width: 100
|
|
90
|
-
|
|
91
|
-
|
|
82
|
+
width: calc(100% + var(--extra-indent));
|
|
83
|
+
height: 100%;
|
|
84
|
+
border: 0 none;
|
|
92
85
|
font-family: var(--typo-font-mono);
|
|
93
|
-
font-size: var(--typo-
|
|
94
|
-
letter-spacing:
|
|
86
|
+
font-size: var(--typo-font-ui);
|
|
87
|
+
letter-spacing: calc(var(--ui-lt-h) + #{spacing(200)});
|
|
88
|
+
margin-left: calc(var(--extra-indent) / -2);
|
|
95
89
|
outline: none;
|
|
90
|
+
background: transparent;
|
|
96
91
|
opacity: 0;
|
|
92
|
+
padding: 0;
|
|
97
93
|
}
|
|
98
94
|
|
|
99
95
|
&_char {
|
|
100
|
-
width: var(--
|
|
101
|
-
height:
|
|
102
|
-
border:
|
|
96
|
+
width: var(--ui-lt-h);
|
|
97
|
+
height: 100%;
|
|
98
|
+
border-style: var(--ui-lt-border-style);
|
|
99
|
+
border-width: var(--ui-lt-border-width);
|
|
100
|
+
border-color: var(--ui-pal-lateral);
|
|
103
101
|
border-radius: var(--ui-lt-border-radius);
|
|
104
|
-
|
|
102
|
+
background: var(--ui-pal-bg);
|
|
103
|
+
color: var(--ui-pal-text);
|
|
105
104
|
align-items: center;
|
|
106
105
|
justify-content: center;
|
|
107
106
|
display: flex;
|
|
107
|
+
gap: spacing(100);
|
|
108
108
|
|
|
109
109
|
&-item {
|
|
110
|
-
|
|
110
|
+
font-family: var(--typo-font-mono);
|
|
111
|
+
font-size: var(--typo-h300);
|
|
112
|
+
border-width: 0 2px 0 2px;
|
|
111
113
|
border-style: solid;
|
|
112
114
|
border-color: transparent;
|
|
113
115
|
background: transparent;
|
|
114
|
-
min-width: 0.75em;
|
|
115
|
-
min-height: 1.5em;
|
|
116
116
|
text-align: center;
|
|
117
|
+
display: flex;
|
|
118
|
+
align-items: center;
|
|
119
|
+
justify-content: center;
|
|
120
|
+
padding: spacing(200);
|
|
121
|
+
min-width: calc(var(--ui-lt-h) / 2);
|
|
122
|
+
min-height: calc(var(--ui-lt-h) / 2);
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
&._select &-item {
|
|
@@ -121,12 +127,17 @@ export default {
|
|
|
121
127
|
background: var(--pal-primary);
|
|
122
128
|
}
|
|
123
129
|
|
|
124
|
-
input:focus ~ &._cursor
|
|
130
|
+
input:focus ~ &._cursor,
|
|
131
|
+
input:focus ~ &._cursor_0 {
|
|
125
132
|
border-color: var(--ui-pal);
|
|
126
133
|
}
|
|
127
134
|
|
|
128
|
-
input:focus ~ &._cursor &-item {
|
|
129
|
-
border-
|
|
135
|
+
input:focus ~ &._cursor &-item, {
|
|
136
|
+
border-right-color: var(--pal-front);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
input:focus ~ &._cursor_0 &-item {
|
|
140
|
+
border-left-color: var(--pal-front);
|
|
130
141
|
}
|
|
131
142
|
}
|
|
132
143
|
}
|
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<ui-button
|
|
3
|
-
:class="{'_hot': isCopied}"
|
|
4
|
-
:hollow="!isCopied"
|
|
5
|
-
class="ui-copy"
|
|
6
|
-
v-bind="$attrs"
|
|
7
|
-
@click="handleCopyToClipboard"
|
|
8
|
-
>
|
|
9
|
-
<slot />
|
|
10
|
-
</ui-button>
|
|
11
|
-
</template>
|
|
12
|
-
|
|
13
|
-
<script>
|
|
14
|
-
import { defineComponent, onBeforeUnmount, ref } from 'vue'
|
|
15
|
-
import UiButton from './UiButton.vue'
|
|
16
|
-
|
|
17
|
-
export default defineComponent({
|
|
18
|
-
name: 'ui-copy',
|
|
19
|
-
components: { UiButton },
|
|
20
|
-
props: {
|
|
21
|
-
value: { type: [ String, null ], required: true },
|
|
22
|
-
},
|
|
23
|
-
setup (props) {
|
|
24
|
-
const isCopied = ref(false)
|
|
25
|
-
let timeout
|
|
26
|
-
|
|
27
|
-
onBeforeUnmount(() => {
|
|
28
|
-
if (timeout) clearTimeout(timeout)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const handleCopyToClipboard = (event) => {
|
|
32
|
-
if (navigator.clipboard) {
|
|
33
|
-
navigator.clipboard.writeText(props.value)
|
|
34
|
-
} else {
|
|
35
|
-
execCopy()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
isCopied.value = false
|
|
39
|
-
requestAnimationFrame(() => (isCopied.value = true))
|
|
40
|
-
|
|
41
|
-
if (timeout) clearTimeout(timeout)
|
|
42
|
-
timeout = setTimeout(() => isCopied.value = false, 1000)
|
|
43
|
-
|
|
44
|
-
event.target.blur()
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// fallback
|
|
48
|
-
const execCopy = () => {
|
|
49
|
-
const textArea = document.createElement('textarea')
|
|
50
|
-
textArea.value = props.value
|
|
51
|
-
textArea.setAttribute('readonly', '')
|
|
52
|
-
textArea.style.position = 'absolute'
|
|
53
|
-
textArea.style.left = '-9999px'
|
|
54
|
-
document.body.appendChild(textArea)
|
|
55
|
-
textArea.select()
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
document.execCommand('copy')
|
|
59
|
-
} catch (err) {
|
|
60
|
-
console.error(err)
|
|
61
|
-
} finally {
|
|
62
|
-
document.body.removeChild(textArea)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
handleCopyToClipboard,
|
|
68
|
-
isCopied,
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
})
|
|
72
|
-
</script>
|
|
73
|
-
|
|
74
|
-
<style lang="scss" scoped>
|
|
75
|
-
@import "../../scss";
|
|
76
|
-
|
|
77
|
-
.ui-copy {
|
|
78
|
-
padding: spacing(0, 200);
|
|
79
|
-
@include ellipsis();
|
|
80
|
-
|
|
81
|
-
--ui-lt-h: 2em;
|
|
82
|
-
--ui-pal: var(--pal-grey900);
|
|
83
|
-
|
|
84
|
-
&._hot {
|
|
85
|
-
color: var(--pal-positive);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<ui-button
|
|
3
|
+
:class="{'_hot': isCopied}"
|
|
4
|
+
:hollow="!isCopied"
|
|
5
|
+
class="ui-copy"
|
|
6
|
+
v-bind="$attrs"
|
|
7
|
+
@click="handleCopyToClipboard"
|
|
8
|
+
>
|
|
9
|
+
<slot />
|
|
10
|
+
</ui-button>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script>
|
|
14
|
+
import { defineComponent, onBeforeUnmount, ref } from 'vue'
|
|
15
|
+
import UiButton from './UiButton.vue'
|
|
16
|
+
|
|
17
|
+
export default defineComponent({
|
|
18
|
+
name: 'ui-copy',
|
|
19
|
+
components: { UiButton },
|
|
20
|
+
props: {
|
|
21
|
+
value: { type: [ String, null ], required: true },
|
|
22
|
+
},
|
|
23
|
+
setup (props) {
|
|
24
|
+
const isCopied = ref(false)
|
|
25
|
+
let timeout
|
|
26
|
+
|
|
27
|
+
onBeforeUnmount(() => {
|
|
28
|
+
if (timeout) clearTimeout(timeout)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const handleCopyToClipboard = (event) => {
|
|
32
|
+
if (navigator.clipboard) {
|
|
33
|
+
navigator.clipboard.writeText(props.value)
|
|
34
|
+
} else {
|
|
35
|
+
execCopy()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
isCopied.value = false
|
|
39
|
+
requestAnimationFrame(() => (isCopied.value = true))
|
|
40
|
+
|
|
41
|
+
if (timeout) clearTimeout(timeout)
|
|
42
|
+
timeout = setTimeout(() => isCopied.value = false, 1000)
|
|
43
|
+
|
|
44
|
+
event.target.blur()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// fallback
|
|
48
|
+
const execCopy = () => {
|
|
49
|
+
const textArea = document.createElement('textarea')
|
|
50
|
+
textArea.value = props.value
|
|
51
|
+
textArea.setAttribute('readonly', '')
|
|
52
|
+
textArea.style.position = 'absolute'
|
|
53
|
+
textArea.style.left = '-9999px'
|
|
54
|
+
document.body.appendChild(textArea)
|
|
55
|
+
textArea.select()
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
document.execCommand('copy')
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error(err)
|
|
61
|
+
} finally {
|
|
62
|
+
document.body.removeChild(textArea)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
handleCopyToClipboard,
|
|
68
|
+
isCopied,
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<style lang="scss" scoped>
|
|
75
|
+
@import "../../scss";
|
|
76
|
+
|
|
77
|
+
.ui-copy {
|
|
78
|
+
padding: spacing(0, 200);
|
|
79
|
+
@include ellipsis();
|
|
80
|
+
|
|
81
|
+
--ui-lt-h: 2em;
|
|
82
|
+
--ui-pal: var(--pal-grey900);
|
|
83
|
+
|
|
84
|
+
&._hot {
|
|
85
|
+
color: var(--pal-positive);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
</style>
|
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div
|
|
3
|
-
v-click-away="isOpen && handleClickaway"
|
|
4
|
-
:class="{ '_is-open': !disabled && isOpen }"
|
|
5
|
-
class="ui-dropdown"
|
|
6
|
-
>
|
|
7
|
-
<div class="ui-dropdown_trigger" @click="toggle">
|
|
8
|
-
<slot :isOpen="!disabled && isOpen" />
|
|
9
|
-
</div>
|
|
10
|
-
|
|
11
|
-
<div v-if="!disabled && isOpen" ref="slotWrap" :class="{ _right: snapToRight }" class="ui-dropdown_content">
|
|
12
|
-
<slot :dropdownClose="close" name="content" />
|
|
13
|
-
</div>
|
|
14
|
-
</div>
|
|
15
|
-
</template>
|
|
16
|
-
|
|
17
|
-
<script>
|
|
18
|
-
// todo: rewrite to composition
|
|
19
|
-
|
|
20
|
-
import { directive as clickAway } from 'vue3-click-away'
|
|
21
|
-
|
|
22
|
-
import { defineComponent } from 'vue'
|
|
23
|
-
|
|
24
|
-
export default defineComponent({
|
|
25
|
-
name: 'ui-dropdown',
|
|
26
|
-
directives: { clickAway },
|
|
27
|
-
props: {
|
|
28
|
-
clickaway: { type: Boolean, default: true },
|
|
29
|
-
snapToRight: { type: Boolean, default: false },
|
|
30
|
-
disabled: { type: Boolean, default: false },
|
|
31
|
-
},
|
|
32
|
-
emits: [ 'open', 'close' ],
|
|
33
|
-
data () {
|
|
34
|
-
return {
|
|
35
|
-
isOpen: false,
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
watch: {
|
|
40
|
-
isOpen (value) {
|
|
41
|
-
this.$emit(value ? 'open' : 'close')
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
methods: {
|
|
46
|
-
handleClickaway (e) {
|
|
47
|
-
/* v-on-click-outside don't recognize slots */
|
|
48
|
-
const path = e.path || (e.composedPath && e.composedPath())
|
|
49
|
-
if (path.includes(this.$refs.slotWrap)) return
|
|
50
|
-
|
|
51
|
-
if (this.clickaway && this.isOpen) {
|
|
52
|
-
this.toggle()
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
toggle () {
|
|
56
|
-
if (this.disabled) return
|
|
57
|
-
this.isOpen = !this.isOpen
|
|
58
|
-
},
|
|
59
|
-
close () {
|
|
60
|
-
this.isOpen = false
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
})
|
|
64
|
-
</script>
|
|
65
|
-
|
|
66
|
-
<style lang="scss" scoped>
|
|
67
|
-
@import "../../scss";
|
|
68
|
-
|
|
69
|
-
.ui-dropdown {
|
|
70
|
-
@include typo(200);
|
|
71
|
-
|
|
72
|
-
padding: 0;
|
|
73
|
-
box-sizing: border-box;
|
|
74
|
-
position: relative;
|
|
75
|
-
|
|
76
|
-
&_trigger {
|
|
77
|
-
display: flex;
|
|
78
|
-
align-items: center;
|
|
79
|
-
justify-content: stretch;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
&_content {
|
|
83
|
-
@include scrollbar-awesome();
|
|
84
|
-
|
|
85
|
-
overflow: auto;
|
|
86
|
-
min-width: 100%;
|
|
87
|
-
max-width: 100vw;
|
|
88
|
-
max-height: var(--ui-dropdown-max-height);
|
|
89
|
-
flex-direction: column;
|
|
90
|
-
justify-content: stretch;
|
|
91
|
-
border-radius: var(--ui-lt-border-radius);
|
|
92
|
-
position: absolute;
|
|
93
|
-
top: 100%;
|
|
94
|
-
background: var(--ui-pal-bg);
|
|
95
|
-
margin-top: spacing(200);
|
|
96
|
-
z-index: var(--lt-z-pop);
|
|
97
|
-
background: var(--pal-bg);
|
|
98
|
-
box-shadow: 0 3px 11px rgba(var(--rgb-front), 0.2);
|
|
99
|
-
|
|
100
|
-
&:not(._right) {
|
|
101
|
-
left: 0;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
&._right {
|
|
105
|
-
right: 0;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
v-click-away="isOpen && handleClickaway"
|
|
4
|
+
:class="{ '_is-open': !disabled && isOpen }"
|
|
5
|
+
class="ui-dropdown"
|
|
6
|
+
>
|
|
7
|
+
<div class="ui-dropdown_trigger" @click="toggle">
|
|
8
|
+
<slot :isOpen="!disabled && isOpen" />
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div v-if="!disabled && isOpen" ref="slotWrap" :class="{ _right: snapToRight }" class="ui-dropdown_content">
|
|
12
|
+
<slot :dropdownClose="close" name="content" />
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script>
|
|
18
|
+
// todo: rewrite to composition
|
|
19
|
+
|
|
20
|
+
import { directive as clickAway } from 'vue3-click-away'
|
|
21
|
+
|
|
22
|
+
import { defineComponent } from 'vue'
|
|
23
|
+
|
|
24
|
+
export default defineComponent({
|
|
25
|
+
name: 'ui-dropdown',
|
|
26
|
+
directives: { clickAway },
|
|
27
|
+
props: {
|
|
28
|
+
clickaway: { type: Boolean, default: true },
|
|
29
|
+
snapToRight: { type: Boolean, default: false },
|
|
30
|
+
disabled: { type: Boolean, default: false },
|
|
31
|
+
},
|
|
32
|
+
emits: [ 'open', 'close' ],
|
|
33
|
+
data () {
|
|
34
|
+
return {
|
|
35
|
+
isOpen: false,
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
watch: {
|
|
40
|
+
isOpen (value) {
|
|
41
|
+
this.$emit(value ? 'open' : 'close')
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
methods: {
|
|
46
|
+
handleClickaway (e) {
|
|
47
|
+
/* v-on-click-outside don't recognize slots */
|
|
48
|
+
const path = e.path || (e.composedPath && e.composedPath())
|
|
49
|
+
if (path.includes(this.$refs.slotWrap)) return
|
|
50
|
+
|
|
51
|
+
if (this.clickaway && this.isOpen) {
|
|
52
|
+
this.toggle()
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
toggle () {
|
|
56
|
+
if (this.disabled) return
|
|
57
|
+
this.isOpen = !this.isOpen
|
|
58
|
+
},
|
|
59
|
+
close () {
|
|
60
|
+
this.isOpen = false
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<style lang="scss" scoped>
|
|
67
|
+
@import "../../scss";
|
|
68
|
+
|
|
69
|
+
.ui-dropdown {
|
|
70
|
+
@include typo(200);
|
|
71
|
+
|
|
72
|
+
padding: 0;
|
|
73
|
+
box-sizing: border-box;
|
|
74
|
+
position: relative;
|
|
75
|
+
|
|
76
|
+
&_trigger {
|
|
77
|
+
display: flex;
|
|
78
|
+
align-items: center;
|
|
79
|
+
justify-content: stretch;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&_content {
|
|
83
|
+
@include scrollbar-awesome();
|
|
84
|
+
|
|
85
|
+
overflow: auto;
|
|
86
|
+
min-width: 100%;
|
|
87
|
+
max-width: 100vw;
|
|
88
|
+
max-height: var(--ui-dropdown-max-height);
|
|
89
|
+
flex-direction: column;
|
|
90
|
+
justify-content: stretch;
|
|
91
|
+
border-radius: var(--ui-lt-border-radius);
|
|
92
|
+
position: absolute;
|
|
93
|
+
top: 100%;
|
|
94
|
+
background: var(--ui-pal-bg);
|
|
95
|
+
margin-top: spacing(200);
|
|
96
|
+
z-index: var(--lt-z-pop);
|
|
97
|
+
background: var(--pal-bg);
|
|
98
|
+
box-shadow: 0 3px 11px rgba(var(--rgb-front), 0.2);
|
|
99
|
+
|
|
100
|
+
&:not(._right) {
|
|
101
|
+
left: 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
&._right {
|
|
105
|
+
right: 0;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
</style>
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div
|
|
3
|
-
:class="{
|
|
4
|
-
'_interactive': interactive || autoClose,
|
|
5
|
-
'_active': active,
|
|
6
|
-
}"
|
|
7
|
-
class="ui-dropdown-item"
|
|
8
|
-
@click="handleClick"
|
|
9
|
-
>
|
|
10
|
-
<slot />
|
|
11
|
-
</div>
|
|
12
|
-
</template>
|
|
13
|
-
|
|
14
|
-
<script>
|
|
15
|
-
import { defineComponent } from 'vue'
|
|
16
|
-
|
|
17
|
-
export default defineComponent({
|
|
18
|
-
name: 'ui-dropdown-item',
|
|
19
|
-
props: {
|
|
20
|
-
autoClose: { type: Boolean, default: false },
|
|
21
|
-
interactive: { type: Boolean, default: false },
|
|
22
|
-
active: { type: Boolean, default: false },
|
|
23
|
-
look: { type: [ String ], default: 'default' },
|
|
24
|
-
},
|
|
25
|
-
methods: {
|
|
26
|
-
handleClick () {
|
|
27
|
-
if (this.autoClose) {
|
|
28
|
-
this.$parent.close()
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
})
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<style lang="scss" scoped>
|
|
36
|
-
@import "../../scss";
|
|
37
|
-
|
|
38
|
-
.ui-dropdown-item {
|
|
39
|
-
padding: spacing(200) spacing(400);
|
|
40
|
-
display: flex;
|
|
41
|
-
align-items: center;
|
|
42
|
-
min-height: var(--ui-lt-h);
|
|
43
|
-
|
|
44
|
-
&._interactive {
|
|
45
|
-
color: var(--ui-pal-text);
|
|
46
|
-
cursor: pointer;
|
|
47
|
-
|
|
48
|
-
&:hover {
|
|
49
|
-
color: var(--ui-pal);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
&:focus,
|
|
53
|
-
&:active {
|
|
54
|
-
outline: none;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
&._active {
|
|
59
|
-
outline: none;
|
|
60
|
-
color: var(--ui-pal);
|
|
61
|
-
|
|
62
|
-
&:hover {
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="{
|
|
4
|
+
'_interactive': interactive || autoClose,
|
|
5
|
+
'_active': active,
|
|
6
|
+
}"
|
|
7
|
+
class="ui-dropdown-item"
|
|
8
|
+
@click="handleClick"
|
|
9
|
+
>
|
|
10
|
+
<slot />
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
import { defineComponent } from 'vue'
|
|
16
|
+
|
|
17
|
+
export default defineComponent({
|
|
18
|
+
name: 'ui-dropdown-item',
|
|
19
|
+
props: {
|
|
20
|
+
autoClose: { type: Boolean, default: false },
|
|
21
|
+
interactive: { type: Boolean, default: false },
|
|
22
|
+
active: { type: Boolean, default: false },
|
|
23
|
+
look: { type: [ String ], default: 'default' },
|
|
24
|
+
},
|
|
25
|
+
methods: {
|
|
26
|
+
handleClick () {
|
|
27
|
+
if (this.autoClose) {
|
|
28
|
+
this.$parent.close()
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<style lang="scss" scoped>
|
|
36
|
+
@import "../../scss";
|
|
37
|
+
|
|
38
|
+
.ui-dropdown-item {
|
|
39
|
+
padding: spacing(200) spacing(400);
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
min-height: var(--ui-lt-h);
|
|
43
|
+
|
|
44
|
+
&._interactive {
|
|
45
|
+
color: var(--ui-pal-text);
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
|
|
48
|
+
&:hover {
|
|
49
|
+
color: var(--ui-pal);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&:focus,
|
|
53
|
+
&:active {
|
|
54
|
+
outline: none;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&._active {
|
|
59
|
+
outline: none;
|
|
60
|
+
color: var(--ui-pal);
|
|
61
|
+
|
|
62
|
+
&:hover {
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
</style>
|