wave-ui 3.28.0 → 4.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.
Files changed (93) hide show
  1. package/dist/.nojekyll +0 -0
  2. package/dist/types/types/$waveui.d.ts +15 -1
  3. package/dist/types/types/colors.d.ts +2 -0
  4. package/dist/types/types/components/WAccordion.d.ts +92 -6
  5. package/dist/types/types/components/WAutocomplete.d.ts +437 -0
  6. package/dist/types/types/components/WCheckbox.d.ts +34 -0
  7. package/dist/types/types/components/WCheckboxes.d.ts +30 -0
  8. package/dist/types/types/components/WInput.d.ts +34 -0
  9. package/dist/types/types/components/WMenu.d.ts +14 -7
  10. package/dist/types/types/components/WRadio.d.ts +34 -0
  11. package/dist/types/types/components/WRadios.d.ts +30 -0
  12. package/dist/types/types/components/WSelect.d.ts +34 -0
  13. package/dist/types/types/components/WSwitch.d.ts +34 -0
  14. package/dist/types/types/components/WTable.d.ts +7 -0
  15. package/dist/types/types/components/WTooltip.d.ts +22 -8
  16. package/dist/types/types/components/WTransitions.d.ts +104 -0
  17. package/dist/types/types/components/WTransitions.js +2 -0
  18. package/dist/types/types/components/WTree.d.ts +7 -0
  19. package/dist/types/types/components/index.d.ts +2 -1
  20. package/dist/types/types/index.d.ts +1 -0
  21. package/dist/types/types/mixins/detachable.d.ts +7 -0
  22. package/dist/types/types/mixins/detachable.js +2 -0
  23. package/dist/wave-ui.cjs.js +3 -3
  24. package/dist/wave-ui.css +1 -1
  25. package/dist/wave-ui.esm.js +1743 -1365
  26. package/dist/wave-ui.umd.js +3 -3
  27. package/package.json +1 -1
  28. package/src/wave-ui/components/index.js +0 -1
  29. package/src/wave-ui/components/transitions/w-transition-bounce.vue +2 -1
  30. package/src/wave-ui/components/transitions/w-transition-expand.vue +3 -2
  31. package/src/wave-ui/components/transitions/w-transition-fade.vue +2 -1
  32. package/src/wave-ui/components/transitions/w-transition-scale-fade.vue +2 -1
  33. package/src/wave-ui/components/transitions/w-transition-scale.vue +2 -1
  34. package/src/wave-ui/components/transitions/w-transition-slide-fade.vue +2 -1
  35. package/src/wave-ui/components/transitions/w-transition-slide.vue +2 -1
  36. package/src/wave-ui/components/transitions/w-transition-twist.vue +2 -1
  37. package/src/wave-ui/components/w-accordion/index.vue +10 -5
  38. package/src/wave-ui/components/w-accordion/item.vue +29 -14
  39. package/src/wave-ui/components/w-alert.vue +27 -29
  40. package/src/wave-ui/components/w-autocomplete.vue +626 -192
  41. package/src/wave-ui/components/w-badge.vue +54 -53
  42. package/src/wave-ui/components/w-breadcrumbs.vue +7 -9
  43. package/src/wave-ui/components/w-button/button.vue +21 -23
  44. package/src/wave-ui/components/w-button/index.vue +4 -4
  45. package/src/wave-ui/components/w-card.vue +8 -7
  46. package/src/wave-ui/components/w-checkbox.vue +31 -11
  47. package/src/wave-ui/components/w-checkboxes.vue +21 -3
  48. package/src/wave-ui/components/w-confirm.vue +22 -22
  49. package/src/wave-ui/components/w-dialog.vue +1 -1
  50. package/src/wave-ui/components/w-divider.vue +5 -5
  51. package/src/wave-ui/components/w-drawer.vue +3 -3
  52. package/src/wave-ui/components/w-form-element.vue +2 -2
  53. package/src/wave-ui/components/w-icon.vue +12 -14
  54. package/src/wave-ui/components/w-image.vue +1 -1
  55. package/src/wave-ui/components/w-input.vue +43 -25
  56. package/src/wave-ui/components/w-list.vue +11 -12
  57. package/src/wave-ui/components/w-menu.vue +57 -55
  58. package/src/wave-ui/components/w-notification.vue +4 -4
  59. package/src/wave-ui/components/w-progress.vue +6 -7
  60. package/src/wave-ui/components/w-radio.vue +32 -7
  61. package/src/wave-ui/components/w-radios.vue +28 -3
  62. package/src/wave-ui/components/w-rating.vue +7 -9
  63. package/src/wave-ui/components/w-scrollable.vue +4 -4
  64. package/src/wave-ui/components/w-select.vue +119 -101
  65. package/src/wave-ui/components/w-slider.vue +26 -26
  66. package/src/wave-ui/components/w-spinner.vue +5 -7
  67. package/src/wave-ui/components/w-switch.vue +71 -47
  68. package/src/wave-ui/components/w-table.vue +69 -36
  69. package/src/wave-ui/components/w-tabs/index.vue +21 -24
  70. package/src/wave-ui/components/w-tag.vue +35 -38
  71. package/src/wave-ui/components/w-textarea.vue +22 -22
  72. package/src/wave-ui/components/w-timeline.vue +6 -6
  73. package/src/wave-ui/components/w-toolbar.vue +8 -8
  74. package/src/wave-ui/components/w-tooltip.vue +30 -25
  75. package/src/wave-ui/components/w-tree.vue +35 -16
  76. package/src/wave-ui/core.js +9 -1
  77. package/src/wave-ui/mixins/detachable.js +118 -55
  78. package/src/wave-ui/mixins/ripple.js +2 -2
  79. package/src/wave-ui/scss/_base.scss +82 -17
  80. package/src/wave-ui/scss/_colors.scss +6 -75
  81. package/src/wave-ui/scss/_layout.scss +39 -47
  82. package/src/wave-ui/scss/_ripple.scss +2 -2
  83. package/src/wave-ui/scss/_transitions.scss +19 -19
  84. package/src/wave-ui/scss/_typography.scss +8 -9
  85. package/src/wave-ui/scss/variables/_mixins.scss +24 -25
  86. package/src/wave-ui/scss/variables/_variables.scss +4 -149
  87. package/src/wave-ui/utils/colors.js +7 -4
  88. package/src/wave-ui/utils/config.js +3 -4
  89. package/src/wave-ui/utils/dynamic-css.js +42 -20
  90. package/src/wave-ui/utils/ripple.js +3 -2
  91. package/dist/types/types/components/WApp.d.ts +0 -83
  92. package/src/wave-ui/components/w-app.vue +0 -24
  93. /package/dist/types/types/components/{WApp.js → WAutocomplete.js} +0 -0
