@ledgerhq/lumen-utils-shared 0.0.13 → 0.0.15
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +64 -56
- package/dist/lib/extractSlottable/extractSlottable.d.ts +29 -0
- package/dist/lib/extractSlottable/extractSlottable.d.ts.map +1 -0
- package/dist/lib/extractSlottable/index.d.ts +2 -0
- package/dist/lib/extractSlottable/index.d.ts.map +1 -0
- package/package.json +3 -2
- package/src/index.ts +1 -0
- package/src/lib/extractSlottable/extractSlottable.test.ts +97 -0
- package/src/lib/extractSlottable/extractSlottable.ts +49 -0
- package/src/lib/extractSlottable/index.ts +1 -0
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './lib/string/string';
|
|
|
2
2
|
export * from './lib/inputFormatter';
|
|
3
3
|
export * from './lib/createSafeContext';
|
|
4
4
|
export * from './lib/cn';
|
|
5
|
+
export * from './lib/extractSlottable';
|
|
5
6
|
export * from './lib/isTextChildren';
|
|
6
7
|
export * from './lib/useMergeRef';
|
|
7
8
|
export * from './lib/getObjectPath';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,UAAU,CAAC;AACzB,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,UAAU,CAAC;AACzB,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,97 +1,104 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { createContext as x, useMemo as
|
|
3
|
-
import { clsx as
|
|
4
|
-
import { twMerge as
|
|
5
|
-
function
|
|
1
|
+
import { jsx as y } from "react/jsx-runtime";
|
|
2
|
+
import { createContext as x, useMemo as d, useContext as C, Children as S, isValidElement as f } from "react";
|
|
3
|
+
import { clsx as A } from "clsx";
|
|
4
|
+
import { twMerge as P } from "tailwind-merge";
|
|
5
|
+
function j(t) {
|
|
6
6
|
return t ? t.split(/[-_ ]+/).map((n) => n.charAt(0).toUpperCase() + n.slice(1).toLowerCase()).join("") : "";
|
|
7
7
|
}
|
|
8
|
-
const
|
|
9
|
-
function
|
|
8
|
+
const E = 48, M = 17, $ = 2;
|
|
9
|
+
function F(t) {
|
|
10
10
|
const n = t.replace(/\D/g, "").length;
|
|
11
11
|
return Math.max(
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
M,
|
|
13
|
+
E - n * $
|
|
14
14
|
);
|
|
15
15
|
}
|
|
16
|
-
function
|
|
16
|
+
function p(t, n = !0) {
|
|
17
17
|
if (!t) return "";
|
|
18
|
-
const i = t.includes("."), [o, r] = t.split("."),
|
|
19
|
-
return i && n ? r ? `${
|
|
18
|
+
const i = t.includes("."), [o, r] = t.split("."), s = o.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
|
|
19
|
+
return i && n ? r ? `${s}.${r}` : `${s}.` : s;
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function I(t, n = {}) {
|
|
22
22
|
const {
|
|
23
23
|
allowDecimals: i = !0,
|
|
24
24
|
thousandsSeparator: o = !0,
|
|
25
25
|
maxIntegerLength: r = 9,
|
|
26
|
-
maxDecimalLength:
|
|
27
|
-
} = n,
|
|
28
|
-
let e =
|
|
26
|
+
maxDecimalLength: s = 9
|
|
27
|
+
} = n, c = t.replace(",", ".").replace(/[^\d.]/g, "");
|
|
28
|
+
let e = c;
|
|
29
29
|
if (e = e.replace(/^0+(?=\d)/, ""), !i)
|
|
30
|
-
return e = e.replace(/\D/g, ""), r > 0 && e.length > r && (e = e.slice(0, r)), o ?
|
|
30
|
+
return e = e.replace(/\D/g, ""), r > 0 && e.length > r && (e = e.slice(0, r)), o ? p(e) : e;
|
|
31
31
|
e === "." && (e = "0.");
|
|
32
|
-
const
|
|
33
|
-
if (
|
|
34
|
-
let
|
|
35
|
-
r > 0 &&
|
|
36
|
-
const
|
|
37
|
-
e =
|
|
32
|
+
const u = e.indexOf(".");
|
|
33
|
+
if (u !== -1) {
|
|
34
|
+
let a = e.slice(0, u), l = e.slice(u + 1).replace(/\./g, "");
|
|
35
|
+
r > 0 && a.length > r && (a = a.slice(0, r)), l = l.slice(0, s), a === "" && (a = "0");
|
|
36
|
+
const h = c.endsWith(".") || e.endsWith(".");
|
|
37
|
+
e = l.length > 0 ? `${a}.${l}` : h ? `${a}.` : a;
|
|
38
38
|
} else
|
|
39
39
|
r > 0 && e.length > r && (e = e.slice(0, r));
|
|
40
|
-
return o ?
|
|
40
|
+
return o ? p(e) : e;
|
|
41
41
|
}
|
|
42
|
-
function
|
|
43
|
-
const i = x(n), o = ({ children:
|
|
44
|
-
const e =
|
|
45
|
-
() =>
|
|
46
|
-
Object.values(
|
|
42
|
+
function O(t, n) {
|
|
43
|
+
const i = x(n), o = ({ children: s, value: c }) => {
|
|
44
|
+
const e = d(
|
|
45
|
+
() => c,
|
|
46
|
+
Object.values(c ?? {})
|
|
47
47
|
);
|
|
48
|
-
return /* @__PURE__ */
|
|
48
|
+
return /* @__PURE__ */ y(i.Provider, { value: e, children: s });
|
|
49
49
|
};
|
|
50
50
|
o.displayName = t + "Provider";
|
|
51
51
|
function r({
|
|
52
|
-
consumerName:
|
|
53
|
-
contextRequired:
|
|
52
|
+
consumerName: s,
|
|
53
|
+
contextRequired: c
|
|
54
54
|
}) {
|
|
55
|
-
const e =
|
|
55
|
+
const e = C(i);
|
|
56
56
|
if (e)
|
|
57
57
|
return e;
|
|
58
|
-
if (
|
|
58
|
+
if (c)
|
|
59
59
|
throw new Error(
|
|
60
|
-
`${
|
|
60
|
+
`${s} must be used within ${t}`
|
|
61
61
|
);
|
|
62
62
|
return n || {};
|
|
63
63
|
}
|
|
64
64
|
return [o, r];
|
|
65
65
|
}
|
|
66
|
-
function
|
|
67
|
-
return
|
|
66
|
+
function z(...t) {
|
|
67
|
+
return P(A(t));
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
function L(t, n) {
|
|
70
|
+
const i = S.toArray(t), o = typeof n == "string" ? (c) => f(c) && c.props["data-slot"] === n : (c) => f(c) && c.type === n, r = i.find(o), s = i.filter((c) => !o(c));
|
|
71
|
+
return {
|
|
72
|
+
slotElement: r ?? null,
|
|
73
|
+
remainingChildren: s
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const g = (t) => typeof t == "string" || typeof t == "number", R = (t) => Array.isArray(t) ? t.every(g) : g(t);
|
|
77
|
+
function m(t, n) {
|
|
71
78
|
if (typeof t == "function")
|
|
72
79
|
return t(n);
|
|
73
80
|
typeof t == "object" && t !== null && "current" in t && (t.current = n);
|
|
74
81
|
}
|
|
75
|
-
function
|
|
82
|
+
function b(...t) {
|
|
76
83
|
const n = /* @__PURE__ */ new Map();
|
|
77
84
|
return (i) => {
|
|
78
85
|
if (i === null) {
|
|
79
86
|
t.forEach((o) => {
|
|
80
87
|
const r = n.get(o);
|
|
81
|
-
typeof r == "function" && r(),
|
|
88
|
+
typeof r == "function" && r(), m(o, null);
|
|
82
89
|
}), n.clear();
|
|
83
90
|
return;
|
|
84
91
|
}
|
|
85
92
|
t.forEach((o) => {
|
|
86
|
-
const r =
|
|
93
|
+
const r = m(o, i);
|
|
87
94
|
typeof r == "function" && n.set(o, r);
|
|
88
95
|
});
|
|
89
96
|
};
|
|
90
97
|
}
|
|
91
|
-
function
|
|
92
|
-
return
|
|
98
|
+
function T(...t) {
|
|
99
|
+
return d(() => b(...t), t);
|
|
93
100
|
}
|
|
94
|
-
const
|
|
101
|
+
const V = (t, n) => {
|
|
95
102
|
let i = t;
|
|
96
103
|
for (const o of n) {
|
|
97
104
|
if (i == null)
|
|
@@ -101,15 +108,16 @@ const z = (t, n) => {
|
|
|
101
108
|
return i;
|
|
102
109
|
};
|
|
103
110
|
export {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
m as assignRef,
|
|
112
|
+
z as cn,
|
|
113
|
+
O as createSafeContext,
|
|
114
|
+
L as extractSlottable,
|
|
115
|
+
p as formatThousands,
|
|
116
|
+
F as getFontSize,
|
|
117
|
+
V as getObjectPath,
|
|
118
|
+
R as isTextChildren,
|
|
119
|
+
b as mergeRefs,
|
|
120
|
+
I as textFormatter,
|
|
121
|
+
j as toPascalCase,
|
|
122
|
+
T as useMergedRef
|
|
115
123
|
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ComponentType, ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Extracts children with a specific data-slot attribute or component type from a React children collection.
|
|
4
|
+
* Useful for separating specific components from general content in composite patterns.
|
|
5
|
+
*
|
|
6
|
+
* @param children - React children to process
|
|
7
|
+
* @param slotNameOrType - The data-slot value to extract, or the component type to match
|
|
8
|
+
* @returns An object containing the extracted slot element and remaining children
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // Extract by data-slot attribute
|
|
12
|
+
* const { slotElement, remainingChildren } = extractSlottable(children, 'secondary-action');
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // Extract by component type
|
|
16
|
+
* const { slotElement, remainingChildren } = extractSlottable(children, MyComponent);
|
|
17
|
+
*
|
|
18
|
+
* return (
|
|
19
|
+
* <div>
|
|
20
|
+
* {slotElement}
|
|
21
|
+
* <button>{remainingChildren}</button>
|
|
22
|
+
* </div>
|
|
23
|
+
* );
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractSlottable(children: ReactNode, slotNameOrType: string | ComponentType<any>): {
|
|
26
|
+
slotElement: ReactNode;
|
|
27
|
+
remainingChildren: ReactNode[];
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=extractSlottable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractSlottable.d.ts","sourceRoot":"","sources":["../../../src/lib/extractSlottable/extractSlottable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,aAAa,EAAkB,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,SAAS,EACnB,cAAc,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,GAC1C;IACD,WAAW,EAAE,SAAS,CAAC;IACvB,iBAAiB,EAAE,SAAS,EAAE,CAAC;CAChC,CAiBA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/extractSlottable/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/lumen-utils-shared",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
|
-
"import": "./dist/index.js"
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
12
13
|
},
|
|
13
14
|
"./package.json": "./package.json"
|
|
14
15
|
},
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './lib/string/string';
|
|
|
2
2
|
export * from './lib/inputFormatter';
|
|
3
3
|
export * from './lib/createSafeContext';
|
|
4
4
|
export * from './lib/cn';
|
|
5
|
+
export * from './lib/extractSlottable';
|
|
5
6
|
export * from './lib/isTextChildren';
|
|
6
7
|
export * from './lib/useMergeRef';
|
|
7
8
|
export * from './lib/getObjectPath';
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { createElement } from 'react';
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import { extractSlottable } from './extractSlottable';
|
|
4
|
+
|
|
5
|
+
describe('extractSlottable', () => {
|
|
6
|
+
it('should extract element with matching data-slot', () => {
|
|
7
|
+
const children = [
|
|
8
|
+
createElement('div', { 'data-slot': 'target', key: '1' }, 'Target'),
|
|
9
|
+
createElement('div', { key: '2' }, 'Other 1'),
|
|
10
|
+
createElement('div', { key: '3' }, 'Other 2'),
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const { slotElement, remainingChildren } = extractSlottable(
|
|
14
|
+
children,
|
|
15
|
+
'target',
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
expect(slotElement).toBeTruthy();
|
|
19
|
+
expect(remainingChildren).toHaveLength(2);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should return null slotElement when no match found', () => {
|
|
23
|
+
const children = [
|
|
24
|
+
createElement('div', { key: '1' }, 'Child 1'),
|
|
25
|
+
createElement('div', { key: '2' }, 'Child 2'),
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const { slotElement, remainingChildren } = extractSlottable(
|
|
29
|
+
children,
|
|
30
|
+
'non-existent',
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
expect(slotElement).toBeNull();
|
|
34
|
+
expect(remainingChildren).toHaveLength(2);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should handle empty children', () => {
|
|
38
|
+
const { slotElement, remainingChildren } = extractSlottable([], 'target');
|
|
39
|
+
|
|
40
|
+
expect(slotElement).toBeNull();
|
|
41
|
+
expect(remainingChildren).toHaveLength(0);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should handle single child', () => {
|
|
45
|
+
const child = createElement(
|
|
46
|
+
'div',
|
|
47
|
+
{ 'data-slot': 'target' },
|
|
48
|
+
'Single Target',
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const { slotElement, remainingChildren } = extractSlottable(
|
|
52
|
+
child,
|
|
53
|
+
'target',
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
expect(slotElement).toBeTruthy();
|
|
57
|
+
expect(remainingChildren).toHaveLength(0);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should extract only first matching element', () => {
|
|
61
|
+
const children = [
|
|
62
|
+
createElement('div', { 'data-slot': 'target', key: '1' }, 'Target 1'),
|
|
63
|
+
createElement('div', { key: '2' }, 'Other'),
|
|
64
|
+
createElement('div', { 'data-slot': 'target', key: '3' }, 'Target 2'),
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
const { slotElement, remainingChildren } = extractSlottable(
|
|
68
|
+
children,
|
|
69
|
+
'target',
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
expect(slotElement).toBeTruthy();
|
|
73
|
+
// Remaining should include only the non-target element (second target is also filtered out)
|
|
74
|
+
expect(remainingChildren).toHaveLength(1);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should preserve non-element children', () => {
|
|
78
|
+
const children = [
|
|
79
|
+
'Text node',
|
|
80
|
+
createElement('div', { 'data-slot': 'target', key: '1' }, 'Target'),
|
|
81
|
+
createElement('div', { key: '2' }, 'Element'),
|
|
82
|
+
123,
|
|
83
|
+
null,
|
|
84
|
+
undefined,
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
const { slotElement, remainingChildren } = extractSlottable(
|
|
88
|
+
children,
|
|
89
|
+
'target',
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
expect(slotElement).toBeTruthy();
|
|
93
|
+
// React.Children.toArray() filters out null and undefined automatically
|
|
94
|
+
// Should preserve text, number, and other element (3 items)
|
|
95
|
+
expect(remainingChildren).toHaveLength(3);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Children, ComponentType, isValidElement, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extracts children with a specific data-slot attribute or component type from a React children collection.
|
|
5
|
+
* Useful for separating specific components from general content in composite patterns.
|
|
6
|
+
*
|
|
7
|
+
* @param children - React children to process
|
|
8
|
+
* @param slotNameOrType - The data-slot value to extract, or the component type to match
|
|
9
|
+
* @returns An object containing the extracted slot element and remaining children
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // Extract by data-slot attribute
|
|
13
|
+
* const { slotElement, remainingChildren } = extractSlottable(children, 'secondary-action');
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Extract by component type
|
|
17
|
+
* const { slotElement, remainingChildren } = extractSlottable(children, MyComponent);
|
|
18
|
+
*
|
|
19
|
+
* return (
|
|
20
|
+
* <div>
|
|
21
|
+
* {slotElement}
|
|
22
|
+
* <button>{remainingChildren}</button>
|
|
23
|
+
* </div>
|
|
24
|
+
* );
|
|
25
|
+
*/
|
|
26
|
+
export function extractSlottable(
|
|
27
|
+
children: ReactNode,
|
|
28
|
+
slotNameOrType: string | ComponentType<any>,
|
|
29
|
+
): {
|
|
30
|
+
slotElement: ReactNode;
|
|
31
|
+
remainingChildren: ReactNode[];
|
|
32
|
+
} {
|
|
33
|
+
const childArray = Children.toArray(children);
|
|
34
|
+
|
|
35
|
+
const matcher =
|
|
36
|
+
typeof slotNameOrType === 'string'
|
|
37
|
+
? (child: ReactNode) =>
|
|
38
|
+
isValidElement(child) && child.props['data-slot'] === slotNameOrType
|
|
39
|
+
: (child: ReactNode) =>
|
|
40
|
+
isValidElement(child) && child.type === slotNameOrType;
|
|
41
|
+
|
|
42
|
+
const slotElement = childArray.find(matcher);
|
|
43
|
+
const remainingChildren = childArray.filter((child) => !matcher(child));
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
slotElement: slotElement ?? null,
|
|
47
|
+
remainingChildren,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './extractSlottable';
|