edu-webcomponents 1.25.0 → 1.27.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.27.0](https://github.com/eduardocruzpalacios/edu-webcomponents/compare/v1.26.0...v1.27.0)
8
+
9
+ - feat: improve accessibility of EduLoadingSpinner [`554e3d3`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/554e3d3ec740db8496182a255de565587b6e1131)
10
+
11
+ #### [v1.26.0](https://github.com/eduardocruzpalacios/edu-webcomponents/compare/v1.25.0...v1.26.0)
12
+
13
+ > 14 January 2026
14
+
15
+ - feat: improve accessibility of EduButton according to 2.5.5 in WCAG 2.1 and 2.4.7 in WCAG 2.2 [`3a559f0`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/3a559f02848035a0feed493c573d1c285bf0792c)
16
+ - refactor: code [`65c723d`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/65c723dc344e9b8bb9da515b76e465c21eab3097)
17
+ - chore: release v1.26.0 [`0ed337c`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/0ed337c4ff2a0d6d98ba52225f3d47dfdba69e33)
18
+
7
19
  #### [v1.25.0](https://github.com/eduardocruzpalacios/edu-webcomponents/compare/v1.24.0...v1.25.0)
8
20
 
9
- - feat: implement dark mode [`4112f1b`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/4112f1b9db41808e3e08204bd9397ffc9448f57e)
21
+ > 11 January 2026
22
+
23
+ - feat: implement dark mode [`a5470d0`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/a5470d0e3d7428ae6084dc3a1c4389ab4223517e)
24
+ - chore: release v1.25.0 [`3e2bbc7`](https://github.com/eduardocruzpalacios/edu-webcomponents/commit/3e2bbc709607880488b421e48d3dc353d7870034)
10
25
 
11
26
  #### [v1.24.0](https://github.com/eduardocruzpalacios/edu-webcomponents/compare/v1.23.0...v1.24.0)
12
27
 
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "license": "MIT",
13
13
  "author": "edu-webcomponents",
14
- "version": "1.25.0",
14
+ "version": "1.27.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>`
@@ -4,10 +4,21 @@ import './index.js';
4
4
  export default {
5
5
  title: 'Edu web components/EduLoadingSpinner',
6
6
  tags: ['autodocs'],
7
+ argTypes: {
8
+ label: {
9
+ control: 'text',
10
+ description: 'Accessible label for screen readers',
11
+ defaultValue: 'Loading',
12
+ },
13
+ },
7
14
  };
8
15
 
9
16
  const createStory = args => {
10
- const story = () => html` <edu-loading-spinner></edu-loading-spinner> `;
17
+ const story = () => html`
18
+ <edu-loading-spinner
19
+ label="${args.label || 'Loading'}"
20
+ ></edu-loading-spinner>
21
+ `;
11
22
  story.parameters = {
12
23
  controls: { expanded: true },
13
24
  docs: { source: { type: 'code' } },
@@ -17,6 +28,12 @@ const createStory = args => {
17
28
  return story;
18
29
  };
19
30
 
20
- const defaultArgs = {};
31
+ const defaultArgs = {
32
+ label: 'Loading',
33
+ };
21
34
 
22
35
  export const EduLoadingSpinnerDefault = createStory({ ...defaultArgs });
36
+
37
+ export const CustomLabel = createStory({
38
+ label: 'Please wait while we process your request',
39
+ });
@@ -2,9 +2,25 @@ import { html, css, LitElement } from 'lit';
2
2
  import { colorsConstants } from '../../stylesConstants.js';
3
3
 
4
4
  export class EduLoadingSpinner extends LitElement {
5
+ static properties = {
6
+ label: { type: String },
7
+ };
8
+
9
+ constructor() {
10
+ super();
11
+ this.label = 'Loading';
12
+ }
13
+
5
14
  static styles = [
6
15
  colorsConstants,
7
16
  css`
17
+ .spinner-container {
18
+ display: flex;
19
+ flex-direction: column;
20
+ align-items: center;
21
+ gap: 8px;
22
+ }
23
+
8
24
  .spinner {
9
25
  border: 8px solid var(--greyLight);
10
26
  border-top: 8px solid var(--primary);
@@ -14,6 +30,18 @@ export class EduLoadingSpinner extends LitElement {
14
30
  animation: spin 1.5s linear infinite;
15
31
  }
16
32
 
33
+ .visually-hidden {
34
+ position: absolute;
35
+ width: 1px;
36
+ height: 1px;
37
+ padding: 0;
38
+ margin: -1px;
39
+ overflow: hidden;
40
+ clip: rect(0, 0, 0, 0);
41
+ white-space: nowrap;
42
+ border-width: 0;
43
+ }
44
+
17
45
  @keyframes spin {
18
46
  0% {
19
47
  transform: rotate(0deg);
@@ -22,11 +50,22 @@ export class EduLoadingSpinner extends LitElement {
22
50
  transform: rotate(360deg);
23
51
  }
24
52
  }
53
+
54
+ @media (prefers-reduced-motion: reduce) {
55
+ .spinner {
56
+ animation: spin 3s linear infinite;
57
+ }
58
+ }
25
59
  `,
26
60
  ];
27
61
 
28
62
  render() {
29
- return html` <div class="spinner"></div> `;
63
+ return html`
64
+ <div class="spinner-container" role="status" aria-live="polite">
65
+ <div class="spinner" aria-hidden="true"></div>
66
+ <span class="visually-hidden">${this.label}</span>
67
+ </div>
68
+ `;
30
69
  }
31
70
  }
32
71
 
@@ -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>
@@ -66,4 +66,4 @@ export class EduSkeletonText extends LitElement {
66
66
  }
67
67
  }
68
68
 
69
- 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 {
@@ -35,3 +35,9 @@ export const colorsConstants = css`
35
35
  }
36
36
  }
37
37
  `;
38
+
39
+ export const typographyConstants = css`
40
+ :host {
41
+ --lineHeight: 1.5;
42
+ }
43
+ `;