@@ -2,6 +2,10 @@
2
2
  * A detachable element is an element that can be appended to another DOM node
3
3
  * (but keeping data-driven Vue DOM refreshes).
4
4
  * This mixin is used by w-tooltip & w-menu.
5
+ *
6
+ * Vue Teleport handles moving the floating content to the right DOM node.
7
+ * Event listeners are auto-attached to the activator slot's root element so
8
+ * callers no longer need the `template(#activator="{ on }") v-on="on"` pattern.
5
9
  */
6
10
 
7
11
  import { consoleWarn } from '../utils/console'
@@ -40,6 +44,11 @@ export default {
40
44
  },
41
45
 
42
46
  data: () => ({
47
+ /**
48
+ * When false (SSR + first hydrated paint), the Teleport subtree is not rendered so HTML matches.
49
+ * Set true in mounted(), then the menu/tooltip portal attaches — avoids Nuxt/Vue hydration mismatches.
50
+ */
51
+ detachableDomReady: false,
43
52
  // The event listeners handlers have to be removed the exact same way they have been attached.
44
53
  // Since the handler functions have variables that change after hot-reload, keep them exactly
45
54
  // as is in an array so we can delete them on destroy.
@@ -55,7 +64,11 @@ export default {
55
64
  // Set to true by computeDetachableCoords after positioning, false until then.
56
65
  // Components use this to bind visibility:hidden, so the element is never visible at the
57
66
  // wrong position before its coordinates are calculated.
58
- detachableReady: false
67
+ detachableReady: false,
68
+ // The Vue Teleport target. Stored as data (not computed) so it is resolved lazily at
69
+ // open()-time — after the DOM is committed — rather than during VNode creation where
70
+ // document.querySelector() may return null for elements that are part of the same render batch.
71
+ teleportTarget: null
59
72
  }),
60
73
 
61
74
  computed: {
@@ -74,7 +87,8 @@ export default {
74
87
 
75
88
  let target = this.appendTo || defaultTarget
76
89
  if (target === true) target = defaultTarget
77
- else if (this.appendTo === 'activator') target = this.$el.previousElementSibling || this.$el.nextElementSibling
90
+ // When appendTo is 'activator', teleport into the activator element itself.
91
+ else if (this.appendTo === 'activator') target = this.activatorEl
78
92
  else if (target && !['object', 'string'].includes(typeof target)) target = defaultTarget
79
93
  else if (typeof target === 'object' && !target.nodeType) {
80
94
  target = defaultTarget
@@ -111,7 +125,9 @@ export default {
111
125
  if (typeof document === 'undefined') return null
112
126
  return document.querySelector(this.activator)
113
127
  }
114
- return this.$el.nextElementSibling
128
+ // For slot-based activators the component root ($el) is a comment fragment anchor in
129
+ // Vue 3 multi-root components; nextElementSibling is the activator slot's first real element.
130
+ return this.$el?.nextElementSibling || null
115
131
  },
116
132
  set () {}
117
133
  },
@@ -154,6 +170,7 @@ export default {
154
170
  // next open starts hidden. Done here rather than on close() to let the leave animation play.
155
171
  onAfterLeave () {
156
172
  this.detachableReady = false
173
+ this.detachableEl = null
157
174
  },
158
175
 
159
176
  unbindActivatorDocEvents () {
@@ -166,6 +183,61 @@ export default {
166
183
  }
167
184
  },
168
185
 
186
+ /**
187
+ * Single delegating handler for auto-attached slot-activator DOM events.
188
+ * Reads the current activatorEventHandlers computed each invocation so that changes to
189
+ * `disable`, `showOnHover`, etc. are always reflected without re-attaching.
190
+ */
191
+ _handleActivatorEvent (e) {
192
+ const handler = this.activatorEventHandlers[e.type]
193
+ if (handler) handler(e)
194
+ },
195
+
196
+ /**
197
+ * Attach DOM event listeners directly to the activator slot's root element.
198
+ * Called once from mounted(); a single delegating handler covers all event types so we never
199
+ * need to re-attach when props like `disable` or `showOnHover` change.
200
+ * ! \ This function uses the DOM - NO SSR.
201
+ */
202
+ _attachActivatorListeners () {
203
+ if (typeof document === 'undefined') return
204
+ const el = this.activatorEl
205
+ if (!el) return
206
+
207
+ // Inspect the activator slot's first VNode for pre-declared event handlers.
208
+ // When the slot root already declares onClick / onMouseenter etc. — whether on a native
209
+ // element (w-select, w-autocomplete) or on a component (w-button @click="...") — the
210
+ // parent is managing that event itself. Skip auto-attaching the competing handler to avoid
211
+ // open/close races (both toggle() and the explicit handler firing on the same click).
212
+ // With the new API, the default slot is the activator (no #activator slot used).
213
+ let existingHandlers = {}
214
+ const activatorSlot = this.$slots.activator || this.$slots.default
215
+ if (activatorSlot) {
216
+ const vnodes = activatorSlot()
217
+ const firstVnode = vnodes?.[0]
218
+ existingHandlers = firstVnode?.props || {}
219
+ }
220
+
221
+ this._activatorDomEl = el
222
+ this._activatorAttachedEvents = []
223
+ ;['click', 'mouseenter', 'mouseleave', 'focus', 'blur'].forEach(evt => {
224
+ // Skip if the slot element already binds this event (camelCase Vue prop name: onClick etc.).
225
+ const vueProp = `on${evt.charAt(0).toUpperCase()}${evt.slice(1)}`
226
+ if (existingHandlers[vueProp]) return
227
+ el.addEventListener(evt, this._handleActivatorEvent)
228
+ this._activatorAttachedEvents.push(evt)
229
+ })
230
+ },
231
+
232
+ _detachActivatorListeners () {
233
+ if (!this._activatorDomEl) return
234
+ ;(this._activatorAttachedEvents || []).forEach(evt => {
235
+ this._activatorDomEl.removeEventListener(evt, this._handleActivatorEvent)
236
+ })
237
+ this._activatorDomEl = null
238
+ this._activatorAttachedEvents = []
239
+ },
240
+
169
241
  // ! \ This function uses the DOM - NO SSR (only trigger from beforeMount and later).
170
242
  async open (e) {
171
243
  if (this.disable) return
@@ -181,13 +253,22 @@ export default {
181
253
 
182
254
  // Hide before entering the DOM; handles rapid re-opens where detachableReady is still true.
183
255
  this.detachableReady = false
256
+
257
+ // Resolve the teleport target here, at open()-time, so the DOM is fully committed and
258
+ // detachableDefaultRoot() (for nested menus/tooltips) returns the correct element.
259
+ // Setting teleportTarget and detachableVisible in the same synchronous block lets Vue
260
+ // batch both into a single render — the content is never shown at the wrong location.
261
+ if (typeof document !== 'undefined') this.teleportTarget = this.appendToTarget
262
+
184
263
  this.detachableVisible = true
185
264
 
186
265
  // If the activator is external, there might be multiple,
187
266
  // so on open, the activator will be set to the event target.
188
267
  if (this.activator) this.activatorEl = e.target
189
268
 
190
- await this.insertInDOM()
269
+ // Wait for Vue Teleport to render the floating element into the target DOM node.
270
+ await this.$nextTick()
271
+ this.detachableEl = this.$refs.detachable?.$el || this.$refs.detachable
191
272
 
192
273
  if (this.minWidth === 'activator' && this.activatorEl) {
193
274
  this.activatorWidth = this.activatorEl.offsetWidth
@@ -361,32 +442,6 @@ export default {
361
442
  }
362
443
  },
363
444
 
364
- insertInDOM () {
365
- return new Promise(resolve => {
366
- this.$nextTick(() => {
367
- this.detachableEl = this.$refs.detachable?.$el || this.$refs.detachable
368
-
369
- // Move the tooltip/menu elsewhere in the DOM.
370
- if (this.detachableEl && this.appendToTarget) this.appendToTarget.appendChild(this.detachableEl)
371
- resolve()
372
- })
373
- })
374
- },
375
-
376
- removeFromDOM () {
377
- if (typeof document !== 'undefined') {
378
- document.removeEventListener('mousedown', this.onOutsideMousedown)
379
- }
380
- if (typeof window !== 'undefined') {
381
- window.removeEventListener('resize', this.onResize)
382
- }
383
- if (this.detachableEl?.parentNode) {
384
- this.detachableVisible = false
385
- this.detachableEl.remove()
386
- this.detachableEl = null
387
- }
388
- },
389
-
390
445
  // If the activator is external, add event listeners to the document and check the target is
391
446
  // the activator when toggling.
392
447
  // This way, the activator can be a future DOM element, that is not yet in the DOM.
@@ -401,8 +456,8 @@ export default {
401
456
  eventName = eventName.replace('mouseenter', 'mouseover').replace('mouseleave', 'mouseout')
402
457
  const handlerWrap = e => {
403
458
  // The activator can be a DOM string selector a ref or a DOM node.
404
- if (activatorIsString && e.target?.matches && e.target.matches(this.activator)) handler(e)
405
- else if (e.target === this.activatorEl || this.activatorEl.contains(e.target)) handler(e)
459
+ if (activatorIsString && e.target?.matches?.(this.activator)) handler(e)
460
+ else if (e.target === this.activatorEl || this.activatorEl?.contains(e.target)) handler(e)
406
461
  }
407
462
  document.addEventListener(eventName, handlerWrap)
408
463
  // The event listeners handlers have to be removed the exact same way they have been attached.
@@ -414,34 +469,39 @@ export default {
414
469
  },
415
470
 
416
471
  mounted () {
417
- // If the activator is external.
418
- if (this.activator) this.bindActivatorEvents()
419
-
420
- // If the activator seems to be undefined, it is probably a DOM node or Vue ref,
421
- // so check it on nextTick.
422
- else {
423
- this.$nextTick(() => {
424
- if (this.activator) this.bindActivatorEvents()
425
- if (this.modelValue && !this.disable) this.open({ target: this.activatorEl })
426
- })
427
- }
472
+ this.detachableDomReady = true
473
+ this.$nextTick(() => {
474
+ if (this.activator) {
475
+ // External activator: attach via document-level delegation.
476
+ this.bindActivatorEvents()
477
+ }
478
+ else {
479
+ // Slot-based activator: auto-attach DOM listeners to the slot's root element on next tick
480
+ // so the slot content is guaranteed to be in the DOM.
481
+ this.$nextTick(() => {
482
+ // Re-check activator prop (might have resolved from a Vue ref after the tick).
483
+ if (this.activator) this.bindActivatorEvents()
484
+ else this._attachActivatorListeners()
485
+
486
+ if (this.modelValue && !this.disable) this.open({ target: this.activatorEl })
487
+ })
488
+ }
428
489
 
429
- // Unwrap the overlay if any.
430
- if (this.overlay) this.overlayEl = this.$refs.overlay?.$el
490
+ // Unwrap the overlay if any.
491
+ if (this.overlay) this.overlayEl = this.$refs.overlay?.$el
431
492
 
432
- if (this.modelValue && this.activator && !this.disable) {
433
- this.toggle({ type: this.shouldShowOnClick ? 'click' : 'mouseenter', target: this.activatorEl })
434
- }
435
- else if (this.modelValue && !this.disable) this.open({ target: this.activatorEl })
493
+ if (this.modelValue && this.activator && !this.disable) {
494
+ this.toggle({ type: this.shouldShowOnClick ? 'click' : 'mouseenter', target: this.activatorEl })
495
+ }
496
+ else if (this.modelValue && !this.disable) this.open({ target: this.activatorEl })
497
+ })
436
498
  },
437
499
 
438
500
  unmounted () {
439
501
  this.close()
440
502
 
441
- this.removeFromDOM()
442
-
443
- // Remove the event listeners the exact same way they have been defined.
444
- // Fixes issues on hot-reloading.
503
+ // Clean up slot-activator DOM listeners and external-activator document listeners.
504
+ this._detachActivatorListeners()
445
505
  this.unbindActivatorDocEvents()
446
506
  },
447
507
 
@@ -451,6 +511,8 @@ export default {
451
511
  this.unbindActivatorDocEvents()
452
512
  if (!disabled) this.bindActivatorEvents()
453
513
  }
514
+ // For slot-based activators, _handleActivatorEvent always reads the current
515
+ // activatorEventHandlers computed which already respects `disable`, so no re-attach needed.
454
516
  if (disabled) this.close()
455
517
  else if (this.modelValue) this.open({ target: this.activatorEl })
456
518
  },
@@ -461,9 +523,10 @@ export default {
461
523
  else if (!bool) this.close()
462
524
  }
463
525
  },
526
+
527
+ // Keep teleportTarget in sync when the appendTo prop changes at runtime.
464
528
  appendTo () {
465
- this.removeFromDOM()
466
- this.insertInDOM()
529
+ if (typeof document !== 'undefined') this.teleportTarget = this.appendToTarget
467
530
  }
468
531
  }
469
532
  }
@@ -21,7 +21,7 @@ export default {
21
21
  * Resolve host for applyRipple. Vue (and some browsers) can leave `event.currentTarget` null
22
22
  * on delegated handlers, which would otherwise skip the ripple entirely.
23
23
  */
24
- onRipple (e, hostEl) {
24
+ onRipple (e, hostEl, options) {
25
25
  if (!this.rippleActive || !e) return
26
26
  let host = hostEl ?? e.currentTarget
27
27
  if (!host?.getBoundingClientRect) {
@@ -33,7 +33,7 @@ export default {
33
33
  host = this.$el
34
34
  }
35
35
  if (!host?.getBoundingClientRect) return
36
- applyRipple(host, e)
36
+ applyRipple(host, e, options)
37
37
  }
38
38
  }
39
39
  }
@@ -1,11 +1,43 @@
1
- @use "sass:map";
2
1
  @use "variables" as *;
3
2
 
4
3
  // The CSS variables are used in the dynamic-css.js file in order to reuse the same SCSS
5
4
  // variable presets.
6
5
  :root {
7
- --w-base-increment: #{$base-increment};
6
+ --w-base-font-size: 14px;
7
+ // Keeps spacing in sync when only --w-base-font-size is overridden (matches former Sass rounding).
8
+ --w-base-increment: round(nearest, calc(var(--w-base-font-size) / 4), 1px);
9
+ // Sass-only: must match $css-scope in _layout.scss and what dynamic-css reads for injected rules.
8
10
  --w-css-scope: #{$css-scope};
11
+ --w-layout-padding: 16px;
12
+ --w-border-radius: 4px;
13
+ --w-border-width: 1px;
14
+ --w-border-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 12%, transparent)};
15
+ --w-border: var(--w-border-width) solid var(--w-border-color);
16
+ --w-transition-duration: 0.25s;
17
+ --w-transition-duration-fast: 0.15s;
18
+ --w-transition-timing-fast-out-slow-in: cubic-bezier(0.4, 0, 0.2, 1);
19
+ --w-box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
20
+ 0 2px 2px 0 rgba(0, 0, 0, 0.15),
21
+ 0 1px 5px 0 rgba(0, 0, 0, 0.15);
22
+ --w-form-field-height: round(nearest, calc(2 * var(--w-base-font-size)), 1px);
23
+ // Even px step (same as former 2 * round(1.3 * $base-font-size / 2)).
24
+ --w-small-form-el-size: round(nearest, calc(1.3 * var(--w-base-font-size)), 2px);
25
+ --w-scrollbar-size: 8px;
26
+
27
+ @for $i from -6 through -1 {
28
+ --w-shadow-n#{-1 * $i}: 0 0 round(nearest, calc(#{$i} * var(--w-base-increment)), 1px) rgba(0, 0, 0, max(0.15, calc(0.15 * #{-$i} / 2))) inset;
29
+ }
30
+ --w-shadow-0: none;
31
+ @for $i from 1 through 6 {
32
+ --w-shadow-#{$i}: 0 0 1px rgba(0, 0, 0, 0.1),
33
+ round(nearest, calc(var(--w-base-increment) * #{$i} / 4), 1px) round(nearest, calc(var(--w-base-increment) * #{$i} / 4), 1px) round(nearest, calc(#{$i} * var(--w-base-increment)), 1px) rgba(0, 0, 0, max(0.15, calc(0.15 * #{$i} / 2)));
34
+ }
35
+
36
+ --w-base-color-muted: #{color-mix(in srgb, var(--w-base-color) 70%, transparent)};
37
+ --w-overlay-scrim-color: #{color-mix(in srgb, #000 30%, transparent)};
38
+ --w-surface-hover-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 5%, transparent)};
39
+ --w-surface-active-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 8%, transparent)};
40
+ --w-surface-selected-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 15%, transparent)};
9
41
  --w-contrast-bg-o025-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 2.5%, transparent)};
