jaxs 0.2.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/.env +1 -0
- package/.parcel-cache/6f14daf302269614-BundleGraph-0 +0 -0
- package/.parcel-cache/7d3d872b02d671a6-AssetGraph-0 +0 -0
- package/.parcel-cache/8e029bb14f8992df-RequestGraph-0 +0 -0
- package/.parcel-cache/a5394978e4ece10b-AssetGraph-0 +0 -0
- package/.parcel-cache/b5686051ae060930.txt +2 -0
- package/.parcel-cache/data.mdb +0 -0
- package/.parcel-cache/lock.mdb +0 -0
- package/README.md +15 -0
- package/bun.lockb +0 -0
- package/bundle.ts +5 -0
- package/bunfig.toml +0 -0
- package/cypress/e2e/add-remove-nested-children.cy.js +39 -0
- package/cypress/e2e/add-remove-root-children.cy.js +37 -0
- package/cypress/jaxs-apps/add-remove-nested-children.html +12 -0
- package/cypress/jaxs-apps/add-remove-nested-children.jsx +84 -0
- package/cypress/jaxs-apps/add-remove-root-children.html +15 -0
- package/cypress/jaxs-apps/add-remove-root-children.jsx +53 -0
- package/cypress/jaxs-apps/dist/add-remove-nested-children.afcab974.js +717 -0
- package/cypress/jaxs-apps/dist/add-remove-nested-children.afcab974.js.map +1 -0
- package/cypress/jaxs-apps/dist/add-remove-nested-children.html +12 -0
- package/cypress/jaxs-apps/dist/add-remove-root-children.3bb9b3f5.js +1682 -0
- package/cypress/jaxs-apps/dist/add-remove-root-children.3bb9b3f5.js.map +1 -0
- package/cypress/jaxs-apps/dist/add-remove-root-children.fbb4ec9b.js +706 -0
- package/cypress/jaxs-apps/dist/add-remove-root-children.fbb4ec9b.js.map +1 -0
- package/cypress/jaxs-apps/dist/add-remove-root-children.html +15 -0
- package/cypress/support/commands.js +25 -0
- package/cypress/support/e2e.js +20 -0
- package/cypress.config.js +10 -0
- package/dist/jaxs.js +1154 -0
- package/package.json +38 -0
- package/src/app.ts +64 -0
- package/src/debugging.js +5 -0
- package/src/jaxs.ts +8 -0
- package/src/jsx.js +27 -0
- package/src/messageBus.ts +70 -0
- package/src/navigation/findHref.js +10 -0
- package/src/navigation/routeState.js +15 -0
- package/src/navigation/setupHistory.js +38 -0
- package/src/navigation/setupNavigation.js +25 -0
- package/src/navigation.ts +2 -0
- package/src/rendering/change/compile.ts +1 -0
- package/src/rendering/change/instructions/attributes.ts +78 -0
- package/src/rendering/change/instructions/children.ts +128 -0
- package/src/rendering/change/instructions/element.ts +42 -0
- package/src/rendering/change/instructions/events.ts +51 -0
- package/src/rendering/change/instructions/generate.ts +122 -0
- package/src/rendering/change/instructions/idMap.js +55 -0
- package/src/rendering/change/instructions/node.ts +38 -0
- package/src/rendering/change/instructions/text.ts +10 -0
- package/src/rendering/change.ts +131 -0
- package/src/rendering/dom/attributesAndEvents.ts +33 -0
- package/src/rendering/dom/create.ts +68 -0
- package/src/rendering/templates/bound.js +55 -0
- package/src/rendering/templates/children.ts +91 -0
- package/src/rendering/templates/root.ts +55 -0
- package/src/rendering/templates/tag.ts +70 -0
- package/src/rendering/templates/text.ts +17 -0
- package/src/state/equality.js +36 -0
- package/src/state/stores.js +63 -0
- package/src/state/testingTypes.js +6 -0
- package/src/state.js +89 -0
- package/src/types.ts +149 -0
- package/src/views/conditionals.jsx +18 -0
- package/src/views/link.jsx +5 -0
- package/src/views.js +7 -0
- package/tsconfig.json +26 -0
package/.env
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DEBUG=false
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/README.md
ADDED
package/bun.lockb
ADDED
|
Binary file
|
package/bundle.ts
ADDED
package/bunfig.toml
ADDED
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
describe('Add and remove child nodes with state', () => {
|
|
2
|
+
beforeEach(() => {
|
|
3
|
+
cy.visit('http://localhost:1234/add-remove-nested-children.html')
|
|
4
|
+
})
|
|
5
|
+
|
|
6
|
+
it('it toggles conditional children correctly', () => {
|
|
7
|
+
cy.get('.validation-error').should('not.exist')
|
|
8
|
+
|
|
9
|
+
cy.get('input[name=email]').type('hello?')
|
|
10
|
+
cy.get('.validation-error').should('not.exist')
|
|
11
|
+
|
|
12
|
+
cy.get('input[name=email]').blur()
|
|
13
|
+
cy.get('.validation-error').contains('Email unknown')
|
|
14
|
+
/* change instructions for blur
|
|
15
|
+
{source: input#email, target: input#email, type: removeNode, data: {…}}
|
|
16
|
+
{target: p.validation-error, source: p.validation-error, type: addNode, data: {…}}
|
|
17
|
+
{target: input#email, source: input#email, type: addNode, data: {…}}
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
cy.get('input[name=email]').focus()
|
|
21
|
+
cy.get('input[name=email]').should('exist')
|
|
22
|
+
cy.get('.validation-error').should('not.exist')
|
|
23
|
+
/* On focus
|
|
24
|
+
{source: p.validation-error, target: p.validation-error, type: removeNode, data: {…}}
|
|
25
|
+
{target: input#email, source: input#email, type: addNode, data: {…}}
|
|
26
|
+
{source: input#email, target: input#email, type: removeNode, data: {…}} // trigger blur?
|
|
27
|
+
*/
|
|
28
|
+
/*
|
|
29
|
+
change triggered on blur:
|
|
30
|
+
{source: input#email, target: input#email, type: removeNode, data: {…}}
|
|
31
|
+
{target: p.validation-error, source: p.validation-error, type: addNode, data: {…}}
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
cy.get('input[name=email]').clear()
|
|
35
|
+
cy.get('input[name=email]').type('kane@example.com')
|
|
36
|
+
cy.get('input[name=email]').blur()
|
|
37
|
+
cy.get('.validation-error').should('not.exist')
|
|
38
|
+
})
|
|
39
|
+
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
describe('Add and remove child nodes with state', () => {
|
|
2
|
+
beforeEach(() => {
|
|
3
|
+
cy.visit('http://localhost:1234/add-remove-root-children.html')
|
|
4
|
+
})
|
|
5
|
+
|
|
6
|
+
it('if/else conditional with nested children and toggling conditions', () => {
|
|
7
|
+
cy.get('.member-content').should('not.exist')
|
|
8
|
+
cy.get('.guest-content').contains('that is fine')
|
|
9
|
+
cy.get('form').should.exist
|
|
10
|
+
cy.get('input[type=submit]').should.exist
|
|
11
|
+
|
|
12
|
+
cy.get('a.exclusive-link').click()
|
|
13
|
+
|
|
14
|
+
cy.get('h1.member-content').contains('Oh great crickets!')
|
|
15
|
+
cy.get('p.member-content').contains('Sing me a tale')
|
|
16
|
+
cy.get('.guest-content').should('not.exist')
|
|
17
|
+
|
|
18
|
+
cy.go('back')
|
|
19
|
+
|
|
20
|
+
cy.get('.member-content').should('not.exist')
|
|
21
|
+
cy.get('.guest-content').contains('that is fine')
|
|
22
|
+
cy.get('form').should.exist
|
|
23
|
+
cy.get('input[type=submit]').should.exist
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('show/hide at the root level', () => {
|
|
27
|
+
cy.get('a.exclusive-link').contains('Go to')
|
|
28
|
+
|
|
29
|
+
cy.get('a.exclusive-link').click()
|
|
30
|
+
|
|
31
|
+
cy.get('a.exclusive-link').should('not.exist')
|
|
32
|
+
|
|
33
|
+
cy.go('back')
|
|
34
|
+
|
|
35
|
+
cy.get('a.exclusive-link').contains('Go to')
|
|
36
|
+
})
|
|
37
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8"/>
|
|
5
|
+
<title>Jaxs integration test</title>
|
|
6
|
+
<script type="module" src="./add-remove-nested-children.jsx"></script>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<article id="app">
|
|
10
|
+
</article>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { bind, createApp, jsx, views } from '../../dist/jaxs.js'
|
|
2
|
+
const { If } = views
|
|
3
|
+
|
|
4
|
+
const app = createApp()
|
|
5
|
+
|
|
6
|
+
app.state.create('form', {
|
|
7
|
+
email: '',
|
|
8
|
+
emailValidation: '',
|
|
9
|
+
emailInvalid: false
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
export const onInput = (event, { state }) => {
|
|
13
|
+
const { form } = state
|
|
14
|
+
const { name, value } = event.target
|
|
15
|
+
state.form.update({
|
|
16
|
+
...form,
|
|
17
|
+
[name]: value
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const onFocus = (event, { state }) => {
|
|
22
|
+
const { form } = state
|
|
23
|
+
const { name } = event.target
|
|
24
|
+
state.form.update({
|
|
25
|
+
...form,
|
|
26
|
+
[`${name}Validation`]: ''
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const onBlur = (event, { state }) => {
|
|
31
|
+
const { form } = state
|
|
32
|
+
const { name, value } = event.target
|
|
33
|
+
|
|
34
|
+
if (value !== 'kane@example.com') {
|
|
35
|
+
state.form.update({
|
|
36
|
+
...form,
|
|
37
|
+
[`${name}Validation`]: 'Email unknown'
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const FormTemplate = ({ email, emailValidation, emailInvalid }) => {
|
|
43
|
+
return (
|
|
44
|
+
<form>
|
|
45
|
+
<div>
|
|
46
|
+
<p>
|
|
47
|
+
<label for='email'>Email</label>
|
|
48
|
+
</p>
|
|
49
|
+
<If condition={emailInvalid}>
|
|
50
|
+
<p class='validation-error'>{emailValidation}</p>
|
|
51
|
+
</If>
|
|
52
|
+
<input
|
|
53
|
+
id='email'
|
|
54
|
+
name='email'
|
|
55
|
+
value={email}
|
|
56
|
+
onInput='onInput'
|
|
57
|
+
onBlur='onBlur'
|
|
58
|
+
onFocus='onFocus'
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<input type='submit' value="Let's go!" class='button-primary mt-6' />
|
|
63
|
+
</form>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const viewModel = ({ form }) => {
|
|
68
|
+
return {
|
|
69
|
+
...form,
|
|
70
|
+
emailInvalid: !!form.emailValidation
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const Form = bind({
|
|
75
|
+
Template: FormTemplate,
|
|
76
|
+
viewModel,
|
|
77
|
+
subscriptions: ['form']
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
app.subscribe('onInput', onInput)
|
|
81
|
+
app.subscribe('onFocus', onFocus)
|
|
82
|
+
app.subscribe('onBlur', onBlur)
|
|
83
|
+
|
|
84
|
+
app.render(<Form />, '#app')
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8"/>
|
|
5
|
+
<title>Jaxs integration test</title>
|
|
6
|
+
<script type="module" src="./add-remove-root-children.jsx"></script>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<header style="background-color: yellowgreen; border: 1px solid blue; padding: 10px;">
|
|
10
|
+
<div>Hello!</div>
|
|
11
|
+
<div id="profile-area" style="width: 25%"></div>
|
|
12
|
+
</header>
|
|
13
|
+
<article id="main-content"></article>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { bind, createApp, jsx, views } from '../../dist/jaxs.js'
|
|
2
|
+
const { If, Unless } = views
|
|
3
|
+
|
|
4
|
+
const app = createApp()
|
|
5
|
+
|
|
6
|
+
export const MainContentTemplate = ({ inMembers }) => {
|
|
7
|
+
return (
|
|
8
|
+
<>
|
|
9
|
+
<Unless condition={inMembers}>
|
|
10
|
+
<form>
|
|
11
|
+
<p class='guest-content'>
|
|
12
|
+
You are a guest, and I guess that is fine.
|
|
13
|
+
</p>
|
|
14
|
+
<input type='submit' value='Agree! or something' />
|
|
15
|
+
</form>
|
|
16
|
+
</Unless>
|
|
17
|
+
<If condition={inMembers}>
|
|
18
|
+
<h1 class='member-content'>Oh great crickets!</h1>
|
|
19
|
+
<p class='member-content'>Sing me a tale of private content.</p>
|
|
20
|
+
</If>
|
|
21
|
+
</>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
const ProfileAreaTemplate = ({ inMembers }) => {
|
|
25
|
+
return (
|
|
26
|
+
<Unless condition={inMembers}>
|
|
27
|
+
<a href='/members' onClick='goToHref' class='exclusive-link'>
|
|
28
|
+
Go to members area
|
|
29
|
+
</a>
|
|
30
|
+
</Unless>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const viewModel = ({ route }) => {
|
|
35
|
+
return {
|
|
36
|
+
inMembers: route && route.path && route.path.match(/members/)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const MainContent = bind({
|
|
41
|
+
Template: MainContentTemplate,
|
|
42
|
+
viewModel,
|
|
43
|
+
subscriptions: ['route']
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const ProfileArea = bind({
|
|
47
|
+
Template: ProfileAreaTemplate,
|
|
48
|
+
viewModel,
|
|
49
|
+
subscriptions: ['route']
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
app.render(<MainContent />, '#main-content')
|
|
53
|
+
app.render(<ProfileArea />, '#profile-area')
|