edu-webcomponents 1.16.1 → 1.19.6
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/.github/workflows/release-and-publish.yaml +50 -0
- package/CHANGELOG.md +36 -0
- package/docs/release-packages-to-github-docs.md +1 -2
- package/index.js +2 -0
- package/package.json +1 -1
- package/src/EduButton.js +29 -25
- package/src/EduProgressBar.js +78 -0
- package/src/EduTooltip.js +126 -0
- package/src/stories/EduProgressBar.stories.js +102 -0
- package/src/stories/EduTooltip.stories.js +68 -0
- package/src/stylesConstants.js +15 -0
- package/test/EduProgressBar.test.js +173 -0
- package/test/EduTooltip.test.js +119 -0
- package/.github/workflows/publish-packages-to-npm-registry.yaml +0 -21
- package/.github/workflows/release-packages-to-github.yaml +0 -19
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Release and Publish to npmjs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release-and-publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
id-token: write
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Node
|
|
19
|
+
uses: actions/setup-node@v4
|
|
20
|
+
with:
|
|
21
|
+
node-version: 20
|
|
22
|
+
registry-url: 'https://registry.npmjs.org'
|
|
23
|
+
|
|
24
|
+
- name: Get version from package.json
|
|
25
|
+
id: version
|
|
26
|
+
run: echo "version=$(jq -r .version package.json)" >> $GITHUB_OUTPUT
|
|
27
|
+
|
|
28
|
+
- name: Set up Git
|
|
29
|
+
run: |
|
|
30
|
+
git config user.name "github-actions"
|
|
31
|
+
git config user.email "github-actions@github.com"
|
|
32
|
+
|
|
33
|
+
- name: Create tag
|
|
34
|
+
run: |
|
|
35
|
+
git tag v${{ steps.version.outputs.version }}
|
|
36
|
+
git push origin v${{ steps.version.outputs.version }}
|
|
37
|
+
|
|
38
|
+
- name: Create GitHub Release using gh
|
|
39
|
+
run: |
|
|
40
|
+
gh release create v${{ steps.version.outputs.version }} \
|
|
41
|
+
--title "v${{ steps.version.outputs.version }}" \
|
|
42
|
+
--notes "Release v${{ steps.version.outputs.version }}"
|
|
43
|
+
env:
|
|
44
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
45
|
+
|
|
46
|
+
- run: npm install -g npm
|
|
47
|
+
- run: npm ci
|
|
48
|
+
- run: npm publish --provenance --access public
|
|
49
|
+
env:
|
|
50
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.19.6 - 2025-08-09
|
|
4
|
+
- Fix released package in GitHub is not published in npm registry
|
|
5
|
+
|
|
6
|
+
## 1.19.5 - 2025-08-09
|
|
7
|
+
- Fix released package in GitHub is not published in npm registry
|
|
8
|
+
|
|
9
|
+
## 1.19.4 - 2025-08-09
|
|
10
|
+
- Fix released package in GitHub is not published in npm registry
|
|
11
|
+
|
|
12
|
+
## 1.19.3 - 2025-08-09
|
|
13
|
+
- Fix released package in GitHub is not published in npm registry
|
|
14
|
+
|
|
15
|
+
## 1.19.2 - 2025-08-08
|
|
16
|
+
- Make EduTooltip have bottom position as default when the prop is not set or is set with invalid value
|
|
17
|
+
|
|
18
|
+
## 1.19.1 - 2025-08-07
|
|
19
|
+
- Improve docs for stories of EduProgressBar
|
|
20
|
+
|
|
21
|
+
## 1.19.0 - 2025-08-06
|
|
22
|
+
- Add EduProgressBar web component
|
|
23
|
+
|
|
24
|
+
## 1.18.0 - 2025-08-05
|
|
25
|
+
- Add EduTooltip web component
|
|
26
|
+
|
|
27
|
+
## 1.17.3 - 2025-08-04
|
|
28
|
+
- Update docs
|
|
29
|
+
|
|
30
|
+
## 1.17.2 - 2025-08-03
|
|
31
|
+
- Make values of colors of EduButton not defined in the component, but as constants accessible by the entire web components catalog
|
|
32
|
+
|
|
33
|
+
## 1.17.1 - 2025-08-02
|
|
34
|
+
- Format code
|
|
35
|
+
|
|
36
|
+
## 1.17.0 - 2025-08-02
|
|
37
|
+
- Make releasing and tagging use the version from package.json
|
|
38
|
+
|
|
3
39
|
## 1.16.1 - 2025-08-02
|
|
4
40
|
- Fix versioning of release
|
|
5
41
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
# Release and tag to GitHub by using GitHub Actions
|
|
2
|
-
Use workflow
|
|
3
|
-
- Add corresponding inputs
|
|
2
|
+
Use workflow located in .github/workflows/release-packages-to-github.yaml:
|
|
4
3
|
- Create the needed token and add it to GitHub secrets
|
package/index.js
CHANGED
package/package.json
CHANGED
package/src/EduButton.js
CHANGED
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
import { html, css, LitElement } from 'lit';
|
|
2
|
+
import { colorsConstants } from './stylesConstants.js';
|
|
2
3
|
|
|
3
4
|
export class EduButton extends LitElement {
|
|
4
|
-
static styles =
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
5
|
+
static styles = [
|
|
6
|
+
colorsConstants,
|
|
7
|
+
css`
|
|
8
|
+
:host {
|
|
9
|
+
display: block;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
button {
|
|
13
|
+
padding: 0.5rem 1rem;
|
|
14
|
+
font-size: 1rem;
|
|
15
|
+
border: none;
|
|
16
|
+
border-radius: 4px;
|
|
17
|
+
background-color: var(--primary);
|
|
18
|
+
color: var(--primaryForeground);
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
transition: background-color 0.2s ease-in-out;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
button:hover:not(:disabled) {
|
|
24
|
+
background-color: var(--primaryHover);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
button:disabled {
|
|
28
|
+
background-color: var(--disabled);
|
|
29
|
+
cursor: not-allowed;
|
|
30
|
+
}
|
|
31
|
+
`,
|
|
32
|
+
];
|
|
29
33
|
|
|
30
34
|
static properties = {
|
|
31
35
|
text: { type: String },
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { LitElement, html, css } from 'lit';
|
|
2
|
+
import { colorsConstants } from './stylesConstants.js';
|
|
3
|
+
|
|
4
|
+
export class EduProgressBar extends LitElement {
|
|
5
|
+
static properties = {
|
|
6
|
+
value: { type: Number },
|
|
7
|
+
max: { type: Number },
|
|
8
|
+
showLabel: { type: Boolean },
|
|
9
|
+
progressbarName: { type: String },
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
static styles = [
|
|
13
|
+
colorsConstants,
|
|
14
|
+
css`
|
|
15
|
+
:host {
|
|
16
|
+
display: block;
|
|
17
|
+
width: 100%;
|
|
18
|
+
}
|
|
19
|
+
.bar-container {
|
|
20
|
+
position: relative;
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 20px;
|
|
23
|
+
background-color: var(--greyLight);
|
|
24
|
+
border-radius: 10px;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
}
|
|
27
|
+
.bar-fill {
|
|
28
|
+
height: 100%;
|
|
29
|
+
background-color: var(--primary);
|
|
30
|
+
transition: width 0.3s ease;
|
|
31
|
+
}
|
|
32
|
+
.label {
|
|
33
|
+
position: absolute;
|
|
34
|
+
top: 0;
|
|
35
|
+
left: 50%;
|
|
36
|
+
transform: translate(-50%, 0);
|
|
37
|
+
height: 100%;
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
font-size: 12px;
|
|
42
|
+
font-weight: bold;
|
|
43
|
+
color: var(--blackLight);
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
}
|
|
46
|
+
`,
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
constructor() {
|
|
50
|
+
super();
|
|
51
|
+
this.value = 0;
|
|
52
|
+
this.max = 100;
|
|
53
|
+
this.progressbarName = 'Progress bar';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
render() {
|
|
57
|
+
const safeMax = this.max > 0 ? this.max : 100;
|
|
58
|
+
const safeValue = Math.max(0, this.value);
|
|
59
|
+
const percentage = Math.min(100, (safeValue / safeMax) * 100);
|
|
60
|
+
const label = `${Math.round(percentage)}%`;
|
|
61
|
+
|
|
62
|
+
return html`
|
|
63
|
+
<div
|
|
64
|
+
class="bar-container"
|
|
65
|
+
role="progressbar"
|
|
66
|
+
aria-valuemin="0"
|
|
67
|
+
aria-valuemax="${safeMax}"
|
|
68
|
+
aria-valuenow="${Math.min(safeValue, safeMax)}"
|
|
69
|
+
aria-label="${this.progressbarName}"
|
|
70
|
+
>
|
|
71
|
+
<div class="bar-fill" style="width: ${percentage}%"></div>
|
|
72
|
+
${this.showLabel ? html`<div class="label">${label}</div>` : null}
|
|
73
|
+
</div>
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
customElements.define('edu-progress-bar', EduProgressBar);
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { LitElement, html, css } from 'lit';
|
|
2
|
+
import { colorsConstants } from './stylesConstants.js';
|
|
3
|
+
|
|
4
|
+
const POSITION = {
|
|
5
|
+
BOTTOM: 'bottom',
|
|
6
|
+
TOP: 'top',
|
|
7
|
+
LEFT: 'left',
|
|
8
|
+
RIGHT: 'right',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function getPositions() {
|
|
12
|
+
return Object.values(POSITION);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isPositionValid(position) {
|
|
16
|
+
return getPositions().includes(position.toLowerCase());
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class EduTooltip extends LitElement {
|
|
20
|
+
static properties = {
|
|
21
|
+
text: { type: String },
|
|
22
|
+
position: { type: String },
|
|
23
|
+
visible: { type: Boolean, reflect: true },
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
constructor() {
|
|
27
|
+
super();
|
|
28
|
+
this._tooltipId = `tooltip-${Math.random().toString(36).slice(2)}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
updated(changedProperties) {
|
|
32
|
+
if (changedProperties.has('position')) {
|
|
33
|
+
if (!isPositionValid(this.position)) {
|
|
34
|
+
this.position = POSITION.BOTTOM;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static styles = [
|
|
40
|
+
colorsConstants,
|
|
41
|
+
css`
|
|
42
|
+
:host {
|
|
43
|
+
position: relative;
|
|
44
|
+
display: inline-block;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.tooltip {
|
|
48
|
+
position: absolute;
|
|
49
|
+
background-color: var(--blackLight);
|
|
50
|
+
color: var(--primaryForeground);
|
|
51
|
+
padding: 6px 10px;
|
|
52
|
+
border-radius: 4px;
|
|
53
|
+
font-size: 12px;
|
|
54
|
+
white-space: nowrap;
|
|
55
|
+
z-index: 10;
|
|
56
|
+
opacity: 0;
|
|
57
|
+
transition: opacity 0.2s;
|
|
58
|
+
pointer-events: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
:host([visible]) .tooltip {
|
|
62
|
+
opacity: 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.top {
|
|
66
|
+
bottom: 100%;
|
|
67
|
+
left: 50%;
|
|
68
|
+
transform: translateX(-50%) translateY(-5px);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.right {
|
|
72
|
+
top: 50%;
|
|
73
|
+
left: 100%;
|
|
74
|
+
transform: translateX(5px) translateY(-50%);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.bottom {
|
|
78
|
+
top: 100%;
|
|
79
|
+
left: 50%;
|
|
80
|
+
transform: translateX(-50%) translateY(5px);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.left {
|
|
84
|
+
top: 50%;
|
|
85
|
+
left: auto;
|
|
86
|
+
right: 100%;
|
|
87
|
+
transform: translateX(-5px) translateY(-50%);
|
|
88
|
+
}
|
|
89
|
+
`,
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
render() {
|
|
93
|
+
const positionClass = this.position
|
|
94
|
+
? this.position.toLocaleLowerCase()
|
|
95
|
+
: POSITION.BOTTOM;
|
|
96
|
+
return html`
|
|
97
|
+
<span
|
|
98
|
+
tabindex="0"
|
|
99
|
+
aria-describedby=${this._tooltipId}
|
|
100
|
+
@mouseenter=${this._show}
|
|
101
|
+
@mouseleave=${this._hide}
|
|
102
|
+
@focus=${this._show}
|
|
103
|
+
@blur=${this._hide}
|
|
104
|
+
>
|
|
105
|
+
<slot></slot>
|
|
106
|
+
</span>
|
|
107
|
+
<div
|
|
108
|
+
id=${this._tooltipId}
|
|
109
|
+
class="tooltip ${positionClass}"
|
|
110
|
+
role="tooltip"
|
|
111
|
+
>
|
|
112
|
+
${this.text}
|
|
113
|
+
</div>
|
|
114
|
+
`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
_show() {
|
|
118
|
+
this.visible = true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
_hide() {
|
|
122
|
+
this.visible = false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
customElements.define('edu-tooltip', EduTooltip);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import '../EduProgressBar.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Edu web components/EduProgressBar',
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
render: ({ value, max, showLabel }) =>
|
|
8
|
+
html`<edu-progress-bar
|
|
9
|
+
.value=${value}
|
|
10
|
+
.max=${max}
|
|
11
|
+
?showLabel=${showLabel}
|
|
12
|
+
></edu-progress-bar>`,
|
|
13
|
+
argTypes: {
|
|
14
|
+
value: {
|
|
15
|
+
value: 'number',
|
|
16
|
+
description: 'Sets the percentage to which the progress bar is filled in',
|
|
17
|
+
name: 'value',
|
|
18
|
+
},
|
|
19
|
+
max: {
|
|
20
|
+
value: 'number',
|
|
21
|
+
description: 'Sets the value to which the percentage is calculated',
|
|
22
|
+
name: 'max',
|
|
23
|
+
},
|
|
24
|
+
showLabel: {
|
|
25
|
+
value: 'boolean',
|
|
26
|
+
description: 'Shows label of percentage filled in',
|
|
27
|
+
name: 'showLabel',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
args: {
|
|
31
|
+
value: 0,
|
|
32
|
+
max: 100,
|
|
33
|
+
showLabel: false,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const EduProgressBarDefault = {
|
|
38
|
+
args: {},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const EduProgressBar25 = {
|
|
42
|
+
args: {
|
|
43
|
+
value: 25,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export const EduProgressBar50 = {
|
|
47
|
+
args: {
|
|
48
|
+
value: 50,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
export const EduProgressBar50WithMaxChanged = {
|
|
52
|
+
args: {
|
|
53
|
+
value: 25,
|
|
54
|
+
max: 50,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
export const EduProgressBar75 = {
|
|
58
|
+
args: {
|
|
59
|
+
value: 75,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
export const EduProgressBar100 = {
|
|
63
|
+
args: {
|
|
64
|
+
value: 100,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const EduProgressBarWithLabel = {
|
|
69
|
+
args: { showLabel: true },
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const EduProgressBar25WithLabel = {
|
|
73
|
+
args: {
|
|
74
|
+
value: 25,
|
|
75
|
+
showLabel: true,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
export const EduProgressBar50WithLabel = {
|
|
79
|
+
args: {
|
|
80
|
+
value: 50,
|
|
81
|
+
showLabel: true,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
export const EduProgressBar50WithLabelAndMaxChanged = {
|
|
85
|
+
args: {
|
|
86
|
+
value: 25,
|
|
87
|
+
max: 50,
|
|
88
|
+
showLabel: true,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
export const EduProgressBar75WithLabel = {
|
|
92
|
+
args: {
|
|
93
|
+
value: 75,
|
|
94
|
+
showLabel: true,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
export const EduProgressBar100WithLabel = {
|
|
98
|
+
args: {
|
|
99
|
+
value: 100,
|
|
100
|
+
showLabel: true,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import '../EduTooltip.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Edu web components/EduTooltip',
|
|
6
|
+
tags: ['autodocs'],
|
|
7
|
+
render: ({ text, position }) =>
|
|
8
|
+
html`<edu-tooltip .text=${text} .position=${position}
|
|
9
|
+
><p>Hello, place the mouse over this text</p></edu-tooltip
|
|
10
|
+
>`,
|
|
11
|
+
argTypes: {
|
|
12
|
+
text: {
|
|
13
|
+
control: 'text',
|
|
14
|
+
description: 'Overwritten button text',
|
|
15
|
+
name: 'text',
|
|
16
|
+
},
|
|
17
|
+
position: {
|
|
18
|
+
control: 'text',
|
|
19
|
+
description:
|
|
20
|
+
'Position of the tooltip respect to the element making it visible: top / bottom / left / right',
|
|
21
|
+
name: 'position',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
args: {
|
|
25
|
+
text: 'Custom text',
|
|
26
|
+
position: '',
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const EduTooltipDefaultPositionBottom = {
|
|
31
|
+
args: {},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const EduTooltipInvalidPositionPropBottom = {
|
|
35
|
+
args: {
|
|
36
|
+
position: 'Edu',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const EduTooltipPositionBottom = {
|
|
41
|
+
args: {
|
|
42
|
+
position: 'bottom',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const EduTooltipPositionTop = {
|
|
47
|
+
args: {
|
|
48
|
+
position: 'top',
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const EduTooltipPositionRight = {
|
|
53
|
+
args: {
|
|
54
|
+
position: 'right',
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const EduTooltipPositionLeft = {
|
|
59
|
+
args: {
|
|
60
|
+
position: 'left',
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const EduTooltipPositionLeftCaseInsensitive = {
|
|
65
|
+
args: {
|
|
66
|
+
position: 'LEFT',
|
|
67
|
+
},
|
|
68
|
+
};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// test/edu-progress-bar.test.js
|
|
2
|
+
import { html, fixture, expect } from '@open-wc/testing';
|
|
3
|
+
import '../src/EduProgressBar.js'; // ajusta la ruta si es necesario
|
|
4
|
+
|
|
5
|
+
describe('EduProgressBar', () => {
|
|
6
|
+
it('renders with default values', async () => {
|
|
7
|
+
const el = await fixture(html`<edu-progress-bar></edu-progress-bar>`);
|
|
8
|
+
|
|
9
|
+
const bar = el.shadowRoot.querySelector('.bar-fill');
|
|
10
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
11
|
+
|
|
12
|
+
expect(el.value).to.equal(0);
|
|
13
|
+
expect(el.max).to.equal(100);
|
|
14
|
+
expect(bar.style.width).to.equal('0%');
|
|
15
|
+
expect(label).to.be.null;
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('renders with default values (with label)', async () => {
|
|
19
|
+
const el = await fixture(
|
|
20
|
+
html`<edu-progress-bar .showLabel=${true}></edu-progress-bar>`,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const bar = el.shadowRoot.querySelector('.bar-fill');
|
|
24
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
25
|
+
|
|
26
|
+
expect(el.value).to.equal(0);
|
|
27
|
+
expect(el.max).to.equal(100);
|
|
28
|
+
expect(bar.style.width).to.equal('0%');
|
|
29
|
+
expect(label.textContent).to.equal('0%');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('calculates percentage correctly', async () => {
|
|
33
|
+
const el = await fixture(
|
|
34
|
+
html`<edu-progress-bar .value=${25} .max=${50}></edu-progress-bar>`,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const bar = el.shadowRoot.querySelector('.bar-fill');
|
|
38
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
39
|
+
|
|
40
|
+
expect(bar.style.width).to.equal('50%');
|
|
41
|
+
expect(label).to.be.null;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('calculates percentage correctly (with label)', async () => {
|
|
45
|
+
const el = await fixture(
|
|
46
|
+
html`<edu-progress-bar
|
|
47
|
+
.value=${25}
|
|
48
|
+
.max=${50}
|
|
49
|
+
.showLabel=${true}
|
|
50
|
+
></edu-progress-bar>`,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const bar = el.shadowRoot.querySelector('.bar-fill');
|
|
54
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
55
|
+
|
|
56
|
+
expect(bar.style.width).to.equal('50%');
|
|
57
|
+
expect(label.textContent).to.equal('50%');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('caps percentage at 100%', async () => {
|
|
61
|
+
const el = await fixture(
|
|
62
|
+
html`<edu-progress-bar .value=${200} .max=${100}></edu-progress-bar>`,
|
|
63
|
+
);
|
|
64
|
+
const bar = el.shadowRoot.querySelector('.bar-fill');
|
|
65
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
66
|
+
|
|
67
|
+
expect(bar.style.width).to.equal('100%');
|
|
68
|
+
expect(label).to.be.null;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('caps percentage at 100% (with label)', async () => {
|
|
72
|
+
const el = await fixture(
|
|
73
|
+
html`<edu-progress-bar
|
|
74
|
+
.value=${200}
|
|
75
|
+
.max=${100}
|
|
76
|
+
.showLabel=${true}
|
|
77
|
+
></edu-progress-bar>`,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const bar = el.shadowRoot.querySelector('.bar-fill');
|
|
81
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
82
|
+
|
|
83
|
+
expect(bar.style.width).to.equal('100%');
|
|
84
|
+
expect(label.textContent).to.equal('100%');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('handles invalid max', async () => {
|
|
88
|
+
const el = await fixture(
|
|
89
|
+
html`<edu-progress-bar .value=${50} .max=${0}></edu-progress-bar>`,
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const bar = el.shadowRoot.querySelector('.bar-fill');
|
|
93
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
94
|
+
|
|
95
|
+
expect(bar.style.width).to.equal('50%');
|
|
96
|
+
expect(label).to.be.null;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('handles invalid max (with label)', async () => {
|
|
100
|
+
const el = await fixture(
|
|
101
|
+
html`<edu-progress-bar
|
|
102
|
+
.value=${50}
|
|
103
|
+
.max=${0}
|
|
104
|
+
.showLabel=${true}
|
|
105
|
+
></edu-progress-bar>`,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const bar = el.shadowRoot.querySelector('.bar-fill');
|
|
109
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
110
|
+
|
|
111
|
+
expect(bar.style.width).to.equal('50%');
|
|
112
|
+
expect(label.textContent).to.equal('50%');
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('hides label when showLabel is false', async () => {
|
|
116
|
+
const el = await fixture(
|
|
117
|
+
html`<edu-progress-bar
|
|
118
|
+
.value=${50}
|
|
119
|
+
.showLabel=${false}
|
|
120
|
+
></edu-progress-bar>`,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
124
|
+
|
|
125
|
+
expect(label).to.equal(null);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('shows label when showLabel is true', async () => {
|
|
129
|
+
const el = await fixture(
|
|
130
|
+
html`<edu-progress-bar
|
|
131
|
+
.value=${50}
|
|
132
|
+
.showLabel=${true}
|
|
133
|
+
></edu-progress-bar>`,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const label = el.shadowRoot.querySelector('.label');
|
|
137
|
+
|
|
138
|
+
expect(label).to.exist;
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('is accessible by default', async () => {
|
|
142
|
+
const el = await fixture(html`<edu-progress-bar></edu-progress-bar>`);
|
|
143
|
+
|
|
144
|
+
await expect(el).to.be.accessible();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('is accessible by default (with value)', async () => {
|
|
148
|
+
const el = await fixture(
|
|
149
|
+
html`<edu-progress-bar .value=${50}></edu-progress-bar>`,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
await expect(el).to.be.accessible();
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('is accessible (with label)', async () => {
|
|
156
|
+
const el = await fixture(
|
|
157
|
+
html`<edu-progress-bar .showLabel=${true}></edu-progress-bar>`,
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
await expect(el).to.be.accessible();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('is accessible (with value and label)', async () => {
|
|
164
|
+
const el = await fixture(
|
|
165
|
+
html`<edu-progress-bar
|
|
166
|
+
.value=${50}
|
|
167
|
+
.showLabel=${true}
|
|
168
|
+
></edu-progress-bar>`,
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
await expect(el).to.be.accessible();
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { fixture, html, expect } from '@open-wc/testing';
|
|
2
|
+
import '../src/EduTooltip.js';
|
|
3
|
+
|
|
4
|
+
describe('EduTooltip', () => {
|
|
5
|
+
it('is not visible by default', async () => {
|
|
6
|
+
const el = await fixture(html`<edu-tooltip></edu-tooltip>`);
|
|
7
|
+
|
|
8
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
9
|
+
const styles = getComputedStyle(tooltip);
|
|
10
|
+
expect(styles.opacity).to.equal('0');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('sets bottom styles for position when there is not value passed in', async () => {
|
|
14
|
+
const el = await fixture(html`<edu-tooltip></edu-tooltip>`);
|
|
15
|
+
|
|
16
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
17
|
+
expect(tooltip.classList.contains('bottom')).to.be.true;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('sets bottom styles for position when the value passed is not valid', async () => {
|
|
21
|
+
const el = await fixture(
|
|
22
|
+
html`<edu-tooltip position="invalidString"></edu-tooltip>`,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
26
|
+
expect(tooltip.classList.contains('bottom')).to.be.true;
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('applies class for position', async () => {
|
|
30
|
+
const el = await fixture(
|
|
31
|
+
html`<edu-tooltip position="right"></edu-tooltip>`,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
35
|
+
expect(tooltip.classList.contains('right')).to.be.true;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('applies class for position (case insensitive)', async () => {
|
|
39
|
+
const el = await fixture(
|
|
40
|
+
html`<edu-tooltip position="RIGHT"></edu-tooltip>`,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
44
|
+
expect(tooltip.classList.contains('right')).to.be.true;
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('renders text of the tooltip', async () => {
|
|
48
|
+
const el = await fixture(html`<edu-tooltip text="Help"></edu-tooltip>`);
|
|
49
|
+
|
|
50
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
51
|
+
expect(tooltip.textContent).to.equal('\n Help\n ');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('shows tooltip when mouseenter event', async () => {
|
|
55
|
+
const el = await fixture(
|
|
56
|
+
html`<edu-tooltip text="Text"><span>Hover me</span></edu-tooltip>`,
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const trigger = el.shadowRoot.querySelector('span');
|
|
60
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
61
|
+
trigger.dispatchEvent(new Event('mouseenter'));
|
|
62
|
+
await el.updateComplete;
|
|
63
|
+
|
|
64
|
+
const styles = getComputedStyle(tooltip);
|
|
65
|
+
expect(styles.opacity).to.equal('1');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('hides tooltip when mouseleave event', async () => {
|
|
69
|
+
const el = await fixture(
|
|
70
|
+
html`<edu-tooltip text="Text"><span>Hover me</span></edu-tooltip>`,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const trigger = el.shadowRoot.querySelector('span');
|
|
74
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
75
|
+
el.visible = true;
|
|
76
|
+
trigger.dispatchEvent(new Event('mouseleave'));
|
|
77
|
+
await el.updateComplete;
|
|
78
|
+
|
|
79
|
+
const styles = getComputedStyle(tooltip);
|
|
80
|
+
expect(styles.opacity).to.equal('0');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('shows tooltip when focus event', async () => {
|
|
84
|
+
const el = await fixture(
|
|
85
|
+
html`<edu-tooltip text="Text"><span>Focus</span></edu-tooltip>`,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const trigger = el.shadowRoot.querySelector('span');
|
|
89
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
90
|
+
trigger.dispatchEvent(new Event('focus'));
|
|
91
|
+
await el.updateComplete;
|
|
92
|
+
|
|
93
|
+
const styles = getComputedStyle(tooltip);
|
|
94
|
+
expect(styles.opacity).to.equal('1');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('hides tooltip when blur event', async () => {
|
|
98
|
+
const el = await fixture(
|
|
99
|
+
html`<edu-tooltip text="Text"><span>Focus</span></edu-tooltip>`,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const trigger = el.shadowRoot.querySelector('span');
|
|
103
|
+
const tooltip = el.shadowRoot.querySelector('.tooltip');
|
|
104
|
+
el.visible = true;
|
|
105
|
+
trigger.dispatchEvent(new Event('blur'));
|
|
106
|
+
await el.updateComplete;
|
|
107
|
+
|
|
108
|
+
const styles = getComputedStyle(tooltip);
|
|
109
|
+
expect(styles.opacity).to.equal('0');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('is accessible', async () => {
|
|
113
|
+
const el = await fixture(
|
|
114
|
+
html`<edu-tooltip text="Text"><span>Trigger</span></edu-tooltip>`,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
await expect(el).to.be.accessible();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
name: Publish Package to npmjs
|
|
2
|
-
on:
|
|
3
|
-
release:
|
|
4
|
-
types: [published]
|
|
5
|
-
jobs:
|
|
6
|
-
build:
|
|
7
|
-
runs-on: ubuntu-latest
|
|
8
|
-
permissions:
|
|
9
|
-
contents: read
|
|
10
|
-
id-token: write
|
|
11
|
-
steps:
|
|
12
|
-
- uses: actions/checkout@v4
|
|
13
|
-
- uses: actions/setup-node@v4
|
|
14
|
-
with:
|
|
15
|
-
node-version: '20.x'
|
|
16
|
-
registry-url: 'https://registry.npmjs.org'
|
|
17
|
-
- run: npm install -g npm
|
|
18
|
-
- run: npm ci
|
|
19
|
-
- run: npm publish --provenance --access public
|
|
20
|
-
env:
|
|
21
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
on:
|
|
2
|
-
push:
|
|
3
|
-
branches:
|
|
4
|
-
- main
|
|
5
|
-
|
|
6
|
-
jobs:
|
|
7
|
-
release-on-merge:
|
|
8
|
-
runs-on: ubuntu-latest
|
|
9
|
-
permissions:
|
|
10
|
-
contents: write
|
|
11
|
-
env:
|
|
12
|
-
GITHUB_TOKEN: ${{ secrets.RELEASE }}
|
|
13
|
-
steps:
|
|
14
|
-
- name: release
|
|
15
|
-
uses: dexwritescode/release-on-merge-action@v1
|
|
16
|
-
with:
|
|
17
|
-
version-increment-strategy: patch
|
|
18
|
-
initial-version: '1.16.0'
|
|
19
|
-
tag-prefix: v
|