wave-ui 3.20.0 → 3.21.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/dist/wave-ui.cjs.js +1 -1
- package/dist/wave-ui.css +1 -1
- package/dist/wave-ui.es.js +960 -976
- package/dist/wave-ui.umd.js +1 -1
- package/package.json +18 -18
- package/src/wave-ui/components/w-scrollable.vue +184 -174
- package/src/wave-ui/scss/_base.scss +11 -0
- package/src/wave-ui/scss/_colors.scss +9 -0
- package/src/wave-ui/scss/_layout.scss +9 -0
- package/src/wave-ui/scss/variables/_variables.scss +7 -0
- package/src/wave-ui/utils/colors.js +4 -4
- package/src/wave-ui/utils/dynamic-css.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.21.1",
|
|
4
4
|
"description": "A UI framework for Vue.js 3 (and 2) with only the bright side. :sunny:",
|
|
5
5
|
"author": "Antoni Andre <antoniandre.web@gmail.com>",
|
|
6
6
|
"homepage": "https://antoniandre.github.io/wave-ui",
|
|
@@ -42,22 +42,10 @@
|
|
|
42
42
|
"vue framework",
|
|
43
43
|
"ui"
|
|
44
44
|
],
|
|
45
|
-
"scripts": {
|
|
46
|
-
"dev": "vite",
|
|
47
|
-
"build": "vite build --base /wave-ui/",
|
|
48
|
-
"build-types": "tsc -p ./tsconfig.json",
|
|
49
|
-
"build-bundle": "BUNDLE=true vite build && npm run build-types",
|
|
50
|
-
"preview": "vite preview --base /wave-ui/",
|
|
51
|
-
"lint": "biome check .",
|
|
52
|
-
"lint:fix": "biome check --apply .",
|
|
53
|
-
"format": "biome format .",
|
|
54
|
-
"format:fix": "biome format --write .",
|
|
55
|
-
"publish-doc": "npm run build && npm run build-bundle && git add . && git commit -m 'Publish documentation on Github.' && git push && git push --tag"
|
|
56
|
-
},
|
|
57
45
|
"devDependencies": {
|
|
58
46
|
"@babel/core": "^7.26.10",
|
|
59
47
|
"@biomejs/biome": "^1.9.4",
|
|
60
|
-
"@faker-js/faker": "^9.
|
|
48
|
+
"@faker-js/faker": "^9.7.0",
|
|
61
49
|
"@mdi/font": "^7.4.47",
|
|
62
50
|
"@tsconfig/recommended": "^1.0.8",
|
|
63
51
|
"@vitejs/plugin-vue": "^5.2.3",
|
|
@@ -71,11 +59,11 @@
|
|
|
71
59
|
"postcss": "^8.5.3",
|
|
72
60
|
"pug": "^3.0.3",
|
|
73
61
|
"rollup-plugin-delete": "^3.0.1",
|
|
74
|
-
"sass": "^1.86.
|
|
62
|
+
"sass": "^1.86.3",
|
|
75
63
|
"simple-syntax-highlighter": "^3.1.1",
|
|
76
64
|
"splitpanes": "^4.0.3",
|
|
77
|
-
"typescript": "^5.8.
|
|
78
|
-
"vite": "^6.2.
|
|
65
|
+
"typescript": "^5.8.3",
|
|
66
|
+
"vite": "^6.2.6",
|
|
79
67
|
"vite-svg-loader": "^5.1.0",
|
|
80
68
|
"vue": "^3.5.13",
|
|
81
69
|
"vue-router": "^4.5.0",
|
|
@@ -88,5 +76,17 @@
|
|
|
88
76
|
"engines": {
|
|
89
77
|
"node": ">=16.0.0",
|
|
90
78
|
"pnpm": ">=8.0.0"
|
|
79
|
+
},
|
|
80
|
+
"scripts": {
|
|
81
|
+
"dev": "vite",
|
|
82
|
+
"build": "vite build --base /wave-ui/",
|
|
83
|
+
"build-types": "tsc -p ./tsconfig.json",
|
|
84
|
+
"build-bundle": "BUNDLE=true vite build && npm run build-types",
|
|
85
|
+
"preview": "vite preview --base /wave-ui/",
|
|
86
|
+
"lint": "biome check .",
|
|
87
|
+
"lint:fix": "biome check --apply .",
|
|
88
|
+
"format": "biome format .",
|
|
89
|
+
"format:fix": "biome format --write .",
|
|
90
|
+
"publish-doc": "npm run build && npm run build-bundle && git add . && git commit -m 'Publish documentation on Github.' && git push && git push --tag"
|
|
91
91
|
}
|
|
92
|
-
}
|
|
92
|
+
}
|
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
.w-scrollable(
|
|
3
|
-
ref="scrollable"
|
|
4
3
|
@mouseenter="onMouseEnter"
|
|
5
4
|
@mouseleave="onMouseLeave"
|
|
6
5
|
@mousewheel="onMouseWheel"
|
|
7
6
|
:class="scrollableClasses"
|
|
8
7
|
v-bind="$attrs"
|
|
9
8
|
:style="scrollableStyles")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.w-
|
|
9
|
+
.w-scrollable__content(ref="scrollableEl")
|
|
10
|
+
slot
|
|
11
|
+
.w-scrollable__scrollbar(ref="trackEl" @mousedown="onTrackMouseDown" :class="scrollbarClasses")
|
|
12
|
+
.w-scrollable__scrollbar-thumb(ref="thumbEl" :style="thumbStyles")
|
|
13
13
|
</template>
|
|
14
14
|
|
|
15
|
-
<script>
|
|
15
|
+
<script setup>
|
|
16
|
+
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
|
|
17
|
+
|
|
18
|
+
defineOptions({ name: 'WScrollable' })
|
|
19
|
+
|
|
20
|
+
const props = defineProps({
|
|
21
|
+
color: { type: String, default: 'primary' },
|
|
22
|
+
bgColor: { type: String },
|
|
23
|
+
width: { type: [Number, String] },
|
|
24
|
+
height: { type: [Number, String] }
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const emit = defineEmits([])
|
|
28
|
+
|
|
16
29
|
const domProps = {
|
|
17
30
|
h: {
|
|
18
31
|
direction: 'horizontal',
|
|
@@ -38,201 +51,198 @@ const domProps = {
|
|
|
38
51
|
}
|
|
39
52
|
}
|
|
40
53
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
thumbSizePercent () {
|
|
86
|
-
if (!this.mounted) return 0
|
|
87
|
-
const size = this[this.m.size] ?? this.$refs.scrollable[[this.m.offsetSize]]
|
|
88
|
-
// if (size === undefined) size = this.$refs.scrollable.offsetSize
|
|
89
|
-
return (size * 100 / this.$refs.scrollable?.[this.m.scrollSize]) || 0
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
scrollableStyles () {
|
|
93
|
-
return {
|
|
94
|
-
[this.m.maxSize]: `${this[this.m.size]}px`
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
thumbStyles () {
|
|
99
|
-
let topOrLeftValue = this.scrollValuePercent
|
|
100
|
-
topOrLeftValue = Math.max(0, Math.min(topOrLeftValue, 100 - this.thumbSizePercent))
|
|
101
|
-
return {
|
|
102
|
-
[this.m.size]: `${this.thumbSizePercent}%`,
|
|
103
|
-
[this.m.topOrLeft]: `${topOrLeftValue}%`
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
},
|
|
54
|
+
// Refs used in template and functions.
|
|
55
|
+
const mounted = ref(false)
|
|
56
|
+
const scrollableEl = ref(null)
|
|
57
|
+
const trackEl = ref(null)
|
|
58
|
+
const thumbEl = ref(null)
|
|
59
|
+
const scrollableState = ref({
|
|
60
|
+
top: null,
|
|
61
|
+
left: null,
|
|
62
|
+
hovered: false
|
|
63
|
+
})
|
|
64
|
+
const scrollValuePercent = ref(0)
|
|
65
|
+
const dragging = ref(false)
|
|
66
|
+
|
|
67
|
+
const isHorizontal = computed(() => {
|
|
68
|
+
if (!mounted.value) return false
|
|
69
|
+
console.log('💂♂️', scrollableEl.value?.scrollWidth, scrollableEl.value?.offsetWidth)
|
|
70
|
+
return (props.width && !props.height) || (scrollableEl.value?.scrollWidth > scrollableEl.value?.offsetWidth)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
const m = computed(() => domProps[isHorizontal.value ? 'h' : 'v'])
|
|
74
|
+
|
|
75
|
+
const scrollableClasses = computed(() => ({
|
|
76
|
+
[`w-scrollable--${m.value.direction}`]: true
|
|
77
|
+
}))
|
|
78
|
+
|
|
79
|
+
const scrollbarClasses = computed(() => ({
|
|
80
|
+
[`w-scrollable__scrollbar--${m.value.direction}`]: true
|
|
81
|
+
}))
|
|
82
|
+
|
|
83
|
+
const refreshThumb = ref(0)
|
|
84
|
+
|
|
85
|
+
const thumbSizePercent = computed(() => {
|
|
86
|
+
refreshThumb.value // Dependency to force re-evaluation.
|
|
87
|
+
if (!mounted.value) return 0
|
|
88
|
+
const size = props[m.value.size] ?? scrollableEl.value?.[m.value.offsetSize]
|
|
89
|
+
return (size * 100 / scrollableEl.value?.[m.value.scrollSize]) || 0
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
function forceRefreshThumb () {
|
|
93
|
+
refreshThumb.value++
|
|
94
|
+
}
|
|
107
95
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// On touch screen don't listen for both touchstart & mousedown.
|
|
112
|
-
if ('ontouchstart' in window && e.type === 'mousedown') return
|
|
113
|
-
|
|
114
|
-
const { top, left, width, height } = this.$refs.track.getBoundingClientRect()
|
|
115
|
-
if (this.isHorizontal) {
|
|
116
|
-
this.$refs.track.width = width
|
|
117
|
-
this.$refs.track.left = left
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
this.$refs.track.height = height
|
|
121
|
-
this.$refs.track.top = top
|
|
122
|
-
}
|
|
123
|
-
this.dragging = true
|
|
124
|
-
|
|
125
|
-
this.computeScroll(e.type === 'touchstart' ? e.touches[0][this.m.clientXorY] : e[this.m.clientXorY])
|
|
126
|
-
this.scroll()
|
|
127
|
-
|
|
128
|
-
document.addEventListener(e.type === 'touchstart' ? 'touchmove' : 'mousemove', this.onDrag)
|
|
129
|
-
document.addEventListener(e.type === 'touchstart' ? 'touchend' : 'mouseup', this.onMouseUp, { once: true })
|
|
130
|
-
},
|
|
131
|
-
|
|
132
|
-
onDrag (e) {
|
|
133
|
-
this.computeScroll((e.type === 'touchmove' ? e.touches[0][this.m.clientXorY] : e[this.m.clientXorY]))
|
|
134
|
-
this.scroll()
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
onMouseUp (e) {
|
|
138
|
-
this.dragging = false
|
|
139
|
-
document.removeEventListener(e.type === 'touchend' ? 'touchmove' : 'mousemove', this.onDrag)
|
|
140
|
-
if (this.$refs.thumb) this.$refs.thumb.focus()
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
onMouseEnter () {
|
|
144
|
-
this.scrollable.hovered = true
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
onMouseLeave () {
|
|
148
|
-
this.scrollable.hovered = false
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
onResize () {
|
|
152
|
-
},
|
|
153
|
-
|
|
154
|
-
onMouseWheel (e) {
|
|
155
|
-
if (!this.scrollable.hovered) return // Only scroll a w-scrollable element that is being hovered.
|
|
156
|
-
|
|
157
|
-
// When scrolling beyond limits, release the mousewheel and scroll the parent.
|
|
158
|
-
if (this.scrollValuePercent <= 0 && e[this.m.deltaXorY] < 0) return
|
|
159
|
-
if (this.scrollValuePercent >= 100 - this.thumbSizePercent && e[this.m.deltaXorY] > 0) return
|
|
160
|
-
|
|
161
|
-
e.preventDefault() // Hold the scroll in the hovered w-scrollable element.
|
|
162
|
-
|
|
163
|
-
this.scrollValuePercent += e[this.m.deltaXorY] * 0.05
|
|
164
|
-
this.scrollValuePercent = Math.max(0, Math.min(this.scrollValuePercent, 100))
|
|
165
|
-
this.scroll()
|
|
166
|
-
},
|
|
167
|
-
|
|
168
|
-
computeScroll (cursorPositionXorY) {
|
|
169
|
-
const { top, left, width, height } = this.$refs.scrollable.getBoundingClientRect()
|
|
170
|
-
const topOrLeft = this.isHorizontal ? left : top
|
|
171
|
-
const size = this.isHorizontal ? width : height
|
|
172
|
-
this.scrollValuePercent = Math.max(0, Math.min(((cursorPositionXorY - topOrLeft) / size) * 100, 100))
|
|
173
|
-
},
|
|
174
|
-
|
|
175
|
-
scroll () {
|
|
176
|
-
this.$refs.scrollable[this.m.scrollTopOrLeft] = this.scrollValuePercent * this.$refs.scrollable?.[this.m.scrollSize] / 100
|
|
177
|
-
this.updateThumbPosition()
|
|
178
|
-
},
|
|
179
|
-
|
|
180
|
-
updateThumbPosition () {
|
|
181
|
-
this.$refs.thumb.style[this.m.topOrLeft] = this.scrollValuePercent
|
|
182
|
-
}
|
|
183
|
-
},
|
|
96
|
+
const scrollableStyles = computed(() => ({
|
|
97
|
+
[m.value.maxSize]: props[m.value.size] ? `${props[m.value.size]}px` : undefined
|
|
98
|
+
}))
|
|
184
99
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
100
|
+
const thumbStyles = computed(() => {
|
|
101
|
+
let topOrLeftValue = scrollValuePercent.value
|
|
102
|
+
topOrLeftValue = Math.max(0, Math.min(topOrLeftValue, 100 - thumbSizePercent.value))
|
|
103
|
+
return {
|
|
104
|
+
[m.value.size]: `${thumbSizePercent.value}%`,
|
|
105
|
+
[m.value.topOrLeft]: `${topOrLeftValue}%`
|
|
106
|
+
}
|
|
107
|
+
})
|
|
190
108
|
|
|
191
|
-
|
|
192
|
-
|
|
109
|
+
function onTrackMouseDown (e) {
|
|
110
|
+
if (props.isDisabled || props.isReadonly) return
|
|
111
|
+
// On touch screen don't listen for both touchstart & mousedown.
|
|
112
|
+
if ('ontouchstart' in window && e.type === 'mousedown') return
|
|
193
113
|
|
|
194
|
-
|
|
114
|
+
const { top, left, width, height } = trackEl.value.getBoundingClientRect()
|
|
115
|
+
if (isHorizontal.value) {
|
|
116
|
+
trackEl.value.width = width
|
|
117
|
+
trackEl.value.left = left
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
trackEl.value.height = height
|
|
121
|
+
trackEl.value.top = top
|
|
195
122
|
}
|
|
123
|
+
dragging.value = true
|
|
124
|
+
|
|
125
|
+
computeScroll(e.type === 'touchstart' ? e.touches[0][m.value.clientXorY] : e[m.value.clientXorY])
|
|
126
|
+
scroll()
|
|
127
|
+
|
|
128
|
+
document.addEventListener(e.type === 'touchstart' ? 'touchmove' : 'mousemove', onDrag)
|
|
129
|
+
document.addEventListener(e.type === 'touchstart' ? 'touchend' : 'mouseup', onMouseUp, { once: true })
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function onDrag (e) {
|
|
133
|
+
computeScroll((e.type === 'touchmove' ? e.touches[0][m.value.clientXorY] : e[m.value.clientXorY]))
|
|
134
|
+
scroll()
|
|
196
135
|
}
|
|
136
|
+
|
|
137
|
+
function onMouseUp (e) {
|
|
138
|
+
dragging.value = false
|
|
139
|
+
document.removeEventListener(e.type === 'touchend' ? 'touchmove' : 'mousemove', onDrag)
|
|
140
|
+
if (thumbEl.value) thumbEl.value.focus()
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function onMouseEnter () {
|
|
144
|
+
scrollableState.value.hovered = true
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function onMouseLeave () {
|
|
148
|
+
scrollableState.value.hovered = false
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function onMouseWheel (e) {
|
|
152
|
+
if (!scrollableState.value.hovered) return // Only scroll a w-scrollable element that is being hovered.
|
|
153
|
+
|
|
154
|
+
// When scrolling beyond limits, release the mousewheel and scroll the parent.
|
|
155
|
+
if (scrollValuePercent.value <= 0 && e[m.value.deltaXorY] < 0) return
|
|
156
|
+
if (scrollValuePercent.value >= 100 - thumbSizePercent.value && e[m.value.deltaXorY] > 0) return
|
|
157
|
+
|
|
158
|
+
e.preventDefault() // Hold the scroll in the hovered w-scrollable element.
|
|
159
|
+
|
|
160
|
+
scrollValuePercent.value += e[m.value.deltaXorY] * 0.05
|
|
161
|
+
scrollValuePercent.value = Math.max(0, Math.min(scrollValuePercent.value, 100))
|
|
162
|
+
scroll()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function computeScroll (cursorPositionXorY) {
|
|
166
|
+
const { top, left, width, height } = scrollableEl.value.getBoundingClientRect()
|
|
167
|
+
const topOrLeft = isHorizontal.value ? left : top
|
|
168
|
+
const size = isHorizontal.value ? width : height
|
|
169
|
+
scrollValuePercent.value = Math.max(0, Math.min(((cursorPositionXorY - topOrLeft) / size) * 100, 100))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function scroll () {
|
|
173
|
+
scrollableEl.value[m.value.scrollTopOrLeft] = scrollValuePercent.value * scrollableEl.value?.[m.value.scrollSize] / 100
|
|
174
|
+
updateThumbPosition()
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function updateThumbPosition () {
|
|
178
|
+
thumbEl.value.style[m.value.topOrLeft] = scrollValuePercent.value
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
onMounted(() => {
|
|
182
|
+
mounted.value = true
|
|
183
|
+
const { top, left } = scrollableEl.value.getBoundingClientRect()
|
|
184
|
+
scrollableState.value.top = top
|
|
185
|
+
scrollableState.value.left = left
|
|
186
|
+
|
|
187
|
+
window.addEventListener('resize', forceRefreshThumb)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
// Clean up event listener.
|
|
191
|
+
onBeforeUnmount(() => {
|
|
192
|
+
window.removeEventListener('resize', forceRefreshThumb)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
defineExpose({ scroll })
|
|
197
196
|
</script>
|
|
198
197
|
|
|
199
198
|
<style lang="scss">
|
|
200
199
|
.w-scrollable {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.w-scrollbar {
|
|
206
|
-
position: absolute;
|
|
207
|
-
background: #000;
|
|
208
|
-
user-select: none;
|
|
200
|
+
display: flex;
|
|
201
|
+
border-radius: inherit;
|
|
209
202
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
203
|
+
&__content {
|
|
204
|
+
padding: 0;
|
|
205
|
+
flex: 1 1 auto;
|
|
206
|
+
overflow: hidden;
|
|
213
207
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
208
|
+
|
|
209
|
+
&__scrollbar {
|
|
210
|
+
position: relative;
|
|
211
|
+
flex: 0 0 auto;
|
|
212
|
+
background: $scrollbar-bg-color;
|
|
213
|
+
user-select: none;
|
|
214
|
+
|
|
215
|
+
&--horizontal {
|
|
216
|
+
inset: auto 0 0;
|
|
217
|
+
border-bottom-left-radius: inherit;
|
|
218
|
+
border-bottom-right-radius: inherit;
|
|
219
|
+
height: $scrollbar-size;
|
|
220
|
+
}
|
|
221
|
+
&--vertical {
|
|
222
|
+
inset: 0 0 0 auto;
|
|
223
|
+
border-top-right-radius: inherit;
|
|
224
|
+
border-bottom-right-radius: inherit;
|
|
225
|
+
width: $scrollbar-size;
|
|
226
|
+
}
|
|
217
227
|
}
|
|
218
228
|
|
|
219
|
-
&
|
|
229
|
+
&__scrollbar-thumb {
|
|
220
230
|
position: absolute;
|
|
221
|
-
background:
|
|
231
|
+
background: $scrollbar-thumb-color;
|
|
222
232
|
border-radius: $border-radius;
|
|
223
233
|
z-index: 1;
|
|
224
234
|
will-change: top left;
|
|
225
235
|
|
|
226
|
-
&:hover {background:
|
|
236
|
+
&:hover {background: $scrollbar-thumb-color;}
|
|
227
237
|
}
|
|
228
|
-
&--horizontal &
|
|
238
|
+
&--horizontal &__scrollbar-thumb {
|
|
229
239
|
height: 6px;
|
|
230
240
|
left: 0;
|
|
231
241
|
right: 0;
|
|
232
242
|
margin-top: 1px;
|
|
233
243
|
margin-bottom: 1px;
|
|
234
244
|
}
|
|
235
|
-
&--vertical &
|
|
245
|
+
&--vertical &__scrollbar-thumb {
|
|
236
246
|
width: 6px;
|
|
237
247
|
top: 0;
|
|
238
248
|
bottom: 0;
|
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
:root {
|
|
7
7
|
--w-base-increment: #{$base-increment};
|
|
8
8
|
--w-css-scope: #{$css-scope};
|
|
9
|
+
--w-contrast-bg-o025-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 2.5%, transparent)};
|
|
10
|
+
--w-contrast-bg-o05-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 5%, transparent)};
|
|
11
|
+
--w-contrast-bg-o1-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 10%, transparent)};
|
|
12
|
+
--w-contrast-bg-o2-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 20%, transparent)};
|
|
13
|
+
--w-contrast-bg-o3-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 30%, transparent)};
|
|
14
|
+
--w-contrast-bg-o4-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 40%, transparent)};
|
|
15
|
+
--w-contrast-bg-o5-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 50%, transparent)};
|
|
16
|
+
--w-contrast-bg-o6-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 60%, transparent)};
|
|
17
|
+
--w-contrast-bg-o7-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 70%, transparent)};
|
|
18
|
+
--w-contrast-bg-o8-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 80%, transparent)};
|
|
19
|
+
--w-contrast-bg-o9-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 90%, transparent)};
|
|
9
20
|
|
|
10
21
|
background-color: var(--w-base-bg-color);
|
|
11
22
|
color: var(--w-base-color);
|
|
@@ -126,6 +126,15 @@
|
|
|
126
126
|
.base-color--bg {background-color: var(--w-base-bg-color);}
|
|
127
127
|
.contrast-color {color: color-mix(in srgb, var(--w-contrast-color) 75%, transparent);}
|
|
128
128
|
.contrast-color--bg {background-color: var(--w-contrast-bg-color);}
|
|
129
|
+
|
|
130
|
+
.contrast-o025 {color: var(--w-contrast-bg-o025-color);}
|
|
131
|
+
.contrast-o025--bg {background-color: var(--w-contrast-bg-o025-color);}
|
|
132
|
+
.contrast-o05 {color: var(--w-contrast-bg-o05-color);}
|
|
133
|
+
.contrast-o05--bg {background-color: var(--w-contrast-bg-o05-color);}
|
|
134
|
+
@for $i from 1 through 9 {
|
|
135
|
+
.contrast-o#{$i} {color: var(--w-contrast-bg-o#{$i}-color);}
|
|
136
|
+
.contrast-o#{$i}--bg {background-color: var(--w-contrast-bg-o#{$i}-color);}
|
|
137
|
+
}
|
|
129
138
|
// ------------------------------------------------------
|
|
130
139
|
|
|
131
140
|
// Status colors - must stay last and have highest priority.
|
|
@@ -52,6 +52,15 @@
|
|
|
52
52
|
.d-iflex {display: inline-flex;}
|
|
53
53
|
.d-block {display: block;}
|
|
54
54
|
.d-iblock {display: inline-block;}
|
|
55
|
+
|
|
56
|
+
.ovh {overflow: hidden;}
|
|
57
|
+
.ovv {overflow: visible;}
|
|
58
|
+
.ova {overflow: auto;}
|
|
59
|
+
|
|
60
|
+
.op05 {opacity: 0.05;}
|
|
61
|
+
@for $i from 0 through 9 {
|
|
62
|
+
.op#{$i} {opacity: $i * 0.1;}
|
|
63
|
+
}
|
|
55
64
|
// ----------------------------------------------
|
|
56
65
|
|
|
57
66
|
// Borders (from 0 to 6), radii (from 0 to 6 + `m` for max).
|
|
@@ -148,3 +148,10 @@ $tooltip-bg-color: $detachable-bg-color !default;
|
|
|
148
148
|
$tooltip-color: $detachable-color !default;
|
|
149
149
|
$tooltip-border-color: $border-color !default;
|
|
150
150
|
// --------------------------------------------------------
|
|
151
|
+
|
|
152
|
+
// w-scrollable.
|
|
153
|
+
// --------------------------------------------------------
|
|
154
|
+
$scrollbar-size: 8px !default;
|
|
155
|
+
$scrollbar-bg-color: color-mix(in srgb, var(--w-contrast-bg-color) 8%, var(--w-base-bg-color)) !default;
|
|
156
|
+
$scrollbar-thumb-color: color-mix(in srgb, var(--w-contrast-bg-color) 25%, var(--w-base-bg-color)) !default;
|
|
157
|
+
// --------------------------------------------------------
|
|
@@ -205,12 +205,12 @@ export function mixColors (color1, color2, weight = 50) {
|
|
|
205
205
|
const red = clamp(Math.round(c1.red * c1Weight + c2.red * c2Weight), 0, 255)
|
|
206
206
|
const green = clamp(Math.round(c1.green * c1Weight + c2.green * c2Weight), 0, 255)
|
|
207
207
|
const blue = clamp(Math.round(c1.blue * c1Weight + c2.blue * c2Weight), 0, 255)
|
|
208
|
-
|
|
209
208
|
const alpha = c1.alpha * percentage + c2.alpha * (1 - percentage)
|
|
210
209
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
const channels = [red, green, blue]
|
|
211
|
+
if (c1.hasAlpha || c2.hasAlpha || alpha !== 1) channels.push(alpha)
|
|
212
|
+
|
|
213
|
+
return hexFromRGB(...channels)
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Defaults CSS variables. Will be overridden in the
|
|
2
|
-
// which fetches the CSS :root variables generated by
|
|
1
|
+
// Defaults CSS variables. Will be overridden in the doDynamicCSS() function
|
|
2
|
+
// which fetches the CSS :root variables generated by _base.scss.
|
|
3
3
|
const cssVars = {
|
|
4
4
|
cssScope: '.w-app',
|
|
5
5
|
baseIncrement: 4
|