@knowark/componarkjs 1.14.0 → 1.14.2

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 (102) hide show
  1. package/README.md +57 -45
  2. package/lib/base/component/README.md +127 -0
  3. package/lib/base/component/component.js +127 -21
  4. package/lib/base/component/component.test.js +296 -3
  5. package/lib/base/component/index.js +3 -0
  6. package/lib/base/styles/index.js +4 -1
  7. package/lib/base/utils/define.js +2 -1
  8. package/lib/base/utils/format.js +12 -6
  9. package/lib/base/utils/helpers.js +31 -5
  10. package/lib/base/utils/index.js +1 -0
  11. package/lib/base/utils/slots.js +3 -2
  12. package/lib/base/utils/uuid.js +1 -1
  13. package/lib/components/audio/components/audio.js +17 -2
  14. package/lib/components/audio/index.js +1 -0
  15. package/lib/components/audio/styles/index.js +5 -1
  16. package/lib/components/camera/components/camera.js +10 -0
  17. package/lib/components/camera/index.js +1 -0
  18. package/lib/components/camera/styles/index.js +5 -1
  19. package/lib/components/capture/components/capture.js +18 -2
  20. package/lib/components/capture/index.js +1 -0
  21. package/lib/components/droparea/components/droparea-preview.js +58 -13
  22. package/lib/components/droparea/components/droparea-preview.test.js +82 -0
  23. package/lib/components/droparea/components/droparea.js +41 -2
  24. package/lib/components/droparea/index.js +1 -0
  25. package/lib/components/droparea/styles/index.js +5 -1
  26. package/lib/components/emit/components/emit.js +11 -1
  27. package/lib/components/emit/index.js +1 -0
  28. package/lib/components/index.js +2 -1
  29. package/lib/components/list/components/item.js +6 -0
  30. package/lib/components/list/components/list.js +18 -4
  31. package/lib/components/list/index.js +1 -0
  32. package/lib/components/paginator/components/paginator.js +34 -8
  33. package/lib/components/paginator/index.js +1 -0
  34. package/lib/components/paginator/styles/index.js +5 -1
  35. package/lib/components/spinner/components/spinner.js +10 -0
  36. package/lib/components/spinner/index.js +1 -0
  37. package/lib/components/spinner/styles/index.js +5 -1
  38. package/lib/components/splitview/components/splitview.detail.js +10 -1
  39. package/lib/components/splitview/components/splitview.js +18 -3
  40. package/lib/components/splitview/components/splitview.master.js +10 -0
  41. package/lib/components/splitview/index.js +1 -0
  42. package/lib/components/translate/components/translate.js +42 -11
  43. package/lib/components/translate/components/translate.test.js +169 -1
  44. package/lib/components/translate/index.js +1 -0
  45. package/lib/index.js +3 -0
  46. package/package.json +2 -1
  47. package/tsconfig.json +1 -1
  48. package/types/base/component/component.d.ts +43 -8
  49. package/types/base/component/component.d.ts.map +1 -1
  50. package/types/base/component/index.d.ts +4 -6
  51. package/types/base/component/index.d.ts.map +1 -1
  52. package/types/base/styles/index.d.ts +3 -2
  53. package/types/base/styles/index.d.ts.map +1 -1
  54. package/types/base/utils/define.d.ts +3 -2
  55. package/types/base/utils/define.d.ts.map +1 -1
  56. package/types/base/utils/format.d.ts +12 -6
  57. package/types/base/utils/format.d.ts.map +1 -1
  58. package/types/base/utils/helpers.d.ts +27 -7
  59. package/types/base/utils/helpers.d.ts.map +1 -1
  60. package/types/base/utils/slots.d.ts +8 -10
  61. package/types/base/utils/slots.d.ts.map +1 -1
  62. package/types/base/utils/uuid.d.ts +1 -1
  63. package/types/base/utils/uuid.d.ts.map +1 -1
  64. package/types/components/audio/components/audio.d.ts +23 -9
  65. package/types/components/audio/components/audio.d.ts.map +1 -1
  66. package/types/components/audio/styles/index.d.ts +3 -2
  67. package/types/components/audio/styles/index.d.ts.map +1 -1
  68. package/types/components/camera/components/camera.d.ts +11 -3
  69. package/types/components/camera/components/camera.d.ts.map +1 -1
  70. package/types/components/camera/styles/index.d.ts +3 -2
  71. package/types/components/camera/styles/index.d.ts.map +1 -1
  72. package/types/components/capture/components/capture.d.ts +23 -3
  73. package/types/components/capture/components/capture.d.ts.map +1 -1
  74. package/types/components/droparea/components/droparea-preview.d.ts +64 -11
  75. package/types/components/droparea/components/droparea-preview.d.ts.map +1 -1
  76. package/types/components/droparea/components/droparea.d.ts +58 -13
  77. package/types/components/droparea/components/droparea.d.ts.map +1 -1
  78. package/types/components/droparea/styles/index.d.ts +3 -2
  79. package/types/components/droparea/styles/index.d.ts.map +1 -1
  80. package/types/components/emit/components/emit.d.ts +15 -3
  81. package/types/components/emit/components/emit.d.ts.map +1 -1
  82. package/types/components/list/components/item.d.ts +8 -1
  83. package/types/components/list/components/item.d.ts.map +1 -1
  84. package/types/components/list/components/list.d.ts +23 -5
  85. package/types/components/list/components/list.d.ts.map +1 -1
  86. package/types/components/paginator/components/paginator.d.ts +32 -8
  87. package/types/components/paginator/components/paginator.d.ts.map +1 -1
  88. package/types/components/paginator/styles/index.d.ts +3 -2
  89. package/types/components/paginator/styles/index.d.ts.map +1 -1
  90. package/types/components/spinner/components/spinner.d.ts +14 -3
  91. package/types/components/spinner/components/spinner.d.ts.map +1 -1
  92. package/types/components/spinner/styles/index.d.ts +3 -2
  93. package/types/components/spinner/styles/index.d.ts.map +1 -1
  94. package/types/components/splitview/components/splitview.d.ts +22 -4
  95. package/types/components/splitview/components/splitview.d.ts.map +1 -1
  96. package/types/components/splitview/components/splitview.detail.d.ts +12 -2
  97. package/types/components/splitview/components/splitview.detail.d.ts.map +1 -1
  98. package/types/components/splitview/components/splitview.master.d.ts +12 -1
  99. package/types/components/splitview/components/splitview.master.d.ts.map +1 -1
  100. package/types/components/translate/components/translate.d.ts +44 -10
  101. package/types/components/translate/components/translate.d.ts.map +1 -1
  102. package/lib/base/component/README.rst +0 -113
