wave-ui 3.13.6 → 3.14.0
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/types/$waveui.d.ts +29 -29
- package/dist/types/colors.d.ts +8 -0
- package/dist/wave-ui.cjs.js +1 -1
- package/dist/wave-ui.es.js +1046 -1002
- package/dist/wave-ui.umd.js +1 -1
- package/package.json +2 -2
- package/src/wave-ui/components/w-button/button.vue +13 -11
- package/src/wave-ui/utils/colors.js +234 -15
- package/src/wave-ui/utils/config.js +1 -1
- package/src/wave-ui/utils/dynamic-css.js +3 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-ui",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "An emerging UI framework for Vue.js (2
|
|
3
|
+
"version": "3.14.0",
|
|
4
|
+
"description": "An emerging 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",
|
|
7
7
|
"repository": "https://github.com/antoniandre/wave-ui",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
component.w-button(
|
|
3
|
-
:is="route ? 'a' : 'button'"
|
|
3
|
+
:is="!disabled && route ? 'a' : 'button'"
|
|
4
4
|
:type="!route && type"
|
|
5
|
-
:href="(route && (externalLink ? route : resolvedRoute)) || null"
|
|
5
|
+
:href="(!disabled && route && (externalLink ? route : resolvedRoute)) || null"
|
|
6
6
|
:class="classes"
|
|
7
7
|
:disabled="!!disabled || null"
|
|
8
8
|
v-bind="attrs"
|
|
@@ -75,20 +75,22 @@ export default {
|
|
|
75
75
|
return this.hasRouter ? this.$router.resolve(this.route).href : this.route
|
|
76
76
|
},
|
|
77
77
|
attrs () {
|
|
78
|
+
const isValidRouterLink = this.route && this.hasRouter && !this.forceLink && !this.externalLink
|
|
78
79
|
// If the button is a router-link, we can't apply events on it since vue-router needs the .native
|
|
79
80
|
// modifier but it's not available with the v-on directive.
|
|
80
81
|
// So do a manual router.push if $router is present.
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
const onRouterLinkClick = e => {
|
|
83
|
+
if (this.$attrs.onClick) this.$attrs.onClick(e)
|
|
84
|
+
|
|
85
|
+
this.$router.push(this.route)
|
|
86
|
+
e.stopPropagation() // If going to a route, no need to bubble up the event.
|
|
87
|
+
e.preventDefault()
|
|
88
|
+
}
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
+
return {
|
|
91
|
+
...this.$attrs,
|
|
92
|
+
onClick: !this.disabled && (isValidRouterLink ? onRouterLinkClick : this.$attrs.onClick)
|
|
90
93
|
}
|
|
91
|
-
return this.route && this.hasRouter && !this.forceLink && !this.externalLink ? attrsForRouterLink : this.$attrs
|
|
92
94
|
},
|
|
93
95
|
size () {
|
|
94
96
|
return (
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
return '#' + color.slice(1).match(/../g)
|
|
3
|
-
.map(x => {
|
|
4
|
-
x = +`0x${x}` + amount
|
|
5
|
-
return (x < 0 ? 0 : (x > 255 ? 255 : x)).toString(16).padStart(2, 0)
|
|
6
|
-
})
|
|
7
|
-
.join('')
|
|
8
|
-
}
|
|
1
|
+
import { consoleError } from './console'
|
|
9
2
|
|
|
10
3
|
/**
|
|
11
4
|
* Generates the color shades for each custom color and status colors for the current theme (only),
|
|
@@ -19,15 +12,18 @@ export const generateColorShades = config => {
|
|
|
19
12
|
const themeOfColors = config.colors[theme]
|
|
20
13
|
themeOfColors.shades = {}
|
|
21
14
|
|
|
22
|
-
for (
|
|
23
|
-
if (
|
|
24
|
-
|
|
15
|
+
for (const label in themeOfColors) {
|
|
16
|
+
if (label === 'shades') continue // Skip if item is the `shades` container.
|
|
17
|
+
|
|
18
|
+
// Account for string colors and the fine tuned shaded colors
|
|
19
|
+
const colorInfo = themeOfColors[label]
|
|
20
|
+
const color = { label, color: (themeOfColors[label]?.color ?? themeOfColors[label]).replace('#', '') }
|
|
25
21
|
const col = color.color
|
|
26
22
|
if (col.length === 3) color.color = col[0] + '' + col[0] + col[1] + col[1] + col[2] + col[2]
|
|
27
23
|
|
|
28
|
-
for (let i = 1; i <=
|
|
29
|
-
const lighterColor =
|
|
30
|
-
const darkerColor =
|
|
24
|
+
for (let i = 1; i <= 6; i++) {
|
|
25
|
+
const lighterColor = lighten(`#${color.color}`, i * (colorInfo?.lightIncrement ?? 16) + (colorInfo?.lightOffset ?? 0))
|
|
26
|
+
const darkerColor = darken(`#${color.color}`, i * (colorInfo?.darkIncrement ?? 12.4) + (colorInfo?.darkOffset ?? 0))
|
|
31
27
|
// Adding the shades to the config object to generate the CSS from w-app.
|
|
32
28
|
themeOfColors.shades[`${color.label}-light${i}`] = lighterColor
|
|
33
29
|
themeOfColors.shades[`${color.label}-dark${i}`] = darkerColor
|
|
@@ -52,6 +48,230 @@ export const flattenColors = (themeColors, colorPalette) => {
|
|
|
52
48
|
return colors
|
|
53
49
|
}
|
|
54
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Clamp a value between a minimum and maximum value.
|
|
53
|
+
*
|
|
54
|
+
* @param {number} value - Value to clamp
|
|
55
|
+
* @param {number} min - Minimum possible value
|
|
56
|
+
* @param {number} max - Maximum possible value
|
|
57
|
+
* @returns {number} The clamped value
|
|
58
|
+
*/
|
|
59
|
+
export function clamp (value, min, max) {
|
|
60
|
+
return Math.min(Math.max(value, min), max)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Convert a number to a hexadecimal string.
|
|
65
|
+
*
|
|
66
|
+
* @param {number} value - The number to convert
|
|
67
|
+
* @throws {Error} - If the value is not in the range 0~255
|
|
68
|
+
* @returns {string} The hexadecimal string
|
|
69
|
+
*/
|
|
70
|
+
export function toHexString (value) {
|
|
71
|
+
const trimmedValue = value.toString(16)
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
(trimmedValue.length === 1 && `0${trimmedValue}`) ||
|
|
75
|
+
(trimmedValue.length === 2 && trimmedValue) ||
|
|
76
|
+
consoleError(`expected value from 0~255, got: ${value}`) ||
|
|
77
|
+
''
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Determines if a string is a valid hex color
|
|
83
|
+
*
|
|
84
|
+
* Valid long hex colors formats:
|
|
85
|
+
* - #ffffff,
|
|
86
|
+
* - #00000033
|
|
87
|
+
*
|
|
88
|
+
* @param {string} str - The string to test
|
|
89
|
+
* @returns {boolean} - Whether the string is a valid hex color
|
|
90
|
+
*/
|
|
91
|
+
export function isValidHex (str) {
|
|
92
|
+
return /^#[0-9a-f]{6}([0-9a-f]{2})?$/i.test(str)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Determines if a string is a short hex color
|
|
97
|
+
*
|
|
98
|
+
* Valid short hex colors formats:
|
|
99
|
+
* - #fff,
|
|
100
|
+
* - #0003
|
|
101
|
+
*
|
|
102
|
+
* @param {string} str - The string to test
|
|
103
|
+
* @returns {boolean} - Whether the string is a short hex color
|
|
104
|
+
*/
|
|
105
|
+
export function isShortHex (str) {
|
|
106
|
+
return /^#[0-9a-f]{3}([0-9a-f])?$/i.test(str)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Expands a short hex color to a full hex color
|
|
111
|
+
*
|
|
112
|
+
* @param {string} str - The short hex color to expand such as '#fff' or '#0003' with an alpha value
|
|
113
|
+
* @returns {string} - The expanded hex color such as '#ffffff' or '#00000033' with an alpha value
|
|
114
|
+
*/
|
|
115
|
+
export function expandShortHex (str) {
|
|
116
|
+
return `#${str.substring(1).split('').map(char => `${char}${char}`).join('')}`
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Parse a color string into a full length hex string
|
|
121
|
+
*
|
|
122
|
+
* @param {string} str - The color string to parse, either a full hex color or short hex color e.g. '#fff' or '#001122'.
|
|
123
|
+
* This can also include an alpha value e.g. '#00112233' or '#0003'.
|
|
124
|
+
* @throws {Error} - If the string is not a valid color
|
|
125
|
+
* @returns {string} - The full parsed hex color for example, with alpha: '#00112233'
|
|
126
|
+
*/
|
|
127
|
+
function getColorFullHex (str) {
|
|
128
|
+
return (isValidHex(str) && str) || (isShortHex(str) && expandShortHex(str)) || consoleError(`expected color hex string, got '${str}'`) || ''
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Break a hex color string into it's components
|
|
133
|
+
*
|
|
134
|
+
* @param {string} color - The color string to parse
|
|
135
|
+
* @returns {{ red, green, blue, alpha, hasAlpha: boolean }} - The color components
|
|
136
|
+
*/
|
|
137
|
+
function getColorComponents (color) {
|
|
138
|
+
const hex = getColorFullHex(color)
|
|
139
|
+
|
|
140
|
+
const red = parseInt(hex.substring(1, 3), 16)
|
|
141
|
+
const green = parseInt(hex.substring(3, 5), 16)
|
|
142
|
+
const blue = parseInt(hex.substring(5, 7), 16)
|
|
143
|
+
|
|
144
|
+
// Compare against length 9 because the full hex string will have the `#` at the beginning of it
|
|
145
|
+
const alpha = hex.length === 9
|
|
146
|
+
? parseInt(hex.substring(7, 9), 16) / 255
|
|
147
|
+
: 1.0
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
red,
|
|
151
|
+
green,
|
|
152
|
+
blue,
|
|
153
|
+
alpha,
|
|
154
|
+
hasAlpha: hex.length === 9
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Convert RGB components to a hex color string
|
|
160
|
+
*
|
|
161
|
+
* @param {number} r - red
|
|
162
|
+
* @param {number} g - green
|
|
163
|
+
* @param {number} b - blue
|
|
164
|
+
* @param {number} [a] - alpha
|
|
165
|
+
* @returns {string} - The hex color string for example: '#001122' or with alpha: '#00112233'
|
|
166
|
+
*/
|
|
167
|
+
export function hexFromRGB (r, g, b, a) {
|
|
168
|
+
return `#${toHexString(r)}${toHexString(g)}${toHexString(b)}${a ? toHexString(Math.floor(a * 255)) : ''}`
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Mix two colors together. The same way that SCSS does it
|
|
173
|
+
*
|
|
174
|
+
* Valid hex colors formats:
|
|
175
|
+
* - #fff
|
|
176
|
+
* - #0003
|
|
177
|
+
* - #ffffff
|
|
178
|
+
* - #00000033
|
|
179
|
+
*
|
|
180
|
+
* @param {string} color1 - Color 1 as a hex
|
|
181
|
+
* @param {string} color2 - Color 2 as a hex
|
|
182
|
+
* @param {number} [weight] - The percentage to mix them at. Default: 50
|
|
183
|
+
* @returns {string} - The new mixed color as a hex for example: '#001122' or with alpha: '#00112233'
|
|
184
|
+
*
|
|
185
|
+
* @see https://gist.github.com/ktnyt/2573047b5b4c7c775f2be22326ebf6a8 for the original Typescript implementation
|
|
186
|
+
*/
|
|
187
|
+
export function mixColors (color1, color2, weight = 50) {
|
|
188
|
+
const c1 = getColorComponents(color1)
|
|
189
|
+
const c2 = getColorComponents(color2)
|
|
190
|
+
|
|
191
|
+
const percentage = clamp(weight, 0, 100) / 100
|
|
192
|
+
const alphaWeight = 2 * percentage - 1
|
|
193
|
+
|
|
194
|
+
const alphaDiff = c1.alpha - c2.alpha
|
|
195
|
+
const c1Weight = (
|
|
196
|
+
(
|
|
197
|
+
alphaWeight * alphaDiff === -1
|
|
198
|
+
? alphaWeight
|
|
199
|
+
: (alphaWeight + alphaDiff) / (1 + alphaWeight * alphaDiff)
|
|
200
|
+
) + 1
|
|
201
|
+
) / 2
|
|
202
|
+
const c2Weight = 1 - c1Weight
|
|
203
|
+
|
|
204
|
+
const red = clamp(Math.round(c1.red * c1Weight + c2.red * c2Weight), 0, 255)
|
|
205
|
+
const green = clamp(Math.round(c1.green * c1Weight + c2.green * c2Weight), 0, 255)
|
|
206
|
+
const blue = clamp(Math.round(c1.blue * c1Weight + c2.blue * c2Weight), 0, 255)
|
|
207
|
+
|
|
208
|
+
const alpha = c1.alpha * percentage + c2.alpha * (1 - percentage)
|
|
209
|
+
|
|
210
|
+
return c1.hasAlpha || c2.hasAlpha || alpha !== 1
|
|
211
|
+
? hexFromRGB(red, green, blue, alpha)
|
|
212
|
+
: hexFromRGB(red, green, blue)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Lighten a color by a percentage
|
|
217
|
+
*
|
|
218
|
+
* Valid hex colors formats:
|
|
219
|
+
* - #fff
|
|
220
|
+
* - #0003
|
|
221
|
+
* - #ffffff
|
|
222
|
+
* - #00000033
|
|
223
|
+
*
|
|
224
|
+
* @param {string} color - The hex color to lighten
|
|
225
|
+
* @param {number} [weight] - The amount to lighten by.
|
|
226
|
+
* Default: `15` to match the SCSS `light-increment` value of `7.5`
|
|
227
|
+
* the way the math is handled here we double the weight to match the SCSS result
|
|
228
|
+
* @returns {string} - The new lightened color as a full hex string, potentially with alpha
|
|
229
|
+
*/
|
|
230
|
+
export function lighten (color, weight = 15) {
|
|
231
|
+
return mixColors('#ffffff', color, weight)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Darken a color by a percentage
|
|
236
|
+
*
|
|
237
|
+
* Valid hex colors formats:
|
|
238
|
+
* - #fff
|
|
239
|
+
* - #0003
|
|
240
|
+
* - #ffffff
|
|
241
|
+
* - #00000033
|
|
242
|
+
*
|
|
243
|
+
* @param {string} color - The hex color to darken
|
|
244
|
+
* @param {number} [weight] - The amount to darken by.
|
|
245
|
+
* Default: `12.4` to match the SCSS `dark-increment` value of `6.2`
|
|
246
|
+
* the way the math is handled here we double the weight to match the SCSS result
|
|
247
|
+
* @returns {string} - The new darkened color as a full hex string, potentially with alpha
|
|
248
|
+
*/
|
|
249
|
+
export function darken (color, weight = 12.4) {
|
|
250
|
+
return mixColors('#000000', color, weight)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Generate a color palette from a color info object
|
|
255
|
+
*
|
|
256
|
+
* @param {Record<string,{color: string, lightOffset: number, lightIncrement: number, darkOffset: number, darkIncrement: number}>} colorInfo - Colors to generate the palette from
|
|
257
|
+
* @returns {Array<{label: string, color: string, shades: Array<{label: string, color: string}>}>} - The color palette
|
|
258
|
+
*/
|
|
259
|
+
export function generateColorPalette (colorInfo) {
|
|
260
|
+
return Object.keys(colorInfo).map(label => {
|
|
261
|
+
const color = colorInfo[label]?.color ?? colorInfo[label]
|
|
262
|
+
return {
|
|
263
|
+
label,
|
|
264
|
+
color,
|
|
265
|
+
shades: [6, 5, 4, 3, 2, 1, -1, -2, -3, -4, -5, -6].map(i => ({
|
|
266
|
+
label: `${label}-${i > 0 ? 'light' : 'dark'}${Math.abs(i)}`,
|
|
267
|
+
color: i > 0
|
|
268
|
+
? lighten(color, (i * (colorInfo[label]?.lightIncrement ?? 15)) - (colorInfo[label]?.lightOffset ?? 0))
|
|
269
|
+
: darken(color, (-i * (colorInfo[label]?.darkIncrement ?? 12.4)) - (colorInfo[label]?.darkOffset ?? 0))
|
|
270
|
+
}))
|
|
271
|
+
}
|
|
272
|
+
})
|
|
273
|
+
}
|
|
274
|
+
|
|
55
275
|
export const colorPalette = [
|
|
56
276
|
{
|
|
57
277
|
label: 'pink',
|
|
@@ -323,7 +543,6 @@ export const colorPalette = [
|
|
|
323
543
|
{ label: 'deep-orange-dark6', color: '#661f00' }
|
|
324
544
|
]
|
|
325
545
|
},
|
|
326
|
-
|
|
327
546
|
{
|
|
328
547
|
label: 'red',
|
|
329
548
|
color: '#fa3317',
|
|
@@ -68,7 +68,7 @@ export const mergeConfig = (options, conf = config) => {
|
|
|
68
68
|
else {
|
|
69
69
|
for (const key in options) {
|
|
70
70
|
const option = options[key]
|
|
71
|
-
if (typeof option === 'object') {
|
|
71
|
+
if (typeof option === 'object' && typeof conf[key] === 'object') {
|
|
72
72
|
mergeConfig(options[key], conf[key])
|
|
73
73
|
}
|
|
74
74
|
else conf[key] = option
|
|
@@ -41,7 +41,7 @@ const generateColors = (themeColors, generateShadeCssVariables) => {
|
|
|
41
41
|
// Status colors must remain after the other colors so they have priority in form validations.
|
|
42
42
|
// That only makes sense when there are 2 colors on the same element: e.g. `span.primary.error`.
|
|
43
43
|
const allColors = { ...colors, info, warning, success, error }
|
|
44
|
-
for (const colorName in allColors) cssVariables[colorName] = allColors[colorName]
|
|
44
|
+
for (const colorName in allColors) cssVariables[colorName] = allColors[colorName]?.color ?? allColors[colorName]
|
|
45
45
|
if (generateShadeCssVariables) {
|
|
46
46
|
for (const colorName in shades) cssVariables[colorName] = shades[colorName]
|
|
47
47
|
}
|
|
@@ -272,12 +272,12 @@ export const injectCSSInDOM = $waveui => {
|
|
|
272
272
|
window.addEventListener('resize', () => getBreakpoint($waveui))
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
export const injectColorsCSSInDOM = (themeColors, generateShadeCssVariables) => {
|
|
275
|
+
export const injectColorsCSSInDOM = (themeColors, colorPalette, generateShadeCssVariables) => {
|
|
276
276
|
// Inject global dynamic CSS classes in document head.
|
|
277
277
|
if (!document.getElementById('wave-ui-colors')) {
|
|
278
278
|
const css = document.createElement('style')
|
|
279
279
|
css.id = 'wave-ui-colors'
|
|
280
|
-
css.innerHTML = generateColors(themeColors, generateShadeCssVariables)
|
|
280
|
+
css.innerHTML = generateColors(themeColors, colorPalette, generateShadeCssVariables)
|
|
281
281
|
|
|
282
282
|
const firstStyle = document.head.querySelectorAll('style,link[rel="stylesheet"]')[0]
|
|
283
283
|
if (firstStyle) firstStyle.before(css)
|