@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 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';
@@ -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 h } from "react/jsx-runtime";
2
- import { createContext as x, useMemo as m, useContext as y } from "react";
3
- import { clsx as P } from "clsx";
4
- import { twMerge as S } from "tailwind-merge";
5
- function w(t) {
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 C = 48, A = 17, M = 2;
9
- function E(t) {
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
- A,
13
- C - n * M
12
+ M,
13
+ E - n * $
14
14
  );
15
15
  }
16
- function f(t, n = !0) {
16
+ function p(t, n = !0) {
17
17
  if (!t) return "";
18
- const i = t.includes("."), [o, r] = t.split("."), c = o.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
19
- return i && n ? r ? `${c}.${r}` : `${c}.` : c;
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 T(t, n = {}) {
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: c = 9
27
- } = n, a = t.replace(",", ".").replace(/[^\d.]/g, "");
28
- let e = a;
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 ? f(e) : e;
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 l = e.indexOf(".");
33
- if (l !== -1) {
34
- let s = e.slice(0, l), u = e.slice(l + 1).replace(/\./g, "");
35
- r > 0 && s.length > r && (s = s.slice(0, r)), u = u.slice(0, c), s === "" && (s = "0");
36
- const d = a.endsWith(".") || e.endsWith(".");
37
- e = u.length > 0 ? `${s}.${u}` : d ? `${s}.` : s;
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 ? f(e) : e;
40
+ return o ? p(e) : e;
41
41
  }
42
- function _(t, n) {
43
- const i = x(n), o = ({ children: c, value: a }) => {
44
- const e = m(
45
- () => a,
46
- Object.values(a ?? {})
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__ */ h(i.Provider, { value: e, children: c });
48
+ return /* @__PURE__ */ y(i.Provider, { value: e, children: s });
49
49
  };
50
50
  o.displayName = t + "Provider";
51
51
  function r({
52
- consumerName: c,
53
- contextRequired: a
52
+ consumerName: s,
53
+ contextRequired: c
54
54
  }) {
55
- const e = y(i);
55
+ const e = C(i);
56
56
  if (e)
57
57
  return e;
58
- if (a)
58
+ if (c)
59
59
  throw new Error(
60
- `${c} must be used within ${t}`
60
+ `${s} must be used within ${t}`
61
61
  );
62
62
  return n || {};
63
63
  }
64
64
  return [o, r];
65
65
  }
66
- function j(...t) {
67
- return S(P(t));
66
+ function z(...t) {
67
+ return P(A(t));
68
68
  }
69
- const p = (t) => typeof t == "string" || typeof t == "number", F = (t) => Array.isArray(t) ? t.every(p) : p(t);
70
- function g(t, n) {
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 $(...t) {
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(), g(o, null);
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 = g(o, i);
93
+ const r = m(o, i);
87
94
  typeof r == "function" && n.set(o, r);
88
95
  });
89
96
  };
90
97
  }
91
- function I(...t) {
92
- return m(() => $(...t), t);
98
+ function T(...t) {
99
+ return d(() => b(...t), t);
93
100
  }
94
- const z = (t, n) => {
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
- g as assignRef,
105
- j as cn,
106
- _ as createSafeContext,
107
- f as formatThousands,
108
- E as getFontSize,
109
- z as getObjectPath,
110
- F as isTextChildren,
111
- $ as mergeRefs,
112
- T as textFormatter,
113
- w as toPascalCase,
114
- I as useMergedRef
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,2 @@
1
+ export * from './extractSlottable';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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.13",
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';