kitzo 2.1.17 → 2.1.19

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/README.md CHANGED
@@ -26,7 +26,7 @@ npm i kitzo
26
26
  or
27
27
 
28
28
  ```javascript
29
- <script src="https://cdn.jsdelivr.net/npm/kitzo@2.1.17/dist/kitzo.umd.min.js"></script>
29
+ <script src="https://cdn.jsdelivr.net/npm/kitzo@2.1.19/dist/kitzo.umd.min.js"></script>
30
30
  ```
31
31
 
32
32
  > Vanilla: Attach this script tag in the html head tag and you are good to go.
@@ -0,0 +1,2 @@
1
+ export * from './types/toast';
2
+ export * from './types/tooltip';
@@ -554,12 +554,23 @@ function ToastContainer(props) {
554
554
 
555
555
  const tooltipStyles = `
556
556
  .kitzo-react-tooltip-content-default-style {
557
- font-family: sans-serif;
557
+ font-family:
558
+ system-ui,
559
+ -apple-system,
560
+ BlinkMacSystemFont,
561
+ 'Segoe UI',
562
+ Roboto,
563
+ Oxygen,
564
+ Ubuntu,
565
+ Cantarell,
566
+ 'Open Sans',
567
+ 'Helvetica Neue',
568
+ sans-serif;
558
569
  font-size: 0.875rem;
559
570
  background-color: hsl(0, 0%, 15%);
560
571
  color: hsl(0, 0%, 95%);
561
- padding-block: 6px;
562
- padding-inline: 10px;
572
+ padding-block: 0.25rem;
573
+ padding-inline: 0.5rem;
563
574
  border-radius: 0.325rem;
564
575
 
565
576
  @media (prefers-color-scheme: dark) {
@@ -569,8 +580,10 @@ const tooltipStyles = `
569
580
  }
570
581
 
571
582
  .kitzo-react-tooltip-wrapper {
572
- transition-duration: 120ms, 50ms;
573
- transition-property: scale opacity;
583
+ --tooltip-transition-delay: calc(var(--delay) * 1ms);
584
+ transition:
585
+ transform 110ms var(--tooltip-transition-delay),
586
+ opacity 110ms var(--tooltip-transition-delay);
574
587
  }
575
588
 
576
589
  .kitzo-react-tooltip-wrapper.top {
@@ -578,8 +591,7 @@ const tooltipStyles = `
578
591
 
579
592
  bottom: calc(var(--tooltip-offset) + 100%);
580
593
  left: 50%;
581
- translate: -50% 0;
582
- scale: 0.7;
594
+ transform: translateX(-50%) translateY(0) scale(0.8);
583
595
  opacity: 0;
584
596
  transform-origin: bottom;
585
597
  }
@@ -589,8 +601,7 @@ const tooltipStyles = `
589
601
 
590
602
  left: calc(var(--tooltip-offset) + 100%);
591
603
  top: 50%;
592
- translate: 0 -50%;
593
- scale: 0.7;
604
+ transform: translateX(0) translateY(-50%) scale(0.8);
594
605
  opacity: 0;
595
606
  transform-origin: left;
596
607
  }
@@ -600,8 +611,7 @@ const tooltipStyles = `
600
611
 
601
612
  top: calc(var(--tooltip-offset) + 100%);
602
613
  left: 50%;
603
- translate: -50% 0;
604
- scale: 0.7;
614
+ transform: translateX(-50%) translateY(0) scale(0.8);
605
615
  opacity: 0;
606
616
  transform-origin: top;
607
617
  }
@@ -611,27 +621,26 @@ const tooltipStyles = `
611
621
 
612
622
  right: calc(var(--tooltip-offset) + 100%);
613
623
  top: 50%;
614
- translate: 0 -50%;
615
- scale: 0.7;
624
+ transform: translateX(0) translateY(-50%) scale(0.8);
616
625
  opacity: 0;
617
626
  transform-origin: right;
618
627
  }
619
628
 
