fu-kit 0.5.0 → 0.6.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/package.json +7 -3
- package/reset.scss +81 -71
- package/root.scss +29 -21
- package/src/components/{FuButton.vue → UiButton.vue} +70 -9
- package/src/components/{FuButtonLink.vue → UiButtonLink.vue} +9 -10
- package/src/components/UiCheck.vue +206 -0
- package/src/components/UiCodeInput.vue +133 -0
- package/src/components/{FuCodeView.vue → UiCodeView.vue} +62 -62
- package/src/components/{FuCopy.vue → UiCopy.vue} +14 -35
- package/src/components/{FuDropdown.vue → UiDropdown.vue} +21 -15
- package/src/components/{FuDropdownItem.vue → UiDropdownItem.vue} +6 -19
- package/src/components/UiIcon.vue +29 -0
- package/src/components/UiIconProvider.vue +45 -0
- package/src/components/{FuModal.vue → UiModal.vue} +36 -18
- package/src/components/{FuProgressRadial.vue → UiProgressRadial.vue} +120 -120
- package/src/components/{FuSelect.vue → UiSelect.vue} +89 -89
- package/src/components/{FuSelectX.vue → UiSelectX.vue} +30 -32
- package/src/components/{FuSidebar.vue → UiSidebar.vue} +38 -9
- package/src/components/{FuText.vue → UiText.vue} +27 -9
- package/src/components/{FuTextarea.vue → UiTextarea.vue} +13 -11
- package/src/entry.js +14 -14
- package/src/scss-kit/typo.scss +3 -11
- package/src/scss-kit/ui.scss +1 -3
- package/src/components/FuCheck.vue +0 -138
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<label class="
|
|
2
|
+
<label v-click-away="onClickAway" class="ui-select-x" v-bind="$attrs">
|
|
3
3
|
<input
|
|
4
|
-
tabindex="0"
|
|
5
|
-
class="fu-select-x_input"
|
|
6
4
|
ref="refSearch"
|
|
7
5
|
v-model="search"
|
|
8
|
-
:placeholder="
|
|
9
|
-
|
|
10
|
-
@focus="onTextFocus"
|
|
11
|
-
@blur="onSomeBlur"
|
|
6
|
+
:placeholder="placeholder"
|
|
7
|
+
class="ui-select-x_input"
|
|
12
8
|
spellcheck="false"
|
|
9
|
+
tabindex="0"
|
|
10
|
+
@focus="onTextFocus"
|
|
11
|
+
@keydown="onTextKeydown"
|
|
13
12
|
/>
|
|
14
|
-
<span
|
|
13
|
+
<span v-show="filteredItems.length" ref="refList" class="ui-select-x_list" @keydown="onArrows">
|
|
15
14
|
<button
|
|
16
|
-
|
|
15
|
+
v-for="(e) in filteredItems"
|
|
17
16
|
:class="{'_selected': e.value === model}"
|
|
17
|
+
class="ui-select-x_list-item"
|
|
18
18
|
tabindex="-1"
|
|
19
|
-
|
|
19
|
+
type="button"
|
|
20
20
|
@click="onSelect($event,e)"
|
|
21
|
-
@blur="onSomeBlur"
|
|
22
21
|
>
|
|
23
22
|
{{ e.label }}
|
|
24
23
|
</button>
|
|
@@ -28,23 +27,26 @@
|
|
|
28
27
|
|
|
29
28
|
<script>
|
|
30
29
|
import { computed, defineComponent, nextTick, ref, watch } from 'vue'
|
|
30
|
+
import { directive as clickAway } from 'vue3-click-away'
|
|
31
31
|
|
|
32
|
-
import
|
|
33
|
-
import
|
|
32
|
+
import UiText from './UiText.vue'
|
|
33
|
+
import UiButton from './UiButton.vue'
|
|
34
34
|
|
|
35
35
|
export default defineComponent({
|
|
36
|
-
name: '
|
|
37
|
-
components: {
|
|
36
|
+
name: 'ui-select-x',
|
|
37
|
+
components: { UiButton, UiText },
|
|
38
|
+
directives: { clickAway },
|
|
38
39
|
props: {
|
|
39
40
|
modelValue: { type: [ String, Number ], default: '' },
|
|
40
41
|
options: { type: Array, default: [] },
|
|
41
42
|
allowCustom: { type: Boolean, default: false },
|
|
43
|
+
placeholder: { type: String },
|
|
42
44
|
},
|
|
43
45
|
emits: [ 'update:modelValue', 'select' ],
|
|
44
46
|
setup (props, { emit }) {
|
|
45
47
|
const refSearch = ref(null)
|
|
46
48
|
const refList = ref(null)
|
|
47
|
-
const search = ref('')
|
|
49
|
+
const search = ref(props.modelValue || '')
|
|
48
50
|
const model = ref(props.modelValue)
|
|
49
51
|
|
|
50
52
|
watch(() => props.modelValue, (value) => {
|
|
@@ -96,6 +98,8 @@ export default defineComponent({
|
|
|
96
98
|
nodes[0].click()
|
|
97
99
|
} else if (props.allowCustom) {
|
|
98
100
|
onSelect(e, { label: search.value, value: search.value })
|
|
101
|
+
} else {
|
|
102
|
+
search.value = model.value
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
e.preventDefault()
|
|
@@ -157,14 +161,8 @@ export default defineComponent({
|
|
|
157
161
|
}
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
if (
|
|
163
|
-
refSearch.value !== document.activeElement &&
|
|
164
|
-
refList.value !== document.activeElement.parentElement
|
|
165
|
-
) {
|
|
166
|
-
search.value = model.value
|
|
167
|
-
}
|
|
164
|
+
const onClickAway = () => {
|
|
165
|
+
search.value = model.value
|
|
168
166
|
}
|
|
169
167
|
|
|
170
168
|
return {
|
|
@@ -178,7 +176,7 @@ export default defineComponent({
|
|
|
178
176
|
onArrows,
|
|
179
177
|
onSelect,
|
|
180
178
|
onTextFocus,
|
|
181
|
-
|
|
179
|
+
onClickAway,
|
|
182
180
|
}
|
|
183
181
|
},
|
|
184
182
|
})
|
|
@@ -187,7 +185,7 @@ export default defineComponent({
|
|
|
187
185
|
<style lang="scss" scoped>
|
|
188
186
|
@import "../../scss";
|
|
189
187
|
|
|
190
|
-
.
|
|
188
|
+
.ui-select-x {
|
|
191
189
|
@include typo(200);
|
|
192
190
|
|
|
193
191
|
padding: 0;
|
|
@@ -208,7 +206,7 @@ export default defineComponent({
|
|
|
208
206
|
|
|
209
207
|
&_input {
|
|
210
208
|
@include typo(200);
|
|
211
|
-
|
|
209
|
+
padding: spacing(100, 300);
|
|
212
210
|
|
|
213
211
|
font-family: var(--typo-font-ui);
|
|
214
212
|
color: var(--ui-pal-text);
|
|
@@ -227,14 +225,14 @@ export default defineComponent({
|
|
|
227
225
|
outline: none;
|
|
228
226
|
}
|
|
229
227
|
|
|
230
|
-
&:not(:focus)::placeholder {
|
|
231
|
-
color: pal(prime);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
228
|
&::selection {
|
|
235
229
|
background-color: var(--ui-pal);
|
|
236
230
|
color: var(--ui-pal-text-select);
|
|
237
231
|
}
|
|
232
|
+
|
|
233
|
+
&::placeholder {
|
|
234
|
+
color: var(--ui-pal-placeholder);
|
|
235
|
+
}
|
|
238
236
|
}
|
|
239
237
|
|
|
240
238
|
&_list {
|
|
@@ -259,7 +257,7 @@ export default defineComponent({
|
|
|
259
257
|
z-index: var(--lt-z-pop);
|
|
260
258
|
|
|
261
259
|
&-item {
|
|
262
|
-
|
|
260
|
+
padding: spacing(200, 300);
|
|
263
261
|
@include typo(200, 300);
|
|
264
262
|
|
|
265
263
|
border: 0 none;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div :class="{'_shown':isOpen}" class="ui-sidebar" @mousedown.self="$emit('close')">
|
|
3
3
|
<transition name="bounce">
|
|
4
|
-
<div
|
|
4
|
+
<div v-if="isOpen" class="ui-sidebar_content">
|
|
5
|
+
<button v-if="showClose" class="ui-sidebar_close" @click="$emit('close')">
|
|
6
|
+
<ui-icon name="cross" />
|
|
7
|
+
</button>
|
|
5
8
|
<slot />
|
|
6
9
|
</div>
|
|
7
10
|
</transition>
|
|
@@ -11,13 +14,23 @@
|
|
|
11
14
|
<script>
|
|
12
15
|
import { defineComponent } from 'vue'
|
|
13
16
|
|
|
17
|
+
import UiIcon from './UiIcon.vue'
|
|
18
|
+
|
|
14
19
|
export default defineComponent({
|
|
15
|
-
name: '
|
|
20
|
+
name: 'ui-sidebar',
|
|
21
|
+
components: { UiIcon },
|
|
16
22
|
emits: [ 'close' ],
|
|
17
23
|
props: {
|
|
18
24
|
isOpen: { type: Boolean, default: false },
|
|
19
25
|
// todo: right side as well
|
|
20
26
|
side: { type: String, default: 'right' },
|
|
27
|
+
showClose: { type: Boolean, default: false },
|
|
28
|
+
},
|
|
29
|
+
watch: {
|
|
30
|
+
isOpen (val) {
|
|
31
|
+
if (val) document.body.style.overflow = 'hidden'
|
|
32
|
+
else document.body.style.overflow = 'visible'
|
|
33
|
+
},
|
|
21
34
|
},
|
|
22
35
|
})
|
|
23
36
|
</script>
|
|
@@ -25,16 +38,16 @@ export default defineComponent({
|
|
|
25
38
|
<style lang="scss">
|
|
26
39
|
@import "../../scss";
|
|
27
40
|
|
|
28
|
-
|
|
41
|
+
html {
|
|
29
42
|
--ui-sidebar-max-w: 45vw;
|
|
30
43
|
--ui-sidebar-min-w: 25vw;
|
|
31
44
|
}
|
|
32
45
|
</style>
|
|
33
46
|
|
|
34
|
-
<style
|
|
47
|
+
<style lang="scss" scoped>
|
|
35
48
|
@import "../../scss";
|
|
36
49
|
|
|
37
|
-
.
|
|
50
|
+
.ui-sidebar {
|
|
38
51
|
position: fixed;
|
|
39
52
|
left: 0;
|
|
40
53
|
top: 0;
|
|
@@ -43,7 +56,7 @@ export default defineComponent({
|
|
|
43
56
|
z-index: var(--lt-z-nav);
|
|
44
57
|
background-color: transparent;
|
|
45
58
|
transition-timing-function: linear;
|
|
46
|
-
transition-duration:
|
|
59
|
+
transition-duration: 200ms;
|
|
47
60
|
transition-property: background-color, visibility;
|
|
48
61
|
pointer-events: none;
|
|
49
62
|
visibility: hidden;
|
|
@@ -63,10 +76,26 @@ export default defineComponent({
|
|
|
63
76
|
top: 0;
|
|
64
77
|
right: 0;
|
|
65
78
|
bottom: 0;
|
|
66
|
-
|
|
79
|
+
border-top-left-radius: var(--lt-border-radius);
|
|
80
|
+
border-bottom-left-radius: var(--lt-border-radius);
|
|
81
|
+
background: var(--pal-white);
|
|
82
|
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.25);
|
|
67
83
|
max-width: var(--ui-sidebar-max-w);
|
|
68
84
|
min-width: var(--ui-sidebar-min-w);
|
|
69
85
|
transform-origin: 100% 50%;
|
|
86
|
+
width: var(--ui-sidebar-width, auto);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&_close {
|
|
90
|
+
--icon-color: var(--pal-grey800);
|
|
91
|
+
|
|
92
|
+
position: absolute;
|
|
93
|
+
top: spacing(500);
|
|
94
|
+
left: spacing(500);
|
|
95
|
+
border: none;
|
|
96
|
+
padding: 0;
|
|
97
|
+
background: transparent;
|
|
98
|
+
cursor: pointer;
|
|
70
99
|
}
|
|
71
100
|
}
|
|
72
101
|
|
|
@@ -86,4 +115,4 @@ export default defineComponent({
|
|
|
86
115
|
transform: translateX(0);
|
|
87
116
|
}
|
|
88
117
|
}
|
|
89
|
-
</style>
|
|
118
|
+
</style>
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
class="
|
|
4
|
-
:class="{'_disabled': $attrs.disabled !== undefined || $attrs.readOnly !== undefined }"
|
|
3
|
+
:class="{'_disabled': disabled || $attrs.readOnly !== undefined, 'ui-text': !naked }"
|
|
5
4
|
v-bind="{ class: $attrs.class }"
|
|
6
5
|
>
|
|
7
6
|
<slot />
|
|
8
7
|
<slot name="left" />
|
|
9
8
|
<input
|
|
10
|
-
|
|
9
|
+
ref="inputRef"
|
|
10
|
+
:class="{ _naked: naked }"
|
|
11
11
|
:value="modelValue"
|
|
12
|
-
class="
|
|
12
|
+
class="ui-text_input"
|
|
13
|
+
v-bind="{...$attrs, disabled, class: undefined}"
|
|
14
|
+
@focus="handleFocus"
|
|
13
15
|
@input="$emit('update:modelValue', $event.target.value)"
|
|
14
16
|
>
|
|
15
17
|
<slot name="right" />
|
|
@@ -20,20 +22,32 @@
|
|
|
20
22
|
import { defineComponent } from 'vue'
|
|
21
23
|
|
|
22
24
|
export default defineComponent({
|
|
23
|
-
name: '
|
|
25
|
+
name: 'ui-text',
|
|
24
26
|
props: {
|
|
27
|
+
disabled: { type: Boolean, default: false },
|
|
28
|
+
autoSelect: { type: Boolean, default: false },
|
|
29
|
+
naked: { type: Boolean, default: false },
|
|
25
30
|
modelValue: {
|
|
26
31
|
type: [ String, Number ],
|
|
27
32
|
default: '',
|
|
28
33
|
},
|
|
29
34
|
},
|
|
30
35
|
emits: [ 'update:modelValue' ],
|
|
36
|
+
expose: [ 'focus' ],
|
|
37
|
+
methods: {
|
|
38
|
+
focus () {
|
|
39
|
+
this.$refs.inputRef.focus()
|
|
40
|
+
},
|
|
41
|
+
handleFocus () {
|
|
42
|
+
if (this.autoSelect) this.$refs.inputRef.select()
|
|
43
|
+
},
|
|
44
|
+
},
|
|
31
45
|
})
|
|
32
46
|
</script>
|
|
33
47
|
<style lang="scss" scoped>
|
|
34
48
|
@import "../../scss";
|
|
35
49
|
|
|
36
|
-
.
|
|
50
|
+
.ui-text {
|
|
37
51
|
@include typo(200);
|
|
38
52
|
|
|
39
53
|
padding: 0;
|
|
@@ -49,11 +63,11 @@ export default defineComponent({
|
|
|
49
63
|
transition-timing-function: ease-in-out;
|
|
50
64
|
transition-property: border-color, box-shadow;
|
|
51
65
|
height: var(--ui-lt-h);
|
|
52
|
-
background: var(--
|
|
66
|
+
background: var(--pal-white);
|
|
53
67
|
|
|
54
68
|
&_input {
|
|
55
69
|
@include typo(200);
|
|
56
|
-
|
|
70
|
+
padding: var(--ui-input-padding, #{spacing(100)} #{spacing(300)});
|
|
57
71
|
|
|
58
72
|
font-family: var(--typo-font-ui);
|
|
59
73
|
color: var(--ui-pal-text);
|
|
@@ -78,9 +92,13 @@ export default defineComponent({
|
|
|
78
92
|
}
|
|
79
93
|
|
|
80
94
|
&[disabled], &[read-only] {
|
|
81
|
-
cursor:
|
|
95
|
+
cursor: not-allowed;
|
|
82
96
|
color: var(--ui-pal-disabled-border);
|
|
83
97
|
}
|
|
98
|
+
|
|
99
|
+
&._naked {
|
|
100
|
+
padding: var(--ui-input-padding, 0);
|
|
101
|
+
}
|
|
84
102
|
}
|
|
85
103
|
|
|
86
104
|
&:hover {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
class="fu-text"
|
|
4
|
-
v-bind="{ class: $attrs.class }"
|
|
5
3
|
:class="{'_disabled': $attrs.disabled !== undefined || $attrs.readOnly !== undefined }"
|
|
4
|
+
class="ui-text"
|
|
5
|
+
v-bind="{ class: $attrs.class }"
|
|
6
6
|
>
|
|
7
7
|
<textarea
|
|
8
8
|
ref="textarea"
|
|
9
|
-
v-bind="{...$attrs, class: undefined}"
|
|
10
9
|
:value="modelValue"
|
|
11
|
-
class="
|
|
10
|
+
class="ui-text_textarea"
|
|
11
|
+
v-bind="{...$attrs, class: undefined}"
|
|
12
12
|
@input="handleInput"
|
|
13
13
|
/>
|
|
14
14
|
</div>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { defineComponent, onMounted, ref } from 'vue'
|
|
19
19
|
|
|
20
20
|
export default defineComponent({
|
|
21
|
-
name: '
|
|
21
|
+
name: 'ui-textarea',
|
|
22
22
|
props: {
|
|
23
23
|
modelValue: {
|
|
24
24
|
type: [ String, Number ],
|
|
@@ -47,7 +47,7 @@ export default defineComponent({
|
|
|
47
47
|
<style lang="scss" scoped>
|
|
48
48
|
@import "../../scss";
|
|
49
49
|
|
|
50
|
-
.
|
|
50
|
+
.ui-text {
|
|
51
51
|
@include typo(200);
|
|
52
52
|
|
|
53
53
|
padding: 0;
|
|
@@ -68,20 +68,22 @@ export default defineComponent({
|
|
|
68
68
|
&_textarea {
|
|
69
69
|
@include scrollbar-awesome();
|
|
70
70
|
@include typo(200);
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
padding: spacing(200, 300);
|
|
72
|
+
margin: spacing(100, 100, 100, 0);
|
|
73
73
|
|
|
74
74
|
color: var(--ui-pal-text);
|
|
75
75
|
caret-color: var(--ui-pal);
|
|
76
|
-
border: none;
|
|
76
|
+
border: 0 none;
|
|
77
77
|
outline: none;
|
|
78
78
|
background: transparent;
|
|
79
79
|
box-sizing: border-box;
|
|
80
80
|
flex: 1;
|
|
81
81
|
display: block;
|
|
82
|
-
min-width: 0;
|
|
82
|
+
min-width: var(--ui-textarea-min-w, 0);
|
|
83
|
+
max-width: var(--ui-textarea-max-w, unset);
|
|
83
84
|
resize: var(--ui-textarea-resize, vertical);
|
|
84
|
-
min-height: var(--ui-
|
|
85
|
+
min-height: var(--ui-textarea-min-h, 4em);
|
|
86
|
+
max-height: var(--ui-textarea-max-h, 400px);
|
|
85
87
|
height: var(--ui-lt-h);
|
|
86
88
|
font-family: var(--typo-font-ui);
|
|
87
89
|
|
package/src/entry.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/* eslint-disable import/prefer-default-export */
|
|
2
|
-
export { default as
|
|
3
|
-
export { default as
|
|
4
|
-
export { default as
|
|
5
|
-
export { default as
|
|
6
|
-
export { default as
|
|
7
|
-
export { default as
|
|
8
|
-
export { default as
|
|
9
|
-
export { default as
|
|
10
|
-
export { default as
|
|
11
|
-
export { default as
|
|
12
|
-
export { default as
|
|
13
|
-
export { default as
|
|
14
|
-
export { default as
|
|
15
|
-
export { default as
|
|
2
|
+
export { default as UiButton } from './components/UiButton.vue'
|
|
3
|
+
export { default as UiButtonLink } from './components/UiButtonLink.vue'
|
|
4
|
+
export { default as UiCodeView } from './components/UiCodeView.vue'
|
|
5
|
+
export { default as UiCopy } from './components/UiCopy.vue'
|
|
6
|
+
export { default as UiSelect } from './components/UiSelect.vue'
|
|
7
|
+
export { default as UiSelectX } from './components/UiSelectX.vue'
|
|
8
|
+
export { default as UiSidebar } from './components/UiSidebar.vue'
|
|
9
|
+
export { default as UiText } from './components/UiText.vue'
|
|
10
|
+
export { default as UiTextarea } from './components/UiTextarea.vue'
|
|
11
|
+
export { default as UiCheck } from './components/UiCheck.vue'
|
|
12
|
+
export { default as UiDropdown } from './components/UiDropdown.vue'
|
|
13
|
+
export { default as UiDropdownItem } from './components/UiDropdownItem.vue'
|
|
14
|
+
export { default as UiIconProvider } from './components/UiIconProvider.vue'
|
|
15
|
+
export { default as UiIcon } from './components/UiIcon.vue'
|
package/src/scss-kit/typo.scss
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
@function
|
|
17
|
+
@function _spacing($spacing-code) {
|
|
18
18
|
@if (
|
|
19
19
|
$spacing-code == 0 or
|
|
20
20
|
$spacing-code == auto or
|
|
@@ -27,16 +27,8 @@
|
|
|
27
27
|
@return var(--lt-sp#{$spacing-code});
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
@
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
@mixin spacing-margin($t, $r: null, $b: null, $l: null) {
|
|
35
|
-
@include spacing-prop('margin', $t, $r, $b, $l);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
@mixin spacing-padding($t, $r: null, $b: null, $l: null) {
|
|
39
|
-
@include spacing-prop('padding', $t, $r, $b, $l);
|
|
30
|
+
@function spacing($t, $r: null, $b: null, $l: null) {
|
|
31
|
+
@return _spacing($t) _spacing($r) _spacing($b) _spacing($l)
|
|
40
32
|
}
|
|
41
33
|
|
|
42
34
|
@mixin ellipsis($display: block) {
|
package/src/scss-kit/ui.scss
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
&::-webkit-scrollbar-thumb {
|
|
14
|
-
border:
|
|
14
|
+
border: 1px solid var(--ui-scroll-bg, inherit);
|
|
15
15
|
border-radius: var(--ui-scroll-width);
|
|
16
16
|
@if ($hide) {
|
|
17
17
|
background-color: inherit;
|
|
@@ -47,5 +47,3 @@
|
|
|
47
47
|
-ms-overflow-style: none;
|
|
48
48
|
scrollbar-width: none;
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<label
|
|
3
|
-
class="fu-check"
|
|
4
|
-
:class="{'_disabled': $attrs.disabled !== undefined, '_checked': modelValue }"
|
|
5
|
-
v-bind="{ class: $attrs.class, style: $attrs.style }"
|
|
6
|
-
>
|
|
7
|
-
<input
|
|
8
|
-
v-bind="{...$attrs, class: undefined, style: undefined, type: 'checkbox'}"
|
|
9
|
-
class="fu-check_input"
|
|
10
|
-
@input="$emit('update:modelValue', $event.target.checked)"
|
|
11
|
-
:checked="modelValue"
|
|
12
|
-
>
|
|
13
|
-
<span class="fu-check_box" :class="switchLike ? 'fu-check_switch' : 'fu-check_check'" />
|
|
14
|
-
<slot />
|
|
15
|
-
</label>
|
|
16
|
-
</template>
|
|
17
|
-
|
|
18
|
-
<script>
|
|
19
|
-
import { defineComponent } from 'vue'
|
|
20
|
-
|
|
21
|
-
export default defineComponent({
|
|
22
|
-
name: 'fu-check',
|
|
23
|
-
props: {
|
|
24
|
-
modelValue: { type: [ Boolean ], default: false },
|
|
25
|
-
switchLike: { type: Boolean, default: false },
|
|
26
|
-
},
|
|
27
|
-
emits: [ 'update:modelValue' ],
|
|
28
|
-
})
|
|
29
|
-
</script>
|
|
30
|
-
<style lang="scss" scoped>
|
|
31
|
-
@import "../../scss";
|
|
32
|
-
|
|
33
|
-
.fu-check {
|
|
34
|
-
@include typo(200);
|
|
35
|
-
|
|
36
|
-
user-select: none;
|
|
37
|
-
display: flex;
|
|
38
|
-
box-sizing: border-box;
|
|
39
|
-
align-items: center;
|
|
40
|
-
justify-content: stretch;
|
|
41
|
-
height: var(--ui-lt-h);
|
|
42
|
-
position: relative;
|
|
43
|
-
outline: none;
|
|
44
|
-
color: var(--pal-text-dimm);
|
|
45
|
-
font-family: var(--typo-font-text);
|
|
46
|
-
|
|
47
|
-
&_input {
|
|
48
|
-
opacity: 0; // weird, but it's working inside the label
|
|
49
|
-
visibility: hidden;
|
|
50
|
-
position: absolute;
|
|
51
|
-
left: 0;
|
|
52
|
-
top: 0;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
&_check {
|
|
56
|
-
border-style: var(--ui-lt-border-style);
|
|
57
|
-
border-width: var(--ui-lt-border-width);
|
|
58
|
-
border-color: var(--ui-pal-lateral);
|
|
59
|
-
height: var(--ui-lt-h-sub);
|
|
60
|
-
width: var(--ui-lt-h-sub);
|
|
61
|
-
border-radius: var(--ui-lt-border-radius);
|
|
62
|
-
display: flex;
|
|
63
|
-
justify-content: stretch;
|
|
64
|
-
align-items: stretch;
|
|
65
|
-
margin-right: spacing(200);
|
|
66
|
-
|
|
67
|
-
&:before {
|
|
68
|
-
content: "";
|
|
69
|
-
display: block;
|
|
70
|
-
background-color: var(--ui-pal);
|
|
71
|
-
border-radius: calc(var(--ui-lt-border-radius) - #{spacing(100)});
|
|
72
|
-
margin: spacing(100);
|
|
73
|
-
flex: 1;
|
|
74
|
-
transform: scale(0);
|
|
75
|
-
transition: all var(--ui-transition);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
&_switch {
|
|
80
|
-
border-style: var(--ui-lt-border-style);
|
|
81
|
-
border-width: var(--ui-lt-border-width);
|
|
82
|
-
border-color: var(--ui-pal-lateral);
|
|
83
|
-
height: var(--ui-lt-h-sub);
|
|
84
|
-
width: calc(var(--ui-lt-h-sub) * 2);
|
|
85
|
-
border-radius: var(--ui-lt-h-sub);
|
|
86
|
-
margin-right: spacing(200);
|
|
87
|
-
display: flex;
|
|
88
|
-
align-items: center;
|
|
89
|
-
justify-content: flex-start;
|
|
90
|
-
padding: spacing(100);
|
|
91
|
-
|
|
92
|
-
&:before {
|
|
93
|
-
content: "";
|
|
94
|
-
display: block;
|
|
95
|
-
background-color: var(--ui-pal-lateral);
|
|
96
|
-
border-radius: calc(var(--ui-lt-h-sub) - #{spacing(100)});
|
|
97
|
-
height: 100%;
|
|
98
|
-
aspect-ratio: 1;
|
|
99
|
-
transition: all var(--ui-transition);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
&._checked &_switch:before {
|
|
104
|
-
transform: translateX(var(--ui-lt-h-sub));
|
|
105
|
-
background-color: var(--ui-pal);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
&._checked {
|
|
109
|
-
color: var(--pal-text);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
&._checked &_check:before {
|
|
113
|
-
transform: scale(1);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
&:hover &_box {
|
|
117
|
-
box-shadow: 0 5px 12px -4px rgb(var(--rgb-dark), 0.2);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
&:hover {
|
|
121
|
-
color: var(--pal-text);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
&:focus-within &_box {
|
|
125
|
-
border-color: var(--ui-pal);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
&._disabled {
|
|
129
|
-
color: var(--ui-pal-disabled-border);
|
|
130
|
-
cursor: not-allowed;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
&._disabled &_box {
|
|
134
|
-
border: var(--ui-lt-border-width) var(--ui-lt-disabled-border-style) var(--ui-pal-disabled-border);
|
|
135
|
-
box-shadow: none;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
</style>
|