@knowark/componarkjs 1.13.4 → 1.14.1

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.
Files changed (118) hide show
  1. package/README.md +57 -45
  2. package/lib/base/component/component.js +142 -20
  3. package/lib/base/component/component.test.js +753 -374
  4. package/lib/base/component/index.js +3 -0
  5. package/lib/base/styles/index.js +4 -1
  6. package/lib/base/utils/define.js +30 -7
  7. package/lib/base/utils/define.test.js +129 -42
  8. package/lib/base/utils/format.js +12 -6
  9. package/lib/base/utils/format.test.js +16 -16
  10. package/lib/base/utils/helpers.js +42 -9
  11. package/lib/base/utils/helpers.test.js +134 -115
  12. package/lib/base/utils/index.js +1 -0
  13. package/lib/base/utils/slots.js +3 -2
  14. package/lib/base/utils/slots.test.js +38 -38
  15. package/lib/base/utils/uuid.js +1 -1
  16. package/lib/base/utils/uuid.test.js +13 -13
  17. package/lib/components/audio/components/audio.js +36 -3
  18. package/lib/components/audio/components/audio.test.js +120 -90
  19. package/lib/components/audio/index.js +1 -0
  20. package/lib/components/audio/styles/index.js +5 -1
  21. package/lib/components/camera/components/camera.js +15 -0
  22. package/lib/components/camera/components/camera.test.js +96 -91
  23. package/lib/components/camera/index.js +1 -0
  24. package/lib/components/camera/styles/index.js +5 -1
  25. package/lib/components/capture/components/capture.js +48 -4
  26. package/lib/components/capture/components/capture.test.js +165 -97
  27. package/lib/components/capture/index.js +1 -0
  28. package/lib/components/droparea/components/droparea-preview.js +114 -19
  29. package/lib/components/droparea/components/droparea-preview.test.js +344 -80
  30. package/lib/components/droparea/components/droparea.js +82 -6
  31. package/lib/components/droparea/components/droparea.test.js +309 -299
  32. package/lib/components/droparea/index.js +1 -0
  33. package/lib/components/droparea/styles/index.js +5 -1
  34. package/lib/components/emit/components/emit.js +34 -4
  35. package/lib/components/emit/components/emit.test.js +192 -134
  36. package/lib/components/emit/index.js +1 -0
  37. package/lib/components/index.js +2 -1
  38. package/lib/components/list/components/item.js +6 -0
  39. package/lib/components/list/components/item.test.js +69 -68
  40. package/lib/components/list/components/list.js +51 -7
  41. package/lib/components/list/components/list.test.js +358 -227
  42. package/lib/components/list/index.js +1 -0
  43. package/lib/components/paginator/components/paginator.js +34 -8
  44. package/lib/components/paginator/components/paginator.test.js +146 -143
  45. package/lib/components/paginator/index.js +1 -0
  46. package/lib/components/paginator/styles/index.js +5 -1
  47. package/lib/components/spinner/components/spinner.js +10 -0
  48. package/lib/components/spinner/components/spinner.test.js +36 -41
  49. package/lib/components/spinner/index.js +1 -0
  50. package/lib/components/spinner/styles/index.js +5 -1
  51. package/lib/components/splitview/components/splitview.detail.js +10 -1
  52. package/lib/components/splitview/components/splitview.detail.test.js +75 -73
  53. package/lib/components/splitview/components/splitview.js +54 -11
  54. package/lib/components/splitview/components/splitview.master.js +37 -2
  55. package/lib/components/splitview/components/splitview.master.test.js +52 -52
  56. package/lib/components/splitview/components/splitview.test.js +135 -31
  57. package/lib/components/splitview/index.js +1 -0
  58. package/lib/components/translate/components/translate.js +65 -14
  59. package/lib/components/translate/components/translate.test.js +658 -131
  60. package/lib/components/translate/index.js +1 -0
  61. package/lib/index.js +3 -0
  62. package/package.json +4 -27
  63. package/scripts/node-test-setup.js +94 -0
  64. package/tsconfig.json +1 -1
  65. package/types/base/component/component.d.ts +43 -8
  66. package/types/base/component/component.d.ts.map +1 -1
  67. package/types/base/component/index.d.ts +4 -6
  68. package/types/base/component/index.d.ts.map +1 -1
  69. package/types/base/styles/index.d.ts +3 -2
  70. package/types/base/styles/index.d.ts.map +1 -1
  71. package/types/base/utils/define.d.ts +3 -2
  72. package/types/base/utils/define.d.ts.map +1 -1
  73. package/types/base/utils/format.d.ts +12 -6
  74. package/types/base/utils/format.d.ts.map +1 -1
  75. package/types/base/utils/helpers.d.ts +27 -7
  76. package/types/base/utils/helpers.d.ts.map +1 -1
  77. package/types/base/utils/slots.d.ts +8 -10
  78. package/types/base/utils/slots.d.ts.map +1 -1
  79. package/types/base/utils/uuid.d.ts +1 -1
  80. package/types/base/utils/uuid.d.ts.map +1 -1
  81. package/types/components/audio/components/audio.d.ts +23 -9
  82. package/types/components/audio/components/audio.d.ts.map +1 -1
  83. package/types/components/audio/styles/index.d.ts +3 -2
  84. package/types/components/audio/styles/index.d.ts.map +1 -1
  85. package/types/components/camera/components/camera.d.ts +11 -3
  86. package/types/components/camera/components/camera.d.ts.map +1 -1
  87. package/types/components/camera/styles/index.d.ts +3 -2
  88. package/types/components/camera/styles/index.d.ts.map +1 -1
  89. package/types/components/capture/components/capture.d.ts +23 -3
  90. package/types/components/capture/components/capture.d.ts.map +1 -1
  91. package/types/components/droparea/components/droparea-preview.d.ts +64 -11
  92. package/types/components/droparea/components/droparea-preview.d.ts.map +1 -1
  93. package/types/components/droparea/components/droparea.d.ts +58 -13
  94. package/types/components/droparea/components/droparea.d.ts.map +1 -1
  95. package/types/components/droparea/styles/index.d.ts +3 -2
  96. package/types/components/droparea/styles/index.d.ts.map +1 -1
  97. package/types/components/emit/components/emit.d.ts +15 -3
  98. package/types/components/emit/components/emit.d.ts.map +1 -1
  99. package/types/components/list/components/item.d.ts +8 -1
  100. package/types/components/list/components/item.d.ts.map +1 -1
  101. package/types/components/list/components/list.d.ts +23 -5
  102. package/types/components/list/components/list.d.ts.map +1 -1
  103. package/types/components/paginator/components/paginator.d.ts +32 -8
  104. package/types/components/paginator/components/paginator.d.ts.map +1 -1
  105. package/types/components/paginator/styles/index.d.ts +3 -2
  106. package/types/components/paginator/styles/index.d.ts.map +1 -1
  107. package/types/components/spinner/components/spinner.d.ts +14 -3
  108. package/types/components/spinner/components/spinner.d.ts.map +1 -1
  109. package/types/components/spinner/styles/index.d.ts +3 -2
  110. package/types/components/spinner/styles/index.d.ts.map +1 -1
  111. package/types/components/splitview/components/splitview.d.ts +22 -4
  112. package/types/components/splitview/components/splitview.d.ts.map +1 -1
  113. package/types/components/splitview/components/splitview.detail.d.ts +12 -2
  114. package/types/components/splitview/components/splitview.detail.d.ts.map +1 -1
  115. package/types/components/splitview/components/splitview.master.d.ts +12 -1
  116. package/types/components/splitview/components/splitview.master.d.ts.map +1 -1
  117. package/types/components/translate/components/translate.d.ts +44 -10
  118. package/types/components/translate/components/translate.d.ts.map +1 -1
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  <p align="center">
2
2
  <a href="https://codecov.io/gh/librark/componark">