620
629
  .kitzo-react-tooltip-root:hover {
621
630
  .kitzo-react-tooltip-wrapper.top {
622
- scale: 1;
631
+ transform: translateX(-50%) translateY(0) scale(1);
623
632
  opacity: 1;
624
633
  }
625
634
  .kitzo-react-tooltip-wrapper.right {
626
- scale: 1;
635
+ transform: translateX(0) translateY(-50%) scale(1);
627
636
  opacity: 1;
628
637
  }
629
638
  .kitzo-react-tooltip-wrapper.bottom {
630
- scale: 1;
639
+ transform: translateX(-50%) translateY(0) scale(1);
631
640
  opacity: 1;
632
641
  }
633
642
  .kitzo-react-tooltip-wrapper.left {
634
- scale: 1;
643
+ transform: translateX(0) translateY(-50%) scale(1);
635
644
  opacity: 1;
636
645
  }
637
646
  }
@@ -644,9 +653,9 @@ const tooltipStyles = `
644
653
  document.head.appendChild(styleTag);
645
654
  }
646
655
  })();
656
+ const allowedPositions = ['top', 'right', 'bottom', 'left'];
647
657
  function getPositionBasedClassName(position) {
648
658
  let defaultClass = 'kitzo-react-tooltip-wrapper';
649
- const allowedPositions = ['top', 'right', 'bottom', 'left'];
650
659
  if (allowedPositions.includes(position)) {
651
660
  return defaultClass + ' ' + position;
652
661
  } else {
@@ -655,26 +664,29 @@ function getPositionBasedClassName(position) {
655
664
  }
656
665
  function Tooltip({
657
666
  content = 'Tooltip',
658
- position = '',
659
- offset = 8,
660
- hideOnTouch = true,
667
+ tooltipOptions = {},
661
668
  children
662
669
  }) {
663
- if (typeof hideOnTouch !== 'boolean') hideOnTouch = true;
670
+ const {
671
+ position = 'top',
672
+ offset = 8,
673
+ hideOnTouch = true,
674
+ delay = 0
675
+ } = tooltipOptions ?? {};
676
+ const finalOptions = {
677
+ position: typeof position === 'string' ? position.trim().toLowerCase() : 'top',
678
+ offset: !isNaN(Number(offset)) ? Number(offset) : 8,
679
+ delay: !isNaN(Number(delay)) ? Number(delay) : 0,
680
+ hideOnTouch: typeof hideOnTouch === 'boolean' ? hideOnTouch : true
681
+ };
664
682
  const isTouch = window.matchMedia('(pointer: coarse)').matches;
665
- if (isTouch && hideOnTouch) return children;
666
-
667
- // sanitize props
668
- if (typeof position !== 'string') {
669
- console.warn(`[kitzo/react]: Tooltip position ignored due to invalid data type.`);
670
- position = 'top';
671
- }
672
- if (isNaN(Number(offset))) offset = 8;
683
+ if (isTouch && finalOptions.hideOnTouch) return children;
673
684
  return /*#__PURE__*/React.createElement("div", {
674
685
  style: {
675
686
  position: 'relative',
676
687
  width: 'fit-content',
677
- '--offset': Math.max(0, offset)
688
+ '--offset': Math.max(0, finalOptions.offset),
689
+ '--delay': Math.max(0, finalOptions.delay)
678
690
  },
679
691
  className: "kitzo-react-tooltip-root"
680
692
  }, children, /*#__PURE__*/React.createElement("div", {
@@ -684,93 +696,10 @@ function Tooltip({
684
696
  pointerEvents: 'none'
685
697
  },
686
698
  tabIndex: -1,
687
- className: getPositionBasedClassName(position.trim().toLowerCase())
699
+ className: getPositionBasedClassName(finalOptions.position)
688
700
  }, typeof content === 'string' || typeof content === 'number' ? /*#__PURE__*/React.createElement("div", {
689
701
  className: "kitzo-react-tooltip-content-default-style"
690
702
  }, content) : /*#__PURE__*/React.createElement(React.Fragment, null, content)));
691
703
  }
692
704
 
693
- function useScrollRestoration(path, key, options = {}) {
694
- if (!path || typeof path !== 'object' && typeof path !== 'string') {
695
- throw new Error('kitzo/react: useScrollRestoration(path, ...) expect location object from the react useLocation hook or unique path string(location.pathname)');
696
- }
697
- if (!key || typeof key !== 'string' && typeof key !== 'number') {
698
- throw new Error('kitzo/react: useScrollRestoration(..., key) expect unique string or number');
699
- }
700
- const pathname = typeof path === 'object' ? path.pathname : path;
701
- const behavior = options?.behavior ? options.behavior : 'instant';
702
- const delay = options?.delay ? isNaN(Number(options.delay)) ? 0 : Number(options.delay) : 0;
703
-
704
- // hook management
705
- const ref = useRef(null);
706
- const history = useRef(new Map());
707
-
708
- // hook logic
709
- useEffect(() => {
710
- const element = ref.current;
711
- const target = element || window;
712
- const isWindow = target === window;
713
- const mapKey = `${pathname}::${key}`;
714
- const saved = history.current.get(mapKey);
715
- const restore = () => {
716
- if (!saved) return;
717
- if (isWindow) {
718
- window.scrollTo({
719
- top: saved.top,
720
- left: saved.left,
721
- behavior
722
- });
723
- } else if (element) {
724
- element.scrollTo({
725
- top: saved.top,
726
- left: saved.left,
727
- behavior
728
- });
729
- }
730
- };
731
- if (saved) {
732
- if (delay > 0) {
733
- const timeoutId = setTimeout(restore, delay);
734
- return () => clearTimeout(timeoutId);
735
- } else {
736
- restore();
737
- }
738
- } else {
739
- if (isWindow) {
740
- window.scrollTo({
741
- top: 0,
742
- left: 0,
743
- behavior: 'auto'
744
- });
745
- } else if (element) {
746
- element.scrollTo({
747
- top: 0,
748
- left: 0,
749
- behavior: 'auto'
750
- });
751
- }
752
- }
753
- let timeoutId = null;
754
- const save = () => {
755
- clearTimeout(timeoutId);
756
- timeoutId = setTimeout(() => {
757
- const top = isWindow ? window.scrollY : element?.scrollTop ?? 0;
758
- const left = isWindow ? window.scrollX : element?.scrollLeft ?? 0;
759
- history.current.set(mapKey, {
760
- top,
761
- left
762
- });
763
- }, 50);
764
- };
765
- target.addEventListener('scroll', save, {
766
- passive: true
767
- });
768
- return () => {
769
- target.removeEventListener('scroll', save);
770
- clearTimeout(timeoutId);
771
- };
772
- }, [pathname, key, behavior, delay]);
773
- return ref;
774
- }
775
-
776
- export { ToastContainer, Tooltip, toast, useScrollRestoration };
705
+ export { ToastContainer, Tooltip, toast };
@@ -0,0 +1,46 @@
1
+ import type { ReactNode, CSSProperties, JSX } from 'react';
2
+
3
+ //! Toast API types declaration
4
+ type Positions =
5
+ | 'top-left'
6
+ | 'top-center'
7
+ | 'top-right'
8
+ | 'bottom-left'
9
+ | 'bottom-center'
10
+ | 'bottom-right';
11
+
12
+ type ToastOptions = {
13
+ position?: Positions;
14
+ duration?: number;
15
+ style?: CSSProperties;
16
+ showIcon?: boolean;
17
+ };
18
+
19
+ type CustomContent = string | ReactNode | ((dismiss: () => void) => ReactNode);
20
+
21
+ type ToastAPI = {
22
+ (text: string, options?: ToastOptions): void;
23
+
24
+ success(text: string, options?: ToastOptions): void;
25
+
26
+ error(text: string, options?: ToastOptions): void;
27
+
28
+ promise<T>(
29
+ callback: Promise<T>,
30
+ msgs: {
31
+ loading: string;
32
+ success: string | ((res: T) => string | Promise<string>);
33
+ error: string | ((err: any) => string | Promise<string>);
34
+ },
35
+ options?: ToastOptions,
36
+ ): void;
37
+
38
+ custom(
39
+ content: CustomContent,
40
+ options?: { duration?: number; exitDelay?: number; position?: Positions },
41
+ ): void;
42
+ };
43
+
44
+ export declare const toast: ToastAPI;
45
+
46
+ export declare function ToastContainer(props: { position?: Positions; gap?: number }): JSX.Element;
@@ -0,0 +1,32 @@
1
+ import type { JSX, PropsWithChildren, ReactNode } from 'react';
2
+
3
+ type TooltipOptions = {
4
+ /**
5
+ * Default position: 'top'
6
+ */
7
+ position?: 'top' | 'right' | 'bottom' | 'left';
8
+ /**
9
+ * Default offset: 8
10
+ */
11
+ offset?: number;
12
+ /**
13
+ * Default delay: 0
14
+ */
15
+ delay?: number;
16
+ /**
17
+ * Default hideOnTouch: true
18
+ */
19
+ hideOnTouch?: boolean;
20
+ };
21
+
22
+ type TooltipCoreProps = {
23
+ /**
24
+ * content is necessary
25
+ */
26
+ content: ReactNode;
27
+ tooltipOptions?: TooltipOptions;
28
+ };
29
+
30
+ type TooltipProps = PropsWithChildren<TooltipCoreProps>;
31
+
32
+ export declare function Tooltip(props: TooltipProps): JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitzo",
3
- "version": "2.1.17",
3
+ "version": "2.1.19",
4
4
  "description": "A lightweight JavaScript & React UI micro-library.",
5
5
  "type": "module",
6
6
  "main": "./dist/vanilla/vanilla.umd.js",
@@ -11,7 +11,7 @@
11
11
  "require": "./dist/vanilla/vanilla.umd.js"
12
12
  },
13
13
  "./react": {
14
- "types": "./dist/react/react.d.ts",
14
+ "types": "./dist/react/index.d.ts",
15
15
  "import": "./dist/react/react.esm.js"
16
16
  }
17
17
  },
@@ -1,75 +0,0 @@
1
- import type { ReactNode, CSSProperties, JSX, PropsWithChildren, RefObject } from 'react';
2
-
3
- //! Toast API types declaration
4
- export type Positions =
5
- | 'top-left'
6
- | 'top-center'
7
- | 'top-right'
8
- | 'bottom-left'
9
- | 'bottom-center'
10
- | 'bottom-right';
11
-
12
- export interface ToastOptions {
13
- position?: Positions;
14
- duration?: number;
15
- style?: CSSProperties;
16
- showIcon?: boolean;
17
- }
18
-
19
- export type CustomContent = string | ReactNode | ((dismiss: () => void) => ReactNode);
20
-
21
- export interface ToastAPI {
22
- (text?: string, options?: ToastOptions): void;
23
-
24
- success(text?: string, options?: ToastOptions): void;
25
-
26
- error(text?: string, options?: ToastOptions): void;
27
-
28
- promise<T>(
29
- callback: Promise<T>,
30
- msgs?: {
31
- loading?: string;
32
- success?: string | ((res: T) => string | Promise<string>);
33
- error?: string | ((err: any) => string | Promise<string>);
34
- },
35
- options?: ToastOptions,
36
- ): void;
37
-
38
- custom(
39
- content: CustomContent,
40
- options?: { duration?: number; exitDelay?: number; position?: Positions },
41
- ): void;
42
- }
43
-
44
- export declare const toast: ToastAPI;
45
-
46
- export declare function ToastContainer(props: { position?: Positions; gap?: number }): JSX.Element;
47
-
48
- //! Tooltip API types declaration
49
- export interface TooltipCoreProps {
50
- content: string | ReactNode;
51
- position?: 'top' | 'right' | 'bottom' | 'left';
52
- offset?: number;
53
- hideOnTouch?: boolean;
54
- }
55
-
56
- export type TooltipProps = PropsWithChildren<TooltipCoreProps>;
57
-
58
- export declare function Tooltip(props: TooltipProps): JSX.Element;
59
-
60
- //! useScrollRestoration hook types declaration
61
- type ScrollHookOptions = {
62
- behavior?: 'auto' | 'smooth' | 'instant';
63
- delay?: number;
64
- };
65
-
66
- type LocationLike = {
67
- pathname: string;
68
- [key: string]: any;
69
- };
70
-
71
- export declare function useScrollRestoration<T extends HTMLElement = HTMLDivElement>(
72
- path: LocationLike | string,
73
- key: string | number,
74
- options?: ScrollHookOptions,
75
- ): RefObject<T | null>;