@rokkit/core 1.0.0-next.107 → 1.0.0-next.109

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.
@@ -1,5 +1,5 @@
1
1
  export class FieldMapper {
2
- constructor(fields?: any, componentMap?: {});
2
+ constructor(fields?: any);
3
3
  hasIcon: ((obj: unknown) => obj is {
4
4
  [x: string]: unknown;
5
5
  }) | undefined;
@@ -23,24 +23,25 @@ export class FieldMapper {
23
23
  }) | undefined;
24
24
  withPrefix: ((x: any) => string) | undefined;
25
25
  excludeFlags: (<U extends Partial<Record<any, any>>>(obj: any extends keyof U ? U : never) => any extends keyof U ? Omit<U, any> : never) | undefined;
26
+ getChildMapper(): null;
27
+ /**
28
+ * @private
29
+ */
30
+ private prop;
31
+ /**
32
+ * Gets a mapped attribute from the original item
33
+ *
34
+ * @param {string} fieldName - Name of the field to get
35
+ * @returns {any|null} - The attribute value or null if not found
36
+ */
37
+ get(fieldName: string, value: any, defaultValue?: null): any | null;
26
38
  set fields(fields: any);
27
39
  get fields(): any;
28
- set componentMap(components: {});
29
- get componentMap(): {};
30
- getComponent(value: any): any;
31
40
  getIcon(value: any): string | null;
32
- getImage(value: any): any;
33
41
  getValue(value: any): any;
34
- getText(value: any): any;
35
- getLabel(value: any): any;
36
- getAttribute(value: any, attr: any): any;
37
42
  getFormattedText(value: any, formatter: any): any;
38
43
  hasChildren(item: any): item is never;
39
- isExpanded(item: any): false;
40
- isHidden(item: any): unknown;
41
44
  isNested(items: any): boolean;
42
- toggleVisibility(items: any, visible: any): void;
43
- toggleExpansion(item: any): void;
44
45
  getChildren(item: any): never[];
45
46
  /**
46
47
  * Finds children by an index path
package/dist/index.d.ts CHANGED
@@ -8,6 +8,6 @@ export { FieldMapper } from "./field-mapper.js";
8
8
  export { createEmitter } from "./events.js";
9
9
  export { getLineTypes } from "./connector.js";
10
10
  export { generateTicks } from "./ticks.js";
11
- export { getValue } from "./mapping.js";
12
11
  export { getItemAtIndex, getIndexForItem } from "./mapped-items.js";
13
12
  export { weekdays, getCalendarDays } from "./calendar.js";
13
+ export { getValue, getNestedFields, hasChildren, isExpanded } from "./mapping.js";
package/dist/mapping.d.ts CHANGED
@@ -66,3 +66,10 @@ export function hasChildren(item: any, fields: import("./types").FieldMapping):
66
66
  * @returns {boolean}
67
67
  */
68
68
  export function isExpanded(item: any, fields: import("./types").FieldMapping): boolean;
69
+ /**
70
+ * Fetches the fieldmapping for a child node
71
+ *
72
+ * @param {import('./types').FieldMapping} fields
73
+ * @returns {import('./types').FieldMapping}
74
+ */
75
+ export function getNestedFields(fields: import("./types").FieldMapping): import("./types").FieldMapping;
package/dist/utils.d.ts CHANGED
@@ -63,6 +63,7 @@ export function getPathFromKey(key: string): string[];
63
63
  * Get snippet function from an object
64
64
  * @param {Object} obj
65
65
  * @param {string} key
66
+ * @param {null|Function} defaultSnippet
66
67
  * @returns {Function|undefined}
67
68
  */
68
- export function getSnippet(obj: Object, key: string): Function | undefined;
69
+ export function getSnippet(obj: Object, key: string, defaultSnippet?: null | Function): Function | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rokkit/core",
3
- "version": "1.0.0-next.107",
3
+ "version": "1.0.0-next.109",
4
4
  "description": "Contains core utility functions and classes that can be used in various components.",
5
5
  "author": "Jerry Thomas <me@jerrythomas.name>",
6
6
  "license": "MIT",
