@lumx/core 4.2.0 → 4.2.1-alpha.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.
- package/js/types/NestedComponents.d.ts +23 -0
- package/js/types/Selector.d.ts +11 -0
- package/js/types/index.d.ts +2 -0
- package/js/utils/classNames/bem/block.d.ts +15 -0
- package/js/utils/classNames/bem/block.js +26 -0
- package/js/utils/classNames/bem/element.d.ts +16 -0
- package/js/utils/classNames/bem/element.js +10 -0
- package/js/utils/classNames/bem/index.d.ts +18 -0
- package/js/utils/classNames/bem/index.js +28 -0
- package/js/utils/classNames/bem/modifier.d.ts +17 -0
- package/js/utils/classNames/bem/modifier.js +21 -0
- package/js/utils/classNames/index.d.ts +1 -0
- package/js/utils/classNames/index.js +1 -0
- package/js/utils/index.d.ts +1 -0
- package/js/utils/index.js +2 -0
- package/js/utils/selectors/getWithSelector.d.ts +3 -0
- package/js/utils/selectors/getWithSelector.js +14 -0
- package/js/utils/selectors/groupBySelector.d.ts +6 -0
- package/js/utils/selectors/groupBySelector.js +21 -0
- package/js/utils/selectors/index.d.ts +2 -0
- package/js/utils/selectors/index.js +2 -0
- package/package.json +5 -4
- package/js/utils/_internal/className/getBasicClass.d.ts +0 -13
- package/js/utils/_internal/className/handleBasicClasses.d.ts +0 -15
- package/js/utils/_internal/className/index.d.ts +0 -2
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A component reference that can be used in nested components.
|
|
3
|
+
* This is framework-agnostic and works with both React components (functions)
|
|
4
|
+
* and Vue components (objects/constructors).
|
|
5
|
+
*/
|
|
6
|
+
export type ComponentLike = any;
|
|
7
|
+
/**
|
|
8
|
+
* Represents a mapping of nested component names to their component implementations.
|
|
9
|
+
* Used to provide component references to LumX core components that accept nested components.
|
|
10
|
+
*
|
|
11
|
+
* This type is framework-agnostic and can accept both React and Vue component types.
|
|
12
|
+
* While ComponentLike is typed as any, this structured type provides better documentation
|
|
13
|
+
* and a centralized location for future refinements.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // React usage
|
|
17
|
+
* Flag(props, { Text });
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // Vue usage with VueToJSX
|
|
21
|
+
* const ui = VueToJSX(FlagUI, { nestedComponents: { Text } });
|
|
22
|
+
*/
|
|
23
|
+
export type NestedComponents = Record<string, ComponentLike>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type FunctionSelector<TObject, TValue> = (o: TObject) => TValue;
|
|
2
|
+
type FieldSelector<TObject, TValue> = keyof {
|
|
3
|
+
[TKey in keyof TObject as TObject[TKey] extends TValue ? TKey : never]: TObject[TKey];
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Value selector on an object
|
|
7
|
+
* - either via an object key
|
|
8
|
+
* - or a selector function
|
|
9
|
+
*/
|
|
10
|
+
export type Selector<TObject, TValue = string> = FieldSelector<TObject, TValue> | FunctionSelector<TObject, TValue>;
|
|
11
|
+
export {};
|
package/js/types/index.d.ts
CHANGED
|
@@ -15,9 +15,11 @@ export type { ValueOf } from './ValueOf';
|
|
|
15
15
|
export type { LumxClassName } from './LumxClassName';
|
|
16
16
|
export type { Direction } from './Direction';
|
|
17
17
|
export type { Spacing } from './Spacing';
|
|
18
|
+
export type { NestedComponents, ComponentLike } from './NestedComponents';
|
|
18
19
|
export type { ObjectValues } from './ObjectValues';
|
|
19
20
|
export type { HasRequiredLinkHref } from './HasRequiredLinkHref';
|
|
20
21
|
export type { HasPolymorphicAs } from './HasPolymorphicAs';
|
|
21
22
|
export type { CommonRef } from './CommonRef';
|
|
22
23
|
export type { HasAriaDisabled } from './HasAriaDisabled';
|
|
23
24
|
export type { AriaAttributes } from './AriaAttributes';
|
|
25
|
+
export type { Selector } from './Selector';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Modifier } from './modifier';
|
|
2
|
+
/**
|
|
3
|
+
* Generates a BEM block + modifier class name string.
|
|
4
|
+
* Combines a base class with optional modifiers and additional classes.
|
|
5
|
+
*
|
|
6
|
+
* @param baseName The base BEM class
|
|
7
|
+
* @param modifier Optional modifiers
|
|
8
|
+
* @returns Combined class name string
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* block('button'); // 'button'
|
|
12
|
+
* block('button', { active: true, disabled: false }); // 'button button--active'
|
|
13
|
+
*/
|
|
14
|
+
export declare function block(baseName: string, additionalClasses: string[]): string;
|
|
15
|
+
export declare function block(baseName: string, modifiers?: Modifier, additionalClasses?: string[]): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import classnames from 'classnames';
|
|
2
|
+
import { modifier } from './modifier.js';
|
|
3
|
+
|
|
4
|
+
function block(baseName, modifiersOrAdditionalClasses, additionalClasses) {
|
|
5
|
+
let modifiers;
|
|
6
|
+
let classes;
|
|
7
|
+
if (Array.isArray(modifiersOrAdditionalClasses)) {
|
|
8
|
+
classes = modifiersOrAdditionalClasses;
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
modifiers = modifiersOrAdditionalClasses;
|
|
12
|
+
classes = additionalClasses;
|
|
13
|
+
}
|
|
14
|
+
if (!modifiers && !classes) {
|
|
15
|
+
return baseName;
|
|
16
|
+
}
|
|
17
|
+
return classnames(
|
|
18
|
+
// Additional classes
|
|
19
|
+
classes,
|
|
20
|
+
// Base class
|
|
21
|
+
baseName,
|
|
22
|
+
// Modifier(s)
|
|
23
|
+
modifiers ? modifier(baseName, modifiers) : null);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { block };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Modifier } from './modifier';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a BEM element class generator function for the given base class.
|
|
4
|
+
* Returns a function that generates BEM element class names with optional modifiers.
|
|
5
|
+
*
|
|
6
|
+
* @param baseClass The base BEM block class name (e.g., 'button', 'card')
|
|
7
|
+
* @param elem The BEM element name (e.g., 'icon', 'title')
|
|
8
|
+
* @param modifier Optional BEM modifier ()
|
|
9
|
+
* @returns combined BEM element class name
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* element('my-button', 'icon'); // 'my-button__icon'
|
|
13
|
+
* element('my-button', 'icon', { active: true }); // 'my-button__icon my-button__icon--active'
|
|
14
|
+
*/
|
|
15
|
+
export declare function element(baseClass: string, elem: string, additionalClasses: string[]): string;
|
|
16
|
+
export declare function element(baseClass: string, elem: string, modifiers?: Modifier, additionalClasses?: string[]): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { block } from './block.js';
|
|
2
|
+
|
|
3
|
+
function element(baseClass, elem, modifiersOrAdditionalClasses, additionalClasses) {
|
|
4
|
+
if (Array.isArray(modifiersOrAdditionalClasses)) {
|
|
5
|
+
return block(`${baseClass}__${elem}`, modifiersOrAdditionalClasses);
|
|
6
|
+
}
|
|
7
|
+
return block(`${baseClass}__${elem}`, modifiersOrAdditionalClasses, additionalClasses);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { element };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { block } from './block';
|
|
2
|
+
import { element } from './element';
|
|
3
|
+
import { type Modifier } from './modifier';
|
|
4
|
+
/**
|
|
5
|
+
* Setup BEM block & element generation for a given base name.
|
|
6
|
+
*/
|
|
7
|
+
export declare function bem(baseName: string): {
|
|
8
|
+
block: {
|
|
9
|
+
(additionalClasses: string[]): string;
|
|
10
|
+
(modifiers?: Modifier, additionalClasses?: string[]): string;
|
|
11
|
+
};
|
|
12
|
+
element: {
|
|
13
|
+
(elem: string, additionalClasses: string[]): string;
|
|
14
|
+
(elem: string, modifiers?: Modifier, additionalClasses?: string[]): string;
|
|
15
|
+
};
|
|
16
|
+
modifier: (modifiers: Modifier) => string;
|
|
17
|
+
};
|
|
18
|
+
export { block, element };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { block } from './block.js';
|
|
2
|
+
import { element } from './element.js';
|
|
3
|
+
import { modifier } from './modifier.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Setup BEM block & element generation for a given base name.
|
|
7
|
+
*/
|
|
8
|
+
function bem(baseName) {
|
|
9
|
+
function blockFn(modifiersOrAdditionalClasses, additionalClasses) {
|
|
10
|
+
if (Array.isArray(modifiersOrAdditionalClasses)) {
|
|
11
|
+
return block(baseName, modifiersOrAdditionalClasses);
|
|
12
|
+
}
|
|
13
|
+
return block(baseName, modifiersOrAdditionalClasses, additionalClasses);
|
|
14
|
+
}
|
|
15
|
+
function elementFn(elem, modifiersOrAdditionalClasses, additionalClasses) {
|
|
16
|
+
if (Array.isArray(modifiersOrAdditionalClasses)) {
|
|
17
|
+
return element(baseName, elem, modifiersOrAdditionalClasses);
|
|
18
|
+
}
|
|
19
|
+
return element(baseName, elem, modifiersOrAdditionalClasses, additionalClasses);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
block: blockFn,
|
|
23
|
+
element: elementFn,
|
|
24
|
+
modifier: (modifiers) => modifier(baseName, modifiers),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { bem, block, element };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modifier
|
|
3
|
+
* @example { 'is-disabled': true, 'is-selected': false }
|
|
4
|
+
*/
|
|
5
|
+
export type Modifier = Record<string, boolean | undefined | null>;
|
|
6
|
+
/**
|
|
7
|
+
* Generates BEM modifier class names.
|
|
8
|
+
*
|
|
9
|
+
* @param baseName The base BEM class to attach modifiers to.
|
|
10
|
+
* @param modifiers Map of modifier names to boolean values.
|
|
11
|
+
* @returns Combined modifier class names string.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* modifier('button', { active: true }); // 'button--active'
|
|
15
|
+
* modifier('button', { active: true, disabled: false }); // 'button--active'
|
|
16
|
+
*/
|
|
17
|
+
export declare function modifier(baseName: string, modifiers: Modifier): string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates BEM modifier class names.
|
|
3
|
+
*
|
|
4
|
+
* @param baseName The base BEM class to attach modifiers to.
|
|
5
|
+
* @param modifiers Map of modifier names to boolean values.
|
|
6
|
+
* @returns Combined modifier class names string.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* modifier('button', { active: true }); // 'button--active'
|
|
10
|
+
* modifier('button', { active: true, disabled: false }); // 'button--active'
|
|
11
|
+
*/
|
|
12
|
+
function modifier(baseName, modifiers) {
|
|
13
|
+
const modifierClasses = [];
|
|
14
|
+
for (const [key, value] of Object.entries(modifiers)) {
|
|
15
|
+
if (value)
|
|
16
|
+
modifierClasses.push(`${baseName}--${key}`);
|
|
17
|
+
}
|
|
18
|
+
return modifierClasses.join(' ');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { modifier };
|
|
@@ -3,3 +3,4 @@ export { background, color, font } from './color/index.js';
|
|
|
3
3
|
export { typography } from './typography/index.js';
|
|
4
4
|
export { margin, margins, padding, paddings, spacing, spacings } from './spacing/index.js';
|
|
5
5
|
export { visuallyHidden } from './visually-hidden/index.js';
|
|
6
|
+
export { bem } from './bem/index.js';
|
package/js/utils/index.d.ts
CHANGED
package/js/utils/index.js
CHANGED
|
@@ -2,3 +2,5 @@ import * as index from './classNames/index.js';
|
|
|
2
2
|
export { index as classNames };
|
|
3
3
|
export { onButtonPressed, onEnterPressed, onEscapePressed } from './events/keyboard.js';
|
|
4
4
|
export { detectHorizontalSwipe } from './events/swipe.js';
|
|
5
|
+
export { getWithSelector } from './selectors/getWithSelector.js';
|
|
6
|
+
export { groupBySelector } from './selectors/groupBySelector.js';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Get value with a string of function selector */
|
|
2
|
+
const getWithSelector = (selector, object) => {
|
|
3
|
+
// Use the provided selector function
|
|
4
|
+
if (typeof selector === 'function') {
|
|
5
|
+
return selector(object);
|
|
6
|
+
}
|
|
7
|
+
// Use the provided selector as a property name
|
|
8
|
+
if (typeof selector === 'string') {
|
|
9
|
+
return object[selector];
|
|
10
|
+
}
|
|
11
|
+
return String(object);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { getWithSelector };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Selector } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Equivalent to `lodash/groupBy` but returns a `Map` of groups items (instead of an object)
|
|
4
|
+
* (has the major advantage to not forcing the keys to be string!)
|
|
5
|
+
*/
|
|
6
|
+
export declare function groupBySelector<TObject, TValue>(array: TObject[], selector: Selector<TObject, TValue>): Map<TValue, TObject[]>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getWithSelector } from './getWithSelector.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Equivalent to `lodash/groupBy` but returns a `Map` of groups items (instead of an object)
|
|
5
|
+
* (has the major advantage to not forcing the keys to be string!)
|
|
6
|
+
*/
|
|
7
|
+
function groupBySelector(array, selector) {
|
|
8
|
+
const groups = new Map();
|
|
9
|
+
for (const item of array) {
|
|
10
|
+
const key = getWithSelector(selector, item);
|
|
11
|
+
let group = groups.get(key);
|
|
12
|
+
if (!group) {
|
|
13
|
+
group = [];
|
|
14
|
+
groups.set(key, group);
|
|
15
|
+
}
|
|
16
|
+
group.push(item);
|
|
17
|
+
}
|
|
18
|
+
return groups;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { groupBySelector };
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"url": "https://github.com/lumapps/design-system/issues"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@lumx/icons": "^4.2.
|
|
9
|
+
"@lumx/icons": "^4.2.1-alpha.1",
|
|
10
10
|
"classnames": "^2.3.2",
|
|
11
11
|
"focus-visible": "^5.0.2",
|
|
12
12
|
"lodash": "4.17.23",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"scripts": {
|
|
33
33
|
"generate:design-tokens": "yarn node style-dictionary/index.cjs",
|
|
34
34
|
"build": "rollup -c",
|
|
35
|
-
"test": "vitest run",
|
|
35
|
+
"test": "vitest run --run",
|
|
36
36
|
"type-check": "yarn tsc -p tsconfig.json",
|
|
37
37
|
"update-version-changelog": "yarn version-changelog ../../CHANGELOG.md"
|
|
38
38
|
},
|
|
39
39
|
"sideEffects": false,
|
|
40
|
-
"version": "4.2.
|
|
40
|
+
"version": "4.2.1-alpha.1",
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
43
43
|
"@testing-library/dom": "^10.4.1",
|
|
@@ -60,5 +60,6 @@
|
|
|
60
60
|
"vite": "^7.3.1",
|
|
61
61
|
"vite-tsconfig-paths": "^5.1.4",
|
|
62
62
|
"vitest": "^4.0.18"
|
|
63
|
-
}
|
|
63
|
+
},
|
|
64
|
+
"stableVersion": "4.2.0"
|
|
64
65
|
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get the basic CSS class for the given type.
|
|
3
|
-
*
|
|
4
|
-
* @param prefix The class name prefix for the generated CSS class.
|
|
5
|
-
* @param type The type of CSS class we want to generate (e.g.: 'color', 'variant', ...).
|
|
6
|
-
* @param value The value of the type of the CSS class (e.g.: 'primary', 'button', ...).
|
|
7
|
-
* @return The basic CSS class.
|
|
8
|
-
*/
|
|
9
|
-
export declare function getBasicClass({ prefix, type, value, }: {
|
|
10
|
-
prefix: string;
|
|
11
|
-
type: string;
|
|
12
|
-
value: string | number | boolean | undefined;
|
|
13
|
-
}): string;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Return all basic LumX CSS classes which are available for every components.
|
|
3
|
-
*
|
|
4
|
-
* @see {@link /src/components/index.d.ts} for the possible values of each parameter.
|
|
5
|
-
*
|
|
6
|
-
* @param prefix The class name prefix for the generated CSS class.
|
|
7
|
-
* @param props All the other props you want to generate a class.
|
|
8
|
-
* The rule of thumb: the key is the name of the prop in the class, the value a string that will
|
|
9
|
-
* be used in the classname to represent the value of the given prop.
|
|
10
|
-
* @return All LumX basic CSS classes.
|
|
11
|
-
*/
|
|
12
|
-
export declare function handleBasicClasses({ prefix, ...props }: {
|
|
13
|
-
prefix: string;
|
|
14
|
-
[prop: string]: any;
|
|
15
|
-
}): string;
|