@rokkit/core 1.0.0-next.105 → 1.0.0-next.107
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/calendar.d.ts +10 -0
- package/dist/connector.d.ts +8 -0
- package/dist/events.d.ts +12 -0
- package/dist/field-mapper.d.ts +59 -17
- package/dist/index.d.ts +6 -0
- package/dist/mapped-items.d.ts +14 -0
- package/dist/string.d.ts +1 -1
- package/dist/theme.d.ts +5 -0
- package/dist/ticks.d.ts +10 -0
- package/dist/types.d.ts +1 -0
- package/dist/utils.d.ts +19 -0
- package/package.json +2 -1
- package/src/calendar.js +44 -0
- package/src/connector.js +34 -0
- package/src/constants.js +8 -3
- package/src/events.js +32 -0
- package/src/field-mapper.js +152 -42
- package/src/index.js +7 -1
- package/src/key-event-map.js +4 -3
- package/src/mapped-items.js +22 -0
- package/src/theme.js +9 -1
- package/src/ticks.js +26 -0
- package/src/types.js +4 -0
- package/src/utils.js +33 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the days in the month.
|
|
3
|
+
*
|
|
4
|
+
* @param {Date} value
|
|
5
|
+
* @param {Array} holidays
|
|
6
|
+
* @param {boolean} fixed
|
|
7
|
+
* @returns {import('./types').CalendarDay[]}
|
|
8
|
+
*/
|
|
9
|
+
export function getCalendarDays(value: Date, holidays?: any[], fixed?: boolean): import("./types").CalendarDay[];
|
|
10
|
+
export const weekdays: string[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constructs an array of line types for tree visualization
|
|
3
|
+
* @param {boolean} hasChildren - Whether the node has children
|
|
4
|
+
* @param {import('./types').LineType[]} parentTypes - Types from parent nodes
|
|
5
|
+
* @param {import('./types').LineType} position - Current position type
|
|
6
|
+
* @returns {import('./types').LineType[]} Array of line types
|
|
7
|
+
*/
|
|
8
|
+
export function getLineTypes(hasChildren?: boolean, parentTypes?: import("./types").LineType[], position?: import("./types").LineType): import("./types").LineType[];
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates an emitter object from the given properties.
|
|
3
|
+
*
|
|
4
|
+
* - Filters attributes that start with 'on' and are functions,
|
|
5
|
+
* - Returns an object with keys that are the event names (without the 'on' prefix)
|
|
6
|
+
* - If a default event is not present in the props, it will be set to a no-op function.
|
|
7
|
+
*
|
|
8
|
+
* @param {Object} props - The properties object to filter.
|
|
9
|
+
* @param {Array<string>} defaults - An array of default events.
|
|
10
|
+
* @returns {import('./types.js').EventHandlers} The emitter object.
|
|
11
|
+
*/
|
|
12
|
+
export function createEmitter(props: Object, defaults?: Array<string>): import("./types.js").EventHandlers;
|
package/dist/field-mapper.d.ts
CHANGED
|
@@ -1,20 +1,62 @@
|
|
|
1
1
|
export class FieldMapper {
|
|
2
|
-
constructor(fields?: any,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
constructor(fields?: any, componentMap?: {});
|
|
3
|
+
hasIcon: ((obj: unknown) => obj is {
|
|
4
|
+
[x: string]: unknown;
|
|
5
|
+
}) | undefined;
|
|
6
|
+
hasImage: ((obj: unknown) => obj is {
|
|
7
|
+
[x: string]: unknown;
|
|
8
|
+
}) | undefined;
|
|
9
|
+
hasText: ((obj: unknown) => obj is {
|
|
10
|
+
[x: string]: unknown;
|
|
11
|
+
}) | undefined;
|
|
12
|
+
hasValue: ((obj: unknown) => obj is {
|
|
13
|
+
[x: string]: unknown;
|
|
14
|
+
}) | undefined;
|
|
15
|
+
hasLabel: ((obj: unknown) => obj is {
|
|
16
|
+
[x: string]: unknown;
|
|
17
|
+
}) | undefined;
|
|
18
|
+
hasComponent: ((obj: unknown) => obj is {
|
|
19
|
+
[x: string]: unknown;
|
|
20
|
+
}) | undefined;
|
|
21
|
+
hasCurrency: ((obj: unknown) => obj is {
|
|
22
|
+
[x: string]: unknown;
|
|
23
|
+
}) | undefined;
|
|
24
|
+
withPrefix: ((x: any) => string) | undefined;
|
|
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
|
+
set fields(fields: any);
|
|
27
|
+
get fields(): any;
|
|
28
|
+
set componentMap(components: {});
|
|
29
|
+
get componentMap(): {};
|
|
30
|
+
getComponent(value: any): any;
|
|
31
|
+
getIcon(value: any): string | null;
|
|
32
|
+
getImage(value: any): any;
|
|
33
|
+
getValue(value: any): any;
|
|
34
|
+
getText(value: any): any;
|
|
35
|
+
getLabel(value: any): any;
|
|
36
|
+
getAttribute(value: any, attr: any): any;
|
|
37
|
+
getFormattedText(value: any, formatter: any): any;
|
|
38
|
+
hasChildren(item: any): item is never;
|
|
39
|
+
isExpanded(item: any): false;
|
|
40
|
+
isHidden(item: any): unknown;
|
|
17
41
|
isNested(items: any): boolean;
|
|
18
|
-
|
|
19
|
-
|
|
42
|
+
toggleVisibility(items: any, visible: any): void;
|
|
43
|
+
toggleExpansion(item: any): void;
|
|
44
|
+
getChildren(item: any): never[];
|
|
45
|
+
/**
|
|
46
|
+
* Finds children by an index path
|
|
47
|
+
*
|
|
48
|
+
* @param {Array<Object>} items
|
|
49
|
+
* @param {Array<number>} path
|
|
50
|
+
* @returns {Array<Object>}
|
|
51
|
+
*/
|
|
52
|
+
getChildrenByPath(items: Array<Object>, path?: Array<number>): Array<Object>;
|
|
53
|
+
/**
|
|
54
|
+
* Finds an item by an index path
|
|
55
|
+
*
|
|
56
|
+
* @param {Array<Object>} items
|
|
57
|
+
* @param {Array<number>} path
|
|
58
|
+
* @returns {Object|null}
|
|
59
|
+
*/
|
|
60
|
+
getItemByPath(items: Array<Object>, path?: Array<number>): Object | null;
|
|
61
|
+
#private;
|
|
20
62
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,3 +5,9 @@ export * from "./nested.js";
|
|
|
5
5
|
export * from "./string.js";
|
|
6
6
|
export * from "./theme.js";
|
|
7
7
|
export { FieldMapper } from "./field-mapper.js";
|
|
8
|
+
export { createEmitter } from "./events.js";
|
|
9
|
+
export { getLineTypes } from "./connector.js";
|
|
10
|
+
export { generateTicks } from "./ticks.js";
|
|
11
|
+
export { getValue } from "./mapping.js";
|
|
12
|
+
export { getItemAtIndex, getIndexForItem } from "./mapped-items.js";
|
|
13
|
+
export { weekdays, getCalendarDays } from "./calendar.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get an item at a specific index
|
|
3
|
+
* @param {Array<any>} items
|
|
4
|
+
* @param {any} index
|
|
5
|
+
* @returns
|
|
6
|
+
*/
|
|
7
|
+
export function getItemAtIndex(items: Array<any>, index: any): any;
|
|
8
|
+
/**
|
|
9
|
+
* Get the index for an item in an array
|
|
10
|
+
* @param {Array<any} items
|
|
11
|
+
* @param {any} item
|
|
12
|
+
* @returns
|
|
13
|
+
*/
|
|
14
|
+
export function getIndexForItem(items: Array<any>, item: any): number;
|
package/dist/string.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export function toHyphenCase(text: string): string;
|
|
|
26
26
|
* @param {String} b
|
|
27
27
|
* @returns
|
|
28
28
|
*/
|
|
29
|
-
export function compareStrings(a: string, b: string):
|
|
29
|
+
export function compareStrings(a: string, b: string): 1 | 0 | -1;
|
|
30
30
|
/**
|
|
31
31
|
* Sort by splitting hyphen separated strings while keeping strings with same number of parts together
|
|
32
32
|
*
|
package/dist/theme.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export function shadesOf(name: string, modifier?: string): {
|
|
|
25
25
|
* @returns {object}
|
|
26
26
|
*/
|
|
27
27
|
export function stateColors(name: string, modifier?: string): object;
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @param {string} modifier
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
28
33
|
export function themeColors(modifier?: string): {};
|
|
29
34
|
/**
|
|
30
35
|
* Generates contrast colors for light and dark modes based on a given palette. Each color variant in the
|
package/dist/ticks.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates an array of tick marks for a range of values.
|
|
3
|
+
*
|
|
4
|
+
* @param {number} lowerBound - The lower bound of the range.
|
|
5
|
+
* @param {number} upperBound - The upper bound of the range.
|
|
6
|
+
* @param {number} [minorTickStep=upperBound-lowerBound] - The step size for minor ticks.
|
|
7
|
+
* @param {number} [majorTickStep=1] - The step size for major ticks.
|
|
8
|
+
* @returns {import('./types').TickMark[]>} An array of tick mark objects.
|
|
9
|
+
*/
|
|
10
|
+
export function generateTicks(lowerBound: number, upperBound: number, minorTickStep?: number, majorTickStep?: number): import("./types").TickMark[];
|
package/dist/types.d.ts
CHANGED
package/dist/utils.d.ts
CHANGED
|
@@ -47,3 +47,22 @@ export function iconShortcuts(icons: string[], collection: string, variants: str
|
|
|
47
47
|
* @returns {string|number}
|
|
48
48
|
*/
|
|
49
49
|
export function scaledPath(size: number, x: string | number): string | number;
|
|
50
|
+
/**
|
|
51
|
+
* Gets a key string from path
|
|
52
|
+
* @param {string[]} path
|
|
53
|
+
* @returns {string}
|
|
54
|
+
*/
|
|
55
|
+
export function getKeyFromPath(path: string[]): string;
|
|
56
|
+
/**
|
|
57
|
+
* Gets a path array from key string
|
|
58
|
+
* @param {string} key
|
|
59
|
+
* @returns {string[]}
|
|
60
|
+
*/
|
|
61
|
+
export function getPathFromKey(key: string): string[];
|
|
62
|
+
/**
|
|
63
|
+
* Get snippet function from an object
|
|
64
|
+
* @param {Object} obj
|
|
65
|
+
* @param {string} key
|
|
66
|
+
* @returns {Function|undefined}
|
|
67
|
+
*/
|
|
68
|
+
export function getSnippet(obj: Object, key: string): Function | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rokkit/core",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.107",
|
|
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",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
+
"date-fns": "^4.1.0",
|
|
31
32
|
"ramda": "^0.30.1"
|
|
32
33
|
}
|
|
33
34
|
}
|
package/src/calendar.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { getDay, getMonth, getYear, getDaysInMonth, format, isWeekend } from 'date-fns'
|
|
2
|
+
|
|
3
|
+
export const weekdays = [
|
|
4
|
+
'Sunday',
|
|
5
|
+
'Monday',
|
|
6
|
+
'Tuesday',
|
|
7
|
+
'Wednesday',
|
|
8
|
+
'Thursday',
|
|
9
|
+
'Friday',
|
|
10
|
+
'Saturday'
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Get the days in the month.
|
|
15
|
+
*
|
|
16
|
+
* @param {Date} value
|
|
17
|
+
* @param {Array} holidays
|
|
18
|
+
* @param {boolean} fixed
|
|
19
|
+
* @returns {import('./types').CalendarDay[]}
|
|
20
|
+
*/
|
|
21
|
+
export function getCalendarDays(value, holidays = [], fixed = false) {
|
|
22
|
+
const month = getMonth(value)
|
|
23
|
+
const year = getYear(value)
|
|
24
|
+
const offset = getDay(new Date(year, month, 1)) + 1
|
|
25
|
+
|
|
26
|
+
holidays = holidays.map((x) => format(new Date(x), 'yyyy-MMM-dd'))
|
|
27
|
+
let days = Array.from({ length: getDaysInMonth(value) }, (_, i) => ({
|
|
28
|
+
day: i + 1,
|
|
29
|
+
offset: i === 0 ? offset : 0,
|
|
30
|
+
date: new Date(year, month, i + 1)
|
|
31
|
+
})).map((x) => ({
|
|
32
|
+
...x,
|
|
33
|
+
text: format(x.date, 'yyyy-MMM-dd'),
|
|
34
|
+
weekend: isWeekend(x.date),
|
|
35
|
+
holiday: holidays.includes(format(x.date, 'yyyy-MMM-dd'))
|
|
36
|
+
}))
|
|
37
|
+
|
|
38
|
+
if (fixed && days[0].offset > 4) {
|
|
39
|
+
const n = 5 * 7 - days[0].offset
|
|
40
|
+
days = [...days.slice(n + 1), ...days.slice(0, n + 1)]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return days
|
|
44
|
+
}
|
package/src/connector.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const LINE_TYPES = {
|
|
2
|
+
CHILD: 'child',
|
|
3
|
+
LAST: 'last',
|
|
4
|
+
SIBLING: 'sibling',
|
|
5
|
+
EMPTY: 'empty',
|
|
6
|
+
ICON: 'icon'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const nextType = {
|
|
10
|
+
[LINE_TYPES.CHILD]: LINE_TYPES.SIBLING,
|
|
11
|
+
[LINE_TYPES.LAST]: LINE_TYPES.EMPTY,
|
|
12
|
+
[LINE_TYPES.SIBLING]: LINE_TYPES.SIBLING,
|
|
13
|
+
[LINE_TYPES.EMPTY]: LINE_TYPES.EMPTY
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Constructs an array of line types for tree visualization
|
|
18
|
+
* @param {boolean} hasChildren - Whether the node has children
|
|
19
|
+
* @param {import('./types').LineType[]} parentTypes - Types from parent nodes
|
|
20
|
+
* @param {import('./types').LineType} position - Current position type
|
|
21
|
+
* @returns {import('./types').LineType[]} Array of line types
|
|
22
|
+
*/
|
|
23
|
+
export function getLineTypes(hasChildren = false, parentTypes = [], position = LINE_TYPES.CHILD) {
|
|
24
|
+
return parentTypes
|
|
25
|
+
.reduce((acc, type, index) => {
|
|
26
|
+
// For all but the last parent type, convert to next type
|
|
27
|
+
if (index < parentTypes.length - 1) {
|
|
28
|
+
return [...acc, nextType[type]]
|
|
29
|
+
}
|
|
30
|
+
// For the last parent type, use the position
|
|
31
|
+
return [...acc, position]
|
|
32
|
+
}, [])
|
|
33
|
+
.concat(hasChildren ? LINE_TYPES.ICON : LINE_TYPES.EMPTY)
|
|
34
|
+
}
|
package/src/constants.js
CHANGED
|
@@ -18,11 +18,16 @@ export const defaultFields = {
|
|
|
18
18
|
props: 'props',
|
|
19
19
|
target: 'target',
|
|
20
20
|
state: 'state',
|
|
21
|
-
isOpen: '_open',
|
|
22
|
-
isDeleted: '_deleted',
|
|
23
21
|
level: 'level',
|
|
24
22
|
parent: 'parent',
|
|
25
|
-
currency: 'currency'
|
|
23
|
+
currency: 'currency',
|
|
24
|
+
label: 'label',
|
|
25
|
+
/* flag fields */
|
|
26
|
+
isSelected: '_selected',
|
|
27
|
+
isHidden: '_hidden',
|
|
28
|
+
isOpen: '_open',
|
|
29
|
+
isDeleted: '_deleted',
|
|
30
|
+
isFiltered: '_filtered'
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
export const defaultIcons = [
|
package/src/events.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { noop } from './utils.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates an emitter object from the given properties.
|
|
5
|
+
*
|
|
6
|
+
* - Filters attributes that start with 'on' and are functions,
|
|
7
|
+
* - Returns an object with keys that are the event names (without the 'on' prefix)
|
|
8
|
+
* - If a default event is not present in the props, it will be set to a no-op function.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} props - The properties object to filter.
|
|
11
|
+
* @param {Array<string>} defaults - An array of default events.
|
|
12
|
+
* @returns {import('./types.js').EventHandlers} The emitter object.
|
|
13
|
+
*/
|
|
14
|
+
export function createEmitter(props, defaults = []) {
|
|
15
|
+
const emit = {}
|
|
16
|
+
|
|
17
|
+
// Filter and add functions that start with 'on'
|
|
18
|
+
Object.entries(props)
|
|
19
|
+
.filter(([key, value]) => key.startsWith('on') && typeof value === 'function')
|
|
20
|
+
.forEach(([key, value]) => {
|
|
21
|
+
emit[key.slice(2)] = value
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// Add default events with no-op function if not present
|
|
25
|
+
defaults.forEach((event) => {
|
|
26
|
+
if (!emit[event]) {
|
|
27
|
+
emit[event] = noop
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
return emit
|
|
32
|
+
}
|
package/src/field-mapper.js
CHANGED
|
@@ -1,81 +1,191 @@
|
|
|
1
|
-
import { defaultFields } from './constants'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
getIcon,
|
|
5
|
-
getValue,
|
|
6
|
-
getText,
|
|
7
|
-
getAttribute,
|
|
8
|
-
getFormattedText,
|
|
9
|
-
hasChildren,
|
|
10
|
-
isExpanded
|
|
11
|
-
} from './mapping'
|
|
12
|
-
import { has } from 'ramda'
|
|
1
|
+
import { defaultFields } from './constants.js'
|
|
2
|
+
import { isNil, has, omit } from 'ramda'
|
|
3
|
+
import { isObject } from './utils.js'
|
|
13
4
|
|
|
14
5
|
export class FieldMapper {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this
|
|
6
|
+
#fields = { ...defaultFields }
|
|
7
|
+
#componentMap = {}
|
|
8
|
+
#childMapper = null
|
|
9
|
+
|
|
10
|
+
constructor(fields = defaultFields, componentMap = {}) {
|
|
11
|
+
this.#updateFields(fields)
|
|
12
|
+
this.#updateComponentMap(componentMap)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#updateFields(fields) {
|
|
16
|
+
Object.keys(fields).forEach((key) => {
|
|
17
|
+
this.#fields[key] = fields[key]
|
|
18
|
+
})
|
|
19
|
+
this.hasIcon = has(this.#fields.icon)
|
|
20
|
+
this.hasImage = has(this.#fields.image)
|
|
21
|
+
this.hasText = has(this.#fields.text)
|
|
22
|
+
this.hasValue = has(this.#fields.value)
|
|
23
|
+
this.hasLabel = has(this.#fields.label)
|
|
24
|
+
this.hasComponent = has(this.#fields.component)
|
|
25
|
+
this.hasCurrency = has(this.#fields.currency)
|
|
26
|
+
this.withPrefix = (x) => [this.#fields.iconPrefix, x].join('-').replace(/^-+/g, '')
|
|
27
|
+
this.excludeFlags = omit([
|
|
28
|
+
this.#fields.isDeleted,
|
|
29
|
+
this.#fields.isHidden,
|
|
30
|
+
this.#fields.isSelected,
|
|
31
|
+
this.#fields.isFiltered,
|
|
32
|
+
this.#fields.isOpen
|
|
33
|
+
])
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
#updateComponentMap(components) {
|
|
37
|
+
if (typeof components === 'object' && components) {
|
|
38
|
+
Object.keys(components).forEach((key) => {
|
|
39
|
+
this.#componentMap[key] = components[key]
|
|
40
|
+
})
|
|
41
|
+
}
|
|
21
42
|
}
|
|
22
43
|
|
|
23
44
|
get fields() {
|
|
24
|
-
return this
|
|
45
|
+
return this.#fields
|
|
25
46
|
}
|
|
26
47
|
|
|
27
48
|
set fields(fields) {
|
|
28
|
-
this
|
|
49
|
+
this.#updateFields(fields)
|
|
29
50
|
}
|
|
30
51
|
|
|
31
|
-
get
|
|
32
|
-
return this
|
|
52
|
+
get componentMap() {
|
|
53
|
+
return this.#componentMap
|
|
33
54
|
}
|
|
34
|
-
|
|
35
|
-
|
|
55
|
+
|
|
56
|
+
set componentMap(components) {
|
|
57
|
+
this.#updateComponentMap(components)
|
|
36
58
|
}
|
|
37
59
|
|
|
38
60
|
getComponent(value) {
|
|
39
|
-
|
|
61
|
+
if (this.hasComponent(value))
|
|
62
|
+
return this.componentMap[value[this.fields.component]] ?? this.componentMap.default
|
|
63
|
+
return this.componentMap.default
|
|
40
64
|
}
|
|
41
65
|
|
|
42
66
|
getIcon(value) {
|
|
43
|
-
|
|
67
|
+
if (!this.hasIcon(value)) return null
|
|
68
|
+
const icon = value[this.fields.icon]
|
|
69
|
+
if (isObject(icon)) return this.withPrefix(icon[value[this.fields.state]])
|
|
70
|
+
return this.withPrefix(icon)
|
|
71
|
+
}
|
|
72
|
+
getImage(value) {
|
|
73
|
+
return this.getAttribute(value, 'image')
|
|
44
74
|
}
|
|
45
75
|
|
|
46
|
-
getValue(
|
|
47
|
-
|
|
76
|
+
getValue(value) {
|
|
77
|
+
if (this.hasValue(value)) {
|
|
78
|
+
return value[this.fields.value]
|
|
79
|
+
}
|
|
80
|
+
return value
|
|
48
81
|
}
|
|
49
82
|
|
|
50
|
-
getText(
|
|
51
|
-
|
|
83
|
+
getText(value) {
|
|
84
|
+
if (this.hasText(value)) {
|
|
85
|
+
return value[this.fields.text]
|
|
86
|
+
}
|
|
87
|
+
return typeof value === 'object' ? null : value
|
|
52
88
|
}
|
|
53
89
|
|
|
54
|
-
|
|
55
|
-
return getAttribute(
|
|
90
|
+
getLabel(value) {
|
|
91
|
+
return this.getAttribute(value, 'label') ?? this.getText(value)
|
|
56
92
|
}
|
|
57
93
|
|
|
58
|
-
|
|
59
|
-
|
|
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
|
+
getFormattedText(value, formatter) {
|
|
102
|
+
const text = this.getText(value)
|
|
103
|
+
if (isNil(text)) return ''
|
|
104
|
+
|
|
105
|
+
if (typeof formatter !== 'function') return text.toString()
|
|
106
|
+
|
|
107
|
+
if (this.hasCurrency(value)) {
|
|
108
|
+
return formatter(text, this.getAttribute(value, 'currency'))
|
|
109
|
+
}
|
|
110
|
+
return formatter(text)
|
|
60
111
|
}
|
|
61
112
|
|
|
62
113
|
hasChildren(item) {
|
|
63
|
-
return
|
|
114
|
+
return (
|
|
115
|
+
!isNil(item) &&
|
|
116
|
+
has(this.fields.children, item) &&
|
|
117
|
+
Array.isArray(item[this.fields.children]) &&
|
|
118
|
+
item[this.fields.children].length > 0
|
|
119
|
+
)
|
|
64
120
|
}
|
|
65
121
|
|
|
66
122
|
isExpanded(item) {
|
|
67
|
-
|
|
123
|
+
if (this.hasChildren(item)) {
|
|
124
|
+
return has(this.fields.isOpen, item) && item[this.fields.isOpen]
|
|
125
|
+
}
|
|
126
|
+
return false
|
|
68
127
|
}
|
|
69
128
|
|
|
70
|
-
|
|
71
|
-
return
|
|
129
|
+
isHidden(item) {
|
|
130
|
+
return has(this.fields.isHidden, item) && item[this.fields.isHidden]
|
|
72
131
|
}
|
|
73
132
|
|
|
74
|
-
|
|
75
|
-
return
|
|
133
|
+
isNested(items) {
|
|
134
|
+
return Array.isArray(items) && items.some((item) => this.hasChildren(item))
|
|
76
135
|
}
|
|
77
136
|
|
|
78
|
-
|
|
79
|
-
|
|
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
|
+
getChildren(item) {
|
|
154
|
+
return this.hasChildren(item) ? item[this.fields.children] : []
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Finds children by an index path
|
|
159
|
+
*
|
|
160
|
+
* @param {Array<Object>} items
|
|
161
|
+
* @param {Array<number>} path
|
|
162
|
+
* @returns {Array<Object>}
|
|
163
|
+
*/
|
|
164
|
+
getChildrenByPath(items, path = []) {
|
|
165
|
+
const result = path.reduce(
|
|
166
|
+
(children, index) => children?.[index]?.[this.fields.children],
|
|
167
|
+
items
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
if (result === undefined) throw new Error('Invalid path')
|
|
171
|
+
return result
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Finds an item by an index path
|
|
176
|
+
*
|
|
177
|
+
* @param {Array<Object>} items
|
|
178
|
+
* @param {Array<number>} path
|
|
179
|
+
* @returns {Object|null}
|
|
180
|
+
*/
|
|
181
|
+
getItemByPath(items, path = []) {
|
|
182
|
+
// skipcq: JS-W1042 default undefined is needed
|
|
183
|
+
const result = path.reduce(
|
|
184
|
+
(item, index, i) => (i === 0 ? items?.[index] : item?.[this.fields.children]?.[index]),
|
|
185
|
+
undefined
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
if (result === undefined) throw new Error('Invalid path')
|
|
189
|
+
return result
|
|
80
190
|
}
|
|
81
191
|
}
|
package/src/index.js
CHANGED
|
@@ -8,6 +8,12 @@ export * from './utils.js'
|
|
|
8
8
|
export * from './nested.js'
|
|
9
9
|
// skipcq: JS-E1004 - Needed for exposing all functions
|
|
10
10
|
export * from './string.js'
|
|
11
|
-
export { FieldMapper } from './field-mapper.js'
|
|
12
11
|
// skipcq: JS-E1004 - Needed for exposing all functions
|
|
13
12
|
export * from './theme.js'
|
|
13
|
+
export { FieldMapper } from './field-mapper.js'
|
|
14
|
+
export { getItemAtIndex, getIndexForItem } from './mapped-items.js'
|
|
15
|
+
export { createEmitter } from './events.js'
|
|
16
|
+
export { getLineTypes } from './connector.js'
|
|
17
|
+
export { weekdays, getCalendarDays } from './calendar.js'
|
|
18
|
+
export { generateTicks } from './ticks.js'
|
|
19
|
+
export { getValue } from './mapping.js'
|
package/src/key-event-map.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { find, toPairs } from 'ramda'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Class to manage key event mappings.
|
|
@@ -26,10 +26,11 @@ export class KeyEventMap {
|
|
|
26
26
|
* @returns {string|null} - The event name or null if no match is found.
|
|
27
27
|
*/
|
|
28
28
|
getEventForKey(key) {
|
|
29
|
-
|
|
29
|
+
// eslint-disable-next-line no-unused-vars
|
|
30
|
+
const matchEvent = ([_, keys]) =>
|
|
30
31
|
(Array.isArray(keys) && keys.includes(key)) || (keys instanceof RegExp && keys.test(key))
|
|
31
32
|
|
|
32
|
-
const event =
|
|
33
|
+
const event = find(matchEvent, toPairs(this.mapping))
|
|
33
34
|
return event ? event[0] : null
|
|
34
35
|
}
|
|
35
36
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { equals, isNil } from 'ramda'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get an item at a specific index
|
|
5
|
+
* @param {Array<any>} items
|
|
6
|
+
* @param {any} index
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export function getItemAtIndex(items, index) {
|
|
10
|
+
if (isNil(index)) return null
|
|
11
|
+
return index >= 0 && index < items.length ? items[index] : null
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get the index for an item in an array
|
|
16
|
+
* @param {Array<any} items
|
|
17
|
+
* @param {any} item
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
export function getIndexForItem(items, item) {
|
|
21
|
+
return items.findIndex((i) => equals(i, item))
|
|
22
|
+
}
|
package/src/theme.js
CHANGED
|
@@ -53,6 +53,11 @@ export function stateColors(name, modifier = 'none') {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param {string} modifier
|
|
59
|
+
* @returns
|
|
60
|
+
*/
|
|
56
61
|
export function themeColors(modifier = 'none') {
|
|
57
62
|
const fn = modifier in modifiers ? modifiers[modifier] : modifiers.none
|
|
58
63
|
|
|
@@ -183,7 +188,10 @@ export function themeRules(name = 'rokkit', mapping = defaultThemeMapping, color
|
|
|
183
188
|
const variants = Object.keys(mapping)
|
|
184
189
|
|
|
185
190
|
const rules = variants.reduce(
|
|
186
|
-
(acc, variant) => [
|
|
191
|
+
(acc, variant) => [
|
|
192
|
+
...acc,
|
|
193
|
+
...generateColorRules(variant, { ...defaultColors, ...colors }, mapping)
|
|
194
|
+
],
|
|
187
195
|
[]
|
|
188
196
|
)
|
|
189
197
|
|
package/src/ticks.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates an array of tick marks for a range of values.
|
|
3
|
+
*
|
|
4
|
+
* @param {number} lowerBound - The lower bound of the range.
|
|
5
|
+
* @param {number} upperBound - The upper bound of the range.
|
|
6
|
+
* @param {number} [minorTickStep=upperBound-lowerBound] - The step size for minor ticks.
|
|
7
|
+
* @param {number} [majorTickStep=1] - The step size for major ticks.
|
|
8
|
+
* @returns {import('./types').TickMark[]>} An array of tick mark objects.
|
|
9
|
+
*/
|
|
10
|
+
export function generateTicks(
|
|
11
|
+
lowerBound,
|
|
12
|
+
upperBound,
|
|
13
|
+
minorTickStep = upperBound - lowerBound,
|
|
14
|
+
majorTickStep = 1
|
|
15
|
+
) {
|
|
16
|
+
const length = 1 + Math.ceil((upperBound - lowerBound) / minorTickStep)
|
|
17
|
+
return Array.from({ length }, (_, i) => {
|
|
18
|
+
const value = i === length - 1 ? upperBound : lowerBound + minorTickStep * i
|
|
19
|
+
const major = i === 0 || i === length - 1 || i % majorTickStep === 0
|
|
20
|
+
return {
|
|
21
|
+
value,
|
|
22
|
+
label: major ? value : '',
|
|
23
|
+
major
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
}
|
package/src/types.js
CHANGED
package/src/utils.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { has } from 'ramda'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Finds the closest ancestor of the given element that has the given attribute.
|
|
3
5
|
*
|
|
@@ -83,3 +85,34 @@ export function scaledPath(size, x) {
|
|
|
83
85
|
if (Array.isArray(x)) return x.map((v) => scaledPath(size, v)).join(' ')
|
|
84
86
|
return typeof x === 'number' ? x * size : x
|
|
85
87
|
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Gets a key string from path
|
|
91
|
+
* @param {string[]} path
|
|
92
|
+
* @returns {string}
|
|
93
|
+
*/
|
|
94
|
+
export function getKeyFromPath(path) {
|
|
95
|
+
return path.join('-')
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Gets a path array from key string
|
|
100
|
+
* @param {string} key
|
|
101
|
+
* @returns {string[]}
|
|
102
|
+
*/
|
|
103
|
+
export function getPathFromKey(key) {
|
|
104
|
+
return key.split('-').map(Number)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get snippet function from an object
|
|
109
|
+
* @param {Object} obj
|
|
110
|
+
* @param {string} key
|
|
111
|
+
* @returns {Function|undefined}
|
|
112
|
+
*/
|
|
113
|
+
export function getSnippet(obj, key) {
|
|
114
|
+
if (has(key, obj) && typeof obj[key] === 'function') {
|
|
115
|
+
return obj[key]
|
|
116
|
+
}
|
|
117
|
+
return undefined
|
|
118
|
+
}
|