10
42
  --w-contrast-bg-o05-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 5%, transparent)};
11
43
  --w-contrast-bg-o1-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 10%, transparent)};
@@ -18,26 +50,59 @@
18
50
  --w-contrast-bg-o8-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 80%, transparent)};
19
51
  --w-contrast-bg-o9-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 90%, transparent)};
20
52
 
53
+ --w-detachable-bg-color: var(--w-base-bg-color);
54
+ --w-detachable-color: var(--w-base-color);
55
+ --w-confirm-bg-color: var(--w-detachable-bg-color);
56
+ --w-confirm-color: var(--w-detachable-color);
57
+ --w-dialog-bg-color: var(--w-base-bg-color);
58
+ --w-divider-color: var(--w-border-color);
59
+ --w-drawer-max-size: 380px;
60
+ --w-drawer-bg-color: var(--w-base-bg-color);
61
+ --w-menu-bg-color: var(--w-detachable-bg-color);
62
+ --w-menu-color: var(--w-detachable-color);
63
+ --w-progress-bg-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 15%, transparent)};
64
+ --w-rating-bg-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 25%, transparent)};
65
+ --w-slider-height: var(--w-base-increment);
66
+ --w-slider-track-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 15%, transparent)};
67
+ --w-slider-thumb-button-bg-color: var(--w-base-bg-color);
68
+ --w-slider-thumb-label-bg-color: var(--w-base-bg-color);
69
+ --w-slider-thumb-label-color: #{color-mix(in srgb, var(--w-base-color) 75%, transparent)};
70
+ --w-slider-step-label-bg-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 20%, transparent)};
71
+ --w-slider-step-label-color: #{color-mix(in srgb, var(--w-base-color) 50%, transparent)};
72
+ --w-switch-inactive-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 25%, transparent)};
73
+ --w-switch-thumb-color: var(--w-base-bg-color);
74
+ --w-table-tr-odd-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 2%, transparent)};
75
+ --w-table-tr-hover-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 5%, transparent)};
76
+ --w-table-color: #{color-mix(in srgb, var(--w-contrast-color) 70%, transparent)};
77
+ --w-textarea-line-height: 1.2;
78
+ --w-timeline-bullet-color: var(--w-base-bg-color);
79
+ --w-timeline-bg-color: #{color-mix(in srgb, var(--w-contrast-bg-color) 25%, transparent)};
80
+ --w-toolbar-max-size: 380px;
81
+ --w-toolbar-bg-color: var(--w-base-bg-color);
82
+ --w-tooltip-bg-color: var(--w-detachable-bg-color);
83
+ --w-tooltip-color: var(--w-detachable-color);
84
+ --w-tooltip-border-color: var(--w-border-color);
85
+
21
86
  background-color: var(--w-base-bg-color);
