Skip to content

Commit 297c0e8

Browse files
Merge pull request #59 from zeixcom/feature/extend-hmr
Feature/extend hmr
2 parents 29b4227 + c7c6497 commit 297c0e8

File tree

186 files changed

+3766
-3362
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

186 files changed

+3766
-3362
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# UIElement
22

3-
Version 0.13.3
3+
Version 0.13.4
44

55
**UIElement** - a HTML-first library for reactive Web Components
66

bun.lockb

-8 Bytes
Binary file not shown.

docs-src/components/basic-button/basic-button-test.html

Lines changed: 4 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
</basic-button>
1515

1616
<basic-button id="test2" disabled>
17-
<button type="submit" class="primary" disabled>Submit</button>
17+
<button type="submit" class="primary" disabled>
18+
<span class="label">Submit</span>
19+
</button>
1820
</basic-button>
1921

2022
<basic-button id="test3">
@@ -23,16 +25,6 @@
2325
</button>
2426
</basic-button>
2527

26-
<basic-button id="test4">
27-
<button type="button">
28-
<span class="badge">99</span>
29-
</button>
30-
</basic-button>
31-
32-
<basic-button id="test5">
33-
<button type="button">Simple Button</button>
34-
</basic-button>
35-
3628
<script type="module">
3729
import { runTests } from '@web/test-runner-mocha'
3830
import { assert } from '@esm-bundle/chai'
@@ -58,13 +50,7 @@
5850
describe('Basic Button Component', () => {
5951
beforeEach(async () => {
6052
// Reset all test components before each test
61-
const testIds = [
62-
'test1',
63-
'test2',
64-
'test3',
65-
'test4',
66-
'test5',
67-
]
53+
const testIds = ['test1', 'test2', 'test3']
6854
for (const id of testIds) {
6955
const el = document.getElementById(id)
7056
if (el) await resetButton(el)
@@ -206,47 +192,6 @@
206192
assert.equal(labelEl.textContent, 'Add to Cart')
207193
})
208194

209-
it('should work with button that has only badge', async () => {
210-
const el = document.getElementById('test4')
211-
const labelEl = el.querySelector('.label')
212-
const badgeEl = el.querySelector('.badge')
213-
214-
assert.isNull(labelEl)
215-
assert.isNotNull(badgeEl)
216-
217-
// Should work normally with just badge
218-
el.badge = '42'
219-
await tick()
220-
221-
assert.equal(badgeEl.textContent, '42')
222-
})
223-
224-
it('should work with simple button without label or badge elements', async () => {
225-
const el = document.getElementById('test5')
226-
const button = el.querySelector('button')
227-
const labelEl = el.querySelector('.label')
228-
const badgeEl = el.querySelector('.badge')
229-
230-
assert.isNotNull(button)
231-
assert.isNull(labelEl)
232-
assert.isNull(badgeEl)
233-
234-
// Should still handle disabled state
235-
el.disabled = true
236-
await tick()
237-
238-
assert.equal(button.disabled, true)
239-
240-
// Label and badge properties should not cause errors
241-
el.label = 'Will not show'
242-
el.badge = 'Will not show'
243-
await tick()
244-
245-
// Should not throw errors, even though elements don't exist
246-
assert.equal(el.label, 'Will not show')
247-
assert.equal(el.badge, 'Will not show')
248-
})
249-
250195
it('should handle boolean disabled values correctly', async () => {
251196
const el = document.getElementById('test1')
252197
const button = el.querySelector('button')
@@ -381,30 +326,6 @@
381326
assert.isTrue(button.classList.contains('primary'))
382327
})
383328

384-
it('should handle component without button element gracefully', () => {
385-
// Create a minimal component structure for edge case testing
386-
const tempDiv = document.createElement('div')
387-
tempDiv.innerHTML = `
388-
<basic-button>
389-
<div>Not a button</div>
390-
</basic-button>
391-
`
392-
document.body.appendChild(tempDiv)
393-
394-
const tempEl = tempDiv.querySelector('basic-button')
395-
396-
// Component should initialize without throwing
397-
assert.isNotNull(tempEl)
398-
399-
// Setting properties should not cause errors
400-
tempEl.disabled = true
401-
tempEl.label = 'Test'
402-
tempEl.badge = 'Test'
403-
404-
// Cleanup
405-
document.body.removeChild(tempDiv)
406-
})
407-
408329
it('should handle RESET values correctly', async () => {
409330
const el = document.getElementById('test1')
410331
const labelEl = el.querySelector('.label')

docs-src/components/basic-button/basic-button.css

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ basic-button {
2525
cursor: pointer;
2626
opacity: var(--opacity-solid);
2727

28-
&:hover {
28+
&:hover,
29+
&:focus {
2930
background-color: var(--color-secondary-hover);
3031
}
3132

@@ -42,7 +43,8 @@ basic-button {
4243
&:not(:disabled) {
4344
opacity: var(--opacity-solid);
4445

45-
&:hover {
46+
&:hover,
47+
&:focus {
4648
background-color: var(--color-primary-hover);
4749
}
4850

@@ -60,7 +62,8 @@ basic-button {
6062
&:not(:disabled) {
6163
opacity: var(--opacity-solid);
6264

63-
&:hover {
65+
&:hover,
66+
&:focus {
6467
background-color: var(--color-error-hover);
6568
}
6669

@@ -78,7 +81,8 @@ basic-button {
7881
&:not(:disabled) {
7982
opacity: var(--opacity-solid);
8083

81-
&:hover {
84+
&:hover,
85+
&:focus {
8286
background-color: var(--color-success-hover);
8387
}
8488

@@ -88,6 +92,63 @@ basic-button {
8892
}
8993
}
9094

95+
&.tertiary {
96+
background: transparent;
97+
border: 0 solid transparent;
98+
padding: var(--space-xs);
99+
height: auto;
100+
color: var(--color-primary);
101+
102+
&:not(:disabled) {
103+
opacity: var(--opacity-solid);
104+
105+
&:hover,
106+
&:focus {
107+
background-color: rgba(0, 0, 0, 0.05);
108+
color: var(--color-primary-hover);
109+
}
110+
111+
&:active {
112+
background-color: rgba(0, 0, 0, 0.1);
113+
color: var(--color-primary-active);
114+
}
115+
}
116+
117+
&.constructive {
118+
color: var(--color-success);
119+
120+
&:not(:disabled) {
121+
opacity: var(--opacity-solid);
122+
123+
&:hover,
124+
&:focus {
125+
color: var(--color-success-hover);
126+
}
127+
128+
&:active {
129+
color: var(--color-success-active);
130+
}
131+
}
132+
}
133+
134+
&.destructive {
135+
color: var(--color-error);
136+
137+
&:not(:disabled) {
138+
opacity: var(--opacity-solid);
139+
140+
&:hover,
141+
&:focus {
142+
color: var(--color-error-hover);
143+
}
144+
145+
&:active {
146+
color: var(--color-error-active);
147+
}
148+
}
149+
}
150+
}
151+
91152
&.small {
92153
--input-height: var(--space-l);
93154
font-size: var(--font-size-xs);

docs-src/components/basic-counter/basic-counter-test.html

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,19 @@
2525

2626
const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
2727
const animationFrame = () => new Promise(requestAnimationFrame)
28+
const microtask = () => new Promise(queueMicrotask)
29+
const tick = async () => {
30+
await animationFrame() // Wait for effects to execute
31+
await microtask() // Wait for DOM to reflect changes
32+
}
2833

2934
runTests(() => {
3035
describe('Basic Counter Component', () => {
3136
it('should initialize with count from attribute', async () => {
3237
const el = document.getElementById('test1')
3338
const countSpan = el.querySelector('span')
3439

35-
await animationFrame() // Wait for scheduled effect execution
40+
await tick()
3641

3742
assert.equal(el.count, 42)
3843
assert.equal(countSpan.textContent, '42')
@@ -42,7 +47,7 @@
4247
const el = document.getElementById('test2')
4348
const countSpan = el.querySelector('span')
4449

45-
await animationFrame() // Wait for scheduled effect execution
50+
await tick()
4651

4752
assert.equal(el.count, 0)
4853
assert.equal(countSpan.textContent, '0')
@@ -52,7 +57,7 @@
5257
const el = document.getElementById('test3')
5358
const countSpan = el.querySelector('span')
5459

55-
await animationFrame() // Wait for scheduled effect execution
60+
await tick()
5661

5762
assert.equal(el.count, -5)
5863
assert.equal(countSpan.textContent, '-5')
@@ -65,7 +70,7 @@
6570

6671
const initialCount = el.count
6772
incrementBtn.click()
68-
await animationFrame() // Wait for event handling and effect execution
73+
await tick()
6974

7075
assert.equal(el.count, initialCount + 1)
7176
assert.equal(
@@ -83,7 +88,7 @@
8388
incrementBtn.click()
8489
incrementBtn.click()
8590
incrementBtn.click()
86-
await animationFrame() // Wait for all event handling and effect execution
91+
await tick()
8792

8893
assert.equal(el.count, 3)
8994
assert.equal(countSpan.textContent, '3')
@@ -92,9 +97,35 @@
9297
it('should not allow programmatic count updates', async () => {
9398
const el = document.getElementById('test2')
9499
const countSpan = el.querySelector('span')
100+
const originalCount = el.count
101+
102+
// Should throw TypeError when trying to set count
95103
assert.throws(() => {
96104
el.count = 100
97105
}, TypeError)
106+
107+
// Count should remain unchanged after failed assignment
108+
assert.equal(el.count, originalCount)
109+
assert.equal(
110+
countSpan.textContent,
111+
String(originalCount),
112+
)
113+
114+
// Should throw for different value types
115+
assert.throws(() => {
116+
el.count = 'invalid'
117+
}, TypeError)
118+
119+
assert.throws(() => {
120+
el.count = null
121+
}, TypeError)
122+
123+
assert.throws(() => {
124+
el.count = undefined
125+
}, TypeError)
126+
127+
// Verify count is still the original value
128+
assert.equal(el.count, originalCount)
98129
})
99130

100131
it('should maintain count across increment cycles', async () => {
@@ -103,11 +134,11 @@
103134

104135
const initialCount = el.count
105136
incrementBtn.click()
106-
await animationFrame() // Wait for event handling and effect execution
137+
await tick()
107138
assert.equal(el.count, initialCount + 1)
108139

109140
incrementBtn.click()
110-
await animationFrame() // Wait for event handling and effect execution
141+
await tick()
111142
assert.equal(el.count, initialCount + 2)
112143
})
113144
})

docs-src/components/basic-counter/basic-counter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from '../../..'
88

99
export type BasicCounterProps = {
10-
count: number
10+
readonly count: number
1111
}
1212

1313
export default component(

docs-src/components/context-media/context-media.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import {
88
} from '../../../'
99

1010
export type ContextMediaProps = {
11-
'media-motion': boolean
12-
'media-theme': 'light' | 'dark'
13-
'media-viewport': 'xs' | 'sm' | 'md' | 'lg' | 'xl'
14-
'media-orientation': 'portrait' | 'landscape'
11+
readonly 'media-motion': boolean
12+
readonly 'media-theme': 'light' | 'dark'
13+
readonly 'media-viewport': 'xs' | 'sm' | 'md' | 'lg' | 'xl'
14+
readonly 'media-orientation': 'portrait' | 'landscape'
1515
}
1616

1717
/* === Exported Contexts === */

docs-src/components/context-router/context-router-test.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ <h2>Custom Outlet Initial Content</h2>
4242

4343
const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
4444
const animationFrame = () => new Promise(requestAnimationFrame)
45+
const microtask = () => new Promise(queueMicrotask)
46+
const tick = async () => {
47+
await animationFrame() // Wait for effects to execute
48+
await microtask() // Wait for DOM to reflect changes
49+
}
4550

4651
runTests(() => {
4752
describe('Client Router Component - Structure', () => {
@@ -126,7 +131,7 @@ <h2>Custom Outlet Initial Content</h2>
126131
invalidLink.href = 'not-a-valid-url'
127132
el.querySelector('nav').appendChild(invalidLink)
128133

129-
await animationFrame()
134+
await tick()
130135

131136
// Should not crash and should not be marked as active
132137
assert.isFalse(invalidLink.classList.contains('active'))

0 commit comments

Comments
 (0)