@knowark/componarkjs 1.7.3 → 1.7.5
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/Makefile +6 -3
- package/jsconfig.json +23 -0
- package/lib/base/component/component.js +27 -26
- package/lib/base/component/component.test.js +76 -32
- package/lib/base/styles/styles.js +34 -5
- package/lib/base/utils/define.js +6 -7
- package/lib/base/utils/define.test.js +5 -5
- package/lib/base/utils/helpers.js +14 -10
- package/lib/base/utils/helpers.test.js +13 -13
- package/lib/base/utils/uuid.js +4 -4
- package/lib/components/audio/components/audio.js +6 -6
- package/lib/components/audio/components/audio.test.js +11 -10
- package/lib/components/audio/styles/ark.css.js +1 -1
- package/lib/components/camera/components/camera.test.js +6 -6
- package/lib/components/camera/styles/ark.css.js +1 -1
- package/lib/components/camera/styles/index.js +1 -1
- package/lib/components/capture/components/capture.js +2 -2
- package/lib/components/capture/components/capture.test.js +1 -1
- package/lib/components/droparea/components/droparea-preview.js +27 -26
- package/lib/components/droparea/components/droparea-preview.test.js +9 -9
- package/lib/components/droparea/components/droparea.js +19 -19
- package/lib/components/droparea/components/droparea.test.js +42 -42
- package/lib/components/droparea/styles/ark.css.js +1 -1
- package/lib/components/emit/components/emit.js +4 -4
- package/lib/components/emit/components/emit.test.js +5 -5
- package/lib/components/list/components/item.test.js +12 -14
- package/lib/components/list/components/list.js +25 -25
- package/lib/components/list/components/list.test.js +27 -29
- package/lib/components/paginator/components/paginator.js +2 -2
- package/lib/components/paginator/components/paginator.test.js +15 -18
- package/lib/components/paginator/styles/ark.css.js +1 -1
- package/lib/components/spinner/components/spinner.js +17 -17
- package/lib/components/spinner/styles/index.js +1 -1
- package/lib/components/splitview/components/splitview.detail.js +3 -3
- package/lib/components/splitview/components/splitview.detail.test.js +23 -23
- package/lib/components/splitview/components/splitview.js +3 -3
- package/lib/components/splitview/components/splitview.master.js +3 -3
- package/lib/components/splitview/components/splitview.master.test.js +2 -2
- package/lib/components/splitview/components/splitview.test.js +5 -7
- package/lib/components/translate/components/translate.js +17 -19
- package/lib/components/translate/components/translate.test.js +13 -14
- package/package.json +1 -1
- package/showcase/assets/knowark.svg +1 -0
- package/showcase/{design/screens/base/audio/audioDemo.js → components/demos/audio.js} +6 -10
- package/showcase/{design/screens/base/camera/cameraDemo.js → components/demos/camera.js} +6 -7
- package/showcase/{design/screens/base/droparea/dropareaDemo.js → components/demos/droparea.js} +7 -7
- package/showcase/{design/screens/base/list/listDemo.js → components/demos/list.js} +2 -3
- package/showcase/{design/screens/base/paginator/paginatorDemo.js → components/demos/paginator.js} +9 -9
- package/showcase/{design/screens/base/splitview/splitViewDemo.js → components/demos/splitview.js} +42 -9
- package/showcase/{design/screens/base/translate/translateDemo.js → components/demos/translate.js} +4 -5
- package/showcase/components/index.html +81 -0
- package/showcase/index.html +40 -82
- package/showcase/index.js +0 -1
- package/webpack.config.cjs +50 -50
- package/showcase/design/core/factories/development/development.factory.js +0 -5
- package/showcase/design/core/factories/development/index.js +0 -1
- package/showcase/design/core/factories/index.js +0 -11
- package/showcase/design/core/factories/standard.factory.js +0 -19
- package/showcase/design/index.html +0 -22
- package/showcase/design/index.js +0 -7
- package/showcase/design/screens/base/audio/index.js +0 -25
- package/showcase/design/screens/base/camera/index.js +0 -25
- package/showcase/design/screens/base/droparea/index.js +0 -25
- package/showcase/design/screens/base/index.js +0 -42
- package/showcase/design/screens/base/list/index.js +0 -25
- package/showcase/design/screens/base/paginator/index.js +0 -25
- package/showcase/design/screens/base/root.component.js +0 -294
- package/showcase/design/screens/base/root.routes.js +0 -28
- package/showcase/design/screens/base/spinner/index.js +0 -25
- package/showcase/design/screens/base/spinner/spinnerDemo.js +0 -55
- package/showcase/design/screens/base/splitview/detailDemo.js +0 -40
- package/showcase/design/screens/base/splitview/index.js +0 -25
- package/showcase/design/screens/base/translate/index.js +0 -20
- package/showcase/design/screens/main.js +0 -12
- package/showcase/design/screens/screens.routes.js +0 -23
- package/tsconfig.json +0 -23
- /package/showcase/{design/.htaccess → .htaccess} +0 -0
package/Makefile
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.PHONY: all tests coverage
|
|
1
|
+
.PHONY: all tests coverage showcase
|
|
2
2
|
|
|
3
3
|
setup:
|
|
4
4
|
npm install -g browser-sync && \
|
|
@@ -15,8 +15,11 @@ test:
|
|
|
15
15
|
clean:
|
|
16
16
|
rm -rf ./dist
|
|
17
17
|
|
|
18
|
+
standard:
|
|
19
|
+
npx standard --fix
|
|
20
|
+
|
|
18
21
|
showcase:
|
|
19
|
-
npx live-server ./showcase
|
|
22
|
+
npx live-server ./showcase
|
|
20
23
|
|
|
21
24
|
dev:
|
|
22
25
|
npm run dev
|
|
@@ -28,7 +31,7 @@ push:
|
|
|
28
31
|
git push && git push --tags
|
|
29
32
|
|
|
30
33
|
deploy:
|
|
31
|
-
sshpass -e rsync -av --delete ./
|
|
34
|
+
sshpass -e rsync -av --delete ./showcase/ \
|
|
32
35
|
${RSYNC_USER}@${RSYNC_HOST}:${RSYNC_DIR}
|
|
33
36
|
|
|
34
37
|
reset:
|
package/jsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "esnext",
|
|
4
|
+
"module": "esnext",
|
|
5
|
+
"moduleResolution": "nodenext",
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"checkJs": true,
|
|
8
|
+
"baseUrl": "lib",
|
|
9
|
+
"paths": {
|
|
10
|
+
"@base*": [
|
|
11
|
+
"base",
|
|
12
|
+
"base*"
|
|
13
|
+
],
|
|
14
|
+
"*": [
|
|
15
|
+
"*"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"exclude": [
|
|
20
|
+
"node_modules",
|
|
21
|
+
"*/node_modules/"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { define, listen, reflect, slot, keys } from
|
|
1
|
+
import { define, listen, reflect, slot, keys } from '../utils/index.js'
|
|
2
2
|
import styles from '../styles/index.js'
|
|
3
3
|
|
|
4
4
|
const tag = 'ark-component'
|
|
5
|
-
export class Component extends HTMLElement {
|
|
6
|
-
constructor() {
|
|
5
|
+
export class Component extends globalThis.HTMLElement {
|
|
6
|
+
constructor () {
|
|
7
7
|
super()
|
|
8
|
-
this.binding =
|
|
8
|
+
this.binding = 'listen'
|
|
9
9
|
reflect(this, this.reflectedProperties())
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -13,74 +13,75 @@ export class Component extends HTMLElement {
|
|
|
13
13
|
* @param {string} tag
|
|
14
14
|
* @param {CustomElementConstructor} element
|
|
15
15
|
* @param {string} styles **/
|
|
16
|
-
static define(tag, element, styles = null) {
|
|
16
|
+
static define (tag, element, styles = null) {
|
|
17
17
|
define(tag, element, styles)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* @param {object} styleMap
|
|
22
22
|
* @return {string} **/
|
|
23
|
-
styleNames(styleMap) {
|
|
23
|
+
styleNames (styleMap) {
|
|
24
24
|
return keys(styleMap)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* @param {
|
|
28
|
+
* @param {object} context
|
|
29
29
|
* @return {Component} */
|
|
30
|
-
init(
|
|
30
|
+
init (context = {}) {
|
|
31
31
|
return this
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/** @return {string[]} */
|
|
35
|
-
reflectedProperties() {
|
|
35
|
+
reflectedProperties () {
|
|
36
36
|
return []
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
get slots() {
|
|
39
|
+
get slots () {
|
|
40
40
|
return slot(this)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/** @param {string} content */
|
|
44
|
-
set content(content) {
|
|
44
|
+
set content (content) {
|
|
45
45
|
this.innerHTML = content
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/** @return {string} */
|
|
49
|
-
get content() {
|
|
49
|
+
get content () {
|
|
50
50
|
return this.innerHTML
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
connectedCallback() {
|
|
53
|
+
connectedCallback () {
|
|
54
54
|
try {
|
|
55
|
-
!this
|
|
55
|
+
!this.state && this.init({})
|
|
56
56
|
this.render()
|
|
57
57
|
} catch (error) {
|
|
58
|
-
this.emit(
|
|
58
|
+
this.emit('error', error)
|
|
59
59
|
throw error
|
|
60
60
|
}
|
|
61
|
-
this.load()
|
|
61
|
+
this.load({})
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/** @return {Component} */
|
|
65
|
-
render() {
|
|
65
|
+
render () {
|
|
66
66
|
this.classList.add(this.tagName.toLowerCase())
|
|
67
67
|
listen(this)
|
|
68
68
|
return this
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
/** @param {object} context */
|
|
72
|
+
async load (context = {}) {}
|
|
72
73
|
|
|
73
74
|
/**
|
|
74
75
|
* @param {string} selectors
|
|
75
76
|
* @return {Component} */
|
|
76
|
-
select(selectors) {
|
|
77
|
+
select (selectors) {
|
|
77
78
|
return /** @type {Component} */ (this.querySelector(selectors))
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
/**
|
|
81
82
|
* @param {string} selectors
|
|
82
83
|
* @return {NodeListOf<Component>} */
|
|
83
|
-
selectAll(selectors) {
|
|
84
|
+
selectAll (selectors) {
|
|
84
85
|
return /** @type {NodeListOf<Component>} */ (this.querySelectorAll(
|
|
85
86
|
selectors
|
|
86
87
|
))
|
|
@@ -89,12 +90,12 @@ export class Component extends HTMLElement {
|
|
|
89
90
|
/**
|
|
90
91
|
* @param {string} type
|
|
91
92
|
* @param {any} detail */
|
|
92
|
-
emit(type, detail) {
|
|
93
|
+
emit (type, detail) {
|
|
93
94
|
this.dispatchEvent(
|
|
94
|
-
new CustomEvent(type, {
|
|
95
|
+
new globalThis.CustomEvent(type, {
|
|
95
96
|
detail,
|
|
96
97
|
bubbles: true,
|
|
97
|
-
cancelable: true
|
|
98
|
+
cancelable: true
|
|
98
99
|
})
|
|
99
100
|
)
|
|
100
101
|
}
|
|
@@ -102,11 +103,11 @@ export class Component extends HTMLElement {
|
|
|
102
103
|
/**
|
|
103
104
|
* @param {string} resource
|
|
104
105
|
* @return {any} */
|
|
105
|
-
resolve(resource) {
|
|
106
|
-
const event = new CustomEvent(
|
|
106
|
+
resolve (resource) {
|
|
107
|
+
const event = new globalThis.CustomEvent('resolve', {
|
|
107
108
|
detail: { resource },
|
|
108
109
|
bubbles: true,
|
|
109
|
-
cancelable: true
|
|
110
|
+
cancelable: true
|
|
110
111
|
})
|
|
111
112
|
this.dispatchEvent(event)
|
|
112
113
|
return event.detail[resource]
|
|
@@ -2,39 +2,44 @@ import { jest } from '@jest/globals'
|
|
|
2
2
|
import { Component } from './component.js'
|
|
3
3
|
|
|
4
4
|
class MockComponent extends Component {
|
|
5
|
-
init(context = {}) {
|
|
5
|
+
init (context = {}) {
|
|
6
6
|
this.context = context
|
|
7
7
|
this.data = {}
|
|
8
8
|
this.dependency = undefined
|
|
9
|
+
this.code = this.code || null
|
|
9
10
|
return super.init()
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
reflectedProperties() { return ['code'] }
|
|
13
|
+
reflectedProperties () { return ['code'] }
|
|
14
|
+
|
|
15
|
+
customHandler (/** @type {CustomEvent} */ event) {
|
|
16
|
+
event.detail.code = this.code
|
|
17
|
+
}
|
|
13
18
|
|
|
14
19
|
erroringHandler (_event) {
|
|
15
20
|
throw new Error('Something went wrong!')
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
async asyncErroringHandler (_event) {
|
|
19
|
-
const callback = async () => {
|
|
20
|
-
throw new Error('Something went async wrong!')
|
|
24
|
+
const callback = async () => {
|
|
25
|
+
throw new Error('Something went async wrong!')
|
|
26
|
+
}
|
|
21
27
|
await callback()
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
render() {
|
|
30
|
+
render () {
|
|
25
31
|
this.dependency = this.resolve('Dependency')
|
|
26
32
|
return super.render()
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
35
|
Component.define('mock-component', MockComponent)
|
|
30
36
|
|
|
31
|
-
|
|
32
37
|
describe('Component', () => {
|
|
33
38
|
let container = null
|
|
34
39
|
let component = null
|
|
35
40
|
beforeEach(() => {
|
|
36
41
|
container = document.createElement('div')
|
|
37
|
-
container.innerHTML =
|
|
42
|
+
container.innerHTML = '<mock-component code="XYZ123"></mock-component>'
|
|
38
43
|
component = container.querySelector('mock-component')
|
|
39
44
|
document.body.append(container)
|
|
40
45
|
})
|
|
@@ -63,15 +68,15 @@ describe('Component', () => {
|
|
|
63
68
|
})
|
|
64
69
|
|
|
65
70
|
it('has an init method through which state is set', () => {
|
|
66
|
-
const response = component.init({attribute: 'value'})
|
|
71
|
+
const response = component.init({ attribute: 'value' })
|
|
67
72
|
expect(response).toBe(component)
|
|
68
73
|
})
|
|
69
74
|
|
|
70
75
|
it('can set its content via a property', () => {
|
|
71
|
-
component.content =
|
|
76
|
+
component.content = '<p>Hello World</p>'
|
|
72
77
|
const paragraph = component.querySelector('p')
|
|
73
|
-
expect(component.content).toBe(
|
|
74
|
-
expect(paragraph.outerHTML).toBe(
|
|
78
|
+
expect(component.content).toBe('<p>Hello World</p>')
|
|
79
|
+
expect(paragraph.outerHTML).toBe('<p>Hello World</p>')
|
|
75
80
|
})
|
|
76
81
|
|
|
77
82
|
it('can have some of its attributes reflected as properties', () => {
|
|
@@ -94,16 +99,16 @@ describe('Component', () => {
|
|
|
94
99
|
|
|
95
100
|
it('emits custom events', () => {
|
|
96
101
|
let detail = null
|
|
97
|
-
const handler = (event) => {detail = event.detail}
|
|
102
|
+
const handler = (event) => { detail = event.detail }
|
|
98
103
|
component.addEventListener('fire', handler)
|
|
99
104
|
|
|
100
|
-
component.emit('fire', {location: 'indoors'})
|
|
105
|
+
component.emit('fire', { location: 'indoors' })
|
|
101
106
|
|
|
102
|
-
expect(detail).toEqual({location: 'indoors'})
|
|
107
|
+
expect(detail).toEqual({ location: 'indoors' })
|
|
103
108
|
})
|
|
104
109
|
|
|
105
110
|
it('calls the load method on connectedCallback', async () => {
|
|
106
|
-
const component = document.createElement('mock-component')
|
|
111
|
+
const component = document.createElement('mock-component')
|
|
107
112
|
const initSpy = jest.spyOn(component, 'init')
|
|
108
113
|
const renderSpy = jest.spyOn(component, 'render')
|
|
109
114
|
const loadSpy = jest.spyOn(component, 'load')
|
|
@@ -117,10 +122,10 @@ describe('Component', () => {
|
|
|
117
122
|
|
|
118
123
|
it('catches and re-raises connectedCallback errors', async () => {
|
|
119
124
|
expect.assertions(1)
|
|
120
|
-
const component = document.createElement('mock-component')
|
|
125
|
+
const component = document.createElement('mock-component')
|
|
121
126
|
const consoleError = console.error
|
|
122
127
|
console.error = jest.fn()
|
|
123
|
-
component.render = () => {
|
|
128
|
+
component.render = () => {
|
|
124
129
|
throw new Error('Render Error!')
|
|
125
130
|
}
|
|
126
131
|
|
|
@@ -133,7 +138,6 @@ describe('Component', () => {
|
|
|
133
138
|
console.error = consoleError
|
|
134
139
|
})
|
|
135
140
|
|
|
136
|
-
|
|
137
141
|
it('selects the children matching a selector', () => {
|
|
138
142
|
container.innerHTML = `
|
|
139
143
|
<mock-component>
|
|
@@ -168,7 +172,7 @@ describe('Component', () => {
|
|
|
168
172
|
footer: [component.select('.footer')]
|
|
169
173
|
})
|
|
170
174
|
})
|
|
171
|
-
|
|
175
|
+
|
|
172
176
|
it('binds its properties to children events', async () => {
|
|
173
177
|
container.innerHTML = `
|
|
174
178
|
<mock-component>
|
|
@@ -179,8 +183,9 @@ describe('Component', () => {
|
|
|
179
183
|
const component = container.querySelector('mock-component')
|
|
180
184
|
const input = component.select('input')
|
|
181
185
|
|
|
182
|
-
|
|
183
|
-
|
|
186
|
+
input.dispatchEvent(
|
|
187
|
+
new globalThis.InputEvent('input', { bubbles: true, data: 'E' })
|
|
188
|
+
)
|
|
184
189
|
|
|
185
190
|
expect(component.data.value).toEqual('E')
|
|
186
191
|
})
|
|
@@ -193,10 +198,10 @@ describe('Component', () => {
|
|
|
193
198
|
`
|
|
194
199
|
const component = container.querySelector('mock-component')
|
|
195
200
|
const input = component.select('input')
|
|
196
|
-
const inputEvent = new InputEvent('input')
|
|
201
|
+
const inputEvent = new globalThis.InputEvent('input')
|
|
197
202
|
const target = { name: 'input', value: 'X' }
|
|
198
203
|
Object.defineProperty(
|
|
199
|
-
inputEvent, 'target', { writable: false, value: target })
|
|
204
|
+
inputEvent, 'target', { writable: false, value: target })
|
|
200
205
|
|
|
201
206
|
input.dispatchEvent(inputEvent)
|
|
202
207
|
|
|
@@ -214,11 +219,46 @@ describe('Component', () => {
|
|
|
214
219
|
const input = component.select('input')
|
|
215
220
|
|
|
216
221
|
input.dispatchEvent(
|
|
217
|
-
new CustomEvent('alter',
|
|
222
|
+
new globalThis.CustomEvent('alter', { bubbles: true, detail: 'A' }))
|
|
218
223
|
|
|
219
224
|
expect(component.data.value).toEqual('A')
|
|
220
225
|
})
|
|
221
226
|
|
|
227
|
+
it('listens to events and handles them with its own methods', async () => {
|
|
228
|
+
container.innerHTML = `
|
|
229
|
+
<mock-component code="ABC123">
|
|
230
|
+
<input type="text" listen on-alter="customHandler"></input>
|
|
231
|
+
</mock-component>
|
|
232
|
+
`
|
|
233
|
+
|
|
234
|
+
const component = container.querySelector('mock-component')
|
|
235
|
+
const input = component.select('input')
|
|
236
|
+
|
|
237
|
+
const event = new globalThis.CustomEvent(
|
|
238
|
+
'alter', { bubbles: true, detail: { code: '' } })
|
|
239
|
+
input.dispatchEvent(event)
|
|
240
|
+
|
|
241
|
+
expect(event.detail.code).toEqual('ABC123')
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('listens to events and redirects them to target components', async () => {
|
|
245
|
+
container.innerHTML = `
|
|
246
|
+
<mock-component code="ABC123">
|
|
247
|
+
<input type="text" listen on-alter="customHandler" at="#child"></input>
|
|
248
|
+
<mock-component id="child" code="XYZ890"></mock-component>
|
|
249
|
+
</mock-component>
|
|
250
|
+
`
|
|
251
|
+
|
|
252
|
+
const component = container.querySelector('mock-component')
|
|
253
|
+
const input = component.select('input')
|
|
254
|
+
|
|
255
|
+
const event = new globalThis.CustomEvent(
|
|
256
|
+
'alter', { bubbles: true, detail: { code: '' } })
|
|
257
|
+
input.dispatchEvent(event)
|
|
258
|
+
|
|
259
|
+
expect(event.detail.code).toEqual('XYZ890')
|
|
260
|
+
})
|
|
261
|
+
|
|
222
262
|
it('emits an error event on declared listeners', async () => {
|
|
223
263
|
container.innerHTML = `
|
|
224
264
|
<mock-component>
|
|
@@ -229,12 +269,14 @@ describe('Component', () => {
|
|
|
229
269
|
const component = container.querySelector('mock-component')
|
|
230
270
|
|
|
231
271
|
let errorEvent = {}
|
|
232
|
-
component.addEventListener('error', (event) => errorEvent = event)
|
|
272
|
+
component.addEventListener('error', (event) => { errorEvent = event })
|
|
233
273
|
|
|
234
274
|
const input = component.select('input')
|
|
235
275
|
|
|
236
276
|
input.dispatchEvent(
|
|
237
|
-
new CustomEvent(
|
|
277
|
+
new globalThis.CustomEvent(
|
|
278
|
+
'alter', { bubbles: true, detail: 'I will error!' }
|
|
279
|
+
))
|
|
238
280
|
|
|
239
281
|
expect(errorEvent.detail.message).toEqual('Something went wrong!')
|
|
240
282
|
})
|
|
@@ -249,12 +291,14 @@ describe('Component', () => {
|
|
|
249
291
|
const component = container.querySelector('mock-component')
|
|
250
292
|
|
|
251
293
|
let errorEvent = {}
|
|
252
|
-
component.addEventListener('error', (event) => errorEvent = event)
|
|
294
|
+
component.addEventListener('error', (event) => { errorEvent = event })
|
|
253
295
|
|
|
254
296
|
const input = component.select('input')
|
|
255
297
|
|
|
256
298
|
input.dispatchEvent(
|
|
257
|
-
new CustomEvent(
|
|
299
|
+
new globalThis.CustomEvent(
|
|
300
|
+
'alter', { bubbles: true, detail: 'I will error!' }
|
|
301
|
+
))
|
|
258
302
|
|
|
259
303
|
// Sleep
|
|
260
304
|
await new Promise(resolve => setTimeout(resolve, 0))
|
|
@@ -279,7 +323,7 @@ describe('Component', () => {
|
|
|
279
323
|
|
|
280
324
|
it('provides the dependencies requested to it by child components', () => {
|
|
281
325
|
class ParentComponent extends MockComponent {
|
|
282
|
-
provide(resource) {
|
|
326
|
+
provide (resource) {
|
|
283
327
|
if (resource === 'Dependency') {
|
|
284
328
|
return `RESOURCE: ${resource} PROVIDED BY: ${this.id}`
|
|
285
329
|
}
|
|
@@ -293,11 +337,11 @@ describe('Component', () => {
|
|
|
293
337
|
<mock-component id="child"></mock-component>
|
|
294
338
|
</parent-component>
|
|
295
339
|
`
|
|
296
|
-
|
|
340
|
+
|
|
297
341
|
const child = container.querySelector('#child')
|
|
298
342
|
|
|
299
343
|
expect(child.dependency).toEqual(
|
|
300
|
-
|
|
344
|
+
'RESOURCE: Dependency PROVIDED BY: parent')
|
|
301
345
|
|
|
302
346
|
const state = child.resolve('state')
|
|
303
347
|
expect(state).toEqual({ key: 'value' })
|
|
@@ -317,7 +361,7 @@ describe('Component', () => {
|
|
|
317
361
|
const styleMap = {
|
|
318
362
|
[`background-${background}`]: background,
|
|
319
363
|
[`color-${color}`]: color,
|
|
320
|
-
[`shadow-${shadow}`]: shadow
|
|
364
|
+
[`shadow-${shadow}`]: shadow
|
|
321
365
|
}
|
|
322
366
|
|
|
323
367
|
const result = component.styleNames(styleMap)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const userActions = ['-hover',
|
|
1
|
+
const userActions = ['-hover', '-active']
|
|
2
2
|
|
|
3
3
|
const formActions = ['-focus-within', '-valid', '-invalid', '-checked']
|
|
4
4
|
|
|
@@ -46,7 +46,8 @@ html {
|
|
|
46
46
|
|
|
47
47
|
/* TYPOGRAPHY */
|
|
48
48
|
|
|
49
|
-
--font-size-
|
|
49
|
+
--font-size-base: 0.5rem;
|
|
50
|
+
--font-size-step: 0.125rem;
|
|
50
51
|
--line-height-step: 0.5;
|
|
51
52
|
--word-spacing-step: 0.1rem;
|
|
52
53
|
--letter-spacing-step: 0.05rem;
|
|
@@ -102,7 +103,8 @@ ${actions.map(action => css`
|
|
|
102
103
|
/* TYPOGRAPHY */
|
|
103
104
|
|
|
104
105
|
[style*='--font-size:'] {
|
|
105
|
-
font-size: calc(var(--font-size-
|
|
106
|
+
font-size: calc(var(--font-size-base) + (
|
|
107
|
+
var(--font-size-step) * var(--font-size)));
|
|
106
108
|
}
|
|
107
109
|
[style*='--line-height:'] {
|
|
108
110
|
line-height: calc(var(--line-height-step) * var(--line-height));
|
|
@@ -114,6 +116,18 @@ ${actions.map(action => css`
|
|
|
114
116
|
letter-spacing: calc(var(--letter-spacing-step) * var(--letter-spacing));
|
|
115
117
|
}
|
|
116
118
|
|
|
119
|
+
[style*='--text-overflow:'] {
|
|
120
|
+
overflow: hidden;
|
|
121
|
+
white-space: nowrap;
|
|
122
|
+
text-overflow: var(--text-overflow);
|
|
123
|
+
}
|
|
124
|
+
[style*='--overflow:'] {
|
|
125
|
+
overflow: var(--overflow);
|
|
126
|
+
}
|
|
127
|
+
[style*='--white-space:'] {
|
|
128
|
+
white-space: var(--white-space);
|
|
129
|
+
}
|
|
130
|
+
|
|
117
131
|
/* SPACING */
|
|
118
132
|
|
|
119
133
|
${sides.map(side => css`
|
|
@@ -252,7 +266,7 @@ ${effects.map(effect => actions.map(action => css`
|
|
|
252
266
|
|
|
253
267
|
/* COMBINATORS */
|
|
254
268
|
|
|
255
|
-
${[...mutableProperties,
|
|
269
|
+
${[...mutableProperties, ...effects].map(
|
|
256
270
|
effect => userActions.map(action => css`
|
|
257
271
|
*${action.replace('-', ':')} > [style*='--${effect}-parent${action}:'] {
|
|
258
272
|
${effect}: var(--${effect}-parent${action});
|
|
@@ -277,7 +291,22 @@ ${[...mutableProperties, ...effects].map(
|
|
|
277
291
|
[style*='--display-large:'] {
|
|
278
292
|
display: var(--display-large);
|
|
279
293
|
}
|
|
280
|
-
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* PSEUDO-ELEMENTS */
|
|
297
|
+
|
|
298
|
+
${actions.map(action => css`
|
|
299
|
+
[style*='--content-before${action}:']${action.replace('-', ':')}::before {
|
|
300
|
+
content: var(--content-before${action});
|
|
301
|
+
}
|
|
302
|
+
[style*='--content-after${action}:']${action.replace('-', ':')}::after {
|
|
303
|
+
content: var(--content-after${action});
|
|
304
|
+
}
|
|
305
|
+
[style*='--background-backdrop${action}:']${action.replace(
|
|
306
|
+
'-', ':')}::backdrop {
|
|
307
|
+
background: var(--background-backdrop${action});
|
|
308
|
+
}
|
|
309
|
+
`.trim()).join('\n')}
|
|
281
310
|
|
|
282
311
|
/* ANIMATIONS */
|
|
283
312
|
|
package/lib/base/utils/define.js
CHANGED
|
@@ -3,19 +3,18 @@
|
|
|
3
3
|
/** @param {string} tag
|
|
4
4
|
* @param {CustomElementConstructor} element
|
|
5
5
|
* @param {string} styles **/
|
|
6
|
-
export function define(tag, element, styles='') {
|
|
7
|
-
customElements.define(tag, element)
|
|
6
|
+
export function define (tag, element, styles = '') {
|
|
7
|
+
globalThis.customElements.define(tag, element)
|
|
8
8
|
if (!styles?.trim()) return
|
|
9
9
|
|
|
10
10
|
try {
|
|
11
|
-
const sheet = new CSSStyleSheet()
|
|
11
|
+
const sheet = new globalThis.CSSStyleSheet()
|
|
12
12
|
sheet.replaceSync(styles)
|
|
13
|
-
return document.adoptedStyleSheets = [
|
|
14
|
-
...document.adoptedStyleSheets, sheet]
|
|
13
|
+
return (document.adoptedStyleSheets = [
|
|
14
|
+
...document.adoptedStyleSheets, sheet])
|
|
15
15
|
} catch (error) {
|
|
16
16
|
const style = document.createElement('style')
|
|
17
17
|
style.textContent = styles
|
|
18
|
-
document.head.appendChild(style)
|
|
18
|
+
document.head.appendChild(style)
|
|
19
19
|
}
|
|
20
|
-
|
|
21
20
|
}
|
|
@@ -3,7 +3,7 @@ import { define } from './define.js'
|
|
|
3
3
|
|
|
4
4
|
describe('Define', () => {
|
|
5
5
|
it('can define a custome element', () => {
|
|
6
|
-
class NewElement extends HTMLElement {}
|
|
6
|
+
class NewElement extends globalThis.HTMLElement {}
|
|
7
7
|
define('new-element', NewElement)
|
|
8
8
|
|
|
9
9
|
const newElement = document.createElement('new-element')
|
|
@@ -12,16 +12,16 @@ describe('Define', () => {
|
|
|
12
12
|
|
|
13
13
|
it('can define a custom element using constructable CSSStyleSheet', () => {
|
|
14
14
|
let definedStyles = null
|
|
15
|
-
class MockCSSStyleSheet extends CSSStyleSheet {
|
|
15
|
+
class MockCSSStyleSheet extends globalThis.CSSStyleSheet {
|
|
16
16
|
replaceSync (styles) {
|
|
17
17
|
definedStyles = styles
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
jest.spyOn(window,
|
|
21
|
+
jest.spyOn(window, 'CSSStyleSheet').mockReturnValue(
|
|
22
22
|
new MockCSSStyleSheet())
|
|
23
23
|
|
|
24
|
-
class CSSStyledElement extends HTMLElement {}
|
|
24
|
+
class CSSStyledElement extends globalThis.HTMLElement {}
|
|
25
25
|
const styles = `
|
|
26
26
|
body {
|
|
27
27
|
color: red;
|
|
@@ -41,7 +41,7 @@ describe('Define', () => {
|
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
it('can define a custom element using an style fallback element', () => {
|
|
44
|
-
class StyledElement extends HTMLElement {}
|
|
44
|
+
class StyledElement extends globalThis.HTMLElement {}
|
|
45
45
|
const styles = `
|
|
46
46
|
body {
|
|
47
47
|
color: red;
|
|
@@ -2,36 +2,41 @@ import { camelToKebab } from './format.js'
|
|
|
2
2
|
|
|
3
3
|
/** @param {HTMLElement} self */
|
|
4
4
|
export function listen (self) {
|
|
5
|
-
const binding = self
|
|
5
|
+
const binding = self.binding
|
|
6
6
|
const elements = self.querySelectorAll(`[${binding}]`)
|
|
7
7
|
for (const element of elements) {
|
|
8
8
|
for (const attribute of Array.from(element.attributes)) {
|
|
9
9
|
if (attribute.name.startsWith('on-')) {
|
|
10
|
-
const eventName = attribute.name.replace('on-', '').trim()
|
|
11
10
|
let handler = self[attribute.value]
|
|
12
11
|
|
|
13
12
|
const [assignment] = attribute.value.match(/[^{{]+(?=\}})/g) || []
|
|
14
13
|
|
|
15
14
|
if (assignment) {
|
|
16
15
|
let [objectPath, eventPath] = assignment.split('=')
|
|
17
|
-
eventPath = eventPath || 'target.value'
|
|
16
|
+
eventPath = eventPath?.trim() || 'target.value'
|
|
18
17
|
handler = function (event) {
|
|
19
18
|
set(this, objectPath.trim(), get(
|
|
20
19
|
event, eventPath, get(event, 'detail', '')))
|
|
21
|
-
}
|
|
22
|
-
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
23
22
|
|
|
24
23
|
if (!handler) continue
|
|
25
24
|
|
|
25
|
+
const at = element.getAttribute('at')
|
|
26
26
|
const catchingHandler = async function (event) {
|
|
27
27
|
try {
|
|
28
|
-
|
|
28
|
+
let receiver = this
|
|
29
|
+
if (at) receiver = this.select(at)
|
|
30
|
+
return await Promise.resolve(handler.bind(receiver)(event))
|
|
29
31
|
} catch (error) {
|
|
30
|
-
this.dispatchEvent(
|
|
31
|
-
|
|
32
|
+
this.dispatchEvent(
|
|
33
|
+
new globalThis.CustomEvent(
|
|
34
|
+
'error', { detail: error, bubbles: true, cancelable: true }
|
|
35
|
+
))
|
|
32
36
|
}
|
|
33
37
|
}
|
|
34
38
|
|
|
39
|
+
const eventName = attribute.name.replace('on-', '').trim()
|
|
35
40
|
element.addEventListener(eventName, catchingHandler.bind(self))
|
|
36
41
|
element.removeAttribute(binding)
|
|
37
42
|
}
|
|
@@ -42,13 +47,12 @@ export function listen (self) {
|
|
|
42
47
|
/** @param {HTMLElement} self */
|
|
43
48
|
function provide (self) {
|
|
44
49
|
if (!self.provide) return
|
|
45
|
-
self.addEventListener('resolve', (event) => {
|
|
50
|
+
self.addEventListener('resolve', (/** @type {CustomEvent} */ event) => {
|
|
46
51
|
const resource = event.detail.resource
|
|
47
52
|
const dependency = self.provide(resource)
|
|
48
53
|
if (dependency === undefined) return
|
|
49
54
|
event.detail[resource] = dependency
|
|
50
55
|
})
|
|
51
|
-
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
/** @param {HTMLElement} self @param {string[]} properties */
|