tyrell-components 1.0.0-TC52 → 1.0.0-TC53
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/css/tyrell-theme.css +25 -2
- package/css/tyrell.css +4 -0
- package/dist/tyrell-colors-static.css +1 -316
- package/dist/tyrell-theme.css +1 -1443
- package/dist/tyrell.css +1 -1390
- package/dist/tyrell.js +1 -1
- package/lib/base/ty-component.js +196 -196
- package/lib/components/button.d.ts +1 -1
- package/lib/components/button.js +260 -259
- package/lib/components/calendar-month.d.ts +2 -2
- package/lib/components/calendar-month.js +426 -416
- package/lib/components/calendar-navigation.js +238 -238
- package/lib/components/calendar.js +605 -602
- package/lib/components/checkbox.d.ts +1 -1
- package/lib/components/checkbox.js +273 -272
- package/lib/components/copy.d.ts +1 -1
- package/lib/components/copy.js +279 -278
- package/lib/components/date-picker.d.ts +1 -1
- package/lib/components/date-picker.js +1103 -1108
- package/lib/components/file-upload.js +404 -404
- package/lib/components/icon.js +141 -141
- package/lib/components/input.d.ts +1 -1
- package/lib/components/input.js +593 -596
- package/lib/components/modal.js +319 -319
- package/lib/components/option.js +167 -167
- package/lib/components/popup.js +233 -233
- package/lib/components/radio.d.ts +2 -2
- package/lib/components/radio.js +407 -406
- package/lib/components/resize-observer.js +67 -67
- package/lib/components/scroll-container.js +294 -294
- package/lib/components/select.d.ts +1 -1
- package/lib/components/select.js +1524 -1532
- package/lib/components/selected-tags.js +184 -184
- package/lib/components/step.js +62 -62
- package/lib/components/switch.d.ts +1 -1
- package/lib/components/switch.js +214 -213
- package/lib/components/tab.js +62 -62
- package/lib/components/tabs.js +507 -507
- package/lib/components/tag.d.ts +1 -1
- package/lib/components/tag.js +236 -235
- package/lib/components/textarea.d.ts +1 -1
- package/lib/components/textarea.js +457 -456
- package/lib/components/tooltip.js +283 -283
- package/lib/components/wizard.js +384 -384
- package/lib/icons/heroicons/micro.js +392 -392
- package/lib/icons/heroicons/mini.js +382 -382
- package/lib/icons/heroicons/outline.js +337 -337
- package/lib/icons/heroicons/solid.js +407 -407
- package/lib/icons/lucide.js +22843 -22843
- package/lib/icons/material/filled.js +9653 -9653
- package/lib/icons/material/outlined.js +10271 -10271
- package/lib/icons/material/round.js +10495 -10495
- package/lib/icons/material/sharp.js +9905 -9905
- package/lib/icons/material/two-tone.js +12792 -12792
- package/lib/index.js +21 -21
- package/lib/styles/button.js +176 -288
- package/lib/styles/calendar-month.js +123 -183
- package/lib/styles/calendar-navigation.js +60 -79
- package/lib/styles/calendar.js +8 -9
- package/lib/styles/checkbox.js +45 -72
- package/lib/styles/copy.js +67 -91
- package/lib/styles/custom-scrollbar.js +80 -100
- package/lib/styles/date-picker.js +261 -331
- package/lib/styles/field-size.d.ts +6 -0
- package/lib/styles/field-size.js +91 -0
- package/lib/styles/file-upload.js +139 -169
- package/lib/styles/icon.js +92 -156
- package/lib/styles/input.js +125 -241
- package/lib/styles/modal.js +67 -102
- package/lib/styles/option.d.ts +1 -1
- package/lib/styles/option.js +47 -67
- package/lib/styles/popup.js +34 -65
- package/lib/styles/radio.js +69 -96
- package/lib/styles/resize-observer.js +2 -5
- package/lib/styles/scroll-container.js +100 -130
- package/lib/styles/select-base.js +525 -778
- package/lib/styles/select.js +140 -228
- package/lib/styles/step.js +22 -29
- package/lib/styles/switch.js +34 -55
- package/lib/styles/tab.js +22 -29
- package/lib/styles/tabs.js +171 -252
- package/lib/styles/tag.js +135 -188
- package/lib/styles/textarea.d.ts +1 -1
- package/lib/styles/textarea.js +205 -271
- package/lib/styles/tooltip.js +3 -3
- package/lib/styles/wizard.js +170 -226
- package/lib/types/common.d.ts +2 -0
- package/lib/types/common.js +6 -5
- package/lib/utils/calendar-utils.js +100 -100
- package/lib/utils/custom-scrollbar.js +272 -272
- package/lib/utils/flavor-sheet.js +14 -14
- package/lib/utils/icon-registry.js +127 -127
- package/lib/utils/loader-registry.js +3 -3
- package/lib/utils/locale.js +34 -34
- package/lib/utils/mobile.js +1 -1
- package/lib/utils/number-format.js +54 -54
- package/lib/utils/positioning.js +212 -212
- package/lib/utils/property-capture.js +36 -36
- package/lib/utils/property-manager.js +125 -125
- package/lib/utils/resize-observer.js +23 -23
- package/lib/utils/scroll-lock.js +57 -57
- package/lib/utils/styles.js +17 -17
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +4 -4
|
@@ -9,155 +9,155 @@ const CACHE_URL_BASE = 'https://ty-icons.local/';
|
|
|
9
9
|
const cacheReadPromises = new Map();
|
|
10
10
|
let oldCachesCleared = false;
|
|
11
11
|
async function clearOldCaches() {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
12
|
+
if (oldCachesCleared || !('caches' in window))
|
|
13
|
+
return;
|
|
14
|
+
oldCachesCleared = true;
|
|
15
|
+
try {
|
|
16
|
+
const cacheNames = await caches.keys();
|
|
17
|
+
const oldCaches = cacheNames.filter(name => name.startsWith('ty-icons-v') && name !== CACHE_NAME);
|
|
18
|
+
await Promise.all(oldCaches.map(name => caches.delete(name)));
|
|
19
|
+
if (oldCaches.length > 0) {
|
|
20
|
+
console.log(`🗑️ Cleared ${oldCaches.length} old icon cache(s)`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
console.warn('[ty-icons] Failed to clear old caches:', err);
|
|
25
|
+
}
|
|
26
26
|
}
|
|
27
27
|
async function cacheIcon(name, svg) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
if (!('caches' in window))
|
|
29
|
+
return;
|
|
30
|
+
try {
|
|
31
|
+
const cache = await caches.open(CACHE_NAME);
|
|
32
|
+
const response = new Response(svg, {
|
|
33
|
+
headers: { 'Content-Type': 'image/svg+xml' }
|
|
34
|
+
});
|
|
35
|
+
await cache.put(`${CACHE_URL_BASE}${name}`, response);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.warn(`[ty-icons] Failed to cache icon "${name}":`, err);
|
|
39
|
+
}
|
|
40
40
|
}
|
|
41
41
|
export async function getCachedIcon(name) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
42
|
+
const existingPromise = cacheReadPromises.get(name);
|
|
43
|
+
if (existingPromise) {
|
|
44
|
+
return existingPromise;
|
|
45
|
+
}
|
|
46
|
+
const readPromise = (async () => {
|
|
47
|
+
try {
|
|
48
|
+
await clearOldCaches();
|
|
49
|
+
const cache = await caches.open(CACHE_NAME);
|
|
50
|
+
const response = await cache.match(`${CACHE_URL_BASE}${name}`);
|
|
51
|
+
if (response) {
|
|
52
|
+
return await response.text();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
console.warn(`[ty-icons] Failed to read icon "${name}" from cache:`, err);
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
})();
|
|
60
|
+
cacheReadPromises.set(name, readPromise);
|
|
61
|
+
readPromise.finally(() => {
|
|
62
|
+
cacheReadPromises.delete(name);
|
|
63
|
+
});
|
|
64
|
+
return readPromise;
|
|
65
65
|
}
|
|
66
66
|
export function registerIcons(icons) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
67
|
+
const changedIcons = new Set();
|
|
68
|
+
Object.entries(icons).forEach(([name, svg]) => {
|
|
69
|
+
iconRegistry.set(name, svg);
|
|
70
|
+
changedIcons.add(name);
|
|
71
|
+
});
|
|
72
|
+
if (changedIcons.size > 0) {
|
|
73
|
+
scheduleNotification(changedIcons);
|
|
74
|
+
}
|
|
75
75
|
}
|
|
76
76
|
export function getIcon(name) {
|
|
77
|
-
|
|
77
|
+
return iconRegistry.get(name);
|
|
78
78
|
}
|
|
79
79
|
export function hasIcon(name) {
|
|
80
|
-
|
|
80
|
+
return iconRegistry.has(name);
|
|
81
81
|
}
|
|
82
82
|
export async function clearIcons() {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
83
|
+
const allIcons = new Set(iconRegistry.keys());
|
|
84
|
+
iconRegistry.clear();
|
|
85
|
+
if ('caches' in window) {
|
|
86
|
+
try {
|
|
87
|
+
await caches.delete(CACHE_NAME);
|
|
88
|
+
oldCachesCleared = false;
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
console.warn('[ty-icons] Failed to clear icon cache:', err);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
scheduleNotification(allIcons);
|
|
95
95
|
}
|
|
96
96
|
export function addWatcher(id, iconName, callback) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
watchers.set(id, callback);
|
|
98
|
+
if (iconName) {
|
|
99
|
+
watcherIconNames.set(id, iconName);
|
|
100
|
+
}
|
|
101
101
|
}
|
|
102
102
|
export function removeWatcher(id) {
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
watchers.delete(id);
|
|
104
|
+
watcherIconNames.delete(id);
|
|
105
105
|
}
|
|
106
106
|
function scheduleNotification(changedIcons) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
107
|
+
if (!pendingNotifications) {
|
|
108
|
+
pendingNotifications = new Set();
|
|
109
|
+
}
|
|
110
|
+
changedIcons.forEach(name => pendingNotifications.add(name));
|
|
111
|
+
if (notificationTimer !== null) {
|
|
112
|
+
clearTimeout(notificationTimer);
|
|
113
|
+
}
|
|
114
|
+
const scheduleCallback = typeof requestIdleCallback !== 'undefined'
|
|
115
|
+
? requestIdleCallback
|
|
116
|
+
: (cb) => setTimeout(cb, 0);
|
|
117
|
+
notificationTimer = scheduleCallback(() => {
|
|
118
|
+
const toNotify = pendingNotifications;
|
|
119
|
+
pendingNotifications = null;
|
|
120
|
+
notificationTimer = null;
|
|
121
|
+
if (toNotify && toNotify.size > 0) {
|
|
122
|
+
notifyWatchers(toNotify);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
125
|
}
|
|
126
126
|
function notifyWatchers(changedIcons) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
127
|
+
watchers.forEach((callback, watcherId) => {
|
|
128
|
+
const watchedIcon = watcherIconNames.get(watcherId);
|
|
129
|
+
if (watchedIcon) {
|
|
130
|
+
if (changedIcons.has(watchedIcon)) {
|
|
131
|
+
callback(new Set([watchedIcon]));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
callback(changedIcons);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
138
|
}
|
|
139
139
|
export function getIconNames() {
|
|
140
|
-
|
|
140
|
+
return Array.from(iconRegistry.keys());
|
|
141
141
|
}
|
|
142
142
|
export async function getCacheInfo() {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
143
|
+
const info = {
|
|
144
|
+
version: VERSION,
|
|
145
|
+
cacheName: CACHE_NAME,
|
|
146
|
+
available: 'caches' in window
|
|
147
|
+
};
|
|
148
|
+
if (!info.available)
|
|
149
|
+
return info;
|
|
150
|
+
try {
|
|
151
|
+
const cache = await caches.open(CACHE_NAME);
|
|
152
|
+
const keys = await cache.keys();
|
|
153
|
+
const iconKeys = keys.filter(req => req.url.startsWith(CACHE_URL_BASE));
|
|
154
|
+
return {
|
|
155
|
+
...info,
|
|
156
|
+
iconCount: iconKeys.length
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
console.warn('[ty-icons] Failed to get cache info:', err);
|
|
161
|
+
return info;
|
|
162
|
+
}
|
|
163
163
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const DEFAULT_LOADER_SVG = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="3" stroke-opacity="0.25"/><path d="M22 12a10 10 0 0 1-10 10" stroke="currentColor" stroke-width="3" stroke-linecap="round"/></svg>`;
|
|
2
2
|
let customLoaderSvg = null;
|
|
3
3
|
export function setLoaderSvg(svg) {
|
|
4
|
-
|
|
4
|
+
customLoaderSvg = svg && svg.trim() ? svg : null;
|
|
5
5
|
}
|
|
6
6
|
export function getLoaderSvg() {
|
|
7
|
-
|
|
7
|
+
return customLoaderSvg ?? DEFAULT_LOADER_SVG;
|
|
8
8
|
}
|
|
9
9
|
export function resetLoaderSvg() {
|
|
10
|
-
|
|
10
|
+
customLoaderSvg = null;
|
|
11
11
|
}
|
package/lib/utils/locale.js
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
export function getEffectiveLocale(element, explicitLocale) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
if (explicitLocale) {
|
|
3
|
+
return explicitLocale;
|
|
4
|
+
}
|
|
5
|
+
const langElement = element.closest('[lang]');
|
|
6
|
+
if (langElement) {
|
|
7
|
+
const lang = langElement.getAttribute('lang');
|
|
8
|
+
if (lang)
|
|
9
|
+
return lang;
|
|
10
|
+
}
|
|
11
|
+
if (document.documentElement.lang) {
|
|
12
|
+
return document.documentElement.lang;
|
|
13
|
+
}
|
|
14
|
+
if (navigator.language) {
|
|
15
|
+
return navigator.language;
|
|
16
|
+
}
|
|
17
|
+
return 'en-US';
|
|
18
18
|
}
|
|
19
19
|
export function observeLocaleChanges(element, callback) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
20
|
+
let currentLocale = getEffectiveLocale(element);
|
|
21
|
+
const observer = new MutationObserver((mutations) => {
|
|
22
|
+
for (const mutation of mutations) {
|
|
23
|
+
if (mutation.type === 'attributes' && mutation.attributeName === 'lang') {
|
|
24
|
+
const newLocale = getEffectiveLocale(element);
|
|
25
|
+
if (newLocale !== currentLocale) {
|
|
26
|
+
currentLocale = newLocale;
|
|
27
|
+
callback(newLocale);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
observer.observe(document.documentElement, {
|
|
33
|
+
attributes: true,
|
|
34
|
+
attributeFilter: ['lang'],
|
|
35
|
+
subtree: true
|
|
36
|
+
});
|
|
37
|
+
return () => observer.disconnect();
|
|
38
38
|
}
|
package/lib/utils/mobile.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
const MOBILE_BREAKPOINT = 768;
|
|
2
2
|
export function isMobileTouch(breakpoint = MOBILE_BREAKPOINT) {
|
|
3
|
-
|
|
3
|
+
return window.matchMedia(`(pointer: coarse) and (max-width: ${breakpoint}px)`).matches;
|
|
4
4
|
}
|
|
@@ -1,60 +1,60 @@
|
|
|
1
1
|
export function formatNumber(value, config) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
2
|
+
const { type, locale = 'en-US', currency = 'USD', precision } = config;
|
|
3
|
+
const options = {};
|
|
4
|
+
if (precision !== undefined) {
|
|
5
|
+
options.minimumFractionDigits = precision;
|
|
6
|
+
options.maximumFractionDigits = precision;
|
|
7
|
+
}
|
|
8
|
+
switch (type) {
|
|
9
|
+
case 'currency':
|
|
10
|
+
options.style = 'currency';
|
|
11
|
+
options.currency = currency;
|
|
12
|
+
break;
|
|
13
|
+
case 'percent':
|
|
14
|
+
options.style = 'percent';
|
|
15
|
+
break;
|
|
16
|
+
case 'compact':
|
|
17
|
+
options.notation = 'compact';
|
|
18
|
+
options.compactDisplay = 'short';
|
|
19
|
+
break;
|
|
20
|
+
case 'number':
|
|
21
|
+
default:
|
|
22
|
+
options.style = 'decimal';
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
const formatter = new Intl.NumberFormat(locale, options);
|
|
26
|
+
const formatted = formatter.format(value);
|
|
27
|
+
return formatted
|
|
28
|
+
.replace(/\u202F/g, '\u00A0')
|
|
29
|
+
.replace(/\u2009/g, '\u00A0');
|
|
30
30
|
}
|
|
31
31
|
export function parseNumericValue(value) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
32
|
+
if (!value || value.trim() === '')
|
|
33
|
+
return null;
|
|
34
|
+
let stripped = value
|
|
35
|
+
.replace(/[^\d.,-]/g, '')
|
|
36
|
+
.trim();
|
|
37
|
+
if (stripped === '' || stripped === '-')
|
|
38
|
+
return null;
|
|
39
|
+
const lastComma = stripped.lastIndexOf(',');
|
|
40
|
+
const lastDot = stripped.lastIndexOf('.');
|
|
41
|
+
const lastSep = Math.max(lastComma, lastDot);
|
|
42
|
+
if (lastSep === -1) {
|
|
43
|
+
const parsed = parseFloat(stripped);
|
|
44
|
+
return isNaN(parsed) ? null : parsed;
|
|
45
|
+
}
|
|
46
|
+
const sepChar = stripped[lastSep];
|
|
47
|
+
const before = stripped.slice(0, lastSep);
|
|
48
|
+
const after = stripped.slice(lastSep + 1);
|
|
49
|
+
if (before.includes(sepChar)) {
|
|
50
|
+
const parsed = parseFloat(stripped.replace(/[.,]/g, ''));
|
|
51
|
+
return isNaN(parsed) ? null : parsed;
|
|
52
|
+
}
|
|
53
|
+
const intPart = before.replace(/[.,]/g, '');
|
|
54
|
+
const decPart = after;
|
|
55
|
+
const parsed = parseFloat(intPart + '.' + decPart);
|
|
56
|
+
return isNaN(parsed) ? null : parsed;
|
|
57
57
|
}
|
|
58
58
|
export function shouldFormat(type) {
|
|
59
|
-
|
|
59
|
+
return ['number', 'currency', 'percent', 'compact'].includes(type);
|
|
60
60
|
}
|