@rolster/react-components 19.8.19 → 19.8.20
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/cjs/index.cjs +166 -34
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/es/index.mjs +167 -35
- package/dist/es/index.mjs.map +1 -1
- package/dist/esm/components/molecules/Slider/Slider.d.ts +2 -1
- package/dist/esm/components/molecules/Slider/Slider.js +125 -35
- package/dist/esm/components/molecules/Slider/Slider.js.map +1 -1
- package/dist/esm/components/organisms/ImageEditor/ImageEditor.js +8 -2
- package/dist/esm/components/organisms/ImageEditor/ImageEditor.js.map +1 -1
- package/dist/esm/helpers/slider.d.ts +4 -0
- package/dist/esm/helpers/slider.js +37 -0
- package/dist/esm/helpers/slider.js.map +1 -0
- package/dist/esm/helpers/slider.spec.d.ts +1 -0
- package/dist/esm/helpers/slider.spec.js +90 -0
- package/dist/esm/helpers/slider.spec.js.map +1 -0
- package/package.json +6 -7
package/dist/es/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import require$$0, { memo, useMemo, useState, useRef, useCallback, useEffect, useInsertionEffect, createContext, useContext } from 'react';
|
|
1
|
+
import require$$0, { memo, useMemo, useState, useRef, useCallback, useEffect, useInsertionEffect, useId, createContext, useContext } from 'react';
|
|
2
2
|
import { currencyFormat, BigDecimal, valueIsDefined, SealedPartial } from '@rolster/commons';
|
|
3
3
|
import { i18n, i18nSubscribe } from '@rolster/i18n';
|
|
4
4
|
import ReactDOM, { createPortal } from 'react-dom';
|
|
@@ -2374,57 +2374,183 @@ function RlsPickerYearComponent({ date, disabled, formControl, maxDate, minDate,
|
|
|
2374
2374
|
}
|
|
2375
2375
|
const RlsPickerYear = memo(RlsPickerYearComponent);
|
|
2376
2376
|
|
|
2377
|
-
|
|
2378
|
-
|
|
2377
|
+
const RATE_MIN = 0;
|
|
2378
|
+
const RATE_MAX = 100;
|
|
2379
|
+
const PRECISION = 12;
|
|
2380
|
+
function clampNumber(value, minValue, maxValue) {
|
|
2381
|
+
if (minValue > maxValue) {
|
|
2382
|
+
return minValue;
|
|
2383
|
+
}
|
|
2384
|
+
return Math.min(Math.max(value, minValue), maxValue);
|
|
2385
|
+
}
|
|
2386
|
+
function normalizeSliderValue(value, minValue, maxValue, step) {
|
|
2387
|
+
const valueClamped = clampNumber(value, minValue, maxValue);
|
|
2388
|
+
if (!step || step <= 0) {
|
|
2389
|
+
return valueClamped;
|
|
2390
|
+
}
|
|
2391
|
+
if (valueClamped <= minValue) {
|
|
2392
|
+
return minValue;
|
|
2393
|
+
}
|
|
2394
|
+
if (valueClamped >= maxValue) {
|
|
2395
|
+
return maxValue;
|
|
2396
|
+
}
|
|
2397
|
+
const steps = Math.round((valueClamped - minValue) / step);
|
|
2398
|
+
const valueStepped = parseFloat((minValue + steps * step).toPrecision(PRECISION));
|
|
2399
|
+
return clampNumber(valueStepped, minValue, maxValue);
|
|
2400
|
+
}
|
|
2401
|
+
function sliderValueToRate(value, minValue, maxValue) {
|
|
2402
|
+
const range = maxValue - minValue;
|
|
2403
|
+
if (range <= 0) {
|
|
2404
|
+
return RATE_MIN;
|
|
2405
|
+
}
|
|
2406
|
+
return clampNumber(((value - minValue) / range) * RATE_MAX, RATE_MIN, RATE_MAX);
|
|
2379
2407
|
}
|
|
2380
|
-
function
|
|
2381
|
-
const
|
|
2382
|
-
const
|
|
2383
|
-
return
|
|
2408
|
+
function sliderRateToValue(rate, minValue, maxValue, step) {
|
|
2409
|
+
const range = maxValue - minValue;
|
|
2410
|
+
const rateClamped = clampNumber(rate, RATE_MIN, RATE_MAX);
|
|
2411
|
+
return normalizeSliderValue(minValue + (range * rateClamped) / RATE_MAX, minValue, maxValue, step);
|
|
2384
2412
|
}
|
|
2385
|
-
|
|
2413
|
+
|
|
2414
|
+
const DEFAULT_STEP = 1;
|
|
2415
|
+
const PAGE_STEP_DIVISOR = 10;
|
|
2416
|
+
function RlsSliderComponent({ children, className, disabled, formControl, identifier, maxValue, minValue, onValue, prefixIcon, rlsTheme, step, value }) {
|
|
2386
2417
|
const minValueSlider = useMemo(() => {
|
|
2387
2418
|
return minValue ?? 0;
|
|
2388
2419
|
}, [minValue]);
|
|
2389
2420
|
const maxValueSlider = useMemo(() => {
|
|
2390
2421
|
return maxValue ?? 100;
|
|
2391
2422
|
}, [maxValue]);
|
|
2392
|
-
const
|
|
2393
|
-
|
|
2394
|
-
|
|
2423
|
+
const stepSlider = useMemo(() => {
|
|
2424
|
+
return step && step > 0 ? step : DEFAULT_STEP;
|
|
2425
|
+
}, [step]);
|
|
2426
|
+
const [valueSlider, setValueSlider] = useState(() => {
|
|
2427
|
+
return normalizeSliderValue(formControl?.value ?? value ?? 0, minValueSlider, maxValueSlider, stepSlider);
|
|
2428
|
+
});
|
|
2429
|
+
const [dragging, setDragging] = useState(false);
|
|
2395
2430
|
const refTrack = useRef(null);
|
|
2396
|
-
const refTrackOn = useRef(null);
|
|
2397
2431
|
const refThumb = useRef(null);
|
|
2432
|
+
const refValue = useRef(valueSlider);
|
|
2433
|
+
const refValueExternal = useRef(formControl?.value ?? value);
|
|
2434
|
+
const labelId = useId();
|
|
2435
|
+
const rate = useMemo(() => {
|
|
2436
|
+
return sliderValueToRate(valueSlider, minValueSlider, maxValueSlider);
|
|
2437
|
+
}, [valueSlider, minValueSlider, maxValueSlider]);
|
|
2398
2438
|
const classNameSlider = renderClassStatus('rls-slider', {
|
|
2399
2439
|
complet: valueSlider === maxValueSlider,
|
|
2400
2440
|
disabled: disabled,
|
|
2441
|
+
dragging: dragging,
|
|
2401
2442
|
empty: valueSlider === minValueSlider
|
|
2402
2443
|
}, className);
|
|
2444
|
+
const commitValue = useCallback((valueNext) => {
|
|
2445
|
+
if (refValue.current === valueNext) {
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2448
|
+
refValue.current = valueNext;
|
|
2449
|
+
setValueSlider(valueNext);
|
|
2450
|
+
formControl?.setValue(valueNext);
|
|
2451
|
+
onValue?.(valueNext);
|
|
2452
|
+
}, [formControl, onValue]);
|
|
2453
|
+
const commitRate = useCallback((rateNext) => {
|
|
2454
|
+
commitValue(sliderRateToValue(rateNext, minValueSlider, maxValueSlider, stepSlider));
|
|
2455
|
+
}, [commitValue, minValueSlider, maxValueSlider, stepSlider]);
|
|
2456
|
+
const calculateRateFromClientX = useCallback((clientX) => {
|
|
2457
|
+
const { left, width } = refTrack.current.getBoundingClientRect();
|
|
2458
|
+
return width > 0 ? ((clientX - left) / width) * 100 : 0;
|
|
2459
|
+
}, []);
|
|
2460
|
+
const onPointerDown = useCallback((event) => {
|
|
2461
|
+
if (disabled) {
|
|
2462
|
+
return;
|
|
2463
|
+
}
|
|
2464
|
+
event.preventDefault();
|
|
2465
|
+
refThumb.current.focus();
|
|
2466
|
+
setDragging(true);
|
|
2467
|
+
commitRate(calculateRateFromClientX(event.clientX));
|
|
2468
|
+
}, [disabled, commitRate, calculateRateFromClientX]);
|
|
2469
|
+
const calculateValueFromKey = useCallback((key) => {
|
|
2470
|
+
const pageStep = Math.max(stepSlider, (maxValueSlider - minValueSlider) / PAGE_STEP_DIVISOR);
|
|
2471
|
+
switch (key) {
|
|
2472
|
+
case 'ArrowRight':
|
|
2473
|
+
case 'ArrowUp':
|
|
2474
|
+
return refValue.current + stepSlider;
|
|
2475
|
+
case 'ArrowLeft':
|
|
2476
|
+
case 'ArrowDown':
|
|
2477
|
+
return refValue.current - stepSlider;
|
|
2478
|
+
case 'PageUp':
|
|
2479
|
+
return refValue.current + pageStep;
|
|
2480
|
+
case 'PageDown':
|
|
2481
|
+
return refValue.current - pageStep;
|
|
2482
|
+
case 'Home':
|
|
2483
|
+
return minValueSlider;
|
|
2484
|
+
case 'End':
|
|
2485
|
+
return maxValueSlider;
|
|
2486
|
+
default:
|
|
2487
|
+
return undefined;
|
|
2488
|
+
}
|
|
2489
|
+
}, [stepSlider, minValueSlider, maxValueSlider]);
|
|
2490
|
+
const onKeyDown = useCallback((event) => {
|
|
2491
|
+
if (disabled) {
|
|
2492
|
+
return;
|
|
2493
|
+
}
|
|
2494
|
+
const valueNext = calculateValueFromKey(event.key);
|
|
2495
|
+
if (valueNext === undefined) {
|
|
2496
|
+
return;
|
|
2497
|
+
}
|
|
2498
|
+
event.preventDefault();
|
|
2499
|
+
commitValue(normalizeSliderValue(valueNext, minValueSlider, maxValueSlider, stepSlider));
|
|
2500
|
+
}, [
|
|
2501
|
+
disabled,
|
|
2502
|
+
calculateValueFromKey,
|
|
2503
|
+
commitValue,
|
|
2504
|
+
minValueSlider,
|
|
2505
|
+
maxValueSlider,
|
|
2506
|
+
stepSlider
|
|
2507
|
+
]);
|
|
2508
|
+
useEffect(() => {
|
|
2509
|
+
if (!dragging) {
|
|
2510
|
+
return;
|
|
2511
|
+
}
|
|
2512
|
+
const onPointerMove = (event) => {
|
|
2513
|
+
commitRate(calculateRateFromClientX(event.clientX));
|
|
2514
|
+
};
|
|
2515
|
+
const onPointerRelease = () => {
|
|
2516
|
+
setDragging(false);
|
|
2517
|
+
};
|
|
2518
|
+
window.addEventListener('pointermove', onPointerMove);
|
|
2519
|
+
window.addEventListener('pointerup', onPointerRelease);
|
|
2520
|
+
window.addEventListener('pointercancel', onPointerRelease);
|
|
2521
|
+
return () => {
|
|
2522
|
+
window.removeEventListener('pointermove', onPointerMove);
|
|
2523
|
+
window.removeEventListener('pointerup', onPointerRelease);
|
|
2524
|
+
window.removeEventListener('pointercancel', onPointerRelease);
|
|
2525
|
+
};
|
|
2526
|
+
}, [dragging, commitRate, calculateRateFromClientX]);
|
|
2403
2527
|
useEffect(() => {
|
|
2404
2528
|
const valueInitial = formControl?.value ?? value ?? 0;
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
formControl?.setValue(valueSlider);
|
|
2409
|
-
onValue?.(valueSlider);
|
|
2529
|
+
if (valueInitial !== refValue.current) {
|
|
2530
|
+
formControl?.setValue(refValue.current);
|
|
2531
|
+
onValue?.(refValue.current);
|
|
2410
2532
|
}
|
|
2411
2533
|
}, []);
|
|
2412
|
-
|
|
2413
|
-
const
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2534
|
+
useEffect(() => {
|
|
2535
|
+
const valueExternal = formControl?.value ?? value;
|
|
2536
|
+
if (valueExternal === undefined ||
|
|
2537
|
+
valueExternal === refValueExternal.current) {
|
|
2538
|
+
return;
|
|
2539
|
+
}
|
|
2540
|
+
refValueExternal.current = valueExternal;
|
|
2541
|
+
commitValue(normalizeSliderValue(valueExternal, minValueSlider, maxValueSlider, stepSlider));
|
|
2542
|
+
}, [
|
|
2543
|
+
value,
|
|
2544
|
+
formControl?.value,
|
|
2545
|
+
commitValue,
|
|
2546
|
+
minValueSlider,
|
|
2547
|
+
maxValueSlider,
|
|
2548
|
+
stepSlider
|
|
2549
|
+
]);
|
|
2550
|
+
useEffect(() => {
|
|
2551
|
+
commitValue(normalizeSliderValue(refValue.current, minValueSlider, maxValueSlider, stepSlider));
|
|
2552
|
+
}, [commitValue, minValueSlider, maxValueSlider, stepSlider]);
|
|
2553
|
+
return (jsxRuntimeExports.jsxs("div", { id: identifier, className: classNameSlider, "rls-theme": rlsTheme, children: [children && (jsxRuntimeExports.jsx("span", { id: labelId, className: "rls-slider__label", children: children })), jsxRuntimeExports.jsxs("div", { className: "rls-slider__body", children: [prefixIcon && jsxRuntimeExports.jsx(RlsIcon, { value: prefixIcon }), jsxRuntimeExports.jsxs("div", { className: "rls-slider__component", onPointerDown: onPointerDown, children: [jsxRuntimeExports.jsx("div", { ref: refTrack, className: "rls-slider__track", children: jsxRuntimeExports.jsx("div", { className: "rls-slider__track__on", style: { width: `${rate}%` } }) }), jsxRuntimeExports.jsx("div", { ref: refThumb, className: "rls-slider__thumb", style: { left: `${rate}%` }, role: "slider", tabIndex: disabled ? -1 : 0, "aria-orientation": "horizontal", "aria-valuemin": minValueSlider, "aria-valuemax": maxValueSlider, "aria-valuenow": valueSlider, "aria-disabled": disabled || undefined, "aria-labelledby": children ? labelId : undefined, onKeyDown: onKeyDown, children: valueSlider })] })] })] }));
|
|
2428
2554
|
}
|
|
2429
2555
|
const RlsSlider = memo(RlsSliderComponent);
|
|
2430
2556
|
|
|
@@ -4641,11 +4767,17 @@ function RlsImageEditorComponent(props) {
|
|
|
4641
4767
|
useResize({ refElement: refImage, onResize: onResizeElement });
|
|
4642
4768
|
const onCropImage = useCallback(() => {
|
|
4643
4769
|
const cropProps = getCropProperties();
|
|
4644
|
-
const width = props.maxWidth
|
|
4645
|
-
|
|
4770
|
+
const width = Math.round(props.maxWidth
|
|
4771
|
+
? Math.min(props.maxWidth, cropProps.width)
|
|
4772
|
+
: cropProps.width);
|
|
4773
|
+
const height = Math.round(width * getRatioFactor(ratio));
|
|
4646
4774
|
refPicture.current.width = width;
|
|
4647
4775
|
refPicture.current.height = height;
|
|
4648
4776
|
const context = refPicture.current.getContext('2d');
|
|
4777
|
+
if (context) {
|
|
4778
|
+
context.imageSmoothingEnabled = true;
|
|
4779
|
+
context.imageSmoothingQuality = 'high';
|
|
4780
|
+
}
|
|
4649
4781
|
context?.drawImage(refCanvas.current, cropProps.left, cropProps.top, cropProps.width, cropProps.height, 0, 0, width, height);
|
|
4650
4782
|
refPicture.current.toBlob((blob) => {
|
|
4651
4783
|
if (blob) {
|