webcake-ui-kit 1.0.0 → 1.0.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/LICENSE +21 -0
- package/README.md +358 -8
- package/package.json +68 -5
- package/src/components/accordion/Accordion.vue +70 -0
- package/src/components/accordion/accordion.css +5 -0
- package/src/components/accordion-item/AccordionItem.vue +98 -0
- package/src/components/accordion-item/accordion-item.css +143 -0
- package/src/components/alert-dialog/AlertDialog.vue +82 -0
- package/src/components/alert-dialog/alert-dialog.css +33 -0
- package/src/components/badge/Badge.vue +2 -2
- package/src/components/badge/badge.css +1 -4
- package/src/components/breadcrumb/Breadcrumb.vue +85 -0
- package/src/components/breadcrumb/breadcrumb.css +90 -0
- package/src/components/button/Button.vue +77 -10
- package/src/components/button/button.css +258 -24
- package/src/components/button-group/ButtonGroup.vue +25 -0
- package/src/components/button-group/button-group.css +30 -0
- package/src/components/checkbox/Checkbox.vue +55 -0
- package/src/components/checkbox/checkbox.css +86 -0
- package/src/components/checkbox-group/CheckboxGroup.vue +50 -0
- package/src/components/checkbox-group/checkbox-group.css +35 -0
- package/src/components/dialog/Dialog.vue +355 -0
- package/src/components/dialog/dialog.css +255 -0
- package/src/components/divider/Divider.vue +35 -0
- package/src/components/divider/divider.css +38 -0
- package/src/components/input/Input.vue +99 -0
- package/src/components/input/input.css +123 -0
- package/src/components/pagination/Pagination.vue +211 -0
- package/src/components/pagination/pagination.css +13 -0
- package/src/components/radio/Radio.vue +74 -0
- package/src/components/radio/radio.css +89 -0
- package/src/components/radio-group/RadioGroup.vue +70 -0
- package/src/components/radio-group/radio_group.css +11 -0
- package/src/components/rich-checkbox-group/RichCheckboxGroup.vue +59 -0
- package/src/components/rich-checkbox-group/rich-checkbox-group.css +54 -0
- package/src/components/rich-switch-group/RichSwitchGroup.vue +49 -0
- package/src/components/rich-switch-group/rich_switch_group.css +45 -0
- package/src/components/select/Select.vue +262 -0
- package/src/components/select/select.css +207 -0
- package/src/components/select-option/SelectOption.vue +82 -0
- package/src/components/select-option/select_option.css +60 -0
- package/src/components/sidebar-group-label/SidebarGroupLabel.vue +68 -0
- package/src/components/sidebar-group-label/sidebar_group_label.css +61 -0
- package/src/components/sidebar-item/SidebarItem.vue +110 -0
- package/src/components/sidebar-item/sidebar_item.css +142 -0
- package/src/components/slider/Slider.vue +255 -0
- package/src/components/slider/slider.css +89 -0
- package/src/components/spinner/Spinner.vue +47 -0
- package/src/components/spinner/spinner.css +48 -0
- package/src/components/switch/Switch.vue +32 -0
- package/src/components/switch/switch.css +46 -0
- package/src/components/switch-group/SwitchGroup.vue +32 -0
- package/src/components/switch-group/switch_group.css +28 -0
- package/src/components/tabs/Tabs.vue +57 -0
- package/src/components/tabs/tabs.css +118 -0
- package/src/components/tag/Tag.vue +47 -0
- package/src/components/tag/tag.css +115 -0
- package/src/components/toggle/Toggle.vue +112 -0
- package/src/components/toggle/toggle.css +174 -0
- package/src/components/toggle-group/ToggleGroup.vue +57 -0
- package/src/components/toggle-group/toggle-group.css +68 -0
- package/src/icons/LoaderIcon.vue +22 -0
- package/src/index.js +29 -2
- package/src/styles/.omc/state/agent-replay-645326b7-372b-463d-ab45-0adaafe31a51.jsonl +2 -0
- package/src/styles/.omc/state/subagent-tracking.json +7 -0
- package/src/styles/alpha_colors.css +35 -37
- package/src/styles/border_radius.css +21 -23
- package/src/styles/brand_colors.css +37 -39
- package/src/styles/chart_colors.css +27 -29
- package/src/styles/color_general.css +206 -201
- package/src/styles/raw_colors.css +267 -269
- package/src/styles/shadow.css +10 -12
- package/src/styles/spacing.css +31 -33
- package/src/styles/typography.css +76 -78
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="ui-slider"
|
|
4
|
+
:class="{
|
|
5
|
+
'ui-slider--vertical': orientation === 'vertical',
|
|
6
|
+
'ui-slider--disabled': disabled,
|
|
7
|
+
'ui-slider--range': range
|
|
8
|
+
}"
|
|
9
|
+
>
|
|
10
|
+
<div class="ui-slider__track" ref="track" @click="onTrackClick">
|
|
11
|
+
<div class="ui-slider__fill" :style="fillStyle" />
|
|
12
|
+
<div
|
|
13
|
+
v-if="!range"
|
|
14
|
+
class="ui-slider__thumb"
|
|
15
|
+
role="slider"
|
|
16
|
+
tabindex="0"
|
|
17
|
+
:aria-valuemin="min"
|
|
18
|
+
:aria-valuemax="max"
|
|
19
|
+
:aria-valuenow="localValue"
|
|
20
|
+
:aria-orientation="orientation"
|
|
21
|
+
:style="thumbStyle(localValue)"
|
|
22
|
+
@mousedown.prevent="startDrag('single', $event)"
|
|
23
|
+
@touchstart.prevent="startDragTouch('single', $event)"
|
|
24
|
+
@keydown="onKeydown('single', $event)"
|
|
25
|
+
@click.stop
|
|
26
|
+
/>
|
|
27
|
+
<template v-if="range">
|
|
28
|
+
<div
|
|
29
|
+
class="ui-slider__thumb"
|
|
30
|
+
role="slider"
|
|
31
|
+
tabindex="0"
|
|
32
|
+
:aria-valuemin="min"
|
|
33
|
+
:aria-valuemax="localRangeMax"
|
|
34
|
+
:aria-valuenow="localRangeMin"
|
|
35
|
+
:aria-orientation="orientation"
|
|
36
|
+
:style="thumbStyle(localRangeMin)"
|
|
37
|
+
@mousedown.prevent="startDrag('min', $event)"
|
|
38
|
+
@touchstart.prevent="startDragTouch('min', $event)"
|
|
39
|
+
@keydown="onKeydown('min', $event)"
|
|
40
|
+
@click.stop
|
|
41
|
+
/>
|
|
42
|
+
<div
|
|
43
|
+
class="ui-slider__thumb"
|
|
44
|
+
role="slider"
|
|
45
|
+
tabindex="0"
|
|
46
|
+
:aria-valuemin="localRangeMin"
|
|
47
|
+
:aria-valuemax="max"
|
|
48
|
+
:aria-valuenow="localRangeMax"
|
|
49
|
+
:aria-orientation="orientation"
|
|
50
|
+
:style="thumbStyle(localRangeMax)"
|
|
51
|
+
@mousedown.prevent="startDrag('max', $event)"
|
|
52
|
+
@touchstart.prevent="startDragTouch('max', $event)"
|
|
53
|
+
@keydown="onKeydown('max', $event)"
|
|
54
|
+
@click.stop
|
|
55
|
+
/>
|
|
56
|
+
</template>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<script>
|
|
62
|
+
export default {
|
|
63
|
+
name: 'Slider',
|
|
64
|
+
props: {
|
|
65
|
+
value: { type: Number, default: 50 },
|
|
66
|
+
rangeValue: {
|
|
67
|
+
type: Array,
|
|
68
|
+
default: function () {
|
|
69
|
+
return [25, 75]
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
min: { type: Number, default: 0 },
|
|
73
|
+
max: { type: Number, default: 100 },
|
|
74
|
+
step: { type: Number, default: 1 },
|
|
75
|
+
range: { type: Boolean, default: false },
|
|
76
|
+
orientation: {
|
|
77
|
+
type: String,
|
|
78
|
+
default: 'horizontal',
|
|
79
|
+
validator: function (v) {
|
|
80
|
+
return ['horizontal', 'vertical'].indexOf(v) !== -1
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
disabled: { type: Boolean, default: false }
|
|
84
|
+
},
|
|
85
|
+
emits: ['change', 'input'],
|
|
86
|
+
data: function () {
|
|
87
|
+
return {
|
|
88
|
+
localValue: this.value,
|
|
89
|
+
localRangeMin: Array.isArray(this.rangeValue) ? this.rangeValue[0] : 25,
|
|
90
|
+
localRangeMax: Array.isArray(this.rangeValue) ? this.rangeValue[1] : 75,
|
|
91
|
+
dragging: null,
|
|
92
|
+
boundMouseMove: null,
|
|
93
|
+
boundMouseUp: null,
|
|
94
|
+
boundTouchMove: null,
|
|
95
|
+
boundTouchEnd: null
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
watch: {
|
|
99
|
+
value: function (v) {
|
|
100
|
+
this.localValue = v
|
|
101
|
+
},
|
|
102
|
+
rangeValue: function (v) {
|
|
103
|
+
if (Array.isArray(v)) {
|
|
104
|
+
this.localRangeMin = v[0]
|
|
105
|
+
this.localRangeMax = v[1]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
computed: {
|
|
110
|
+
fillStyle: function () {
|
|
111
|
+
var minPct = (this.localRangeMin - this.min) / (this.max - this.min)
|
|
112
|
+
var maxPct = (this.localRangeMax - this.min) / (this.max - this.min)
|
|
113
|
+
var valPct = (this.localValue - this.min) / (this.max - this.min)
|
|
114
|
+
if (this.orientation === 'vertical') {
|
|
115
|
+
if (this.range) {
|
|
116
|
+
return { bottom: minPct * 100 + '%', height: (maxPct - minPct) * 100 + '%' }
|
|
117
|
+
}
|
|
118
|
+
return { bottom: '0%', height: valPct * 100 + '%' }
|
|
119
|
+
}
|
|
120
|
+
if (this.range) {
|
|
121
|
+
return { left: minPct * 100 + '%', width: (maxPct - minPct) * 100 + '%' }
|
|
122
|
+
}
|
|
123
|
+
return { left: '0%', width: valPct * 100 + '%' }
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
created: function () {
|
|
127
|
+
this.boundMouseMove = this.onMouseMove.bind(this)
|
|
128
|
+
this.boundMouseUp = this.stopDrag.bind(this)
|
|
129
|
+
this.boundTouchMove = this.onTouchMove.bind(this)
|
|
130
|
+
this.boundTouchEnd = this.stopDrag.bind(this)
|
|
131
|
+
},
|
|
132
|
+
beforeUnmount: function () {
|
|
133
|
+
this.cleanup()
|
|
134
|
+
},
|
|
135
|
+
methods: {
|
|
136
|
+
cleanup: function () {
|
|
137
|
+
document.removeEventListener('mousemove', this.boundMouseMove)
|
|
138
|
+
document.removeEventListener('mouseup', this.boundMouseUp)
|
|
139
|
+
document.removeEventListener('touchmove', this.boundTouchMove)
|
|
140
|
+
document.removeEventListener('touchend', this.boundTouchEnd)
|
|
141
|
+
},
|
|
142
|
+
thumbStyle: function (val) {
|
|
143
|
+
var p = (val - this.min) / (this.max - this.min)
|
|
144
|
+
if (this.orientation === 'vertical') {
|
|
145
|
+
return { bottom: p * 100 + '%' }
|
|
146
|
+
}
|
|
147
|
+
return { left: p * 100 + '%' }
|
|
148
|
+
},
|
|
149
|
+
snap: function (val) {
|
|
150
|
+
var stepped = Math.round((val - this.min) / this.step) * this.step + this.min
|
|
151
|
+
return Math.max(this.min, Math.min(this.max, parseFloat(stepped.toFixed(10))))
|
|
152
|
+
},
|
|
153
|
+
valueFromPointer: function (clientX, clientY) {
|
|
154
|
+
var rect = this.$refs.track.getBoundingClientRect()
|
|
155
|
+
var ratio
|
|
156
|
+
if (this.orientation === 'vertical') {
|
|
157
|
+
ratio = 1 - (clientY - rect.top) / rect.height
|
|
158
|
+
} else {
|
|
159
|
+
ratio = (clientX - rect.left) / rect.width
|
|
160
|
+
}
|
|
161
|
+
ratio = Math.max(0, Math.min(1, ratio))
|
|
162
|
+
return this.snap(this.min + ratio * (this.max - this.min))
|
|
163
|
+
},
|
|
164
|
+
startDrag: function (which) {
|
|
165
|
+
if (this.disabled) return
|
|
166
|
+
this.dragging = which
|
|
167
|
+
document.addEventListener('mousemove', this.boundMouseMove)
|
|
168
|
+
document.addEventListener('mouseup', this.boundMouseUp)
|
|
169
|
+
},
|
|
170
|
+
startDragTouch: function (which) {
|
|
171
|
+
if (this.disabled) return
|
|
172
|
+
this.dragging = which
|
|
173
|
+
document.addEventListener('touchmove', this.boundTouchMove, { passive: false })
|
|
174
|
+
document.addEventListener('touchend', this.boundTouchEnd)
|
|
175
|
+
},
|
|
176
|
+
onMouseMove: function (event) {
|
|
177
|
+
if (!this.dragging) return
|
|
178
|
+
this.applyValue(this.dragging, this.valueFromPointer(event.clientX, event.clientY))
|
|
179
|
+
},
|
|
180
|
+
onTouchMove: function (event) {
|
|
181
|
+
if (!this.dragging) return
|
|
182
|
+
event.preventDefault()
|
|
183
|
+
var t = event.touches[0]
|
|
184
|
+
this.applyValue(this.dragging, this.valueFromPointer(t.clientX, t.clientY))
|
|
185
|
+
},
|
|
186
|
+
stopDrag: function () {
|
|
187
|
+
this.dragging = null
|
|
188
|
+
document.removeEventListener('mousemove', this.boundMouseMove)
|
|
189
|
+
document.removeEventListener('mouseup', this.boundMouseUp)
|
|
190
|
+
document.removeEventListener('touchmove', this.boundTouchMove)
|
|
191
|
+
document.removeEventListener('touchend', this.boundTouchEnd)
|
|
192
|
+
},
|
|
193
|
+
applyValue: function (which, val) {
|
|
194
|
+
if (which === 'single') {
|
|
195
|
+
this.localValue = val
|
|
196
|
+
this.$emit('input', val)
|
|
197
|
+
this.$emit('change', val)
|
|
198
|
+
} else if (which === 'min') {
|
|
199
|
+
var newMin = Math.min(val, this.localRangeMax - this.step)
|
|
200
|
+
this.localRangeMin = this.snap(newMin)
|
|
201
|
+
this.$emit('change', [this.localRangeMin, this.localRangeMax])
|
|
202
|
+
} else if (which === 'max') {
|
|
203
|
+
var newMax = Math.max(val, this.localRangeMin + this.step)
|
|
204
|
+
this.localRangeMax = this.snap(newMax)
|
|
205
|
+
this.$emit('change', [this.localRangeMin, this.localRangeMax])
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
onTrackClick: function (event) {
|
|
209
|
+
if (this.disabled) return
|
|
210
|
+
var val = this.valueFromPointer(event.clientX, event.clientY)
|
|
211
|
+
if (!this.range) {
|
|
212
|
+
this.applyValue('single', val)
|
|
213
|
+
return
|
|
214
|
+
}
|
|
215
|
+
var distMin = Math.abs(val - this.localRangeMin)
|
|
216
|
+
var distMax = Math.abs(val - this.localRangeMax)
|
|
217
|
+
this.applyValue(distMin <= distMax ? 'min' : 'max', val)
|
|
218
|
+
},
|
|
219
|
+
onKeydown: function (which, event) {
|
|
220
|
+
if (this.disabled) return
|
|
221
|
+
var key = event.key
|
|
222
|
+
var isIncrease = key === 'ArrowRight' || key === 'ArrowUp'
|
|
223
|
+
var isDecrease = key === 'ArrowLeft' || key === 'ArrowDown'
|
|
224
|
+
var isHome = key === 'Home'
|
|
225
|
+
var isEnd = key === 'End'
|
|
226
|
+
if (!isIncrease && !isDecrease && !isHome && !isEnd) return
|
|
227
|
+
event.preventDefault()
|
|
228
|
+
var current, newVal
|
|
229
|
+
if (which === 'single') {
|
|
230
|
+
current = this.localValue
|
|
231
|
+
newVal = isHome ? this.min : isEnd ? this.max : current + (isIncrease ? this.step : -this.step)
|
|
232
|
+
this.applyValue('single', this.snap(newVal))
|
|
233
|
+
} else if (which === 'min') {
|
|
234
|
+
current = this.localRangeMin
|
|
235
|
+
newVal = isHome
|
|
236
|
+
? this.min
|
|
237
|
+
: isEnd
|
|
238
|
+
? this.localRangeMax - this.step
|
|
239
|
+
: current + (isIncrease ? this.step : -this.step)
|
|
240
|
+
this.applyValue('min', this.snap(newVal))
|
|
241
|
+
} else if (which === 'max') {
|
|
242
|
+
current = this.localRangeMax
|
|
243
|
+
newVal = isHome
|
|
244
|
+
? this.localRangeMin + this.step
|
|
245
|
+
: isEnd
|
|
246
|
+
? this.max
|
|
247
|
+
: current + (isIncrease ? this.step : -this.step)
|
|
248
|
+
this.applyValue('max', this.snap(newVal))
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
</script>
|
|
254
|
+
|
|
255
|
+
<style src="./slider.css" scoped></style>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
.ui-slider {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
width: 100%;
|
|
5
|
+
min-width: 120px;
|
|
6
|
+
padding: var(--spacing-xs) 0;
|
|
7
|
+
user-select: none;
|
|
8
|
+
-webkit-user-select: none;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.ui-slider--vertical {
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
width: auto;
|
|
14
|
+
min-width: unset;
|
|
15
|
+
min-height: 120px;
|
|
16
|
+
height: 100%;
|
|
17
|
+
padding: 0 var(--spacing-xs);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.ui-slider--disabled {
|
|
21
|
+
opacity: 0.4;
|
|
22
|
+
pointer-events: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.ui-slider__track {
|
|
26
|
+
position: relative;
|
|
27
|
+
flex: 1;
|
|
28
|
+
height: 6px;
|
|
29
|
+
background: var(--tertiary-bg);
|
|
30
|
+
border-radius: var(--radius-infinite);
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.ui-slider--vertical .ui-slider__track {
|
|
35
|
+
flex: 1;
|
|
36
|
+
width: 6px;
|
|
37
|
+
height: auto;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.ui-slider__fill {
|
|
41
|
+
position: absolute;
|
|
42
|
+
top: 0;
|
|
43
|
+
bottom: 0;
|
|
44
|
+
background: var(--primary-brand-bg);
|
|
45
|
+
border-radius: var(--radius-infinite);
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ui-slider--vertical .ui-slider__fill {
|
|
50
|
+
top: auto;
|
|
51
|
+
left: 0;
|
|
52
|
+
right: 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.ui-slider__thumb {
|
|
56
|
+
position: absolute;
|
|
57
|
+
top: 50%;
|
|
58
|
+
width: 14px;
|
|
59
|
+
height: 14px;
|
|
60
|
+
background: var(--primary-brand-bg);
|
|
61
|
+
border: 1.5px solid var(--inverse-fg);
|
|
62
|
+
border-radius: var(--radius-infinite);
|
|
63
|
+
box-shadow: var(--shadow-xs);
|
|
64
|
+
transform: translate(-50%, -50%);
|
|
65
|
+
cursor: grab;
|
|
66
|
+
outline: none;
|
|
67
|
+
z-index: 1;
|
|
68
|
+
transition: box-shadow 0.1s ease;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.ui-slider--vertical .ui-slider__thumb {
|
|
72
|
+
top: auto;
|
|
73
|
+
left: 50%;
|
|
74
|
+
transform: translate(-50%, 50%);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.ui-slider__thumb:hover {
|
|
78
|
+
box-shadow:
|
|
79
|
+
var(--shadow-xs),
|
|
80
|
+
0 0 0 5px color-mix(in srgb, var(--primary-brand-bg) 20%, transparent);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.ui-slider__thumb:focus-visible {
|
|
84
|
+
box-shadow: var(--shadow-xs), var(--shadow-focus-ring);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.ui-slider__thumb:active {
|
|
88
|
+
cursor: grabbing;
|
|
89
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="ui-spinner" :class="[`ui-spinner--${size}`, `ui-spinner--${type}`]" role="status" :aria-label="label">
|
|
3
|
+
<svg
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="1.75"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
class="lucide lucide-loader-circle-icon lucide-loader-circle ui-spinner__svg"
|
|
14
|
+
>
|
|
15
|
+
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
|
|
16
|
+
</svg>
|
|
17
|
+
</span>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script>
|
|
21
|
+
export default {
|
|
22
|
+
name: 'Spinner',
|
|
23
|
+
props: {
|
|
24
|
+
size: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: 'sm',
|
|
27
|
+
validator: function (v) {
|
|
28
|
+
return ['sm', 'md', 'lg'].indexOf(v) !== -1
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
type: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: 'default',
|
|
34
|
+
validator: function (v) {
|
|
35
|
+
return ['default', 'mirrored'].indexOf(v) !== -1
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
label: {
|
|
39
|
+
type: String,
|
|
40
|
+
default: 'Loading'
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
emits: []
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<style src="./spinner.css" scoped></style>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
.ui-spinner {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
flex-shrink: 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.ui-spinner--sm {
|
|
9
|
+
width: 16px;
|
|
10
|
+
height: 16px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.ui-spinner--md {
|
|
14
|
+
width: 24px;
|
|
15
|
+
height: 24px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.ui-spinner--lg {
|
|
19
|
+
width: 32px;
|
|
20
|
+
height: 32px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.ui-spinner__svg {
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: 100%;
|
|
26
|
+
animation: ui-spinner-spin 0.7s linear infinite;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.ui-spinner--mirrored .ui-spinner__svg {
|
|
30
|
+
animation-direction: reverse;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.ui-spinner__track {
|
|
34
|
+
stroke: var(--tertiary-bg);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.ui-spinner__arc {
|
|
38
|
+
stroke: currentColor;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@keyframes ui-spinner-spin {
|
|
42
|
+
from {
|
|
43
|
+
transform: rotate(0deg);
|
|
44
|
+
}
|
|
45
|
+
to {
|
|
46
|
+
transform: rotate(360deg);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<button
|
|
3
|
+
class="ui-switch"
|
|
4
|
+
:class="{ 'ui-switch--on': value }"
|
|
5
|
+
role="switch"
|
|
6
|
+
type="button"
|
|
7
|
+
:aria-checked="value ? 'true' : 'false'"
|
|
8
|
+
:disabled="disabled || undefined"
|
|
9
|
+
@click="toggle"
|
|
10
|
+
>
|
|
11
|
+
<span class="ui-switch__thumb" />
|
|
12
|
+
</button>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
export default {
|
|
17
|
+
props: {
|
|
18
|
+
value: { type: Boolean, default: false },
|
|
19
|
+
disabled: { type: Boolean, default: false }
|
|
20
|
+
},
|
|
21
|
+
emits: ['change', 'input'],
|
|
22
|
+
methods: {
|
|
23
|
+
toggle: function () {
|
|
24
|
+
var next = !this.value
|
|
25
|
+
this.$emit('input', next)
|
|
26
|
+
this.$emit('change', next)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<style src="./switch.css" scoped></style>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
.ui-switch {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
flex-shrink: 0;
|
|
6
|
+
width: 33px;
|
|
7
|
+
height: 18px;
|
|
8
|
+
border-radius: var(--radius-infinite);
|
|
9
|
+
background: var(--border-primary);
|
|
10
|
+
border: none;
|
|
11
|
+
padding: 0;
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
transition: background 0.15s ease;
|
|
14
|
+
box-shadow: var(--shadow-xs);
|
|
15
|
+
outline: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.ui-switch--on {
|
|
19
|
+
background: var(--primary-brand-bg);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.ui-switch:disabled {
|
|
23
|
+
opacity: 0.4;
|
|
24
|
+
cursor: not-allowed;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.ui-switch:focus-visible {
|
|
28
|
+
box-shadow: var(--shadow-xs), var(--shadow-focus-ring);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.ui-switch__thumb {
|
|
32
|
+
position: absolute;
|
|
33
|
+
top: 1px;
|
|
34
|
+
left: 1px;
|
|
35
|
+
width: 16px;
|
|
36
|
+
height: 16px;
|
|
37
|
+
border-radius: 50%;
|
|
38
|
+
background: var(--inverse-fg);
|
|
39
|
+
box-shadow: var(--shadow-xs);
|
|
40
|
+
transition: transform 0.15s ease;
|
|
41
|
+
pointer-events: none;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.ui-switch--on .ui-switch__thumb {
|
|
45
|
+
transform: translateX(15px);
|
|
46
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ui-switch-group" :class="[`ui-switch-group--${layout}`, { 'ui-switch-group--disabled': disabled }]">
|
|
3
|
+
<WkSwitch :value="value" :disabled="disabled" @change="$emit('change', $event)" @input="$emit('input', $event)" />
|
|
4
|
+
<span class="ui-switch-group__label"
|
|
5
|
+
><slot>{{ label }}</slot></span
|
|
6
|
+
>
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
import WkSwitch from '../switch/Switch.vue'
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
name: 'SwitchGroup',
|
|
15
|
+
components: { WkSwitch },
|
|
16
|
+
props: {
|
|
17
|
+
value: { type: Boolean, default: false },
|
|
18
|
+
disabled: { type: Boolean, default: false },
|
|
19
|
+
layout: {
|
|
20
|
+
type: String,
|
|
21
|
+
default: 'inline',
|
|
22
|
+
validator: function (v) {
|
|
23
|
+
return ['inline', 'block'].indexOf(v) !== -1
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
label: { type: String, default: '' }
|
|
27
|
+
},
|
|
28
|
+
emits: ['change', 'input']
|
|
29
|
+
}
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<style src="./switch_group.css" scoped></style>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.ui-switch-group {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: var(--spacing-xs);
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.ui-switch-group--block {
|
|
9
|
+
display: flex;
|
|
10
|
+
width: 100%;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.ui-switch-group--block .ui-switch-group__label {
|
|
14
|
+
flex: 1;
|
|
15
|
+
min-width: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.ui-switch-group--disabled {
|
|
19
|
+
cursor: not-allowed;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.ui-switch-group__label {
|
|
23
|
+
font-family: var(--font-family-body);
|
|
24
|
+
font-size: var(--paragraph-small-font-size);
|
|
25
|
+
line-height: var(--paragraph-small-line-height);
|
|
26
|
+
color: var(--secondary-fg);
|
|
27
|
+
user-select: none;
|
|
28
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ui-tabs" :class="`ui-tabs--${size}`">
|
|
3
|
+
<button
|
|
4
|
+
v-for="tab in tabs"
|
|
5
|
+
:key="tab.value"
|
|
6
|
+
type="button"
|
|
7
|
+
class="ui-tabs__item"
|
|
8
|
+
:class="{
|
|
9
|
+
'ui-tabs__item--active': tab.value === value,
|
|
10
|
+
'ui-tabs__item--disabled': tab.disabled
|
|
11
|
+
}"
|
|
12
|
+
:disabled="tab.disabled || undefined"
|
|
13
|
+
@click="select(tab.value)"
|
|
14
|
+
>
|
|
15
|
+
<span v-if="hasIconSlot" class="ui-tabs__icon"><slot name="tab-icon" :tab="tab" /></span>
|
|
16
|
+
<span v-if="tab.label" class="ui-tabs__label">{{ tab.label }}</span>
|
|
17
|
+
<span v-if="tab.counter > 0" class="ui-tabs__counter">{{ tab.counter }}</span>
|
|
18
|
+
</button>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script>
|
|
23
|
+
export default {
|
|
24
|
+
name: 'Tabs',
|
|
25
|
+
props: {
|
|
26
|
+
value: { type: [String, Number], default: null },
|
|
27
|
+
tabs: {
|
|
28
|
+
type: Array,
|
|
29
|
+
default: function () {
|
|
30
|
+
return []
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
size: {
|
|
34
|
+
type: String,
|
|
35
|
+
default: 'sm',
|
|
36
|
+
validator: function (v) {
|
|
37
|
+
return ['mini', 'sm', 'md', 'lg'].includes(v)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
emits: ['input', 'change'],
|
|
42
|
+
computed: {
|
|
43
|
+
hasIconSlot: function () {
|
|
44
|
+
return !!((this.$scopedSlots && this.$scopedSlots['tab-icon']) || this.$slots['tab-icon'])
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
methods: {
|
|
48
|
+
select: function (val) {
|
|
49
|
+
if (val === this.value) return
|
|
50
|
+
this.$emit('input', val)
|
|
51
|
+
this.$emit('change', val)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<style src="./tabs.css" scoped></style>
|