@newtonedev/components 0.1.9 → 0.1.11
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/composites/range-inputs/HueSlider/HueSlider.d.ts.map +1 -1
- package/dist/composites/range-inputs/Slider/Slider.d.ts.map +1 -1
- package/dist/fonts/measureFont.d.ts +2 -1
- package/dist/fonts/measureFont.d.ts.map +1 -1
- package/dist/index.cjs +26 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +26 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.tsx +5 -5
- package/src/composites/range-inputs/HueSlider/HueSlider.tsx +5 -2
- package/src/composites/range-inputs/Slider/Slider.tsx +5 -2
- package/src/fonts/measureFont.ts +15 -2
package/package.json
CHANGED
|
@@ -38,6 +38,7 @@ export function ColorScaleSlider({
|
|
|
38
38
|
const trackPageX = React.useRef(0);
|
|
39
39
|
const isDragging = React.useRef(false);
|
|
40
40
|
const thumbAnim = React.useRef(new Animated.Value(0)).current;
|
|
41
|
+
const [layoutWidth, setLayoutWidth] = React.useState(0);
|
|
41
42
|
|
|
42
43
|
// Mutable refs to avoid stale closures in PanResponder
|
|
43
44
|
const onValueChangeRef = React.useRef(onValueChange);
|
|
@@ -104,7 +105,7 @@ export function ColorScaleSlider({
|
|
|
104
105
|
? Math.min(maxNV, Math.max(minNV, value))
|
|
105
106
|
: (maxNV + minNV) / 2;
|
|
106
107
|
const ratio = range > 0 ? (maxNV - clampedValue) / range : 0.5;
|
|
107
|
-
const usableWidth = Math.max(0,
|
|
108
|
+
const usableWidth = Math.max(0, layoutWidth - THUMB_SIZE);
|
|
108
109
|
const thumbLeft = ratio * usableWidth;
|
|
109
110
|
|
|
110
111
|
// Sync animated thumb position: animate on prop-driven changes, instant during drag
|
|
@@ -131,10 +132,9 @@ export function ColorScaleSlider({
|
|
|
131
132
|
ref={trackRef}
|
|
132
133
|
style={styles.trackContainer}
|
|
133
134
|
onLayout={(e) => {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
thumbAnim.setValue(ratio * newUsableWidth);
|
|
135
|
+
const w = e.nativeEvent.layout.width;
|
|
136
|
+
trackWidth.current = w;
|
|
137
|
+
setLayoutWidth(w);
|
|
138
138
|
trackRef.current?.measure((_x, _y, _w, _h, pageX) => {
|
|
139
139
|
if (pageX != null) trackPageX.current = pageX;
|
|
140
140
|
});
|
|
@@ -44,6 +44,7 @@ export function HueSlider({
|
|
|
44
44
|
const trackRef = React.useRef<View>(null);
|
|
45
45
|
const trackWidth = React.useRef(0);
|
|
46
46
|
const trackPageX = React.useRef(0);
|
|
47
|
+
const [layoutWidth, setLayoutWidth] = React.useState(0);
|
|
47
48
|
|
|
48
49
|
// Mutable refs to avoid stale closures in PanResponder
|
|
49
50
|
const onValueChangeRef = React.useRef(onValueChange);
|
|
@@ -80,7 +81,7 @@ export function HueSlider({
|
|
|
80
81
|
// For wrapping ranges (max > 359), convert stored value to slider range
|
|
81
82
|
const sliderValue = max > 359 && value < min ? value + 360 : value;
|
|
82
83
|
const ratio = max > min ? (sliderValue - min) / (max - min) : 0;
|
|
83
|
-
const usableWidth = Math.max(0,
|
|
84
|
+
const usableWidth = Math.max(0, layoutWidth - THUMB_SIZE);
|
|
84
85
|
const thumbLeft = ratio * usableWidth;
|
|
85
86
|
|
|
86
87
|
const handleValueTextSubmit = React.useCallback(
|
|
@@ -123,7 +124,9 @@ export function HueSlider({
|
|
|
123
124
|
ref={trackRef}
|
|
124
125
|
style={styles.trackContainer}
|
|
125
126
|
onLayout={(e) => {
|
|
126
|
-
|
|
127
|
+
const w = e.nativeEvent.layout.width;
|
|
128
|
+
trackWidth.current = w;
|
|
129
|
+
setLayoutWidth(w);
|
|
127
130
|
trackRef.current?.measure((_x, _y, _w, _h, pageX) => {
|
|
128
131
|
if (pageX != null) trackPageX.current = pageX;
|
|
129
132
|
});
|
|
@@ -26,6 +26,7 @@ export function Slider({
|
|
|
26
26
|
const trackRef = React.useRef<View>(null);
|
|
27
27
|
const trackWidth = React.useRef(0);
|
|
28
28
|
const trackPageX = React.useRef(0);
|
|
29
|
+
const [layoutWidth, setLayoutWidth] = React.useState(0);
|
|
29
30
|
|
|
30
31
|
// Mutable refs to avoid stale closures in PanResponder
|
|
31
32
|
const onValueChangeRef = React.useRef(onValueChange);
|
|
@@ -62,7 +63,7 @@ export function Slider({
|
|
|
62
63
|
).current;
|
|
63
64
|
|
|
64
65
|
const ratio = max > min ? (value - min) / (max - min) : 0;
|
|
65
|
-
const usableWidth = Math.max(0,
|
|
66
|
+
const usableWidth = Math.max(0, layoutWidth - THUMB_SIZE);
|
|
66
67
|
const thumbLeft = ratio * usableWidth;
|
|
67
68
|
const fillWidth = thumbLeft + THUMB_SIZE / 2;
|
|
68
69
|
|
|
@@ -106,7 +107,9 @@ export function Slider({
|
|
|
106
107
|
ref={trackRef}
|
|
107
108
|
style={styles.trackContainer}
|
|
108
109
|
onLayout={(e) => {
|
|
109
|
-
|
|
110
|
+
const w = e.nativeEvent.layout.width;
|
|
111
|
+
trackWidth.current = w;
|
|
112
|
+
setLayoutWidth(w);
|
|
110
113
|
trackRef.current?.measure((_x, _y, _w, _h, pageX) => {
|
|
111
114
|
if (pageX != null) trackPageX.current = pageX;
|
|
112
115
|
});
|
package/src/fonts/measureFont.ts
CHANGED
|
@@ -5,10 +5,19 @@
|
|
|
5
5
|
const REF_STRING =
|
|
6
6
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ';
|
|
7
7
|
|
|
8
|
+
/** Race a promise against a timeout. Resolves with fallback if the promise doesn't settle in time. */
|
|
9
|
+
function withTimeout<T>(promise: Promise<T>, ms: number, fallback: T): Promise<T> {
|
|
10
|
+
return Promise.race([
|
|
11
|
+
promise,
|
|
12
|
+
new Promise<T>((resolve) => setTimeout(() => resolve(fallback), ms)),
|
|
13
|
+
]);
|
|
14
|
+
}
|
|
15
|
+
|
|
8
16
|
/**
|
|
9
17
|
* Measure the average character width ratio for a font using the Canvas API.
|
|
10
18
|
*
|
|
11
|
-
* Waits for the font to load via `document.fonts.load()` before measuring
|
|
19
|
+
* Waits for the font to load via `document.fonts.load()` before measuring,
|
|
20
|
+
* with a 3-second timeout to prevent hangs when fonts fail to load silently.
|
|
12
21
|
* Falls back to 0.55 if the browser context is unavailable, the font fails
|
|
13
22
|
* to load, or canvas is not supported.
|
|
14
23
|
*
|
|
@@ -29,7 +38,11 @@ export async function measureAvgCharWidth(
|
|
|
29
38
|
): Promise<number> {
|
|
30
39
|
if (typeof document === 'undefined') return 0.55;
|
|
31
40
|
try {
|
|
32
|
-
await
|
|
41
|
+
await withTimeout(
|
|
42
|
+
document.fonts.load(`${fontWeight} ${fontSize}px "${fontFamily}"`),
|
|
43
|
+
3000,
|
|
44
|
+
[] as FontFace[],
|
|
45
|
+
);
|
|
33
46
|
const canvas = document.createElement('canvas');
|
|
34
47
|
const ctx = canvas.getContext('2d');
|
|
35
48
|
if (!ctx) return 0.55;
|