22
87
  color: var(--w-base-color);
23
88
  }
24
89
 
25
90
  :root[data-theme="light"] {
26
- --w-base-bg-color: #{map.get($theme-light, 'base-bg-color')};
27
- --w-base-color: #{map.get($theme-light, 'base-color')};
28
- --w-contrast-bg-color: #{map.get($theme-light, 'contrast-bg-color')};
29
- --w-contrast-color: #{map.get($theme-light, 'contrast-color')};
30
- --w-caption-color: #{map.get($theme-light, 'caption-color')};
31
- --w-disabled-color: #{map.get($theme-light, 'disabled-color')};
91
+ --w-base-bg-color: #fff;
92
+ --w-base-color: #000;
93
+ --w-contrast-bg-color: #000;
94
+ --w-contrast-color: #fff;
95
+ --w-caption-color: #a0a0a0;
96
+ --w-disabled-color: #ccc;
32
97
  }
33
98
 
34
99
  :root[data-theme="dark"] {
35
- --w-base-bg-color: #{map.get($theme-dark, 'base-bg-color')};
36
- --w-base-color: #{map.get($theme-dark, 'base-color')};
37
- --w-contrast-bg-color: #{map.get($theme-dark, 'contrast-bg-color')};
38
- --w-contrast-color: #{map.get($theme-dark, 'contrast-color')};
39
- --w-caption-color: #{map.get($theme-dark, 'caption-color')};
40
- --w-disabled-color: #{map.get($theme-dark, 'disabled-color')};
100
+ --w-base-bg-color: #222;
101
+ --w-base-color: #fff;
102
+ --w-contrast-bg-color: #fff;
103
+ --w-contrast-color: #000;
104
+ --w-caption-color: #6e6e6e;
105
+ --w-disabled-color: #4a4a4a;
41
106
  }