3
- <img src="https://codecov.io/gh/librark/componark/graph/badge.svg?token=IWNapsPUch"/>
3
+ <img src="https://codecov.io/gh/librark/componark/graph/badge.svg?token=IWNapsPUch" alt="codecov" />
4
4
  </a>
5
5
  </p>
6
6
  <p align="center">
7
7
  <a href="https://codecov.io/gh/librark/componark">
8
- <img src="https://codecov.io/gh/librark/componark/graphs/sunburst.svg?token=IWNapsPUch"/>
8
+ <img src="https://codecov.io/gh/librark/componark/graphs/sunburst.svg?token=IWNapsPUch" alt="coverage sunburst" />
9
9
  </a>
10
10
  </p>
11
11
 
@@ -13,46 +13,58 @@
13
13
 
14
14
  Pragmatic Web Components Library
15
15
 
16
- Introduction
17
- ============
18
-
19
- Componark is a collection of ready to use web components to propel the creation
20
- of user interfaces. A common *Component* base class is provided to ensure
21
- inter-component compatibility and common development idioms. This class is only
22
- a thin wrapper on top of the *HTMLElement* custom elements class, and might be
23
- extended in your own application code to create new components.
24
-
25
- Reference
26
- =========
27
-
28
- - `Base Component <lib/base/component>`_
29
-
30
- Components library
31
- ------------------
32
-
33
- - `<ark-accordion> <lib/components/accordion>`_
34
- - `<ark-alert> <lib/components/alert>`_
35
- - `<ark-audio> <lib/components/audio>`_
36
- - `<ark-button> <lib/components/button>`_
37
- - `<ark-camera> <lib/components/camera>`_
38
- - `<ark-card> <lib/components/card>`_
39
- - `<ark-chart> <lib/components/chart>`_
40
- - `<ark-checkbox> <lib/components/checkbox>`_
41
- - `<ark-droparea> <lib/components/droparea>`_
42
- - `<ark-gallery> <lib/components/gallery>`_
43
- - `<ark-icon> <lib/components/icon>`_
44
- - `<ark-list> <lib/components/list>`_
45
- - `<ark-input> <lib/components/input>`_
46
- - `<ark-location> <lib/components/location>`_
47
- - `<ark-map> <lib/components/map>`_
48
- - `<ark-modal> <lib/components/modal>`_
49
- - `<ark-multiselect> <lib/components/multiselect>`_
50
- - `<ark-paginator> <lib/components/paginator>`_
51
- - `<ark-radio> <lib/components/radio>`_
52
- - `<ark-select> <lib/components/select>`_
53
- - `<ark-sidebar> <lib/components/sidebar>`_
54
- - `<ark-signature> <lib/components/signature>`_
55
- - `<ark-spinner> <lib/components/spinner>`_
56
- - `<ark-splitview> <lib/components/splitview>`_
57
- - `<ark-tabs> <lib/components/tabs>`_
58
- - `<ark-tooltip> <lib/components/tooltip>`_
16
+ ## Introduction
17
+
18
+ ComponArk is a lightweight Web Components library with a shared base class for
19
+ consistency and event-driven composition.
20
+
21
+ The library is organized as custom elements that can be used directly in HTML or
22
+ combined with your application code.
23
+
24
+ ## Reference
25
+
26
+ - [Base Component](lib/base/component)
27
+ - [Showcase](showcase)
28
+
29
+ ## Components library
30
+
31
+ > Components marked in **bold** are available in this repository.
32
+
33
+ - **`ark-audio`** ([docs](lib/components/audio/README.md))
34
+ - **`ark-camera`** ([docs](lib/components/camera/README.md))
35
+ - **`ark-capture`** ([docs](lib/components/capture/README.md))
36
+ - **`ark-droparea`** ([docs](lib/components/droparea/README.md))
37
+ - **`ark-emit`** ([docs](lib/components/emit/README.md))
38
+ - **`ark-list`** ([docs](lib/components/list/README.md))
39
+ - **`ark-paginator`** ([docs](lib/components/paginator/README.md))
40
+ - **`ark-spinner`** ([docs](lib/components/spinner/README.md))
41
+ - **`ark-splitview`** ([docs](lib/components/splitview/README.md))
42
+ - **`ark-translate`** ([docs](lib/components/translate/README.md))
43
+
44
+ ## Why this exists
45
+
46
+ - Minimal, reusable base (`Component`) with lifecycle hooks and dependency
47
+ resolution.
48
+ - Template/event binding helper (`listen`) with custom attribute syntax.
49
+ - Lightweight styling support with constructor stylesheet + fallback support.
50
+ - Small test surface included with native Node test runner.
51
+
52
+ ## Basic usage
53
+
54
+ ```html
55
+ <ark-translate languages="en,es"></ark-translate>
56
+
57
+ <span data-i18n="hello">Hello</span>
58
+ ```
59
+
60
+ ## Development
61
+
62
+ - Run tests: `npm test`
63
+ - Build production bundle: `npm run prod`
64
+ - Start local dev server: `npm run dev`
65
+
66
+ ## Notes
67
+
68
+ Some older docs in the previous release referenced components that are not in the
69
+ current snapshot of this repository. If you need one of those modules, check
70
+ the release tags or open a request with expected parity.
@@ -2,20 +2,31 @@ 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
+ /**
6
+ * Base composable UI component.
7
+ * @extends {globalThis.HTMLElement}
8
+ */
5
9
  export class Component extends globalThis.HTMLElement {
6
10
  constructor () {
7
11
  super()
8
12
  this.binding = 'listen'
9
13
  this.local = {}
14
+ this._isConnected = false
15
+ this._cleanupCallbacks = []
16
+ this._needsBinding = true
17
+ this.global = globalThis
10
18
  reflect(this, this.reflectedProperties())
11
19
  }
12
20
 
13
21
  /**
14
- * @param {string} tag
22
+ * Register a custom element and optional CSS for the same tag.
23
+ * @param {string} tagName
15
24
  * @param {CustomElementConstructor} element
16
- * @param {string} styles **/
17
- static define (tag, element, styles = null) {
18
- define(tag, element, styles)
25
+ * @param {string} [styles]
26
+ * @returns {void}
27
+ */
28
+ static define (tagName, element, styles = null) {
29
+ define(tagName, element, styles)
19
30
  }
20
31
 
21
32
  /**
@@ -27,7 +38,7 @@ export class Component extends globalThis.HTMLElement {
27
38
 
28
39
  /**
29
40
  * @param {object} context
30
- * @return {Component} */
41
+ * @return {this} */
31
42
  init (context = {}) {
32
43
  return this
33
44
  }
@@ -44,6 +55,7 @@ export class Component extends globalThis.HTMLElement {
44
55
  /** @param {string} content */
45
56
  set content (content) {
46
57
  this.innerHTML = content
58
+ this._needsBinding = true
47
59
  }
48
60
 
49
61
  /** @return {string} */
@@ -51,26 +63,62 @@ export class Component extends globalThis.HTMLElement {
51
63
  return this.innerHTML
52
64
  }
53
65
 
66
+ /** @returns {void} */
54
67
  connectedCallback () {
68
+ this._isConnected = true
55
69
  try {
56
70
  !Boolean(Object.keys(this.local).length) && this.init({})
57
71
  this.render()
58
72
  } catch (error) {
59
- this.emit('error', error)
73
+ this.emit('error', this._enhanceError(error, 'init-render'))
74
+ throw error
75
+ }
76
+ try {
77
+ const load = this.load({})
78
+ if (load && typeof load.catch === 'function') {
79
+ load.catch(error => {
80
+ this.emit('error', this._enhanceError(error, 'load'))
81
+ })
82
+ }
83
+ } catch (error) {
84
+ this.emit('error', this._enhanceError(error, 'load'))
60
85
  throw error
61
86
  }
62
- this.load({})
63
87
  }
64
88
 
65
- /** @return {Component} */
89
+ /** @returns {void} */
90
+ disconnectedCallback () {
91
+ this._isConnected = false
92
+ this._cleanup()
93
+ }
94
+
95
+ /**
96
+ * @param {Function} callback
97
+ * @return {Function} */
98
+ registerCleanup (callback) {
99
+ if (!callback || typeof callback !== 'function') return () => {}
100
+
101
+ this._cleanupCallbacks.push(callback)
102
+ return () => {
103
+ const index = this._cleanupCallbacks.indexOf(callback)
104
+ if (index === -1) return
105
+ this._cleanupCallbacks.splice(index, 1)
106
+ }
107
+ }
108
+
109
+ /** @return {this} */
66
110
  render () {
67
111
  this.classList.add(this.tagName.toLowerCase())
68
- listen(this)
112
+ if (this._needsBinding) {
113
+ listen(this)
114
+ this._needsBinding = false
115
+ }
69
116
  return this
70
117
  }
71
118
 
72
- /** @param {object} context */
73
- async load (context = {}) {}
119
+ /** @param {object} context
120
+ * @returns {void | Promise<void>} */
121
+ load (context = {}) {}
74
122
 
75
123
  /**
76
124
  * @param {string} selectors
@@ -92,26 +140,100 @@ export class Component extends globalThis.HTMLElement {
92
140
  * @param {string} type
93
141
  * @param {any} detail */
94
142
  emit (type, detail) {
95
- this.dispatchEvent(
96
- new globalThis.CustomEvent(type, {
97
- detail,
98
- bubbles: true,
99
- cancelable: true
100
- })
101
- )
143
+ this.dispatchEvent(this._createEvent(type, detail, {
144
+ bubbles: true,
145
+ cancelable: true
146
+ }))
102
147
  }
103
148
 
104
149
  /**
105
150
  * @param {string} resource
106
151
  * @return {any} */
107
152
  resolve (resource) {
108
- const event = new globalThis.CustomEvent('resolve', {
109
- detail: { resource },
153
+ const event = this._createEvent('resolve', { resource }, {
110
154
  bubbles: true,
111
155
  cancelable: true
112
156
  })
113
157
  this.dispatchEvent(event)
114
158
  return event.detail[resource]
115
159
  }
160
+
161
+ /**
162
+ * @param {any} detail
163
+ * @param {string} phase
164
+ * @return {Error} */
165
+ _enhanceError (detail, phase) {
166
+ if (!detail) return detail
167
+
168
+ const error = detail instanceof Error ? detail : new Error(
169
+ `${detail.message || detail}`
170
+ )
171
+ /** @type {Error & { phase?: string, component?: string }} */
172
+ const enhancedError = error
173
+ enhancedError.phase = phase
174
+ enhancedError.component = this.tagName
175
+ return error
176
+ }
177
+
178
+ /** @returns {void} */
179
+ _cleanup () {
180
+ const callbacks = [...this._cleanupCallbacks]
181
+ this._cleanupCallbacks = []
182
+
183
+ for (const callback of callbacks) {
184
+ try {
185
+ callback()
186
+ } catch (error) {
187
+ this.emit('error', this._enhanceError(error, 'cleanup'))
188
+ }
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Creates an event object for dispatch.
194
+ * @param {string} type
195
+ * @param {any} detail
196
+ * @param {{ bubbles?: boolean, cancelable?: boolean }} [options]
197
+ * @returns {CustomEvent}
198
+ */
199
+ _createEvent (type, detail, options = {}) {
200
+ /** @type {{ [key: string]: any }} */
201
+ const contextGlobal = this.global || {}
202
+ const contextWindow = contextGlobal.document?.defaultView || contextGlobal.window || contextGlobal
203
+ const { bubbles = true, cancelable = true } = options
204
+
205
+ if (typeof contextWindow.CustomEvent === 'function') {
206
+ return new contextWindow.CustomEvent(type, { detail, bubbles, cancelable })
207
+ }
208
+
209
+ if (typeof contextWindow.Event === 'function') {
210
+ const event = new contextWindow.Event(type, { bubbles, cancelable })
211
+ ;(/** @type {any} */ (event)).detail = detail
212
+ return /** @type {CustomEvent} */ (event)
213
+ }
214
+
215
+ if (typeof globalThis.CustomEvent === 'function') {
216
+ return new globalThis.CustomEvent(type, { detail, bubbles, cancelable })
217
+ }
218
+
219
+ if (typeof globalThis.Event === 'function') {
220
+ const event = new globalThis.Event(type, { bubbles, cancelable })
221
+ ;(/** @type {any} */ (event)).detail = detail
222
+ return /** @type {CustomEvent} */ (event)
223
+ }
224
+
225
+ return /** @type {CustomEvent} */ (/** @type {unknown} */ ({
226
+ type,
227
+ detail,
228
+ bubbles,
229
+ cancelable,
230
+ currentTarget: this,
231
+ defaultPrevented: false,
232
+ cancelBubble: false,
233
+ target: this,
234
+ stopPropagation () {},
235
+ preventDefault () {}
236
+ }))
237
+ }
116
238
  }
117
239
  Component.define(tag, Component, styles)