@geoinsight/react-components 1.1.0 → 1.1.1
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.css +120 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +236 -46
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.css +120 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +237 -48
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -5,7 +5,8 @@ import { TfiAngleDown, TfiAngleUp } from 'react-icons/tfi';
|
|
|
5
5
|
import { BsCheckCircleFill, BsXCircleFill } from 'react-icons/bs';
|
|
6
6
|
import { useForm, FormProvider, useFormContext, Controller } from 'react-hook-form';
|
|
7
7
|
import { TbArrowsDiagonal2 } from 'react-icons/tb';
|
|
8
|
-
import { IoClose } from 'react-icons/io5';
|
|
8
|
+
import { IoClose, IoPause, IoPlay, IoStop } from 'react-icons/io5';
|
|
9
|
+
import { RiMapPinTimeFill, RiMapPinTimeLine } from 'react-icons/ri';
|
|
9
10
|
|
|
10
11
|
const generateId = () => {
|
|
11
12
|
return `id-${Math.random().toString(36).slice(2, 11)}`;
|
|
@@ -290,6 +291,240 @@ function Modal({ className, modalref, children, title, subtitle, footer, hasOver
|
|
|
290
291
|
return (jsxs(Fragment, { children: [hasOverlay && jsx("div", { className: "modal-overlay" }), jsxs("div", { ref: modalref, className: clsx("modal", className), ...rest, children: [hasCloseButton && (jsx(Button, { mode: "secondary", className: "modal__close", size: "small", onClick: handleClose, children: jsx(IoClose, {}) })), jsxs("div", { className: "modal__content", children: [title && (jsxs("div", { className: "modal__header", children: [jsx("h3", { children: title }), jsx("h6", { children: subtitle })] })), jsx("div", { className: "modal__children", children: children }), footer && jsx("div", { className: "modal__footer", children: footer })] })] })] }));
|
|
291
292
|
}
|
|
292
293
|
|
|
294
|
+
function usePositions(panelRef) {
|
|
295
|
+
const [allPositions, setAllPositions] = useState(undefined);
|
|
296
|
+
const [pixelPosition, setPixelPosition] = useState(undefined);
|
|
297
|
+
const [thumbPosition, setThumbPosition] = useState(undefined);
|
|
298
|
+
// find positions of all values
|
|
299
|
+
useEffect(() => {
|
|
300
|
+
if (panelRef?.current) {
|
|
301
|
+
const current = panelRef.current;
|
|
302
|
+
if (current) {
|
|
303
|
+
const valuesRef = Array.from(current.getElementsByClassName("range__content"));
|
|
304
|
+
const parentBounds = current.getBoundingClientRect();
|
|
305
|
+
setAllPositions(valuesRef.map((values) => {
|
|
306
|
+
const childBounds = values.getBoundingClientRect();
|
|
307
|
+
return childBounds.right - parentBounds.x;
|
|
308
|
+
}));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}, []);
|
|
312
|
+
// initial position
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
if (allPositions) {
|
|
315
|
+
setPixelPosition(`${allPositions[0]}px`);
|
|
316
|
+
setThumbPosition(`${allPositions[0] / 2 - getThumbBounds().width / 2}px`);
|
|
317
|
+
}
|
|
318
|
+
}, [allPositions]);
|
|
319
|
+
return {
|
|
320
|
+
panelRef,
|
|
321
|
+
allPositions,
|
|
322
|
+
setAllPositions,
|
|
323
|
+
pixelPosition,
|
|
324
|
+
setPixelPosition,
|
|
325
|
+
thumbPosition,
|
|
326
|
+
setThumbPosition,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function getThumbBounds() {
|
|
330
|
+
const thumb = document.getElementsByClassName("range__thumb")[0];
|
|
331
|
+
return thumb.getBoundingClientRect();
|
|
332
|
+
}
|
|
333
|
+
function useTimer({ allPositions, indexPosition, handlePosition, handleOverContent, values, }) {
|
|
334
|
+
const timeoutRef = useRef(null);
|
|
335
|
+
const [isPlay, setIsPlay] = useState(false);
|
|
336
|
+
// timer
|
|
337
|
+
useEffect(() => {
|
|
338
|
+
resetTimeout();
|
|
339
|
+
if (isPlay) {
|
|
340
|
+
if (allPositions) {
|
|
341
|
+
timeoutRef.current = setTimeout(() => {
|
|
342
|
+
const newThumbPosition = allPositions[indexPosition] +
|
|
343
|
+
allPositions[0] / 2 -
|
|
344
|
+
getThumbBounds().width / 2;
|
|
345
|
+
handlePosition(allPositions[indexPosition + 1], newThumbPosition, indexPosition + 1, true);
|
|
346
|
+
handleOverContent(values[indexPosition + 1]);
|
|
347
|
+
}, 500);
|
|
348
|
+
if (indexPosition === allPositions.length - 1) {
|
|
349
|
+
setIsPlay(false);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return () => {
|
|
354
|
+
resetTimeout();
|
|
355
|
+
};
|
|
356
|
+
}, [isPlay, indexPosition]);
|
|
357
|
+
const resetTimeout = () => {
|
|
358
|
+
if (timeoutRef.current) {
|
|
359
|
+
clearTimeout(timeoutRef.current);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
const handlePlay = () => {
|
|
363
|
+
setIsPlay(!isPlay);
|
|
364
|
+
};
|
|
365
|
+
const handleStop = () => {
|
|
366
|
+
if (allPositions) {
|
|
367
|
+
handlePosition(allPositions[0], allPositions[0] / 2 - getThumbBounds().width / 2, 0, false);
|
|
368
|
+
setIsPlay(false);
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
return { isPlay, setIsPlay, handlePlay, handleStop };
|
|
372
|
+
}
|
|
373
|
+
function useThumb({ allPositions, panelRef, handlePosition, handleOverContent, values, }) {
|
|
374
|
+
// Add drag
|
|
375
|
+
const startDragging = (event) => {
|
|
376
|
+
if (allPositions && panelRef?.current) {
|
|
377
|
+
const current = panelRef.current;
|
|
378
|
+
const panelBounds = current?.getBoundingClientRect();
|
|
379
|
+
const x = event.pageX - panelBounds.left;
|
|
380
|
+
const absX = Math.abs(x);
|
|
381
|
+
if (x >= 0 && x <= allPositions[allPositions.length - 1]) {
|
|
382
|
+
const desiredPosition = allPositions.reduce((prev, curr) => Math.abs(prev - absX) < Math.abs(curr - absX) ? prev : curr);
|
|
383
|
+
const index = allPositions.indexOf(desiredPosition);
|
|
384
|
+
const newThumbPosition = index === 0
|
|
385
|
+
? allPositions[index] -
|
|
386
|
+
allPositions[0] / 2 -
|
|
387
|
+
getThumbBounds().width / 2
|
|
388
|
+
: allPositions[index - 1] +
|
|
389
|
+
allPositions[0] / 2 -
|
|
390
|
+
getThumbBounds().width / 2;
|
|
391
|
+
handlePosition(desiredPosition, newThumbPosition, index, true);
|
|
392
|
+
handleOverContent(values[index]);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
const stopDragging = () => {
|
|
397
|
+
window.removeEventListener("mousemove", startDragging, false);
|
|
398
|
+
window.removeEventListener("mouseup", stopDragging, false);
|
|
399
|
+
};
|
|
400
|
+
const handleDownThumb = () => {
|
|
401
|
+
window.addEventListener("mousemove", startDragging, false);
|
|
402
|
+
window.addEventListener("mouseup", stopDragging, false);
|
|
403
|
+
};
|
|
404
|
+
return { handleDownThumb };
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const ThemeContext = createContext(undefined);
|
|
408
|
+
function ThemeProvider({ children, dataTheme: dataThemeProp, dataPalette: dataPaletteProp = "water", }) {
|
|
409
|
+
const [dataTheme, setDataTheme] = useState();
|
|
410
|
+
const [dataPalette, setDataPalette] = useState();
|
|
411
|
+
useEffect(() => {
|
|
412
|
+
if (dataPaletteProp) {
|
|
413
|
+
switchDataPalette(dataPaletteProp);
|
|
414
|
+
}
|
|
415
|
+
}, [dataPaletteProp]);
|
|
416
|
+
useEffect(() => {
|
|
417
|
+
if (dataThemeProp) {
|
|
418
|
+
switchDataTheme(dataThemeProp);
|
|
419
|
+
}
|
|
420
|
+
}, [dataThemeProp]);
|
|
421
|
+
useEffect(() => {
|
|
422
|
+
if (window.matchMedia) {
|
|
423
|
+
if (localStorage.getItem("data-theme")) {
|
|
424
|
+
document.documentElement.setAttribute("data-theme", localStorage.getItem("data-theme"));
|
|
425
|
+
setDataTheme(localStorage.getItem("data-theme"));
|
|
426
|
+
}
|
|
427
|
+
else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
428
|
+
document.documentElement.setAttribute("data-theme", "dark");
|
|
429
|
+
setDataTheme("dark");
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}, []);
|
|
433
|
+
const switchDataTheme = (mode) => {
|
|
434
|
+
document.documentElement.setAttribute("data-theme", mode);
|
|
435
|
+
setDataTheme(mode);
|
|
436
|
+
localStorage.setItem("data-theme", mode);
|
|
437
|
+
};
|
|
438
|
+
const switchDataPalette = (mode) => {
|
|
439
|
+
document.documentElement.setAttribute("data-palette", mode);
|
|
440
|
+
setDataPalette(mode);
|
|
441
|
+
localStorage.setItem("palette-theme", mode);
|
|
442
|
+
};
|
|
443
|
+
return (jsx(ThemeContext.Provider, { value: { dataTheme, switchDataTheme, dataPalette, switchDataPalette }, children: children }));
|
|
444
|
+
}
|
|
445
|
+
function useTheme() {
|
|
446
|
+
const context = useContext(ThemeContext);
|
|
447
|
+
if (context === undefined) {
|
|
448
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
449
|
+
}
|
|
450
|
+
return context;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function RangeThumb({ thumbPosition, handleOverContent, handleDownThumb }) {
|
|
454
|
+
const { dataTheme } = useTheme();
|
|
455
|
+
return (jsx(Button, { mode: "icon", className: "range__thumb", size: "small", style: {
|
|
456
|
+
left: `${thumbPosition}`,
|
|
457
|
+
}, onMouseOver: () => handleOverContent(thumbPosition), onMouseDown: handleDownThumb, children: dataTheme === "dark" ? (jsx(RiMapPinTimeFill, { size: "1.5rem" })) : (jsx(RiMapPinTimeLine, { size: "1.5rem" })) }));
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function RangeContent({ period, values, allPositions, handlePosition, handleOverContent, handleOutContent, over, }) {
|
|
461
|
+
const handleClickRange = (index) => {
|
|
462
|
+
if (allPositions) {
|
|
463
|
+
const newThumbPosition = index === 0
|
|
464
|
+
? allPositions[index] -
|
|
465
|
+
allPositions[0] / 2 -
|
|
466
|
+
getThumbBounds().width / 2
|
|
467
|
+
: allPositions[index - 1] +
|
|
468
|
+
allPositions[0] / 2 -
|
|
469
|
+
getThumbBounds().width / 2;
|
|
470
|
+
handlePosition(allPositions[index], newThumbPosition, index, true);
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
return period
|
|
474
|
+
? values.map((value, index) => (jsx("div", { className: "range__content range__content__period", onClick: () => handleClickRange(index), onMouseOver: () => handleOverContent(value), onMouseOut: () => handleOutContent(), children: index % period === 0 ? (jsxs(Fragment, { children: [jsx("div", { className: "range__tick range__tick__large" }), jsx("div", { className: clsx("range__value", "range__value__period", {
|
|
475
|
+
"range__value--over": value === over,
|
|
476
|
+
}), children: value })] })) : (jsxs(Fragment, { children: [jsx("div", { className: "range__tick range__tick__small" }), value === over && (jsx("div", { className: clsx("range__value", "range__value__period", {
|
|
477
|
+
"range__value--over": value === over,
|
|
478
|
+
}), children: value }))] })) })))
|
|
479
|
+
: values.map((value, index) => (jsxs("div", { className: "range__content", onClick: () => handleClickRange(index), children: [jsx("div", { className: "range__tick range__tick__large" }), jsx("div", { className: "range__value", children: value })] })));
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function RangeControls({ indexPosition, isPlay, handlePlay, handleStop, }) {
|
|
483
|
+
return (jsxs(Fragment, { children: [jsx(Button, { mode: "icon", size: "small", className: "range__play", onClick: handlePlay, children: isPlay ? (jsx(IoPause, { color: "var(--color-primary-base)", size: "2rem" })) : (jsx(IoPlay, { color: "var(--color-primary-base)", size: "2rem" })) }), jsx(Button, { mode: "icon", size: "small", className: "range__play", disabled: !isPlay && indexPosition === 0, onClick: handleStop, children: jsx(IoStop, { color: "var(--color-primary-base)", size: "2rem" }) })] }));
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function Range({ period, values, handleSelected }) {
|
|
487
|
+
const panelRef = useRef(null);
|
|
488
|
+
const [indexPosition, setIndexPosition] = useState(0);
|
|
489
|
+
const [over, setOver] = useState(undefined);
|
|
490
|
+
const { allPositions, pixelPosition, setPixelPosition, thumbPosition, setThumbPosition, } = usePositions(panelRef);
|
|
491
|
+
const handlePosition = (pixelPosition, thumbPosition, index, isHandleSelected = false) => {
|
|
492
|
+
setPixelPosition(`${pixelPosition}px`);
|
|
493
|
+
setThumbPosition(`${thumbPosition}px`);
|
|
494
|
+
setIndexPosition(index);
|
|
495
|
+
if (isHandleSelected && handleSelected) {
|
|
496
|
+
handleSelected({
|
|
497
|
+
value: values[index],
|
|
498
|
+
index,
|
|
499
|
+
position: pixelPosition,
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
const handleOverContent = (value) => {
|
|
504
|
+
setOver(value);
|
|
505
|
+
};
|
|
506
|
+
const handleOutContent = () => {
|
|
507
|
+
setOver(undefined);
|
|
508
|
+
};
|
|
509
|
+
const { isPlay, handlePlay, handleStop } = useTimer({
|
|
510
|
+
allPositions,
|
|
511
|
+
indexPosition,
|
|
512
|
+
handlePosition,
|
|
513
|
+
handleOverContent,
|
|
514
|
+
values,
|
|
515
|
+
});
|
|
516
|
+
const { handleDownThumb } = useThumb({
|
|
517
|
+
allPositions,
|
|
518
|
+
panelRef,
|
|
519
|
+
handlePosition,
|
|
520
|
+
handleOverContent,
|
|
521
|
+
values,
|
|
522
|
+
});
|
|
523
|
+
return (jsxs("div", { className: "range", children: [jsxs("div", { ref: panelRef, className: "range__panel", children: [jsx(RangeContent, { period: period, values: values, allPositions: allPositions, handlePosition: handlePosition, handleOverContent: handleOverContent, handleOutContent: handleOutContent, over: over }), jsx("div", { className: "range__track", style: {
|
|
524
|
+
width: `${pixelPosition}`,
|
|
525
|
+
} }), jsx(RangeThumb, { thumbPosition: thumbPosition, handleOverContent: handleOverContent, handleDownThumb: handleDownThumb })] }), jsx(RangeControls, { indexPosition: indexPosition, isPlay: isPlay, handlePlay: handlePlay, handleStop: handleStop })] }));
|
|
526
|
+
}
|
|
527
|
+
|
|
293
528
|
const LoadingContext = createContext(undefined);
|
|
294
529
|
function loadingReducer(state, action) {
|
|
295
530
|
switch (action.type) {
|
|
@@ -421,51 +656,5 @@ function useModal({} = {}) {
|
|
|
421
656
|
return context;
|
|
422
657
|
}
|
|
423
658
|
|
|
424
|
-
|
|
425
|
-
function ThemeProvider({ children, dataTheme: dataThemeProp, dataPalette: dataPaletteProp = "water", }) {
|
|
426
|
-
const [dataTheme, setDataTheme] = useState();
|
|
427
|
-
const [dataPalette, setDataPalette] = useState();
|
|
428
|
-
useEffect(() => {
|
|
429
|
-
if (dataPaletteProp) {
|
|
430
|
-
switchDataPalette(dataPaletteProp);
|
|
431
|
-
}
|
|
432
|
-
}, [dataPaletteProp]);
|
|
433
|
-
useEffect(() => {
|
|
434
|
-
if (dataThemeProp) {
|
|
435
|
-
switchDataTheme(dataThemeProp);
|
|
436
|
-
}
|
|
437
|
-
}, [dataThemeProp]);
|
|
438
|
-
useEffect(() => {
|
|
439
|
-
if (window.matchMedia) {
|
|
440
|
-
if (localStorage.getItem("data-theme")) {
|
|
441
|
-
document.documentElement.setAttribute("data-theme", localStorage.getItem("data-theme"));
|
|
442
|
-
setDataTheme(localStorage.getItem("data-theme"));
|
|
443
|
-
}
|
|
444
|
-
else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
445
|
-
document.documentElement.setAttribute("data-theme", "dark");
|
|
446
|
-
setDataTheme("dark");
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}, []);
|
|
450
|
-
const switchDataTheme = (mode) => {
|
|
451
|
-
document.documentElement.setAttribute("data-theme", mode);
|
|
452
|
-
setDataTheme(mode);
|
|
453
|
-
localStorage.setItem("data-theme", mode);
|
|
454
|
-
};
|
|
455
|
-
const switchDataPalette = (mode) => {
|
|
456
|
-
document.documentElement.setAttribute("data-palette", mode);
|
|
457
|
-
setDataPalette(mode);
|
|
458
|
-
localStorage.setItem("palette-theme", mode);
|
|
459
|
-
};
|
|
460
|
-
return (jsx(ThemeContext.Provider, { value: { dataTheme, switchDataTheme, dataPalette, switchDataPalette }, children: children }));
|
|
461
|
-
}
|
|
462
|
-
function useTheme() {
|
|
463
|
-
const context = useContext(ThemeContext);
|
|
464
|
-
if (context === undefined) {
|
|
465
|
-
throw new Error("useTheme must be used within a ThemeProvider");
|
|
466
|
-
}
|
|
467
|
-
return context;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
export { Button, Form, FormInput, FormSelect, FormTextArea, Input, Loading, LoadingContext, LoadingProvider, Menu, Modal, ModalContext, ModalProvider, Select, TextArea, ThemeContext, ThemeProvider, useLoading, useModal, useTheme };
|
|
659
|
+
export { Button, Form, FormInput, FormSelect, FormTextArea, Input, Loading, LoadingContext, LoadingProvider, Menu, Modal, ModalContext, ModalProvider, Range, Select, TextArea, ThemeContext, ThemeProvider, useLoading, useModal, useTheme };
|
|
471
660
|
//# sourceMappingURL=index.js.map
|