42
107
 
43
108
  * {
@@ -72,13 +137,13 @@ a {text-decoration: none;}
72
137
  }
73
138
 
74
139
  .w-main {
75
- padding-left: 3 * $base-increment;
76
- padding-right: 3 * $base-increment;
140
+ padding-left: calc(3 * var(--w-base-increment));
141
+ padding-right: calc(3 * var(--w-base-increment));
77
142
  }
78
143
 
79
144
  // Structure classes.
80
145
  // ----------------------------------------------
81
146
  .content-wrap {
82
147
  position: relative;
83
- padding: $layout-padding;
148
+ padding: var(--w-layout-padding);
84
149
  }
@@ -1,4 +1,3 @@
1
- @use 'sass:color';
2
1
  @use 'variables' as *;
3
2
 
4
3
  #{$css-scope} {
@@ -29,82 +28,14 @@
29
28
  // For each color, create a [color] and a [color]--bg associated classes,
30
29
  // + 6 shades lighter and 6 shades darker.
31
30
  @each $label, $color in $colors {
32
- .#{$label}--bg {background-color: $color;}
33
- .#{$label} {color: $color;}
31
+ .#{$label}--bg {background-color: var(--w-#{$label}-color);}
32
+ .#{$label} {color: var(--w-#{$label}-color);}
34
33
 
35
34
  @for $i from 1 through 6 {
36
- $light-increment: 7.5;
37
- $light-offset: 0;
38
- $dark-increment: 6.2;
39
- // Some color shades need bigger or smaller increments to end up with the same scale.
40
- @if $label == 'deep-orange' {
41
- $light-increment: 6.4;
42
- }
43
- @if $label == 'orange' {
44
- }
45
- @else if $label == 'green' {
46
- $light-increment: 7.6;
47
- $dark-increment: 5.7;
48
- }
49
- @else if $label == 'amber' {
50
- }
51
- @else if $label == 'pink' {
52
- $light-increment: 6.7;
53
- $light-offset: -4;
54
- }
55
- @else if $label == 'red' {
56
- $light-increment: 6.5;
57
- $light-offset: -1;
58
- }
59
- @else if $label == 'indigo' {
60
- $light-increment: 8;
61
- $dark-increment: 5.7;
62
- }
63
- @else if $label == 'deep-purple' {
64
- $light-increment: 8;
65
- $dark-increment: 5.7;
66
- }
67
- @else if $label == 'light-blue' {
68
- $light-increment: 7.8;
69
- }
70
- @else if $label == 'light-green' {
71
- $light-increment: 6;
72
- $light-offset: -5;
73
- }
74
- @else if $label == 'lime' {
75
- $light-increment: 6.2;
76
- $light-offset: -6;
77
- }
78
- @else if $label == 'yellow' {
79
- $light-increment: 5.5;
80
- $light-offset: -8;
81
- }
82
- @else if $label == 'purple' {
83
- $light-increment: 6.5;
84
- $light-offset: -8.5;
85
- }
86
- @else if $label == 'cyan' {
87
- $light-increment: 9.4;
88
- $light-offset: 6.5;
89
- $dark-increment: 5.7;
90
- }
91
- @else if $label == 'teal' {
92
- $light-increment: 9.6;
93
- $light-offset: 5;
94
- $dark-increment: 5.4;
95
- }
96
- @else if $label == 'blue' {
97
- $light-increment: 6.8;
98
- $dark-increment: 6.8;
99
- }
100
- @else if $label == 'brown' {
101
- $light-increment: 8.8;
102
- $dark-increment: 5;
103
- }
104
- .#{$label}-light#{$i}--bg {background-color: color.adjust($color, $lightness: $light-increment * $i * 1% - $light-offset);}
105
- .#{$label}-light#{$i} {color: color.adjust($color, $lightness: $light-increment * $i * 1% - $light-offset);}
106
- .#{$label}-dark#{$i}--bg {background-color: color.adjust($color, $lightness: - $dark-increment * $i * 1%);}
107
- .#{$label}-dark#{$i} {color: color.adjust($color, $lightness: - $dark-increment * $i * 1%);}
35
+ .#{$label}-light#{$i}--bg {background-color: var(--w-#{$label}-light#{$i}-color);}
36
+ .#{$label}-light#{$i} {color: var(--w-#{$label}-light#{$i}-color);}
37
+ .#{$label}-dark#{$i}--bg {background-color: var(--w-#{$label}-dark#{$i}-color);}
38
+ .#{$label}-dark#{$i} {color: var(--w-#{$label}-dark#{$i}-color);}
108
39
  }
109
40
  }
110
41