Skip to content

Commit 29b4227

Browse files
Merge pull request #58 from zeixcom/feature/effects-refactor
Feature/effects refactor
2 parents e1c0693 + 476df25 commit 29b4227

File tree

246 files changed

+3997
-4520
lines changed

Some content is hidden

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

246 files changed

+3997
-4520
lines changed

.rules

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,9 @@ You are an expert TypeScript engineer assisting with a TypeScript library for re
9595
- Maintain focus on simplicity and Web Platform alignment
9696
- Balance feature completeness with library size constraints
9797

98-
## LLM Note-Taking Process
99-
100-
- Maintain LLM_NOTES.md to document unexpected behavior and solutions
101-
- When encountering unexpected library behavior, check if similar issues are documented
102-
- For new issues, document:
103-
- What was expected vs actual behavior
104-
- Root cause analysis
105-
- Solution or workaround found
106-
- Lessons learned and takeaways
107-
- Use these notes to identify patterns and potential library improvements
108-
- Flag recurring issues as candidates for library design changes
109-
- Structure notes with clear dates, components, and problem descriptions
98+
## LLM Documentation
99+
100+
- Maintain llms.txt to document core API usage in a form suitable for LLMs to quickly grasp the intent and functionality
110101

111102
## Always ask for user guidance when:
112103

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.2
3+
Version 0.13.3
44

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

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { requireDescendant } from '../../..'
12
import {
23
type Component,
34
RESET,
@@ -19,13 +20,18 @@ export default component(
1920
{
2021
disabled: asBoolean(),
2122
label: asString(RESET),
22-
badge: asString(RESET),
23+
badge: asString(),
24+
},
25+
(el, { first }) => {
26+
requireDescendant(el, 'button')
27+
requireDescendant(el, '.label')
28+
29+
return [
30+
first('button', setProperty('disabled')),
31+
first('.label', setText('label')),
32+
first('.badge', setText('badge')),
33+
]
2334
},
24-
(_, { first }) => [
25-
first('button', setProperty('disabled')),
26-
first('.label', setText('label')),
27-
first('.badge', setText('badge')),
28-
],
2935
)
3036

3137
declare global {

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

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
const animationFrame = () => new Promise(requestAnimationFrame)
2828

2929
runTests(() => {
30-
describe('My Counter Component', () => {
30+
describe('Basic Counter Component', () => {
3131
it('should initialize with count from attribute', async () => {
3232
const el = document.getElementById('test1')
3333
const countSpan = el.querySelector('span')
@@ -79,9 +79,6 @@
7979
const incrementBtn = el.querySelector('button')
8080
const countSpan = el.querySelector('span')
8181

82-
el.count = 0
83-
await animationFrame() // Wait for scheduled effect execution
84-
8582
// Click multiple times rapidly
8683
incrementBtn.click()
8784
incrementBtn.click()
@@ -92,45 +89,26 @@
9289
assert.equal(countSpan.textContent, '3')
9390
})
9491

95-
it('should handle programmatic count updates', async () => {
96-
const el = document.getElementById('test2')
97-
const countSpan = el.querySelector('span')
98-
99-
el.count = 100
100-
await animationFrame() // Wait for scheduled effect execution
101-
102-
assert.equal(countSpan.textContent, '100')
103-
104-
el.count = 101
105-
await animationFrame() // Wait for scheduled effect execution
106-
107-
assert.equal(countSpan.textContent, '101')
108-
})
109-
110-
it('should handle zero correctly', async () => {
92+
it('should not allow programmatic count updates', async () => {
11193
const el = document.getElementById('test2')
11294
const countSpan = el.querySelector('span')
113-
114-
el.count = 0
115-
await animationFrame()
116-
117-
assert.equal(countSpan.textContent, '0')
95+
assert.throws(() => {
96+
el.count = 100
97+
}, TypeError)
11898
})
11999

120100
it('should maintain count across increment cycles', async () => {
121101
const el = document.getElementById('test2')
122102
const incrementBtn = el.querySelector('button')
123103

124-
el.count = 10
125-
await animationFrame() // Wait for initial state update
126-
104+
const initialCount = el.count
127105
incrementBtn.click()
128106
await animationFrame() // Wait for event handling and effect execution
129-
assert.equal(el.count, 11)
107+
assert.equal(el.count, initialCount + 1)
130108

131109
incrementBtn.click()
132110
await animationFrame() // Wait for event handling and effect execution
133-
assert.equal(el.count, 12)
111+
assert.equal(el.count, initialCount + 2)
134112
})
135113
})
136114
})
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
<basic-counter count="42">
1+
<basic-counter>
22
<button type="button">💐 <span>42</span></button>
33
</basic-counter>

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

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { type Component, asInteger, component, on, setText } from '../../..'
1+
import {
2+
type Component,
3+
asInteger,
4+
component,
5+
fromEvents,
6+
setText,
7+
} from '../../..'
28

39
export type BasicCounterProps = {
410
count: number
@@ -7,17 +13,15 @@ export type BasicCounterProps = {
713
export default component(
814
'basic-counter',
915
{
10-
count: asInteger(),
11-
},
12-
(el, { first }) => [
13-
first('span', setText('count')),
14-
first(
16+
count: fromEvents(
17+
el => asInteger()(el, el.querySelector('span')?.textContent),
1518
'button',
16-
on('click', () => {
17-
el.count++
18-
}),
19+
{
20+
click: ({ value }) => ++value,
21+
},
1922
),
20-
],
23+
},
24+
(_, { first }) => [first('span', setText('count'))],
2125
)
2226

2327
declare global {

docs-src/components/calc-table/calc-table.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
state,
1111
} from '../../../'
1212

13-
import { SpinButtonProps } from '../form-spinbutton/form-spinbutton'
13+
import { FormSpinbuttonProps } from '../form-spinbutton/form-spinbutton'
1414

1515
export type CalcTableProps = {
1616
columns: number
@@ -59,14 +59,14 @@ export default component(
5959
setProperty(
6060
'rows',
6161
() =>
62-
el.querySelector<Component<SpinButtonProps>>(
62+
el.querySelector<Component<FormSpinbuttonProps>>(
6363
'.rows form-spinbutton',
6464
)?.value,
6565
),
6666
setProperty(
6767
'columns',
6868
() =>
69-
el.querySelector<Component<SpinButtonProps>>(
69+
el.querySelector<Component<FormSpinbuttonProps>>(
7070
'.columns form-spinbutton',
7171
)?.value,
7272
),
@@ -191,7 +191,7 @@ export default component(
191191
/* Update column values when cells change */
192192
all(
193193
'tbody input',
194-
on('change', (e: Event) => {
194+
on('change', e => {
195195
const colKey = (e.target as HTMLInputElement)?.dataset[
196196
'key'
197197
]
@@ -202,7 +202,7 @@ export default component(
202202
/* Update sums for each column */
203203
all(
204204
'tfoot td',
205-
setText((target: HTMLTableCellElement) =>
205+
setText(target =>
206206
String(colSums.get(target.dataset['key']!)!.get()),
207207
),
208208
),

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
type Context,
44
type State,
55
component,
6-
provide,
6+
provideContexts,
77
state,
88
} from '../../../'
99

@@ -59,7 +59,7 @@ export default component(
5959
},
6060

6161
// Context for screen viewport size
62-
[MEDIA_VIEWPORT]: el => {
62+
[MEDIA_VIEWPORT]: (el: HTMLElement) => {
6363
const getBreakpoint = (attr: string, fallback: string) => {
6464
const value = el.getAttribute(attr)
6565
const trimmed = value?.trim()
@@ -114,7 +114,12 @@ export default component(
114114
},
115115
},
116116
() => [
117-
provide([MEDIA_MOTION, MEDIA_THEME, MEDIA_VIEWPORT, MEDIA_ORIENTATION]),
117+
provideContexts([
118+
MEDIA_MOTION,
119+
MEDIA_THEME,
120+
MEDIA_VIEWPORT,
121+
MEDIA_ORIENTATION,
122+
]),
118123
],
119124
)
120125

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
computed,
99
dangerouslySetInnerHTML,
1010
on,
11-
provide,
11+
provideContexts,
1212
setText,
1313
show,
1414
state,
@@ -134,7 +134,7 @@ export default component(
134134

135135
return [
136136
// Provide contexts
137-
provide([ROUTER_PATHNAME, ROUTER_QUERY]),
137+
provideContexts([ROUTER_PATHNAME, ROUTER_QUERY]),
138138

139139
// Navigate and update 'active' class
140140
all(
@@ -145,7 +145,7 @@ export default component(
145145
isInternalLink(target) &&
146146
el[ROUTER_PATHNAME] === target.pathname,
147147
),
148-
on('click', (e: Event) => {
148+
on('click', e => {
149149
if (!isInternalLink(e.target)) return
150150
const url = new URL(e.target.href)
151151
if (url.origin === window.location.origin) {

0 commit comments

Comments
 (0)