@ledgerhq/lumen-utils-shared 0.1.4 → 0.1.6

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.js CHANGED
@@ -1,24 +1,24 @@
1
1
  import { jsx as k } from "react/jsx-runtime";
2
- import { createContext as F, useRef as W, useContext as _, useMemo as I } from "react";
3
- import { clsx as R } from "clsx";
4
- import { twMerge as w } from "tailwind-merge";
5
- function Q(t) {
2
+ import { createContext as W, useRef as F, useContext as w, useMemo as I } from "react";
3
+ import { clsx as B } from "clsx";
4
+ import { twMerge as R } from "tailwind-merge";
5
+ function G(t) {
6
6
  return t ? t.split(/[-_ ]+/).map((e) => e.charAt(0).toUpperCase() + e.slice(1).toLowerCase()).join("") : "";
7
7
  }
8
- const B = 48, N = 17, q = 2;
9
- function Y(t) {
10
- const e = t.replace(/\D/g, "").length;
11
- return Math.max(
12
- N,
13
- B - e * q
14
- );
8
+ const _ = {
9
+ md: { max: 48, min: 17, scale: 2, startAt: 0 },
10
+ sm: { max: 28, min: 12, scale: 2, startAt: 6 }
11
+ };
12
+ function J(t, e = "md") {
13
+ const { max: r, min: o, scale: s, startAt: l } = _[e], i = t.replace(/\D/g, "").length;
14
+ return Math.max(o, r - Math.max(0, i - l) * s);
15
15
  }
16
16
  function A(t, e = !0) {
17
17
  if (!t) return "";
18
18
  const r = t.includes("."), [o, s] = t.split("."), l = o.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
19
19
  return r && e ? s ? `${l}.${s}` : `${l}.` : l;
20
20
  }
21
- function tt(t, e = {}) {
21
+ function Q(t, e = {}) {
22
22
  const {
23
23
  allowDecimals: r = !0,
24
24
  thousandsSeparator: o = !0,
@@ -29,34 +29,35 @@ function tt(t, e = {}) {
29
29
  if (n = n.replace(/^0+(?=\d)/, ""), !r)
30
30
  return n = n.replace(/\D/g, ""), s > 0 && n.length > s && (n = n.slice(0, s)), o ? A(n) : n;
31
31
  n === "." && (n = "0.");
32
- const a = n.indexOf(".");
33
- if (a !== -1) {
34
- let u = n.slice(0, a), f = n.slice(a + 1).replace(/\./g, "");
35
- s > 0 && u.length > s && (u = u.slice(0, s)), f = f.slice(0, l), u === "" && (u = "0");
36
- const h = i.endsWith(".") || n.endsWith(".");
37
- n = f.length > 0 ? `${u}.${f}` : h ? `${u}.` : u;
38
- } else
32
+ const u = n.indexOf(".");
33
+ if (u === -1)
39
34
  s > 0 && n.length > s && (n = n.slice(0, s));
35
+ else {
36
+ let a = n.slice(0, u), f = n.slice(u + 1).replace(/\./g, "");
37
+ s > 0 && a.length > s && (a = a.slice(0, s)), f = f.slice(0, l), a === "" && (a = "0");
38
+ const h = i.endsWith(".") || n.endsWith(".");
39
+ n = f.length > 0 ? `${a}.${f}` : h ? `${a}.` : a;
40
+ }
40
41
  return o ? A(n) : n;
41
42
  }
42
- function z(t, e) {
43
+ function q(t, e) {
43
44
  if (Object.is(t, e)) return !0;
44
45
  const r = t, o = e, s = Object.keys(r), l = Object.keys(o);
45
46
  return s.length !== l.length ? !1 : s.every(
46
47
  (i) => Object.prototype.hasOwnProperty.call(o, i) && Object.is(r[i], o[i])
47
48
  );
48
49
  }
49
- function K(t, e) {
50
- const r = F(e), o = ({ children: l, value: i }) => {
51
- const n = W(i);
52
- return z(n.current, i) || (n.current = i), /* @__PURE__ */ k(r.Provider, { value: n.current, children: l });
50
+ function z(t, e) {
51
+ const r = W(e), o = ({ children: l, value: i }) => {
52
+ const n = F(i);
53
+ return q(n.current, i) || (n.current = i), /* @__PURE__ */ k(r.Provider, { value: n.current, children: l });
53
54
  };
54
55
  o.displayName = t + "Provider";
55
56
  function s({
56
57
  consumerName: l,
57
58
  contextRequired: i
58
59
  }) {
59
- const n = _(r);
60
+ const n = w(r);
60
61
  if (n)
61
62
  return n;
62
63
  if (i)
@@ -67,46 +68,46 @@ function K(t, e) {
67
68
  }
68
69
  return [o, s];
69
70
  }
70
- const [et, Z] = K("Disabled", { disabled: !1 }), nt = ({
71
+ const [X, K] = z("Disabled", { disabled: !1 }), tt = ({
71
72
  consumerName: t,
72
73
  contextRequired: e,
73
74
  mergeWith: r
74
75
  }) => {
75
- const o = Z({
76
+ const o = K({
76
77
  consumerName: t,
77
78
  contextRequired: e ?? !1
78
79
  });
79
80
  return !!(r?.disabled || o.disabled);
80
81
  };
81
- function rt(...t) {
82
- return w(R(t));
82
+ function et(...t) {
83
+ return R(B(t));
83
84
  }
84
- const O = (t) => typeof t == "string" || typeof t == "number", ot = (t) => Array.isArray(t) ? t.every(O) : O(t);
85
- function C(t, e) {
85
+ const O = (t) => typeof t == "string" || typeof t == "number", nt = (t) => Array.isArray(t) ? t.every(O) : O(t);
86
+ function S(t, e) {
86
87
  if (typeof t == "function")
87
88
  return t(e);
88
89
  typeof t == "object" && t !== null && "current" in t && (t.current = e);
89
90
  }
90
- function H(...t) {
91
+ function N(...t) {
91
92
  const e = /* @__PURE__ */ new Map();
92
93
  return (r) => {
93
94
  if (r === null) {
94
95
  t.forEach((o) => {
95
96
  const s = e.get(o);
96
- typeof s == "function" && s(), C(o, null);
97
+ typeof s == "function" && s(), S(o, null);
97
98
  }), e.clear();
98
99
  return;
99
100
  }
100
101
  t.forEach((o) => {
101
- const s = C(o, r);
102
+ const s = S(o, r);
102
103
  typeof s == "function" && e.set(o, s);
103
104
  });
104
105
  };
105
106
  }
106
- function it(...t) {
107
- return I(() => H(...t), t);
107
+ function rt(...t) {
108
+ return I(() => N(...t), t);
108
109
  }
109
- const st = (t, e) => {
110
+ const ot = (t, e) => {
110
111
  let r = t;
111
112
  for (const o of e) {
112
113
  if (r == null)
@@ -114,7 +115,7 @@ const st = (t, e) => {
114
115
  r = r[o];
115
116
  }
116
117
  return r;
117
- }, ct = ({
118
+ }, it = ({
118
119
  currentStep: t,
119
120
  totalSteps: e,
120
121
  size: r,
@@ -122,11 +123,11 @@ const st = (t, e) => {
122
123
  strokeWidth: s = 4,
123
124
  arcPercentage: l = 0.75
124
125
  }) => {
125
- const i = Math.min(Math.max(t, 0), e), n = o ?? `${i}/${e}`, a = e <= 0 ? 0 : i / e, u = (r - s) / 2, f = r / 2, h = r / 2, d = 2 * Math.PI * u, g = d * l, b = g * (1 - a), p = i <= 0, D = `${g} ${d}`, P = p ? g - 2 : b;
126
+ const i = Math.min(Math.max(t, 0), e), n = o ?? `${i}/${e}`, u = e <= 0 ? 0 : i / e, a = (r - s) / 2, f = r / 2, h = r / 2, d = 2 * Math.PI * a, g = d * l, b = g * (1 - u), p = i <= 0, D = `${g} ${d}`, P = p ? g - 2 : b;
126
127
  return {
127
128
  displayLabel: n,
128
- progress: a,
129
- r: u,
129
+ progress: u,
130
+ r: a,
130
131
  cx: f,
131
132
  cy: h,
132
133
  circumference: d,
@@ -136,7 +137,7 @@ const st = (t, e) => {
136
137
  progressDashOffset: P,
137
138
  showMinimalDot: p
138
139
  };
139
- }, lt = (t) => I(
140
+ }, st = (t) => I(
140
141
  () => ({
141
142
  integerPart: Array.from(t.integerPart, (e) => ({
142
143
  value: e,
@@ -148,57 +149,57 @@ const st = (t, e) => {
148
149
  })) : []
149
150
  }),
150
151
  [t.integerPart, t.decimalPart]
151
- ), ut = (t, e, r) => {
152
+ ), ct = (t, e, r) => {
152
153
  if (e) return r;
153
154
  const o = t.decimalPart ? `${t.decimalSeparator}${t.decimalPart}` : "", s = `${t.integerPart}${o}`;
154
155
  return t.currencyPosition === "end" ? `${s} ${t.currencyText}` : `${t.currencyText} ${s}`;
155
156
  };
156
- function U(t, e, r = {}) {
157
+ function Z(t, e, r = {}) {
157
158
  const { leading: o = !1, trailing: s = !0, maxWait: l } = r;
158
- let i = null, n = null, a = null, u = 0, f = null, h = null, d;
159
+ let i = null, n = null, u = null, a = 0, f = null, h = null, d;
159
160
  const g = l !== void 0, b = g ? Math.max(l, e) : 0, p = (c) => {
160
- u = c;
161
- const m = f, x = h;
162
- return f = null, h = null, d = t.apply(x, m), d;
161
+ a = c;
162
+ const m = f, y = h;
163
+ return f = null, h = null, d = t.apply(y, m), d;
163
164
  }, D = (c) => {
164
- const m = a ? c - a : 0;
165
+ const m = u ? c - u : 0;
165
166
  return e - m;
166
167
  }, P = (c) => {
167
- const m = a ? c - a : e, x = c - u;
168
- return a === null || m >= e || m < 0 || g && x >= b;
169
- }, $ = (c) => (i = null, s && f ? p(c) : (f = null, h = null, d)), y = () => {
168
+ const m = u ? c - u : e, y = c - a;
169
+ return u === null || m >= e || m < 0 || g && y >= b;
170
+ }, $ = (c) => (i = null, s && f ? p(c) : (f = null, h = null, d)), x = () => {
170
171
  const c = Date.now();
171
172
  if (P(c)) {
172
173
  $(c);
173
174
  return;
174
175
  }
175
- i = setTimeout(y, D(c));
176
+ i = setTimeout(x, D(c));
176
177
  }, M = () => {
177
178
  const c = Date.now();
178
- n = null, f && (p(c), i !== null && (clearTimeout(i), i = setTimeout(y, e)));
179
- }, E = (c) => (u = c, i = setTimeout(y, e), g && (n = setTimeout(M, b)), o ? p(c) : d), v = () => {
180
- i !== null && clearTimeout(i), n !== null && clearTimeout(n), u = 0, f = null, h = null, a = null, i = null, n = null;
179
+ n = null, f && (p(c), i !== null && (clearTimeout(i), i = setTimeout(x, e)));
180
+ }, v = (c) => (a = c, i = setTimeout(x, e), g && (n = setTimeout(M, b)), o ? p(c) : d), E = () => {
181
+ i !== null && clearTimeout(i), n !== null && clearTimeout(n), a = 0, f = null, h = null, u = null, i = null, n = null;
181
182
  }, L = () => i === null && n === null ? d : $(Date.now()), j = () => i !== null || n !== null, T = function(...c) {
182
- const m = Date.now(), x = P(m);
183
- if (f = c, h = this, a = m, x) {
183
+ const m = Date.now(), y = P(m);
184
+ if (f = c, h = this, u = m, y) {
184
185
  if (i === null)
185
- return E(m);
186
+ return v(m);
186
187
  if (g)
187
- return clearTimeout(i), i = setTimeout(y, e), p(m);
188
+ return clearTimeout(i), i = setTimeout(x, e), p(m);
188
189
  }
189
- return i === null && (i = setTimeout(y, e)), d;
190
+ return i === null && (i = setTimeout(x, e)), d;
190
191
  };
191
- return T.cancel = v, T.flush = L, T.pending = j, T;
192
+ return T.cancel = E, T.flush = L, T.pending = j, T;
192
193
  }
193
- function at(t, e, r = {}) {
194
+ function lt(t, e, r = {}) {
194
195
  const { leading: o = !0, trailing: s = !0 } = r;
195
- return U(t, e, {
196
+ return Z(t, e, {
196
197
  leading: o,
197
198
  trailing: s,
198
199
  maxWait: e
199
200
  });
200
201
  }
201
- const ft = ({
202
+ const at = ({
202
203
  onClick: t,
203
204
  disabled: e
204
205
  }) => t ? e ? {
@@ -212,39 +213,39 @@ const ft = ({
212
213
  (o.key === "Enter" || o.key === " ") && (o.preventDefault(), t?.(o));
213
214
  },
214
215
  onClick: t
215
- } : void 0, S = " ", dt = ({
216
+ } : void 0, C = " ", ut = ({
216
217
  label: t,
217
218
  placeholder: e
218
219
  }) => {
219
220
  const r = typeof e == "string" && e.trim().length > 0 ? e : void 0;
220
221
  return t ? {
221
- inputPlaceholder: r ?? S,
222
+ inputPlaceholder: r ?? C,
222
223
  labelStaysFloatedWithPlaceholder: r !== void 0
223
224
  } : {
224
- inputPlaceholder: e ?? S,
225
+ inputPlaceholder: e ?? C,
225
226
  labelStaysFloatedWithPlaceholder: !1
226
227
  };
227
228
  };
228
229
  export {
229
- et as DisabledProvider,
230
- C as assignRef,
231
- ut as buildAriaLabel,
232
- rt as cn,
233
- K as createSafeContext,
234
- U as debounce,
230
+ X as DisabledProvider,
231
+ S as assignRef,
232
+ ct as buildAriaLabel,
233
+ et as cn,
234
+ z as createSafeContext,
235
+ Z as debounce,
235
236
  A as formatThousands,
236
- ft as getButtonA11yProps,
237
- Y as getFontSize,
238
- st as getObjectPath,
239
- ct as getStepperCalculations,
240
- ot as isTextChildren,
241
- H as mergeRefs,
242
- dt as resolveBaseInputPlaceholder,
243
- z as shallowEqual,
244
- tt as textFormatter,
245
- at as throttle,
246
- Q as toPascalCase,
247
- nt as useDisabledContext,
248
- it as useMergedRef,
249
- lt as useSplitText
237
+ at as getButtonA11yProps,
238
+ J as getFontSize,
239
+ ot as getObjectPath,
240
+ it as getStepperCalculations,
241
+ nt as isTextChildren,
242
+ N as mergeRefs,
243
+ ut as resolveBaseInputPlaceholder,
244
+ q as shallowEqual,
245
+ Q as textFormatter,
246
+ lt as throttle,
247
+ G as toPascalCase,
248
+ tt as useDisabledContext,
249
+ rt as useMergedRef,
250
+ st as useSplitText
250
251
  };
@@ -1,6 +1,24 @@
1
+ declare const FONT_SIZE_BY_SIZE: {
2
+ readonly md: {
3
+ readonly max: 48;
4
+ readonly min: 17;
5
+ readonly scale: 2;
6
+ readonly startAt: 0;
7
+ };
8
+ readonly sm: {
9
+ readonly max: 28;
10
+ readonly min: 12;
11
+ readonly scale: 2;
12
+ readonly startAt: 6;
13
+ };
14
+ };
15
+ export type AmountInputFontSizeSize = keyof typeof FONT_SIZE_BY_SIZE;
1
16
  /**
2
17
  * Calculates the font size based on the number of digits in the input value.
3
- * Scales from 48px (max) to 17px (min) as digit count increases.
18
+ * Scales from max to min as digit count increases.
19
+ * - md: 48px (heading-0-semi-bold) down to 17px, shrinks from the first digit
20
+ * - sm: 28px (heading-2-semi-bold) down to 12px, shrinks after 6 digits
4
21
  */
5
- export declare function getFontSize(value: string): number;
22
+ export declare function getFontSize(value: string, size?: AmountInputFontSizeSize): number;
23
+ export {};
6
24
  //# sourceMappingURL=fontSizeFormatter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fontSizeFormatter.d.ts","sourceRoot":"","sources":["../../../src/lib/inputFormatter/fontSizeFormatter.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOjD"}
1
+ {"version":3,"file":"fontSizeFormatter.d.ts","sourceRoot":"","sources":["../../../src/lib/inputFormatter/fontSizeFormatter.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;CAGb,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,iBAAiB,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,uBAA8B,GACnC,MAAM,CAKR"}
@@ -1,4 +1,4 @@
1
- export { getFontSize } from './fontSizeFormatter';
1
+ export { getFontSize, type AmountInputFontSizeSize } from './fontSizeFormatter';
2
2
  export { formatThousands } from './formatThousands';
3
3
  export { textFormatter } from './textFormatter';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/inputFormatter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/inputFormatter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/lumen-utils-shared",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -0,0 +1,46 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { getFontSize } from './fontSizeFormatter';
3
+
4
+ describe('getFontSize', () => {
5
+ describe('md (default)', () => {
6
+ it('returns 48px for empty value', () => {
7
+ expect(getFontSize('')).toBe(48);
8
+ });
9
+
10
+ it('returns 46px for single digit', () => {
11
+ expect(getFontSize('5')).toBe(46);
12
+ });
13
+
14
+ it('scales down as digit count increases', () => {
15
+ expect(getFontSize('12345')).toBe(38);
16
+ expect(getFontSize('123456789')).toBe(30);
17
+ });
18
+
19
+ it('does not go below 17px', () => {
20
+ expect(getFontSize('123456789012345678')).toBe(17);
21
+ });
22
+ });
23
+
24
+ describe('sm', () => {
25
+ it('returns 28px for empty value', () => {
26
+ expect(getFontSize('', 'sm')).toBe(28);
27
+ });
28
+
29
+ it('stays at 28px for up to 6 digits (scaling starts after startAt)', () => {
30
+ expect(getFontSize('5', 'sm')).toBe(28);
31
+ expect(getFontSize('123456', 'sm')).toBe(28);
32
+ });
33
+
34
+ it('scales down after 6 digits', () => {
35
+ // 7 digits: 28 - 1 * 2 = 26
36
+ expect(getFontSize('1234567', 'sm')).toBe(26);
37
+ // 10 digits: 28 - 4 * 2 = 20
38
+ expect(getFontSize('1234567890', 'sm')).toBe(20);
39
+ });
40
+
41
+ it('does not go below 12px', () => {
42
+ // 15 digits: 28 - 9 * 2 = 10 → clamped to 12
43
+ expect(getFontSize('123456789012345', 'sm')).toBe(12);
44
+ });
45
+ });
46
+ });
@@ -1,16 +1,22 @@
1
- const MAX_FONT_SIZE = 48;
2
- const MIN_FONT_SIZE = 17;
3
- const SCALE_FACTOR = 2;
1
+ const FONT_SIZE_BY_SIZE = {
2
+ md: { max: 48, min: 17, scale: 2, startAt: 0 },
3
+ sm: { max: 28, min: 12, scale: 2, startAt: 6 },
4
+ } as const;
5
+
6
+ export type AmountInputFontSizeSize = keyof typeof FONT_SIZE_BY_SIZE;
4
7
 
5
8
  /**
6
9
  * Calculates the font size based on the number of digits in the input value.
7
- * Scales from 48px (max) to 17px (min) as digit count increases.
10
+ * Scales from max to min as digit count increases.
11
+ * - md: 48px (heading-0-semi-bold) down to 17px, shrinks from the first digit
12
+ * - sm: 28px (heading-2-semi-bold) down to 12px, shrinks after 6 digits
8
13
  */
9
- export function getFontSize(value: string): number {
14
+ export function getFontSize(
15
+ value: string,
16
+ size: AmountInputFontSizeSize = 'md',
17
+ ): number {
18
+ const { max, min, scale, startAt } = FONT_SIZE_BY_SIZE[size];
10
19
  const digits = value.replace(/\D/g, '').length;
11
- const fontSize = Math.max(
12
- MIN_FONT_SIZE,
13
- MAX_FONT_SIZE - digits * SCALE_FACTOR,
14
- );
20
+ const fontSize = Math.max(min, max - Math.max(0, digits - startAt) * scale);
15
21
  return fontSize;
16
22
  }
@@ -1,3 +1,3 @@
1
- export { getFontSize } from './fontSizeFormatter';
1
+ export { getFontSize, type AmountInputFontSizeSize } from './fontSizeFormatter';
2
2
  export { formatThousands } from './formatThousands';
3
3
  export { textFormatter } from './textFormatter';
@@ -61,7 +61,12 @@ export function textFormatter(
61
61
  }
62
62
 
63
63
  const firstDot = cleaned.indexOf('.');
64
- if (firstDot !== -1) {
64
+ if (firstDot === -1) {
65
+ // No decimal point, just apply integer length limit
66
+ if (maxIntegerLength > 0 && cleaned.length > maxIntegerLength) {
67
+ cleaned = cleaned.slice(0, maxIntegerLength);
68
+ }
69
+ } else {
65
70
  // Split integer and decimal parts
66
71
  let integerPart = cleaned.slice(0, firstDot);
67
72
  let decimalPart = cleaned.slice(firstDot + 1).replace(/\./g, '');
@@ -84,11 +89,6 @@ export function textFormatter(
84
89
  : hasTrailingDot
85
90
  ? `${integerPart}.`
86
91
  : integerPart;
87
- } else {
88
- // No decimal point, just apply integer length limit
89
- if (maxIntegerLength > 0 && cleaned.length > maxIntegerLength) {
90
- cleaned = cleaned.slice(0, maxIntegerLength);
91
- }
92
92
  }
93
93
 
94
94
  return thousandsSeparator ? formatThousands(cleaned) : cleaned;