mi-element 0.0.1 → 0.1.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/LICENSE +20 -0
- package/README.md +88 -0
- package/dist/context.js +62 -0
- package/dist/element.js +109 -0
- package/dist/escape.js +9 -0
- package/dist/index.js +11 -0
- package/dist/refs.js +15 -0
- package/dist/signal.js +24 -0
- package/dist/store.js +28 -0
- package/package.json +87 -4
- package/src/context.js +162 -0
- package/src/element.js +342 -0
- package/src/escape.js +38 -0
- package/src/index.js +22 -0
- package/src/refs.js +47 -0
- package/src/signal.js +76 -0
- package/src/store.js +99 -0
- package/types/context.d.ts +70 -0
- package/types/element.d.ts +169 -0
- package/types/escape.d.ts +3 -0
- package/types/index.d.ts +14 -0
- package/types/refs.d.ts +24 -0
- package/types/signal.d.ts +36 -0
- package/types/store.d.ts +46 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} HostController controller
|
|
3
|
+
* @property {() => void} hostConnected is called when host element is added to
|
|
4
|
+
* the DOM, usually with connectedCallback()
|
|
5
|
+
* @property {() => void} hostDisconnected is called when host element is
|
|
6
|
+
* removed from the DOM, usually with disconnectedCallback()
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* class extening HTMLElement to enable deferred rendering on attribute changes
|
|
10
|
+
* either via `setAttribute(name, value)` or `this[name] = value`.
|
|
11
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
|
|
12
|
+
* @example
|
|
13
|
+
* ```js
|
|
14
|
+
* class Example extends MiElement {
|
|
15
|
+
* // define all observed attributes with its default value.
|
|
16
|
+
* // attributes are accessible via `this[prop]`
|
|
17
|
+
* // avoid using attributes which are HTMLElement properties e.g. className
|
|
18
|
+
* static get attributes () {
|
|
19
|
+
* return { text: 'Hi' }
|
|
20
|
+
* }
|
|
21
|
+
* render() {
|
|
22
|
+
* this.renderRoot.innerHTML = `<div></div>`
|
|
23
|
+
* this.refs = {
|
|
24
|
+
* div: this.renderRoot.querySelector('div')
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* // render method called every time an attribute changes
|
|
28
|
+
* update() {
|
|
29
|
+
* this.refs.div.textContent = this.text
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* // create a custom element with the `define` function (see below)
|
|
33
|
+
* define('x-example', Example)
|
|
34
|
+
* // create a DOM node and re-render via attribute or property changes
|
|
35
|
+
* const elem = document.createElement('x-example')
|
|
36
|
+
* elem.setAttribute('text', 'set attribute')
|
|
37
|
+
* // or if change is triggered by property
|
|
38
|
+
* elem.text = 'set property'
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export class MiElement extends HTMLElement {
|
|
42
|
+
/**
|
|
43
|
+
* Default options used when calling `attachShadow`. Used in
|
|
44
|
+
* `connectedCallback()`.
|
|
45
|
+
* If override is `null`, no shadow-root will be attached.
|
|
46
|
+
*/
|
|
47
|
+
static shadowRootOptions: {
|
|
48
|
+
mode: string
|
|
49
|
+
}
|
|
50
|
+
__attr: {}
|
|
51
|
+
__attrLc: Map<any, any>
|
|
52
|
+
__types: Map<any, any>
|
|
53
|
+
__disposers: Set<any>
|
|
54
|
+
__controllers: Set<any>
|
|
55
|
+
__changedAttr: {}
|
|
56
|
+
/**
|
|
57
|
+
* requests update on component when property changes
|
|
58
|
+
*/
|
|
59
|
+
__observedAttributes(): void
|
|
60
|
+
/**
|
|
61
|
+
* return camelCased value instead of possible lowercased
|
|
62
|
+
* @param {string} name
|
|
63
|
+
* @returns
|
|
64
|
+
*/
|
|
65
|
+
__getName(name: string): any
|
|
66
|
+
__getType(name: any): any
|
|
67
|
+
/**
|
|
68
|
+
* creates the element's renderRoot, sets up styling
|
|
69
|
+
* @category lifecycle
|
|
70
|
+
*/
|
|
71
|
+
connectedCallback(): void
|
|
72
|
+
renderRoot: any
|
|
73
|
+
/**
|
|
74
|
+
* unsubscribe from all events and disconnect controllers
|
|
75
|
+
*/
|
|
76
|
+
disconnectedCallback(): void
|
|
77
|
+
/**
|
|
78
|
+
* @param {string} name change attribute
|
|
79
|
+
* @param {any} _oldValue
|
|
80
|
+
* @param {any} newValue new value
|
|
81
|
+
*/
|
|
82
|
+
attributeChangedCallback(name: string, _oldValue: any, newValue: any): void
|
|
83
|
+
/**
|
|
84
|
+
* Set string and number attributes on element only. Set all other values as
|
|
85
|
+
* properties to avoid type conversion to and from string
|
|
86
|
+
* @param {string} name
|
|
87
|
+
* @param {any} newValue
|
|
88
|
+
*/
|
|
89
|
+
setAttribute(name: string, newValue: any): void
|
|
90
|
+
/**
|
|
91
|
+
* request rendering
|
|
92
|
+
*/
|
|
93
|
+
requestUpdate(): void
|
|
94
|
+
/**
|
|
95
|
+
* initial rendering
|
|
96
|
+
*/
|
|
97
|
+
render(): void
|
|
98
|
+
/**
|
|
99
|
+
* controls if component shall be updated
|
|
100
|
+
* @param {Record<string,any>} _changedAttributes changed attributes
|
|
101
|
+
* @returns {boolean}
|
|
102
|
+
*/
|
|
103
|
+
shouldUpdate(_changedAttributes: Record<string, any>): boolean
|
|
104
|
+
/**
|
|
105
|
+
* called every time the components needs a render update
|
|
106
|
+
* @param {Record<string,any>} _changedAttributes changed attributes
|
|
107
|
+
*/
|
|
108
|
+
update(_changedAttributes: Record<string, any>): void
|
|
109
|
+
/**
|
|
110
|
+
* Adds listener function for eventName. listener is removed before component
|
|
111
|
+
* disconnects
|
|
112
|
+
* @param {string} eventName
|
|
113
|
+
* @param {EventListenerOrEventListenerObject} listener
|
|
114
|
+
* @param {Node|Document|Window} [node=this]
|
|
115
|
+
*/
|
|
116
|
+
on(
|
|
117
|
+
eventName: string,
|
|
118
|
+
listener: EventListenerOrEventListenerObject,
|
|
119
|
+
node?: Node | Document | Window | undefined
|
|
120
|
+
): void
|
|
121
|
+
/**
|
|
122
|
+
* Adds one-time listener function for eventName. The next time eventName is
|
|
123
|
+
* triggered, this listener is removed and then invoked.
|
|
124
|
+
* @param {string} eventName
|
|
125
|
+
* @param {EventListenerOrEventListenerObject} listener
|
|
126
|
+
* @param {Node|Document|Window} node
|
|
127
|
+
*/
|
|
128
|
+
once(
|
|
129
|
+
eventName: string,
|
|
130
|
+
listener: EventListenerOrEventListenerObject,
|
|
131
|
+
node?: Node | Document | Window
|
|
132
|
+
): void
|
|
133
|
+
/**
|
|
134
|
+
* Unsubscribe a listener function for disposal on disconnectedCallback()
|
|
135
|
+
* @param {function} listener
|
|
136
|
+
*/
|
|
137
|
+
dispose(listener: Function): void
|
|
138
|
+
/**
|
|
139
|
+
* adds a connected controller
|
|
140
|
+
* @param {HostController} controller
|
|
141
|
+
*/
|
|
142
|
+
addController(controller: HostController): void
|
|
143
|
+
/**
|
|
144
|
+
* removes a connected controller
|
|
145
|
+
* @param {HostController} controller
|
|
146
|
+
*/
|
|
147
|
+
removeController(controller: HostController): void
|
|
148
|
+
}
|
|
149
|
+
export function define(
|
|
150
|
+
name: string,
|
|
151
|
+
element: typeof MiElement,
|
|
152
|
+
options?: object
|
|
153
|
+
): void
|
|
154
|
+
export function convertType(any: any, type: any): any
|
|
155
|
+
/**
|
|
156
|
+
* controller
|
|
157
|
+
*/
|
|
158
|
+
export type HostController = {
|
|
159
|
+
/**
|
|
160
|
+
* is called when host element is added to
|
|
161
|
+
* the DOM, usually with connectedCallback()
|
|
162
|
+
*/
|
|
163
|
+
hostConnected: () => void
|
|
164
|
+
/**
|
|
165
|
+
* is called when host element is
|
|
166
|
+
* removed from the DOM, usually with disconnectedCallback()
|
|
167
|
+
*/
|
|
168
|
+
hostDisconnected: () => void
|
|
169
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type Context = import('./context.js').Context
|
|
2
|
+
export type HostController = import('./element.js').HostController
|
|
3
|
+
export type Callback = import('./signal.js').Callback
|
|
4
|
+
export type Action = import('./store.js').Action
|
|
5
|
+
export {
|
|
6
|
+
ContextConsumer,
|
|
7
|
+
ContextProvider,
|
|
8
|
+
ContextRequestEvent
|
|
9
|
+
} from './context.js'
|
|
10
|
+
export { MiElement, convertType, define } from './element.js'
|
|
11
|
+
export { esc, escAttr, escHtml } from './escape.js'
|
|
12
|
+
export { refsById, refsBySelector } from './refs.js'
|
|
13
|
+
export { Signal, createSignal, isSignalLike } from './signal.js'
|
|
14
|
+
export { Store, subscribeToStore } from './store.js'
|
package/types/refs.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper function to find `id` attributes in `container`s node tree
|
|
3
|
+
* @param {Element} container root element
|
|
4
|
+
* @returns {Record<string, Node>|{}} record of found references
|
|
5
|
+
* @example
|
|
6
|
+
* el.innerHTML = `<p id>unnamed <span id="named">and named</span> reference</p>`
|
|
7
|
+
* references = refs(el)
|
|
8
|
+
* //> references = { p: <p>, named: <span> }
|
|
9
|
+
*/
|
|
10
|
+
export function refsById(container: Element): Record<string, Node> | {}
|
|
11
|
+
/**
|
|
12
|
+
* Helper function to gather references by a map of selectors
|
|
13
|
+
* @param {Element} container root element
|
|
14
|
+
* @param {Record<string, string>} selectors
|
|
15
|
+
* @returns {Record<string, Node>|{}}
|
|
16
|
+
* @example
|
|
17
|
+
* el.innerHTML = `<p>some <span>and other</span> reference</p>`
|
|
18
|
+
* references = refs(el, { p: 'p', named: 'p > span' })
|
|
19
|
+
* //> references = { p: <p>, named: <span> }
|
|
20
|
+
*/
|
|
21
|
+
export function refsBySelector(
|
|
22
|
+
container: Element,
|
|
23
|
+
selectors: Record<string, string>
|
|
24
|
+
): Record<string, Node> | {}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {(value: any) => void} Callback
|
|
3
|
+
*/
|
|
4
|
+
export class Signal {
|
|
5
|
+
/**
|
|
6
|
+
* creates a new signal with an initial value
|
|
7
|
+
* @param {any} [initialValue]
|
|
8
|
+
*/
|
|
9
|
+
constructor(initialValue?: any)
|
|
10
|
+
_subscribers: Set<any>
|
|
11
|
+
_value: any
|
|
12
|
+
/**
|
|
13
|
+
* set new value on signal;
|
|
14
|
+
* if value has changed all subscribers are called
|
|
15
|
+
* @param {any} newValue
|
|
16
|
+
*/
|
|
17
|
+
set value(newValue: any)
|
|
18
|
+
/**
|
|
19
|
+
* return current value
|
|
20
|
+
* @returns {any}
|
|
21
|
+
*/
|
|
22
|
+
get value(): any
|
|
23
|
+
/**
|
|
24
|
+
* notify all subscribers on current value
|
|
25
|
+
*/
|
|
26
|
+
notify(): void
|
|
27
|
+
/**
|
|
28
|
+
* subscribe to signal to receive value updates
|
|
29
|
+
* @param {Callback} callback
|
|
30
|
+
* @returns {() => void} unsubscribe function
|
|
31
|
+
*/
|
|
32
|
+
subscribe(callback: Callback): () => void
|
|
33
|
+
}
|
|
34
|
+
export function createSignal(initialValue?: any): Signal
|
|
35
|
+
export function isSignalLike(possibleSignal: any): boolean
|
|
36
|
+
export type Callback = (value: any) => void
|
package/types/store.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('./element.js').MiElement} MiElement
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {(state: any, data?: any) => any} Action
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Store implementing [Flux](https://www.npmjs.com/package/flux) pattern based
|
|
9
|
+
* on Signals
|
|
10
|
+
*/
|
|
11
|
+
export class Store extends Signal {
|
|
12
|
+
/**
|
|
13
|
+
* @param {Record<string, Action>} actions
|
|
14
|
+
* @param {any} [initialValue]
|
|
15
|
+
* @example
|
|
16
|
+
* ```js
|
|
17
|
+
* const actions = { increment: (by = 1) => (current) => current + by }
|
|
18
|
+
* const initialValue = 1
|
|
19
|
+
* const store = new Store(actions, initialValue)
|
|
20
|
+
* // subscribe with a callback function
|
|
21
|
+
* const unsubscribe = store.subscribe((value) => console.log(`count is ${value}`))
|
|
22
|
+
* // change the store
|
|
23
|
+
* store.increment(2) // increment by 2
|
|
24
|
+
* //> count is 3
|
|
25
|
+
* unsubscribe()
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* if `initialValue` is an object, the object's reference must be changed
|
|
29
|
+
* using the spread operator, in order to notify on state changes, e.g.
|
|
30
|
+
* ```js
|
|
31
|
+
* const initialValue = { count: 0, other: 'foo' }
|
|
32
|
+
* const actions = {
|
|
33
|
+
* increment: (by = 1) => (state) => ({...state, count: state.count + by})
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
constructor(actions: Record<string, Action>, initialValue?: any)
|
|
38
|
+
}
|
|
39
|
+
export function subscribeToStore(
|
|
40
|
+
element: MiElement,
|
|
41
|
+
store: Store,
|
|
42
|
+
prop: string | string[]
|
|
43
|
+
): void
|
|
44
|
+
export type MiElement = import('./element.js').MiElement
|
|
45
|
+
export type Action = (state: any, data?: any) => any
|
|
46
|
+
import { Signal } from './signal.js'
|