package/src/constants.js CHANGED
@@ -12,7 +12,6 @@ export const defaultFields = {
12
12
  icon: 'icon',
13
13
  iconPrefix: null,
14
14
  image: 'image',
15
- component: 'component',
16
15
  summary: 'summary',
17
16
  notes: 'notes',
18
17
  props: 'props',
@@ -22,12 +21,12 @@ export const defaultFields = {
22
21
  parent: 'parent',
23
22
  currency: 'currency',
24
23
  label: 'label',
24
+ component: 'component',
25
+ snippet: '_snippet',
25
26
  /* flag fields */
26
- isSelected: '_selected',
27
- isHidden: '_hidden',
28
- isOpen: '_open',
29
- isDeleted: '_deleted',
30
- isFiltered: '_filtered'
27
+ deleted: '_deleted',
28
+ expanded: '_expanded',
29
+ selected: '_selected'
31
30
  }
32
31
 
33
32
  export const defaultIcons = [
@@ -1,15 +1,13 @@
1
- import { defaultFields } from './constants.js'
2
1
  import { isNil, has, omit } from 'ramda'
2
+ import { defaultFields } from './constants.js'
3
3
  import { isObject } from './utils.js'
4
4
 
5
5
  export class FieldMapper {
6
6
  #fields = { ...defaultFields }
7
- #componentMap = {}
8
7
  #childMapper = null
9
8
 
10
- constructor(fields = defaultFields, componentMap = {}) {
9
+ constructor(fields = defaultFields) {
11
10
  this.#updateFields(fields)
12
- this.#updateComponentMap(componentMap)
13
11
  }
14
12
 
15
13
  #updateFields(fields) {
@@ -33,34 +31,41 @@ export class FieldMapper {
33
31
  ])
34
32
  }
35
33
 
36
- #updateComponentMap(components) {
37
- if (typeof components === 'object' && components) {
38
- Object.keys(components).forEach((key) => {
39
- this.#componentMap[key] = components[key]
40
- })
34
+ getChildMapper() {
35
+ if (!this.#childMapper) {
36
+ this.#childMapper = new FieldMapper(this.fields.fields ?? this.fields)
41
37
  }
38
+ return this.#childMapper
42
39
  }
40
+ /**
41
+ * @private
42
+ */
43
+ prop(fieldName, value) {
44
+ if (isNil(value)) return null
43
45
 
44
- get fields() {
45
- return this.#fields
46
- }
46
+ if (typeof value === 'object') {
47
+ return value[this.fields[fieldName]]
48
+ }
47
49
 
48
- set fields(fields) {
49
- this.#updateFields(fields)
50
+ return fieldName === 'text' ? value : null
50
51
  }
51
52
 
52
- get componentMap() {
53
- return this.#componentMap
53
+ /**
54
+ * Gets a mapped attribute from the original item
55
+ *
56
+ * @param {string} fieldName - Name of the field to get
57
+ * @returns {any|null} - The attribute value or null if not found
58
+ */
59
+ get(fieldName, value, defaultValue = null) {
60
+ return this.prop(fieldName, value) ?? defaultValue
54
61
  }
55
62
 
56
- set componentMap(components) {
57
- this.#updateComponentMap(components)
63
+ get fields() {
64
+ return this.#fields
58
65
  }
59
66
 
60
- getComponent(value) {
61
- if (this.hasComponent(value))
62
- return this.componentMap[value[this.fields.component]] ?? this.componentMap.default
63
- return this.componentMap.default
67
+ set fields(fields) {
68
+ this.#updateFields(fields)
64
69
  }
65
70
 
66
71
  getIcon(value) {
@@ -69,9 +74,6 @@ export class FieldMapper {
69
74
  if (isObject(icon)) return this.withPrefix(icon[value[this.fields.state]])
70
75
  return this.withPrefix(icon)
71
76
  }
72
- getImage(value) {
73
- return this.getAttribute(value, 'image')
74
- }
75
77
 
76
78
  getValue(value) {
77
79
  if (this.hasValue(value)) {
@@ -80,32 +82,15 @@ export class FieldMapper {
80
82
  return value
81
83
  }
82
84
 
83
- getText(value) {
84
- if (this.hasText(value)) {
85
- return value[this.fields.text]
86
- }
87
- return typeof value === 'object' ? null : value
88
- }
89
-
90
- getLabel(value) {
91
- return this.getAttribute(value, 'label') ?? this.getText(value)
92
- }
93
-
94
- getAttribute(value, attr) {
95
- if (has(attr, this.fields)) {
96
- return has(this.fields[attr], value) ? value[this.fields[attr]] : null
97
- }
98
- return null
99
- }
100
-
101
85
  getFormattedText(value, formatter) {
102
- const text = this.getText(value)
86
+ const text = this.get('text', value)
87
+
103
88
  if (isNil(text)) return ''
104
89
 
105
90
  if (typeof formatter !== 'function') return text.toString()
106
91
 
107
92
  if (this.hasCurrency(value)) {
108
- return formatter(text, this.getAttribute(value, 'currency'))
93
+ return formatter(text, this.get('currency', value))
109
94
  }
110
95
  return formatter(text)
111
96
  }
@@ -119,37 +104,10 @@ export class FieldMapper {
119
104
  )
120
105
  }
121
106
 
122
- isExpanded(item) {
123
- if (this.hasChildren(item)) {
124
- return has(this.fields.isOpen, item) && item[this.fields.isOpen]
125
- }
126
- return false
127
- }
128
-
129
- isHidden(item) {
130
- return has(this.fields.isHidden, item) && item[this.fields.isHidden]
131
- }
132
-
133
107
  isNested(items) {
134
108
  return Array.isArray(items) && items.some((item) => this.hasChildren(item))
135
109
  }
136
110
 
137
- toggleVisibility(items, visible) {
138
- items.forEach((item) => {
139
- item[this.fields.isHidden] = !visible
140
- if (this.hasChildren(item)) {
141
- this.toggleVisibility(item[this.fields.children], visible && item[this.fields.isOpen])
142
- }
143
- })
144
- }
145
-
146
- toggleExpansion(item) {
147
- if (this.hasChildren(item)) {
148
- item[this.fields.isOpen] = !item[this.fields.isOpen]
149
- this.toggleVisibility(item[this.fields.children], item[this.fields.isOpen])
150
- }
151
- }
152
-
153
111
  getChildren(item) {
154
112
  return this.hasChildren(item) ? item[this.fields.children] : []
155
113
  }
@@ -179,10 +137,9 @@ export class FieldMapper {
179
137
  * @returns {Object|null}
180
138
  */
181
139
  getItemByPath(items, path = []) {
182
- // skipcq: JS-W1042 default undefined is needed
183
140
  const result = path.reduce(
184
141
  (item, index, i) => (i === 0 ? items?.[index] : item?.[this.fields.children]?.[index]),
185
- undefined
142
+ /* skipcq: JS-W1042 default undefined is needed */ undefined
186
143
  )
187
144
 
188
145
  if (result === undefined) throw new Error('Invalid path')
package/src/index.js CHANGED
@@ -16,4 +16,4 @@ export { createEmitter } from './events.js'
16
16
  export { getLineTypes } from './connector.js'
17
17
  export { weekdays, getCalendarDays } from './calendar.js'
18
18
  export { generateTicks } from './ticks.js'
19
- export { getValue } from './mapping.js'
19
+ export { getValue, getNestedFields, hasChildren, isExpanded } from './mapping.js'
package/src/mapping.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defaultFields } from './constants.js'
2
2
  import { toString, isObject } from './utils.js'
3
-
3
+ import { has } from 'ramda'
4
4
  /**
5
5
  * Get the component to be used to render the item.
6
6
  * If the component is null or undefined, it will return the default component.
@@ -104,12 +104,7 @@ export function getFormattedText(node, fields = defaultFields, formatter = toStr
104
104
  * @returns {boolean}
105
105
  */
106
106
  export function hasChildren(item, fields) {
107
- return (
108
- item !== null &&
109
- typeof item === 'object' &&
110
- fields.children in item &&
111
- Array.isArray(item[fields.children])
112
- )
107
+ return has(fields.children, item) && Array.isArray(item[fields.children])
113
108
  }
114
109
 
115
110
  /**
@@ -122,8 +117,18 @@ export function hasChildren(item, fields) {
122
117
  export function isExpanded(item, fields) {
123
118
  if (item === null) return false
124
119
  if (!hasChildren(item, fields)) return false
125
- if (fields.isOpen in item) {
126
- return item[fields.isOpen]
120
+ if (has(fields.expanded, item)) {
121
+ return item[fields.expanded]
127
122
  }
128
123
  return false
129
124
  }
125
+
126
+ /**
127
+ * Fetches the fieldmapping for a child node
128
+ *
129
+ * @param {import('./types').FieldMapping} fields
130
+ * @returns {import('./types').FieldMapping}
131
+ */
132
+ export function getNestedFields(fields) {
133
+ return { ...defaultFields, ...(fields.fields ?? fields) }
134
+ }
package/src/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { has } from 'ramda'
1
+ import { has, isNil } from 'ramda'
2
2
 
3
3
  /**
4
4
  * Finds the closest ancestor of the given element that has the given attribute.
@@ -36,7 +36,7 @@ export function id() {
36
36
  * @returns {boolean}
37
37
  */
38
38
  export function isObject(val) {
39
- return typeof val === 'object' && val !== null && !(val instanceof Date)
39
+ return typeof val === 'object' && !isNil(val) && !(val instanceof Date)
40
40
  }
41
41
 
42
42
  /**
@@ -92,7 +92,7 @@ export function scaledPath(size, x) {
92
92
  * @returns {string}
93
93
  */
94
94
  export function getKeyFromPath(path) {
95
- return path.join('-')
95
+ return Array.isArray(path) ? path.join('-') : [path].join('-')
96
96
  }
97
97
 
98
98
  /**
@@ -108,11 +108,12 @@ export function getPathFromKey(key) {
108
108
  * Get snippet function from an object
109
109
  * @param {Object} obj
110
110
  * @param {string} key
111
+ * @param {null|Function} defaultSnippet
111
112
  * @returns {Function|undefined}
112
113
  */
113
- export function getSnippet(obj, key) {
114
+ export function getSnippet(obj, key, defaultSnippet = null) {
114
115
  if (has(key, obj) && typeof obj[key] === 'function') {
115
116
  return obj[key]
116
117
  }
117
- return undefined
118
+ return defaultSnippet
118
119
  }