@@ -3,6 +3,9 @@ import { ListItem } from './item.js'
3
3
 
4
4
  const tag = 'ark-list'
5
5
 
6
+ /**
7
+ * List component (array-driven rendering).
8
+ */
6
9
  export class List extends Component {
7
10
  constructor () {
8
11
  super()
@@ -10,7 +13,8 @@ export class List extends Component {
10
13
  this.addEventListener('delete', this._onDeleted.bind(this))
11
14
  }
12
15
 
13
- /** @param {Object} context */
16
+ /** @param {object} context
17
+ * @returns {this} */
14
18
  init (context = {}) {
15
19
  this.source = /** @type {Array} */ (context.source) || this.source || []
16
20
  this.template = context.template || this.template || ((data) => `${data}`)
@@ -18,6 +22,7 @@ export class List extends Component {
18
22
  return super.init()
19
23
  }
20
24
 
25
+ /** @returns {this} */
21
26
  render () {
22
27
  const listData = this.select('data')
23
28
  const list = this._parseJSON(listData?.textContent)
@@ -48,7 +53,10 @@ export class List extends Component {
48
53
  return super.render()
49
54
  }
50
55
 
51
- /** @param {number} start @param {number?} deleteCount */
56
+ /** @param {number} start
57
+ * @param {number} [deleteCount=1]
58
+ * @returns {void}
59
+ */
52
60
  delete (start, deleteCount = 1) {
53
61
  this.source.splice(start, deleteCount)
54
62
  const deletions = []
@@ -59,6 +67,8 @@ export class List extends Component {
59
67
  deletions.map(item => item.remove())
60
68
  }
61
69
 
70
+ /** @param {string} template
71
+ * @returns {(data: any)=>string} */
62
72
  _format (template) {
63
73
  let render = null
64
74
 
@@ -80,7 +90,8 @@ export class List extends Component {
80
90
  }
81
91
  }
82
92
 
83
- /** @param {MouseEvent} event */
93
+ /** @param {MouseEvent} event
94
+ * @returns {void} */
84
95
  _onSelected (event) {
85
96
  event.stopImmediatePropagation()
86
97
 
@@ -101,7 +112,8 @@ export class List extends Component {
101
112
  )
102
113
  }
103
114
 
104
- /** @param {MouseEvent} event */
115
+ /** @param {MouseEvent} event
116
+ * @returns {void} */
105
117
  _onDeleted (event) {
106
118
  event.stopImmediatePropagation()
107
119
 
@@ -112,6 +124,8 @@ export class List extends Component {
112
124
  this.delete(Number(item.index))
113
125
  }
114
126
 
127
+ /** @param {string|null} source
128
+ * @returns {any[]|null} */
115
129
  _parseJSON (source) {
116
130
  if (!source) return null
117
131
 
@@ -1,2 +1,3 @@
1
+ /** List and list-item components. */
1
2
  export { ListItem } from './components/item.js'
2
3
  export { List } from './components/list.js'
@@ -2,7 +2,12 @@ import { Component } from '#base/index.js'
2
2
  import styles from '../styles/index.js'
3
3
 
4
4
  const tag = 'ark-paginator'
5
+ /**
6
+ * Pagination control component.
7
+ */
5
8
  export class Paginator extends Component {
9
+ /** @param {object} context
10
+ * @returns {this} */
6
11
  init (context = {}) {
7
12
  this.binding = 'paginator-listen'
8
13
  this.collectionSize = (
@@ -21,6 +26,7 @@ export class Paginator extends Component {
21
26
  return ['collectionSize', 'pageSize', 'displayedPages', 'currentPage']
22
27
  }
23
28
 
29
+ /** @returns {this} */
24
30
  render () {
25
31
  this._grabSlots()
26
32
  this.content = /* html */`
@@ -42,12 +48,13 @@ export class Paginator extends Component {
42
48
  this._buildButton(this.previousButton, '_prev', '<'))
43
49
 
44
50
  for (const page of this.currentPages) {
45
- const attributes = [['data-page', page]]
51
+ /** @type {[string, string][]} */
52
+ const attributes = [['data-page', String(page)]]
46
53
  if ((Number(page) === Number(this.currentPage))) {
47
54
  attributes.unshift(['active', ''])
48
55
  }
49
56
  this.querySelector('[data-middle]').appendChild(
50
- this._buildButton(this.pageButton, null, page, attributes))
57
+ this._buildButton(this.pageButton, null, `${page}`, attributes))
51
58
  }
52
59
 
53
60
  this.querySelector('[data-end]').appendChild(
@@ -58,10 +65,12 @@ export class Paginator extends Component {
58
65
  return super.render()
59
66
  }
60
67
 
68
+ /** @returns {number} */
61
69
  get totalPages () {
62
70
  return Math.ceil(this.collectionSize / this.pageSize)
63
71
  }
64
72
 
73
+ /** @returns {number[]} */
65
74
  get currentPages () {
66
75
  const displayedPages = Math.min(
67
76
  parseInt(this.displayedPages), this.totalPages)
@@ -72,6 +81,7 @@ export class Paginator extends Component {
72
81
  return Array.from({ length: displayedPages }, (_, i) => i + startPage)
73
82
  }
74
83
 
84
+ /** @returns {void} */
75
85
  _notifyChange () {
76
86
  const page = parseInt(this.currentPage)
77
87
  const limit = parseInt(this.pageSize)
@@ -80,6 +90,8 @@ export class Paginator extends Component {
80
90
  }
81
91
 
82
92
  /** @param {number} currentPage */
93
+ /** @param {number} currentPage
94
+ * @returns {void} */
83
95
  _setCurrentPage (currentPage) {
84
96
  if (currentPage > 0 && currentPage <= this.totalPages) {
85
97
  this.currentPage = currentPage
@@ -88,19 +100,22 @@ export class Paginator extends Component {
88
100
  }
89
101
  }
90
102
 
91
- /** @param {Event} event */
103
+ /** @param {Event} event
104
+ * @returns {void} */
92
105
  _first (event) {
93
106
  event.stopPropagation()
94
107
  this._setCurrentPage(1)
95
108
  }
96
109
 
97
- /** @param {Event} event */
110
+ /** @param {Event} event
111
+ * @returns {void} */
98
112
  _prev (event) {
99
113
  event.stopPropagation()
100
114
  this._setCurrentPage(parseInt(this.currentPage) - 1)
101
115
  }
102
116
 
103
- /** @param {Event} event */
117
+ /** @param {Event} event
118
+ * @returns {void} */
104
119
  _move (event) {
105
120
  event.stopPropagation()
106
121
  const target = /** @type {HTMLElement} */ (event.target)
@@ -108,18 +123,21 @@ export class Paginator extends Component {
108
123
  this._setCurrentPage(page)
109
124
  }
110
125
 
111
- /** @param {Event} event */
126
+ /** @param {Event} event
127
+ * @returns {void} */
112
128
  _next (event) {
113
129
  event.stopPropagation()
114
130
  this._setCurrentPage(parseInt(this.currentPage) + 1)
115
131
  }
116
132
 
117
- /** @param {Event} event */
133
+ /** @param {Event} event
134
+ * @returns {void} */
118
135
  _last (event) {
119
136
  event.stopPropagation()
120
137
  this._setCurrentPage(this.totalPages)
121
138
  }
122
139
 
140
+ /** @returns {void} */
123
141
  _grabSlots() {
124
142
  const [pageButton] = [this.slots.page].flat()
125
143
  this.pageButton = this.pageButton ?? pageButton
@@ -133,8 +151,16 @@ export class Paginator extends Component {
133
151
  this.lastButton = this.lastButton ?? lastButton
134
152
  }
135
153
 
154
+ /**
155
+ * @param {HTMLButtonElement|null} element
156
+ * @param {string|null} handler
157
+ * @param {string} content
158
+ * @param {Array<[string,string]>} attributes
159
+ * @returns {HTMLButtonElement}
160
+ */
136
161
  _buildButton (element, handler, content, attributes = []) {
137
- const button = (element ?? document.createElement('button')).cloneNode(true)
162
+ const button = /** @type {HTMLButtonElement} */ (
163
+ (element ?? document.createElement('button')).cloneNode(true))
138
164
  button.innerHTML = button.innerHTML || content
139
165
  if (handler) {
140
166
  button.setAttribute('paginator-listen', '')
@@ -1 +1,2 @@
1
+ /** Pagination controls component. */
1
2
  export { Paginator } from './components/paginator.js'
@@ -1,2 +1,6 @@
1
1
  import styles from './ark.css.js'
2
- export default styles
2
+
3
+ /** @type {string} */
4
+ const stylesText = styles
5
+
6
+ export default stylesText
@@ -2,7 +2,12 @@ import { Component } from '#base/index.js'
2
2
  import styles from '../styles/index.js'
3
3
 
4
4
  const tag = 'ark-spinner'
5
+ /**
6
+ * Configurable loading spinner component.
7
+ */
5
8
  export class Spinner extends Component {
9
+ /** @param {object} context
10
+ * @returns {this} */
6
11
  init (context = {}) {
7
12
  this.scale = context.scale || this.scale || '1'
8
13
  this.type = context.type || this.type || 'circle'
@@ -14,6 +19,7 @@ export class Spinner extends Component {
14
19
  return ['scale', 'type']
15
20
  }
16
21
 
22
+ /** @returns {this} */
17
23
  render () {
18
24
  this.innerHTML = /* html */ `
19
25
  ${this.spinnerType(this.type)}
@@ -22,6 +28,8 @@ export class Spinner extends Component {
22
28
  return super.render()
23
29
  }
24
30
 
31
+ /** @param {string} scale
32
+ * @returns {void} */
25
33
  setScale (scale) {
26
34
  this.style.setProperty('transform', `scale(${scale})`)
27
35
  }
@@ -31,6 +39,8 @@ export class Spinner extends Component {
31
39
  return this.querySelector('[data-loader]')
32
40
  }
33
41
 
42
+ /** @param {string} type
43
+ * @returns {string} */
34
44
  spinnerType (type) {
35
45
  let content = ''
36
46
 
@@ -1 +1,2 @@
1
+ /** Loading indicator component. */
1
2
  export { Spinner } from './components/spinner.js'
@@ -1,2 +1,6 @@
1
1
  import styles from './ark.css.js'
2
- export default styles
2
+
3
+ /** @type {string} */
4
+ const stylesText = styles
5
+
6
+ export default stylesText
@@ -1,6 +1,9 @@
1
1
  import { Component } from "#base/index.js"
2
2
 
3
3
  const tag = 'ark-splitview-detail'
4
+ /**
5
+ * Detail slot wrapper for split-view component.
6
+ */
4
7
  export class SplitViewDetail extends Component {
5
8
  constructor () {
6
9
  super()
@@ -8,6 +11,8 @@ export class SplitViewDetail extends Component {
8
11
  'close', this.onClose.bind(this))
9
12
  }
10
13
 
14
+ /** @param {object} context
15
+ * @returns {this} */
11
16
  init (context = {}) {
12
17
  this.binding = 'splitview-detail-listen'
13
18
 
@@ -22,6 +27,7 @@ export class SplitViewDetail extends Component {
22
27
  return super.init(context)
23
28
  }
24
29
 
30
+ /** @returns {this} */
25
31
  render () {
26
32
  this.content = ''
27
33
  this.append(this.main)
@@ -29,16 +35,19 @@ export class SplitViewDetail extends Component {
29
35
  return super.render()
30
36
  }
31
37
 
32
- /** @param {Event} event */
38
+ /** @param {Event} event
39
+ * @returns {void} */
33
40
  onClose (event) {
34
41
  event.stopPropagation()
35
42
  this.hide()
36
43
  }
37
44
 
45
+ /** @returns {void} */
38
46
  show () {
39
47
  this.removeAttribute('hidden')
40
48
  }
41
49
 
50
+ /** @returns {void} */
42
51
  hide () {
43
52
  this.setAttribute('hidden', '')
44
53
  }
@@ -1,8 +1,12 @@
1
1
  import { Component, css } from "#base/index.js"
2
2
 
3
3
  /** @import {SplitViewDetail} from './splitview.detail.js' */
4
+ /** @import {SplitViewMaster} from './splitview.master.js' */
4
5
 
5
6
  const tag = 'ark-splitview'
7
+ /**
8
+ * Master-detail split view orchestrator.
9
+ */
6
10
  export class SplitView extends Component {
7
11
  constructor () {
8
12
  super()
@@ -12,6 +16,7 @@ export class SplitView extends Component {
12
16
  this._master = null
13
17
  }
14
18
 
19
+ /** @returns {void} */
15
20
  setDimensions () {
16
21
  if (typeof globalThis.innerHeight !== 'number') return
17
22
  if (typeof globalThis.innerWidth !== 'number') return
@@ -20,18 +25,21 @@ export class SplitView extends Component {
20
25
  this.style.setProperty('--inner-width', `${globalThis.innerWidth}px`)
21
26
  }
22
27
 
28
+ /** @returns {void} */
23
29
  connectedCallback () {
24
30
  this.setDimensions()
25
31
  globalThis.addEventListener('resize', this._onResize)
26
32
  super.connectedCallback()
27
33
  }
28
34
 
35
+ /** @returns {void} */
29
36
  disconnectedCallback () {
30
37
  globalThis.removeEventListener('resize', this._onResize)
31
38
  this._removeMasterListener()
32
39
  super.disconnectedCallback()
33
40
  }
34
41
 
42
+ /** @returns {void} */
35
43
  _setMasterListener () {
36
44
  const master = this.master
37
45
  if (master === this._master) return
@@ -41,34 +49,41 @@ export class SplitView extends Component {
41
49
  this._master?.addEventListener('master-change', this._onMasterChange)
42
50
  }
43
51
 
52
+ /** @returns {void} */
44
53
  _removeMasterListener () {
45
54
  if (!this._master) return
46
55
  this._master.removeEventListener('master-change', this._onMasterChange)
47
56
  this._master = null
48
57
  }
49
58
 
59
+ /** @returns {(SplitViewMaster|null)} */
50
60
  get master () {
51
- return this.select('ark-splitview-master')
61
+ return /** @type {SplitViewMaster|null} */ (
62
+ this.querySelector('ark-splitview-master'))
52
63
  }
53
64
 
65
+ /** @returns {SplitViewDetail} */
54
66
  get detail () {
55
67
  return /** @type {SplitViewDetail} */ (this.select('ark-splitview-detail'))
56
68
  }
57
69
 
70
+ /** @returns {this} */
58
71
  render () {
59
72
  this.renderDetail()
60
73
  this._setMasterListener()
61
74
  return super.render()
62
75
  }
63
76
 
64
- /** @param {Object} context */
77
+ /** @param {object} context
78
+ * @returns {void} */
65
79
  renderDetail (context = {}) {
66
80
  if (!this.detail || !this.detail.init) return
67
81
 
68
82
  this.detail.init(context).render()
69
83
  }
70
84
 
71
- /** @param {CustomEvent} event */
85
+ /** @param {CustomEvent} event
86
+ * @returns {void} */
72
87
  onMasterChange (event) {
73
88
  event.stopPropagation()
74
89
 
@@ -1,6 +1,9 @@
1
1
  import { Component } from "#base/index.js"
2
2
 
3
3
  const tag = 'ark-splitview-master'
4
+ /**
5
+ * Master pane controller for split-view layout.
6
+ */
4
7
  export class SplitViewMaster extends Component {
5
8
  constructor () {
6
9
  super()
@@ -9,25 +12,31 @@ export class SplitViewMaster extends Component {
9
12
  this.masterEvent = this.masterEvent
10
13
  }
11
14
 
15
+ /** @param {object} context
16
+ * @returns {this} */
12
17
  init (context = {}) {
13
18
  this.binding = 'splitview-master-listen'
14
19
  return super.init(context)
15
20
  }
16
21
 
22
+ /** @returns {string[]} */
17
23
  reflectedProperties () {
18
24
  return ['masterEvent']
19
25
  }
20
26
 
27
+ /** @returns {void} */
21
28
  connectedCallback () {
22
29
  this._syncMasterEventListener()
23
30
  super.connectedCallback()
24
31
  }
25
32
 
33
+ /** @returns {void} */
26
34
  disconnectedCallback () {
27
35
  this._removeMasterEventListener()
28
36
  super.disconnectedCallback()
29
37
  }
30
38
 
39
+ /** @returns {void} */
31
40
  _syncMasterEventListener () {
32
41
  const masterEvent = (this.masterEvent || '').trim()
33
42
  if (!masterEvent || masterEvent === this._boundMasterEvent) return
@@ -37,6 +46,7 @@ export class SplitViewMaster extends Component {
37
46
  this._boundMasterEvent = masterEvent
38
47
  }
39
48
 
49
+ /** @returns {void} */
40
50
  _removeMasterEventListener () {
41
51
  if (!this._boundMasterEvent) return
42
52
  this.removeEventListener(this._boundMasterEvent, this._onMasterEvent)
@@ -1,3 +1,4 @@
1
+ /** Master-detail split view components. */
1
2
  export { SplitViewDetail } from './components/splitview.detail.js'
2
3
  export { SplitViewMaster } from './components/splitview.master.js'
3
4
  export { SplitView } from './components/splitview.js'
@@ -1,13 +1,24 @@
1
1
  import { Component } from "#base/index.js"
2
2
 
3
3
  const tag = 'ark-translate'
4
+ /**
5
+ * Translation component.
6
+ * @typedef {{key:string, namespace:string}} TranslatedKey
7
+ * @typedef {Record<string, Record<string, Record<string, string>>>} DictionaryStore
8
+ * @typedef {{language?:string, root?:string}} TransliterateOptions
9
+ */
4
10
  export class Translate extends Component {
11
+ /** @type {DictionaryStore} */
12
+ dictionary
13
+ /** @param {object} context
14
+ * @returns {this} */
5
15
  init (context = {}) {
6
16
  this.languages = this.languages
7
17
  this.global = context.global || window
8
18
  this.endpoint = context.endpoint || this.endpoint || '/locales'
9
19
  this.namespace = context.namespace || this.namespace || 'default'
10
20
  this.root = context.root || this.root || 'body'
21
+ /** @type {DictionaryStore} */
11
22
  this.dictionary = context.dictionary || {}
12
23
 
13
24
  const dictionary = (
@@ -15,7 +26,7 @@ export class Translate extends Component {
15
26
  if (dictionary) {
16
27
  const content = dictionary.content.textContent
17
28
  try {
18
- this.dictionary = JSON.parse(content)
29
+ this.dictionary = /** @type {DictionaryStore} */ (JSON.parse(content))
19
30
  } catch (error) {
20
31
  this.emit('error', error)
21
32
  }
@@ -24,10 +35,12 @@ export class Translate extends Component {
24
35
  return super.init(context)
25
36
  }
26
37
 
38
+ /** @returns {string[]} */
27
39
  reflectedProperties () {
28
40
  return ['languages', 'endpoint', 'namespace', 'root']
29
41
  }
30
42
 
43
+ /** @returns {this} */
31
44
  render () {
32
45
  const languages = this.languages.split(',').filter(
33
46
  item => Boolean(item) && item.trim())
@@ -46,12 +59,17 @@ export class Translate extends Component {
46
59
  return super.render()
47
60
  }
48
61
 
62
+ /** @param {Event} event
63
+ * @returns {Promise<void>} */
49
64
  async onLanguageChanged (event) {
50
65
  event.stopPropagation()
51
- const language = event.target.value
66
+ const target = /** @type {HTMLSelectElement|null} */ (event.target)
67
+ const language = target?.value
52
68
  await this.transliterate({ language })
53
69
  }
54
70
 
71
+ /** @param {TransliterateOptions} options
72
+ * @returns {Promise<void>} */
55
73
  async transliterate (options = {}) {
56
74
  const language = options.language || 'es'
57
75
  const root = this.global.document.querySelector(
@@ -67,12 +85,15 @@ export class Translate extends Component {
67
85
  language, namespace
68
86
  )
69
87
  )
70
- const dictionary = dictionaries[namespace]
88
+ const dictionary = /** @type {Record<string, string>} */ (
89
+ dictionaries[namespace])
71
90
 
72
91
  node.textContent = dictionary[key] || node.textContent
73
92
  }
74
93
  }
75
94
 
95
+ /** @param {string} value
96
+ * @returns {TranslatedKey} */
76
97
  parseKey (value) {
77
98
  let key = value
78
99
  let namespace = this.namespace
@@ -86,26 +107,36 @@ export class Translate extends Component {
86
107
  return { key, namespace }
87
108
  }
88
109
 
110
+ /** @param {string} language
111
+ * @param {string} namespace
112
+ * @returns {Promise<Record<string,string>>} */
89
113
  async resolveDictionary (language, namespace) {
90
- let dictionary = ((this.dictionary[language] ||
91
- {})[namespace] || null)
114
+ /** @type {DictionaryStore} */
115
+ const translations = this.dictionary
116
+ /** @type {Record<string, string>|null} */
117
+ let dictionary = /** @type {Record<string, string>|null} */ (
118
+ /** @type {unknown} */ (translations[language]?.[namespace]) || null)
92
119
 
93
120
  if (dictionary !== null) return dictionary
94
121
 
95
- if (!this.global.fetch) return {}
122
+ if (!this.global.fetch) return /** @type {Record<string, string>} */ ({})
96
123
 
97
124
  const url = `${this.endpoint}/${language}/${namespace}.json`
98
125
  try {
99
126
  const response = await this.global.fetch(url)
100
- if (response.ok === false) return {}
101
- dictionary = await response.json()
127
+ if (response.ok === false) return /** @type {Record<string, string>} */ ({})
128
+ dictionary = /** @type {Record<string, string>} */ (
129
+ await response.json())
102
130
  } catch (error) {
103
131
  this.emit('error', error)
104
- return {}
132
+ return /** @type {Record<string, string>} */ ({})
105
133
  }
106
134
 
107
- this.dictionary[language] || (this.dictionary[language] = {})
108
- this.dictionary[language][namespace] = dictionary
135
+ const cache = /** @type {Record<string, Record<string, Record<string, string>>>} */ (
136
+ /** @type {unknown} */ (translations))
137
+ cache[language] = cache[language] || {}
138
+ cache[language][namespace] = /** @type {Record<string, string>} */ (
139
+ /** @type {unknown} */ (dictionary || {}))
109
140
 
110
141
  return dictionary
111
142
  }