mi-element 0.9.1 → 0.9.3
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/dist/element.js +2 -6
- package/dist/html.js +12 -7
- package/dist/index.js +1 -1
- package/dist/styling.js +10 -4
- package/docs/element.md +66 -60
- package/package.json +1 -1
- package/src/element.js +1 -27
- package/src/html.js +16 -9
- package/src/index.js +9 -2
- package/src/styling.js +33 -3
- package/types/html.d.ts +3 -2
- package/types/index.d.ts +2 -2
- package/types/styling.d.ts +2 -0
package/dist/element.js
CHANGED
|
@@ -52,13 +52,9 @@ class MiElement extends HTMLElement {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
connectedCallback() {
|
|
55
|
-
const {shadowRootInit: shadowRootInit, useGlobalStyles: useGlobalStyles, template: template
|
|
56
|
-
|
|
55
|
+
const {shadowRootInit: shadowRootInit, useGlobalStyles: useGlobalStyles, template: template} = this.constructor;
|
|
56
|
+
this.#controllers.forEach(controller => controller.hostConnected?.()), this.renderRoot = shadowRootInit ? this.shadowRoot ?? this.attachShadow(shadowRootInit) : this,
|
|
57
57
|
this.addTemplate(template), useGlobalStyles && addGlobalStyles(this.renderRoot),
|
|
58
|
-
formAssociated && this.handleFormdata) {
|
|
59
|
-
const internals = this.attachInternals();
|
|
60
|
-
internals.form && this.on('formdata', ev => this.handleFormdata(ev), internals.form);
|
|
61
|
-
}
|
|
62
58
|
this.render(), this.requestUpdate();
|
|
63
59
|
}
|
|
64
60
|
disconnectedCallback() {
|
package/dist/html.js
CHANGED
|
@@ -2,21 +2,26 @@ import { toJson } from './utils.js';
|
|
|
2
2
|
|
|
3
3
|
const globalRenderCache = new class {
|
|
4
4
|
cnt=0;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
cache=new Map;
|
|
6
|
+
last=0;
|
|
7
|
+
get size() {
|
|
8
|
+
return this.cache.size;
|
|
9
|
+
}
|
|
7
10
|
_inc() {
|
|
8
11
|
return this.cnt = 268435455 & ++this.cnt, this.cnt;
|
|
9
12
|
}
|
|
10
13
|
clear() {
|
|
11
|
-
this.cnt = 0, this.
|
|
14
|
+
this.cnt = 0, this.cache.clear();
|
|
12
15
|
}
|
|
13
16
|
set(value) {
|
|
14
|
-
const
|
|
15
|
-
|
|
17
|
+
const now = Date.now();
|
|
18
|
+
this.last < now && this.cache.clear(), this.last = now + 5e3;
|
|
19
|
+
const key = '__rc:' + this._inc().toString(36);
|
|
20
|
+
return this.cache.set(key, value), key;
|
|
16
21
|
}
|
|
17
22
|
get(key) {
|
|
18
|
-
const
|
|
19
|
-
return this.
|
|
23
|
+
const value = this.cache.get(key);
|
|
24
|
+
return this.cache.delete(key), value;
|
|
20
25
|
}
|
|
21
26
|
};
|
|
22
27
|
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,6 @@ export { refsBySelector } from './refs.js';
|
|
|
8
8
|
|
|
9
9
|
export { Store } from './store.js';
|
|
10
10
|
|
|
11
|
-
export { addGlobalStyles, classNames, css, styleMap } from './styling.js';
|
|
11
|
+
export { addGlobalStyles, classNames, css, escCss, styleMap, unsafeCss } from './styling.js';
|
|
12
12
|
|
|
13
13
|
export { default as Signal } from 'mi-signal';
|
package/dist/styling.js
CHANGED
|
@@ -3,7 +3,7 @@ import { camelToKebabCase } from './case.js';
|
|
|
3
3
|
const classNames = (...args) => {
|
|
4
4
|
const classList = [];
|
|
5
5
|
return args.forEach(arg => {
|
|
6
|
-
arg && ('string' == typeof arg ? classList.push(arg) :
|
|
6
|
+
arg && ('string' == typeof arg ? classList.push(arg) : 'object' == typeof arg && Object.entries(arg).forEach(([key, value]) => {
|
|
7
7
|
value && classList.push(key);
|
|
8
8
|
}));
|
|
9
9
|
}), classList.join(' ');
|
|
@@ -26,8 +26,14 @@ function addGlobalStyles(renderRoot) {
|
|
|
26
26
|
})), globalSheets));
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
class UnsafeCss extends String {}
|
|
30
|
+
|
|
31
|
+
const unsafeCss = str => new UnsafeCss(str), escMap = {
|
|
32
|
+
'&': '\\26 ',
|
|
33
|
+
'<': '\\3c ',
|
|
34
|
+
'>': '\\3e '
|
|
35
|
+
}, escCss = string => string instanceof UnsafeCss ? string : unsafeCss((string => string.replace(/[&<>]/g, tag => escMap[tag]))('' + string)), css = (strings, ...values) => String.raw({
|
|
30
36
|
raw: strings
|
|
31
|
-
}, ...values);
|
|
37
|
+
}, ...values.map(escCss));
|
|
32
38
|
|
|
33
|
-
export { addGlobalStyles, classNames, css, styleMap };
|
|
39
|
+
export { addGlobalStyles, classNames, css, escCss, styleMap, unsafeCss };
|
package/docs/element.md
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- !toc (minlevel=2) -->
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
- [constructor()](#constructor)
|
|
6
|
+
- [connectedCallback()](#connectedcallback)
|
|
7
|
+
- [disconnectedCallback()](#disconnectedcallback)
|
|
8
|
+
- [attributeChangedCallback(name, oldValue, newValue)](#attributechangedcallbackname-oldvalue-newvalue)
|
|
9
|
+
- [Update Cycle](#update-cycle)
|
|
10
|
+
- [Form-Associated Elements](#form-associated-elements)
|
|
11
|
+
- [render()](#render)
|
|
12
|
+
- [update(changedAttributes)](#updatechangedattributes)
|
|
13
|
+
- [shouldUpdate(changedAttributes)](#shouldupdatechangedattributes)
|
|
14
|
+
- [on(eventName, listener, \[node\])](#oneventname-listener-node)
|
|
15
|
+
- [once(eventName, listener, \[node\])](#onceeventname-listener-node)
|
|
16
16
|
|
|
17
17
|
<!-- toc! -->
|
|
18
18
|
|
|
@@ -29,16 +29,15 @@ from the `static attributes` object. From there setters and getters for property
|
|
|
29
29
|
changes using `.[name] = newValue` instead of `setAttribute(name, newValue)` are
|
|
30
30
|
applied.
|
|
31
31
|
|
|
32
|
-
|
|
33
32
|
```js
|
|
34
33
|
class extends MiElement {
|
|
35
34
|
/**
|
|
36
|
-
* Declare observable attributes with this getter.
|
|
35
|
+
* Declare observable attributes with this getter.
|
|
37
36
|
* Use `true` to define boolean attributes!
|
|
38
|
-
* Do not use `static attribute = { text: false }` as components attributes
|
|
39
|
-
* will use a shallow copy only. With the getter we always get a real "deep"
|
|
37
|
+
* Do not use `static attribute = { text: false }` as components attributes
|
|
38
|
+
* will use a shallow copy only. With the getter we always get a real "deep"
|
|
40
39
|
* copy.
|
|
41
|
-
*
|
|
40
|
+
*
|
|
42
41
|
* Avoid using attributes which are HTMLElement properties e.g. `className`.
|
|
43
42
|
* camelCased attributes will be made observable using its kebab-cased name.
|
|
44
43
|
*/
|
|
@@ -77,7 +76,7 @@ Then the first `render()` is issued with a `requestUpdate()`
|
|
|
77
76
|
|
|
78
77
|
```js
|
|
79
78
|
class extends MiElement {
|
|
80
|
-
// { mode: 'open' } is the default shadow root option
|
|
79
|
+
// { mode: 'open' } is the default shadow root option
|
|
81
80
|
// use `null` for no shadow root or { mode: 'closed' } for closed mode
|
|
82
81
|
static shadowRootInit = { mode: 'open' }
|
|
83
82
|
|
|
@@ -127,11 +126,11 @@ prevent memory leaks.
|
|
|
127
126
|
|
|
128
127
|
See previous example.
|
|
129
128
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
> ℹ️ **No need to remove internal event listeners**
|
|
130
|
+
>
|
|
131
|
+
> You don't need to remove event listeners added on the component's own
|
|
132
|
+
> DOM. This includes those added in your template. Unlike external
|
|
133
|
+
> event listeners, these will be garbage collected with the component.
|
|
135
134
|
|
|
136
135
|
## attributeChangedCallback(name, oldValue, newValue)
|
|
137
136
|
|
|
@@ -212,16 +211,18 @@ class Counter extends MiElement {
|
|
|
212
211
|
MiElement supports [form-associated custom elements][form-associated], allowing
|
|
213
212
|
your components to participate in HTML forms just like native form controls.
|
|
214
213
|
|
|
215
|
-
[form-associated]: https://web.dev/articles/
|
|
214
|
+
[form-associated]: https://web.dev/articles/more-capable-form-controls
|
|
216
215
|
|
|
217
216
|
### Declaring a Form-Associated Element
|
|
218
217
|
|
|
219
218
|
Set `static formAssociated = true` on your component to enable form association:
|
|
220
219
|
|
|
221
220
|
```js
|
|
222
|
-
import { define, MiElement
|
|
221
|
+
import { define, MiElement } from 'mi-element'
|
|
223
222
|
|
|
224
223
|
class CustomInput extends MiElement {
|
|
224
|
+
#internals
|
|
225
|
+
|
|
225
226
|
static formAssociated = true
|
|
226
227
|
|
|
227
228
|
static get properties() {
|
|
@@ -231,41 +232,48 @@ class CustomInput extends MiElement {
|
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
234
|
|
|
234
|
-
static template =
|
|
235
|
-
|
|
235
|
+
static template = `<input type="text" />`
|
|
236
|
+
|
|
236
237
|
render() {
|
|
238
|
+
this.#internals = this.attachInternals()
|
|
239
|
+
// define the aria role
|
|
240
|
+
this.#internals.ariaRole = 'textbox'
|
|
241
|
+
// set the initial form value
|
|
242
|
+
this.#internals.setFormValue(this.value)
|
|
243
|
+
|
|
237
244
|
this.refs = this.refsBySelector({ input: 'input' })
|
|
238
245
|
this.refs.input.addEventListener('input', (ev) => {
|
|
239
246
|
this.value = ev.target.value
|
|
247
|
+
// !needs a `name` attribute on the custom element
|
|
248
|
+
this.#internals.setFormValue(this.value)
|
|
249
|
+
this.checkValidity(this.value)
|
|
240
250
|
})
|
|
241
251
|
}
|
|
242
|
-
}
|
|
243
252
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
253
|
+
checkValidity(newValue) {
|
|
254
|
+
if (newValue >= 2) {
|
|
255
|
+
this.#internals.setValidity({})
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
this.#internals.setValidity(
|
|
259
|
+
{ tooSort: true },
|
|
260
|
+
'value too short',
|
|
261
|
+
this.refs.input
|
|
262
|
+
)
|
|
263
|
+
this.#internals.reportValidity()
|
|
264
|
+
}
|
|
255
265
|
|
|
256
|
-
|
|
266
|
+
formResetCallback() {
|
|
267
|
+
this.value = this.refs.input.value = ''
|
|
268
|
+
}
|
|
257
269
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if (this.name) {
|
|
261
|
-
ev.formData.append(this.name, this.refs.input.value)
|
|
262
|
-
}
|
|
270
|
+
formStateRestoreCallback(state, reason) {
|
|
271
|
+
this.value = this.refs.input.value = state
|
|
263
272
|
}
|
|
264
273
|
}
|
|
265
|
-
```
|
|
266
274
|
|
|
267
|
-
|
|
268
|
-
|
|
275
|
+
define('custom-input', CustomInput)
|
|
276
|
+
```
|
|
269
277
|
|
|
270
278
|
### Usage Example
|
|
271
279
|
|
|
@@ -279,13 +287,12 @@ when `FormData` is created from the form.
|
|
|
279
287
|
<script>
|
|
280
288
|
const form = document.getElementById('my-form')
|
|
281
289
|
const formData = new FormData(form)
|
|
282
|
-
|
|
290
|
+
|
|
283
291
|
console.log(formData.get('username')) // 'john'
|
|
284
|
-
console.log(formData.get('email'))
|
|
292
|
+
console.log(formData.get('email')) // 'john@example.com'
|
|
285
293
|
</script>
|
|
286
294
|
```
|
|
287
295
|
|
|
288
|
-
|
|
289
296
|
## render()
|
|
290
297
|
|
|
291
298
|
Initial rendering of the component. Try to render the component only once!
|
|
@@ -296,10 +303,10 @@ Within the `render()` method, bear in mind to:
|
|
|
296
303
|
- Avoid producing any side effects.
|
|
297
304
|
- Use only the component's properties as input.
|
|
298
305
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
306
|
+
> ⚠️ **XSS - Cross-Site Scripting**
|
|
307
|
+
>
|
|
308
|
+
> Using [`innerHTML`][innerHTML] to create the components DOM is susceptible to
|
|
309
|
+
> [XSS][XSS] attacks in case that user-supplied data contains valid HTML markup.
|
|
303
310
|
|
|
304
311
|
In all other cases you may consider the <code>html``</code> template literal or
|
|
305
312
|
`escHtml()` from the "mi-element" import, which escapes user-supplied data.
|
|
@@ -403,9 +410,9 @@ import { MiElement, Signal } from 'mi-element'
|
|
|
403
410
|
|
|
404
411
|
class Counter extends MiElement {
|
|
405
412
|
static get properties() {
|
|
406
|
-
return {
|
|
407
|
-
value: { type: Number }
|
|
408
|
-
|
|
413
|
+
return {
|
|
414
|
+
value: { type: Number }
|
|
415
|
+
}
|
|
409
416
|
}
|
|
410
417
|
|
|
411
418
|
static template = `
|
|
@@ -419,7 +426,6 @@ class Counter extends MiElement {
|
|
|
419
426
|
this.value = 0
|
|
420
427
|
}
|
|
421
428
|
|
|
422
|
-
|
|
423
429
|
render() {
|
|
424
430
|
const refs = this.refsBySelector({
|
|
425
431
|
button: 'button',
|
|
@@ -431,7 +437,7 @@ class Counter extends MiElement {
|
|
|
431
437
|
})
|
|
432
438
|
|
|
433
439
|
Signal.effect(() => {
|
|
434
|
-
// an update only happens if `this.value` changes;
|
|
440
|
+
// an update only happens if `this.value` changes;
|
|
435
441
|
// other attribute changes are ignored.
|
|
436
442
|
refs.count.textContent = this.value
|
|
437
443
|
})
|
|
@@ -447,7 +453,7 @@ disconnects.
|
|
|
447
453
|
```js
|
|
448
454
|
class Router extends MiElement {
|
|
449
455
|
render() {
|
|
450
|
-
// add event listener 'hashchange' to `window` which is disposed as soon as
|
|
456
|
+
// add event listener 'hashchange' to `window` which is disposed as soon as
|
|
451
457
|
// the component unmounts
|
|
452
458
|
this.on('hashchange', this.update, window)
|
|
453
459
|
}
|
package/package.json
CHANGED
package/src/element.js
CHANGED
|
@@ -160,8 +160,7 @@ export class MiElement extends HTMLElement {
|
|
|
160
160
|
*/
|
|
161
161
|
connectedCallback() {
|
|
162
162
|
// @ts-expect-error
|
|
163
|
-
const { shadowRootInit, useGlobalStyles, template
|
|
164
|
-
this.constructor
|
|
163
|
+
const { shadowRootInit, useGlobalStyles, template } = this.constructor
|
|
165
164
|
// connect all controllers
|
|
166
165
|
this.#controllers.forEach((controller) => controller.hostConnected?.())
|
|
167
166
|
this.renderRoot = shadowRootInit
|
|
@@ -171,31 +170,6 @@ export class MiElement extends HTMLElement {
|
|
|
171
170
|
if (useGlobalStyles) {
|
|
172
171
|
addGlobalStyles(this.renderRoot)
|
|
173
172
|
}
|
|
174
|
-
/**
|
|
175
|
-
* handle formdata event if `handleFormdata` method is defined on the component.
|
|
176
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/formdata_event
|
|
177
|
-
* ```js
|
|
178
|
-
* class MyElement extends MiElement {
|
|
179
|
-
* static formAssociated = true // required to receive formdata event
|
|
180
|
-
* handleFormdata(ev) {
|
|
181
|
-
* const { name, value } = this.refs.input
|
|
182
|
-
* ev.formData.append(name, value)
|
|
183
|
-
* }
|
|
184
|
-
* render() {
|
|
185
|
-
* this.renderRoot.innerHTML = html`<input name="${this.name}" value="${this.value}">`
|
|
186
|
-
* this.refs = { input: this.renderRoot.querySelector('input') }
|
|
187
|
-
* }
|
|
188
|
-
* }
|
|
189
|
-
* ```
|
|
190
|
-
*/
|
|
191
|
-
// @ts-expect-error
|
|
192
|
-
if (formAssociated && this.handleFormdata) {
|
|
193
|
-
const internals = this.attachInternals()
|
|
194
|
-
if (internals.form) {
|
|
195
|
-
// @ts-expect-error
|
|
196
|
-
this.on('formdata', (ev) => this.handleFormdata(ev), internals.form)
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
173
|
this.render() // initial render
|
|
200
174
|
this.requestUpdate() // request initial update
|
|
201
175
|
}
|
package/src/html.js
CHANGED
|
@@ -5,8 +5,12 @@ import { toJson } from './utils.js'
|
|
|
5
5
|
*/
|
|
6
6
|
class RenderCache {
|
|
7
7
|
cnt = 0
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
cache = new Map()
|
|
9
|
+
last = 0
|
|
10
|
+
|
|
11
|
+
get size() {
|
|
12
|
+
return this.cache.size
|
|
13
|
+
}
|
|
10
14
|
|
|
11
15
|
_inc() {
|
|
12
16
|
this.cnt = ++this.cnt & 0xfffffff
|
|
@@ -15,21 +19,24 @@ class RenderCache {
|
|
|
15
19
|
|
|
16
20
|
clear() {
|
|
17
21
|
this.cnt = 0
|
|
18
|
-
this.
|
|
22
|
+
this.cache.clear()
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
set(value) {
|
|
26
|
+
const now = Date.now()
|
|
27
|
+
if (this.last < now) {
|
|
28
|
+
this.cache.clear()
|
|
29
|
+
}
|
|
30
|
+
this.last = now + 5e3
|
|
22
31
|
const key = '__rc:' + this._inc().toString(36)
|
|
23
|
-
|
|
24
|
-
this.map.set(key, ref)
|
|
25
|
-
this.cache.set(ref, value)
|
|
32
|
+
this.cache.set(key, value)
|
|
26
33
|
return key
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
get(key) {
|
|
30
|
-
const
|
|
31
|
-
this.
|
|
32
|
-
return
|
|
37
|
+
const value = this.cache.get(key)
|
|
38
|
+
this.cache.delete(key)
|
|
39
|
+
return value
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
42
|
|
package/src/index.js
CHANGED
|
@@ -10,11 +10,18 @@ export {
|
|
|
10
10
|
* @typedef {import('./element.js').HostController} HostController
|
|
11
11
|
*/
|
|
12
12
|
export { MiElement, convertType, define } from './element.js'
|
|
13
|
-
export {
|
|
13
|
+
export { html, unsafeHtml, escHtml, render, renderAttrs } from './html.js'
|
|
14
14
|
export { refsBySelector } from './refs.js'
|
|
15
15
|
/**
|
|
16
16
|
* @typedef {import('./store.js').Action} Action
|
|
17
17
|
*/
|
|
18
18
|
export { Store } from './store.js'
|
|
19
|
-
export {
|
|
19
|
+
export {
|
|
20
|
+
classNames,
|
|
21
|
+
styleMap,
|
|
22
|
+
addGlobalStyles,
|
|
23
|
+
css,
|
|
24
|
+
unsafeCss,
|
|
25
|
+
escCss
|
|
26
|
+
} from './styling.js'
|
|
20
27
|
export { default as Signal } from 'mi-signal'
|
package/src/styling.js
CHANGED
|
@@ -11,8 +11,6 @@ export const classNames = (...args) => {
|
|
|
11
11
|
if (!arg) return
|
|
12
12
|
if (typeof arg === 'string') {
|
|
13
13
|
classList.push(arg)
|
|
14
|
-
} else if (Array.isArray(arg)) {
|
|
15
|
-
classList.push(classNames(...arg))
|
|
16
14
|
} else if (typeof arg === 'object') {
|
|
17
15
|
Object.entries(arg).forEach(([key, value]) => {
|
|
18
16
|
if (value) {
|
|
@@ -77,9 +75,41 @@ export function addGlobalStyles(renderRoot) {
|
|
|
77
75
|
renderRoot.adoptedStyleSheets.push(...getGlobalStyleSheets())
|
|
78
76
|
}
|
|
79
77
|
|
|
78
|
+
/**
|
|
79
|
+
* A helper class to avoid double escaping of HTML strings
|
|
80
|
+
*/
|
|
81
|
+
class UnsafeCss extends String {}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* tag a string as css for not to be escaped
|
|
85
|
+
* @param {string} str
|
|
86
|
+
* @returns {string}
|
|
87
|
+
*/
|
|
88
|
+
// @ts-expect-error
|
|
89
|
+
export const unsafeCss = (str) => new UnsafeCss(str)
|
|
90
|
+
|
|
91
|
+
const escMap = {
|
|
92
|
+
'&': '\\26 ',
|
|
93
|
+
'<': '\\3c ',
|
|
94
|
+
'>': '\\3e '
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const esc = (string) => string.replace(/[&<>]/g, (tag) => escMap[tag])
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @see https://mathiasbynens.be/notes/css-escapes
|
|
101
|
+
* Escape a value interpolated into a css tagged template literal.
|
|
102
|
+
* Prevents injection of closing style tags or unexpected CSS constructs.
|
|
103
|
+
* @param {*} string
|
|
104
|
+
* @returns {string}
|
|
105
|
+
*/
|
|
106
|
+
export const escCss = (string) =>
|
|
107
|
+
// @ts-expect-error
|
|
108
|
+
string instanceof UnsafeCss ? string : unsafeCss(esc('' + string))
|
|
109
|
+
|
|
80
110
|
/**
|
|
81
111
|
* Helper literal to show css styles in JS e.g. with
|
|
82
112
|
* https://marketplace.visualstudio.com/items?itemName=Tobermory.es6-string-html
|
|
83
113
|
*/
|
|
84
114
|
export const css = (strings, ...values) =>
|
|
85
|
-
String.raw({ raw: strings }, ...values)
|
|
115
|
+
String.raw({ raw: strings }, ...values.map(escCss))
|
package/types/html.d.ts
CHANGED
|
@@ -40,8 +40,9 @@ declare class UnsafeHtml extends String {
|
|
|
40
40
|
*/
|
|
41
41
|
declare class RenderCache {
|
|
42
42
|
cnt: number;
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
cache: Map<any, any>;
|
|
44
|
+
last: number;
|
|
45
|
+
get size(): number;
|
|
45
46
|
_inc(): number;
|
|
46
47
|
clear(): void;
|
|
47
48
|
set(value: any): string;
|
package/types/index.d.ts
CHANGED
|
@@ -6,5 +6,5 @@ export type HostController = import("./element.js").HostController;
|
|
|
6
6
|
export type Action = import("./store.js").Action;
|
|
7
7
|
export { ContextConsumer, ContextProvider, ContextRequestEvent } from "./context.js";
|
|
8
8
|
export { MiElement, convertType, define } from "./element.js";
|
|
9
|
-
export {
|
|
10
|
-
export { classNames, styleMap, addGlobalStyles, css } from "./styling.js";
|
|
9
|
+
export { html, unsafeHtml, escHtml, render, renderAttrs } from "./html.js";
|
|
10
|
+
export { classNames, styleMap, addGlobalStyles, css, unsafeCss, escCss } from "./styling.js";
|
package/types/styling.d.ts
CHANGED