edu-webcomponents 1.24.0 โ†’ 1.26.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/CHANGELOG.md CHANGED
@@ -4,9 +4,24 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [v1.26.0](https://github.com/eduardocruzpalacios/edu-webcomponents/compare/v1.25.0...v1.26.0)
8
+
9
+ - feat: improve accessibility of EduButton according to 2.5.5 in WCAG 2.1 and 2.4.7 in WCAG 2.2 [`969a143`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/969a143fee573fcb0d93072de73a143a2e2116b6)
10
+ - refactor: code [`65c723d`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/65c723dc344e9b8bb9da515b76e465c21eab3097)
11
+
12
+ #### [v1.25.0](https://github.com/eduardocruzpalacios/edu-webcomponents/compare/v1.24.0...v1.25.0)
13
+
14
+ > 11 January 2026
15
+
16
+ - feat: implement dark mode [`a5470d0`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/a5470d0e3d7428ae6084dc3a1c4389ab4223517e)
17
+ - chore: release v1.25.0 [`3e2bbc7`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/3e2bbc709607880488b421e48d3dc353d7870034)
18
+
7
19
  #### [v1.24.0](https://github.com/eduardocruzpalacios/edu-webcomponents/compare/v1.23.0...v1.24.0)
8
20
 
9
- - docs: improve README.md [`f14c2e0`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/f14c2e0201036091fb21e1f649be85ea63f6ffaa)
21
+ > 9 January 2026
22
+
23
+ - docs: improve README.md [`9300008`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/9300008a5fe9dedd24bc8b2ee39b663d01b9ef85)
24
+ - chore: release v1.24.0 [`c66fe45`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/c66fe45ca3b150cb62126dfbd102b2244f59802b)
10
25
 
11
26
  #### [v1.23.0](https://github.com/eduardocruzpalacios/edu-webcomponents/compare/v1.22.0...v1.23.0)
12
27
 
package/README.md CHANGED
@@ -14,6 +14,7 @@ A modern, lightweight collection of reusable web components built with [Lit](htt
14
14
  - โ™ฟ **Accessible** - ARIA-compliant components with keyboard support
15
15
  - ๐ŸŽฏ **Framework-agnostic** - Works with any JavaScript framework or vanilla JS
16
16
  - ๐ŸŽจ **Customizable** - CSS custom properties for easy theming
17
+ - ๐ŸŒ“ **Dark mode support** - Automatic theme switching with `@media (prefers-color-scheme: dark)`
17
18
  - ๐Ÿ“ฆ **Tree-shakeable** - Import only what you need
18
19
  - โœ… **Well-tested** - Comprehensive test coverage
19
20
 
@@ -261,9 +262,33 @@ Components use CSS custom properties for easy theming. Override these in your CS
261
262
  --greyLight: #e0e0e0;
262
263
  --greyDark: #757575;
263
264
  --blackLight: #424242;
265
+ --skeletonBase: #e0e0e0;
266
+ --skeletonHighlight: #f0f0f0;
264
267
  }
265
268
  ```
266
269
 
270
+ ### ๐ŸŒ“ Dark Mode Support
271
+
272
+ All components automatically support dark mode via `@media (prefers-color-scheme: dark)`. When your operating system or browser is set to dark mode, the components will automatically adapt with optimized color schemes:
273
+
274
+ ```css
275
+ @media (prefers-color-scheme: dark) {
276
+ :host {
277
+ --primary: #4db8ff;
278
+ --primaryHover: #66c2ff;
279
+ --primaryForeground: #000;
280
+ --blackLight: #e0e0e0;
281
+ --greyLight: #3d3d3d;
282
+ --greyDark: #666;
283
+ --disabled: #555;
284
+ --skeletonBase: #3d3d3d;
285
+ --skeletonHighlight: #4d4d4d;
286
+ }
287
+ }
288
+ ```
289
+
290
+ No additional configuration required - dark mode works out of the box!
291
+
267
292
  ## ๐Ÿงช Development
268
293
 
269
294
  ### Local Demo
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "license": "MIT",
13
13
  "author": "edu-webcomponents",
14
- "version": "1.24.0",
14
+ "version": "1.26.0",
15
15
  "repository": {
16
16
  "type": "git",
17
17
  "url": "https://github.com/eduardocruzpalacios/edu-webcomponents"
@@ -1,9 +1,10 @@
1
1
  import { html, css, LitElement } from 'lit';
2
- import { colorsConstants } from '../../stylesConstants.js';
2
+ import { colorsConstants, typographyConstants } from '../../stylesConstants.js';
3
3
 
4
4
  export class EduButton extends LitElement {
5
5
  static styles = [
6
6
  colorsConstants,
7
+ typographyConstants,
7
8
  css`
8
9
  :host {
9
10
  display: block;
@@ -18,12 +19,21 @@ export class EduButton extends LitElement {
18
19
  color: var(--primaryForeground);
19
20
  cursor: pointer;
20
21
  transition: background-color 0.2s ease-in-out;
22
+ font-family: inherit;
23
+ line-height: var(--lineHeight);
24
+ min-height: 44px;
25
+ min-width: 44px;
21
26
  }
22
27
 
23
28
  button:hover:not(:disabled) {
24
29
  background-color: var(--primaryHover);
25
30
  }
26
31
 
32
+ button:focus-visible {
33
+ outline: 2px solid var(--primary);
34
+ outline-offset: 2px;
35
+ }
36
+
27
37
  button:disabled {
28
38
  background-color: var(--disabled);
29
39
  cursor: not-allowed;
@@ -42,15 +52,16 @@ export class EduButton extends LitElement {
42
52
  super();
43
53
  this.text = 'Default text';
44
54
  this.type = 'button';
45
- this.ariaLabel = this.text;
55
+ this.ariaLabel = '';
46
56
  }
47
57
 
48
58
  render() {
49
59
  return html`
50
60
  <button
51
61
  type=${this.type}
52
- aria-label=${this.ariaLabel}
62
+ aria-label=${this.ariaLabel || this.text}
53
63
  ?disabled=${this.disabled}
64
+ aria-disabled=${this.disabled ? 'true' : 'false'}
54
65
  >
55
66
  ${this.text}
56
67
  </button>
@@ -58,4 +69,4 @@ export class EduButton extends LitElement {
58
69
  }
59
70
  }
60
71
 
61
- window.customElements.define('edu-button', EduButton);
72
+ customElements.define('edu-button', EduButton);
@@ -45,7 +45,7 @@ describe('EduButton', () => {
45
45
  expect(button.getAttribute('aria-label')).to.equal(textDefault);
46
46
  });
47
47
 
48
- it('allows overriding aria-label via attribute', async () => {
48
+ it('allows overriding aria-label via ariaLabel property', async () => {
49
49
  const ariaLabel = 'Custom label';
50
50
  const el = await fixture(
51
51
  html`<edu-button aria-label=${ariaLabel}></edu-button>`
@@ -6,7 +6,7 @@ export class EduLoadingSpinner extends LitElement {
6
6
  colorsConstants,
7
7
  css`
8
8
  .spinner {
9
- border: 8px solid var(--primaryForeground);
9
+ border: 8px solid var(--greyLight);
10
10
  border-top: 8px solid var(--primary);
11
11
  border-radius: 50%;
12
12
  width: 60px;
@@ -53,10 +53,14 @@ export class EduProgressBar extends LitElement {
53
53
  this.progressbarName = 'Progress bar';
54
54
  }
55
55
 
56
- render() {
56
+ _calculatePercentage() {
57
57
  const safeMax = this.max > 0 ? this.max : 100;
58
58
  const safeValue = Math.max(0, this.value);
59
- const percentage = Math.min(100, (safeValue / safeMax) * 100);
59
+ return Math.min(100, (safeValue / safeMax) * 100);
60
+ }
61
+
62
+ render() {
63
+ const percentage = this._calculatePercentage();
60
64
  const label = `${Math.round(percentage)}%`;
61
65
 
62
66
  return html`
@@ -64,8 +68,11 @@ export class EduProgressBar extends LitElement {
64
68
  class="bar-container"
65
69
  role="progressbar"
66
70
  aria-valuemin="0"
67
- aria-valuemax="${safeMax}"
68
- aria-valuenow="${Math.min(safeValue, safeMax)}"
71
+ aria-valuemax="${this.max > 0 ? this.max : 100}"
72
+ aria-valuenow="${Math.min(
73
+ Math.max(0, this.value),
74
+ this.max > 0 ? this.max : 100
75
+ )}"
69
76
  aria-label="${this.progressbarName}"
70
77
  >
71
78
  <div class="bar-fill" style="width: ${percentage}%"></div>
@@ -1,4 +1,5 @@
1
1
  import { LitElement, html, css } from 'lit';
2
+ import { colorsConstants } from '../../stylesConstants.js';
2
3
 
3
4
  export class EduSkeletonText extends LitElement {
4
5
  static properties = {
@@ -14,34 +15,42 @@ export class EduSkeletonText extends LitElement {
14
15
  this.lines = 1;
15
16
  }
16
17
 
17
- static styles = css`
18
- :host {
19
- display: grid;
20
- gap: 0.5em;
21
- }
22
-
23
- .line {
24
- border-radius: 4px;
25
- background: linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 37%, #e0e0e0 63%);
26
- background-size: 400% 100%;
27
- animation: shimmer 1.4s ease infinite;
28
- }
29
-
30
- @keyframes shimmer {
31
- 0% {
32
- background-position: 100% 0;
18
+ static styles = [
19
+ colorsConstants,
20
+ css`
21
+ :host {
22
+ display: grid;
23
+ gap: 0.5em;
33
24
  }
34
- 100% {
35
- background-position: -100% 0;
36
- }
37
- }
38
25
 
39
- @media (prefers-reduced-motion: reduce) {
40
26
  .line {
41
- animation: none;
27
+ border-radius: 4px;
28
+ background: linear-gradient(
29
+ 90deg,
30
+ var(--skeletonBase) 25%,
31
+ var(--skeletonHighlight) 37%,
32
+ var(--skeletonBase) 63%
33
+ );
34
+ background-size: 400% 100%;
35
+ animation: shimmer 1.4s ease infinite;
36
+ }
37
+
38
+ @keyframes shimmer {
39
+ 0% {
40
+ background-position: 100% 0;
41
+ }
42
+ 100% {
43
+ background-position: -100% 0;
44
+ }
45
+ }
46
+
47
+ @media (prefers-reduced-motion: reduce) {
48
+ .line {
49
+ animation: none;
50
+ }
42
51
  }
43
- }
44
- `;
52
+ `,
53
+ ];
45
54
 
46
55
  render() {
47
56
  return html`
@@ -57,4 +66,4 @@ export class EduSkeletonText extends LitElement {
57
66
  }
58
67
  }
59
68
 
60
- window.customElements.define('edu-skeleton-text', EduSkeletonText);
69
+ customElements.define('edu-skeleton-text', EduSkeletonText);
@@ -8,12 +8,10 @@ const POSITION = {
8
8
  RIGHT: 'right',
9
9
  };
10
10
 
11
- function getPositions() {
12
- return Object.values(POSITION);
13
- }
11
+ const VALID_POSITIONS = Object.values(POSITION);
14
12
 
15
13
  function isPositionValid(position) {
16
- return getPositions().includes(position.toLowerCase());
14
+ return VALID_POSITIONS.includes(position.toLowerCase());
17
15
  }
18
16
 
19
17
  export class EduTooltip extends LitElement {
@@ -12,5 +12,32 @@ export const colorsConstants = css`
12
12
  --greyDark: #aaa;
13
13
 
14
14
  --disabled: #ccc;
15
+
16
+ --skeletonBase: #e0e0e0;
17
+ --skeletonHighlight: #f0f0f0;
18
+ }
19
+
20
+ @media (prefers-color-scheme: dark) {
21
+ :host {
22
+ --primary: #4db8ff;
23
+ --primaryHover: #66c2ff;
24
+ --primaryForeground: #000;
25
+
26
+ --blackLight: #e0e0e0;
27
+
28
+ --greyLight: #3d3d3d;
29
+ --greyDark: #666;
30
+
31
+ --disabled: #555;
32
+
33
+ --skeletonBase: #3d3d3d;
34
+ --skeletonHighlight: #4d4d4d;
35
+ }
36
+ }
37
+ `;
38
+
39
+ export const typographyConstants = css`
40
+ :host {
41
+ --lineHeight: 1.5;
15
42
  }
16
43
  `;