@olenbetong/synergi-react 0.6.7

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.
Files changed (92) hide show
  1. package/dist/esm/ob.react.css +708 -0
  2. package/dist/esm/ob.react.js +3077 -0
  3. package/dist/esm/ob.react.min.css +2 -0
  4. package/dist/esm/ob.react.min.css.map +7 -0
  5. package/dist/esm/ob.react.min.js +8 -0
  6. package/dist/esm/ob.react.min.js.map +7 -0
  7. package/dist/iife/ob.react.css +708 -0
  8. package/dist/iife/ob.react.js +3089 -0
  9. package/dist/iife/ob.react.min.css +2 -0
  10. package/dist/iife/ob.react.min.css.map +7 -0
  11. package/dist/iife/ob.react.min.js +8 -0
  12. package/dist/iife/ob.react.min.js.map +7 -0
  13. package/dist/styles/styles.css +1 -0
  14. package/dist/styles/styles.css.map +1 -0
  15. package/es/Checkbox/index.css +1 -0
  16. package/es/ColorCard/index.css +1 -0
  17. package/es/DateNavigator/index.css +1 -0
  18. package/es/LinkedCardList/index.css +1 -0
  19. package/es/PageBanner/index.css +1 -0
  20. package/es/ProgressBar/index.css +1 -0
  21. package/es/Sidebar/index.css +1 -0
  22. package/es/Spinner/index.css +1 -0
  23. package/es/SplitContainer/index.css +1 -0
  24. package/es/ValueToggle/index.css +1 -0
  25. package/es/appframe-react/src/useDebounce.d.ts +8 -0
  26. package/es/appframe-react/src/useDebounce.js +16 -0
  27. package/es/index.css +1 -0
  28. package/es/styles/_mixins.css +0 -0
  29. package/es/styles/_variables.css +0 -0
  30. package/es/synergi-react/src/Checkbox/index.d.ts +9 -0
  31. package/es/synergi-react/src/Checkbox/index.js +41 -0
  32. package/es/synergi-react/src/ColorCard/index.d.ts +14 -0
  33. package/es/synergi-react/src/ColorCard/index.js +16 -0
  34. package/es/synergi-react/src/DateNavigator/index.d.ts +6 -0
  35. package/es/synergi-react/src/DateNavigator/index.js +51 -0
  36. package/es/synergi-react/src/LinkedCardList/index.d.ts +9 -0
  37. package/es/synergi-react/src/LinkedCardList/index.js +13 -0
  38. package/es/synergi-react/src/PageBanner/index.d.ts +27 -0
  39. package/es/synergi-react/src/PageBanner/index.js +24 -0
  40. package/es/synergi-react/src/Portal/index.d.ts +6 -0
  41. package/es/synergi-react/src/Portal/index.js +32 -0
  42. package/es/synergi-react/src/ProgressBar/index.d.ts +4 -0
  43. package/es/synergi-react/src/ProgressBar/index.js +7 -0
  44. package/es/synergi-react/src/Sidebar/index.d.ts +10 -0
  45. package/es/synergi-react/src/Sidebar/index.js +57 -0
  46. package/es/synergi-react/src/Spinner/index.d.ts +10 -0
  47. package/es/synergi-react/src/Spinner/index.js +6 -0
  48. package/es/synergi-react/src/SplitContainer/index.d.ts +20 -0
  49. package/es/synergi-react/src/SplitContainer/index.js +151 -0
  50. package/es/synergi-react/src/ValueToggle/index.d.ts +19 -0
  51. package/es/synergi-react/src/ValueToggle/index.js +38 -0
  52. package/es/synergi-react/src/index.d.ts +15 -0
  53. package/es/synergi-react/src/index.js +15 -0
  54. package/es/synergi-react/src/useDebounce.d.ts +9 -0
  55. package/es/synergi-react/src/useDebounce.js +17 -0
  56. package/es/synergi-react/src/usePersistedSetting.d.ts +7 -0
  57. package/es/synergi-react/src/usePersistedSetting.js +53 -0
  58. package/es/synergi-react/src/useSearchParamState.d.ts +13 -0
  59. package/es/synergi-react/src/useSearchParamState.js +42 -0
  60. package/es/synergi-react/src/useTranslation/index.d.ts +7 -0
  61. package/es/synergi-react/src/useTranslation/index.js +64 -0
  62. package/package.json +90 -0
  63. package/src/Checkbox/index.scss +119 -0
  64. package/src/Checkbox/index.tsx +81 -0
  65. package/src/ColorCard/index.scss +154 -0
  66. package/src/ColorCard/index.tsx +58 -0
  67. package/src/DateNavigator/index.scss +60 -0
  68. package/src/DateNavigator/index.tsx +92 -0
  69. package/src/LinkedCardList/index.scss +86 -0
  70. package/src/LinkedCardList/index.tsx +38 -0
  71. package/src/PageBanner/index.scss +99 -0
  72. package/src/PageBanner/index.tsx +79 -0
  73. package/src/Portal/index.tsx +36 -0
  74. package/src/ProgressBar/index.scss +86 -0
  75. package/src/ProgressBar/index.tsx +13 -0
  76. package/src/Sidebar/index.scss +53 -0
  77. package/src/Sidebar/index.tsx +117 -0
  78. package/src/Spinner/index.scss +71 -0
  79. package/src/Spinner/index.tsx +21 -0
  80. package/src/SplitContainer/index.scss +43 -0
  81. package/src/SplitContainer/index.tsx +271 -0
  82. package/src/ValueToggle/index.scss +50 -0
  83. package/src/ValueToggle/index.tsx +75 -0
  84. package/src/global.d.ts +2 -0
  85. package/src/index.scss +9 -0
  86. package/src/index.ts +27 -0
  87. package/src/styles/_mixins.scss +19 -0
  88. package/src/styles/_variables.scss +70 -0
  89. package/src/useDebounce.ts +21 -0
  90. package/src/usePersistedSetting.ts +78 -0
  91. package/src/useSearchParamState.ts +78 -0
  92. package/src/useTranslation/index.ts +74 -0
@@ -0,0 +1,79 @@
1
+ import "./index.scss";
2
+
3
+ import clsx from "clsx";
4
+ import React from "react";
5
+
6
+ export type PageBannerProps = React.HTMLProps<HTMLDivElement> & {
7
+ as?: "header" | "section" | "div";
8
+ };
9
+
10
+ export function PageBanner({ as, className, children, ...other }: PageBannerProps) {
11
+ const Component = as ? as : "section";
12
+
13
+ return (
14
+ <Component className={clsx("ObPageBanner-root", className)} {...other}>
15
+ <div className="container px-0">
16
+ <div className={"ObPageBanner-pageBannerInner"}>{children}</div>
17
+ </div>
18
+ </Component>
19
+ );
20
+ }
21
+
22
+ export type BannerImageProps = React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>;
23
+
24
+ export const BannerImage = React.forwardRef<HTMLImageElement, BannerImageProps>(function BannerImage(
25
+ props: BannerImageProps,
26
+ ref
27
+ ) {
28
+ const { className, ...other } = props;
29
+ return <img ref={ref} className={clsx("ObPageBanner-bannerImage", className)} {...other} />;
30
+ });
31
+
32
+ export type TabListProps = Pick<React.HTMLProps<HTMLDivElement>, "id" | "className" | "children"> & {
33
+ as?: "ul" | "ol" | "nav" | "div" | "span";
34
+ sticky?: boolean;
35
+ };
36
+
37
+ export function TabList({ as, className, children, sticky, ...other }: TabListProps) {
38
+ const Component = as ? as : "nav";
39
+
40
+ return (
41
+ <Component
42
+ className={clsx("ObPageBanner-pageBanner", "ObPageBanner-tabList", sticky && "sticky", className)}
43
+ {...other}
44
+ >
45
+ <div className="container px-0">
46
+ <div className={"ObPageBanner-tabListInner"}>{children}</div>
47
+ </div>
48
+ </Component>
49
+ );
50
+ }
51
+
52
+ export type TabProps = Pick<React.HTMLProps<HTMLDivElement>, "id" | "className" | "children"> & {
53
+ active?: boolean;
54
+ as?: "a" | "li" | "div" | "span";
55
+ };
56
+
57
+ export function Tab({ active, as, className, children, ...other }: TabProps) {
58
+ const Component = as ? as : "a";
59
+
60
+ return (
61
+ <Component className={clsx("ObPageBanner-tab", active && "active", className)} {...other}>
62
+ {children}
63
+ </Component>
64
+ );
65
+ }
66
+
67
+ export type TitleProps = Pick<React.HTMLProps<HTMLDivElement>, "id" | "className" | "children"> & {
68
+ as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "div" | "span" | "p";
69
+ };
70
+
71
+ export function Title({ as, className, children, ...other }) {
72
+ const Component = as ? as : "h1";
73
+
74
+ return (
75
+ <Component className={clsx("ObPageBanner-bannerTitle", className)} {...other}>
76
+ {children}
77
+ </Component>
78
+ );
79
+ }
@@ -0,0 +1,36 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import { createPortal } from "react-dom";
3
+
4
+ function useForceUpdate() {
5
+ const [, setVal] = useState(false);
6
+
7
+ return () => setVal(val => !val);
8
+ }
9
+
10
+ export function Portal({ children, root, type = "div" }) {
11
+ const forceUpdate = useForceUpdate();
12
+ const mountNode = useRef<HTMLDivElement>(null);
13
+ const portalNode = useRef<HTMLElement>(null);
14
+
15
+ useEffect(() => {
16
+ const ownerDocument = mountNode.current?.ownerDocument;
17
+ let portalElem = portalNode.current;
18
+ if (ownerDocument && portalElem) {
19
+ let parent = root ? ownerDocument.querySelector(root) || ownerDocument.body : ownerDocument.body;
20
+ const node = ownerDocument.createElement(type);
21
+ portalElem = node;
22
+ parent.appendChild(node);
23
+ forceUpdate();
24
+
25
+ return () => {
26
+ parent.removeChild(node);
27
+ };
28
+ }
29
+ }, []);
30
+
31
+ if (!portalNode.current) {
32
+ return <div ref={mountNode} />;
33
+ } else {
34
+ return createPortal(children, portalNode.current);
35
+ }
36
+ }
@@ -0,0 +1,86 @@
1
+ @import "../styles/variables";
2
+
3
+ .ObProgressBar-root {
4
+ height: 1.5em;
5
+ width: 100%;
6
+ appearance: none;
7
+ -webkit-appearance: none;
8
+ background-color: whiteSmoke;
9
+ border: none;
10
+ border-radius: 3px;
11
+ box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2) inset;
12
+ color: royalblue;
13
+ position: relative;
14
+
15
+ &::-webkit-progress-bar {
16
+ background-color: whiteSmoke;
17
+ border-radius: 3px;
18
+ box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2) inset;
19
+ }
20
+
21
+ &::-webkit-progress-value {
22
+ background-image: linear-gradient(
23
+ 135deg,
24
+ transparent,
25
+ transparent 33%,
26
+ rgba(0, 0, 0, 0.1) 33%,
27
+ rgba(0, 0, 0, 0.1) 66%,
28
+ transparent 66%
29
+ ),
30
+ linear-gradient(top, rgba(255, 255, 255, 0.25), rgba(0, 0, 0, 0.2)),
31
+ linear-gradient(left, var(--brand-primary, $brand-primary), var(--brand-light, $brand-light));
32
+ background-image: -webkit-linear-gradient(
33
+ 135deg,
34
+ transparent,
35
+ transparent 33%,
36
+ rgba(0, 0, 0, 0.1) 33%,
37
+ rgba(0, 0, 0, 0.1) 66%,
38
+ transparent 66%
39
+ ),
40
+ -webkit-linear-gradient(top, rgba(255, 255, 255, 0.25), rgba(0, 0, 0, 0.2)),
41
+ -webkit-linear-gradient(left, var(--brand-primary), $brand-primary, var(--brand-light, $brand-light));
42
+ background-size: 35px 20px, 100% 100%, 100% 100%;
43
+ border-radius: 3px;
44
+ position: relative;
45
+ transition: width 0.5s ease-out;
46
+ }
47
+
48
+ &::-webkit-progress-value:after {
49
+ background-color: white;
50
+ content: "";
51
+
52
+ border-radius: 100%;
53
+ height: 5px;
54
+
55
+ position: absolute;
56
+ right: 7px;
57
+ top: 7px;
58
+ width: 5px;
59
+ }
60
+
61
+ &::-moz-progress-bar {
62
+ background-image: linear-gradient(
63
+ 135deg,
64
+ transparent,
65
+ transparent 33%,
66
+ rgba(0, 0, 0, 0.1) 33%,
67
+ rgba(0, 0, 0, 0.1) 66%,
68
+ transparent 66%
69
+ ),
70
+ linear-gradient(top, rgba(255, 255, 255, 0.25), rgba(0, 0, 0, 0.2)),
71
+ linear-gradient(left, var(--brand-primary), var(--brand-light));
72
+ background-image: -moz-linear-gradient(
73
+ 135deg,
74
+ transparent,
75
+ transparent 33%,
76
+ rgba(0, 0, 0, 0.1) 33%,
77
+ rgba(0, 0, 0, 0.1) 66%,
78
+ transparent 66%
79
+ ),
80
+ -moz-linear-gradient(top, rgba(255, 255, 255, 0.25), rgba(0, 0, 0, 0.2)),
81
+ -moz-linear-gradient(left, var(--brand-primary), var(--brand-light));
82
+ background-size: 35px 20px, 100% 100%, 100% 100%;
83
+ border-radius: 3px;
84
+ transition: width 0.5s ease-out;
85
+ }
86
+ }
@@ -0,0 +1,13 @@
1
+ import "./index.scss";
2
+
3
+ import clsx from "clsx";
4
+ import { forwardRef } from "react";
5
+
6
+ export type ProgressBarProps = React.HTMLProps<HTMLProgressElement>;
7
+
8
+ export const ProgressBar = forwardRef<HTMLProgressElement, ProgressBarProps>(function ProgressBar(
9
+ { className, ...props }: ProgressBarProps,
10
+ ref
11
+ ) {
12
+ return <progress className={clsx("ObProgressBar-root", className)} {...props} ref={ref} />;
13
+ });
@@ -0,0 +1,53 @@
1
+ .ObSidebar-root {
2
+ position: fixed;
3
+ bottom: 0;
4
+ left: 0;
5
+ top: 0;
6
+ z-index: 2;
7
+
8
+ background-color: white;
9
+
10
+ transform: translateX(-100%);
11
+ transition: transform 0.2s ease-out;
12
+ will-change: transform;
13
+
14
+ &.Ob-right {
15
+ left: unset;
16
+ right: 0;
17
+ transform: translateX(100%);
18
+ }
19
+
20
+ overflow-y: auto;
21
+
22
+ &.Ob-open {
23
+ transform: translateX(0);
24
+ }
25
+
26
+ &.ObSidebar-shadow {
27
+ box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
28
+
29
+ &.Ob-right {
30
+ box-shadow: -2px 2px 4px rgba(0, 0, 0, 0.15);
31
+ }
32
+ }
33
+ }
34
+
35
+ .ObSidebar-overlay {
36
+ position: fixed;
37
+ bottom: 0;
38
+ left: 0;
39
+ right: 0;
40
+ top: 0;
41
+ z-index: 1;
42
+
43
+ opacity: 0;
44
+ visibility: hidden;
45
+
46
+ transition: opacity 0.3s ease-out, visibility 0.3s ease-out;
47
+ background-color: rgba(0, 0, 0, 0.3);
48
+
49
+ &.Ob-open {
50
+ opacity: 1;
51
+ visibility: visible;
52
+ }
53
+ }
@@ -0,0 +1,117 @@
1
+ import "./index.scss";
2
+
3
+ import clsx from "clsx";
4
+ import { useEffect, useRef, useState } from "react";
5
+
6
+ export type SidebarProps = React.HTMLProps<HTMLDivElement> & {
7
+ open?: boolean;
8
+ onClose?: () => void;
9
+ overlayProps: React.HTMLProps<HTMLDivElement>;
10
+ pullRight?: boolean;
11
+ shadow?: boolean;
12
+ };
13
+
14
+ export function Sidebar(props: SidebarProps) {
15
+ const {
16
+ children,
17
+ className,
18
+ open = false,
19
+ onClose = () => {},
20
+ overlayProps = {},
21
+ pullRight = false,
22
+ shadow = true,
23
+ ...other
24
+ } = props;
25
+
26
+ const [hidden, setHidden] = useState(!open);
27
+ const sidebar = useRef<HTMLDivElement>(null);
28
+ const prevFocus = useRef<HTMLElement | null>(null);
29
+
30
+ function closeSidebar() {
31
+ if (open && typeof onClose === "function") {
32
+ onClose();
33
+ }
34
+ }
35
+
36
+ useEffect(() => {
37
+ let element = sidebar.current;
38
+
39
+ if (open) {
40
+ setHidden(false);
41
+ }
42
+
43
+ function toggleHiddenContent() {
44
+ setHidden(!open);
45
+ }
46
+
47
+ element?.addEventListener("transitionend", toggleHiddenContent);
48
+
49
+ return () => element?.removeEventListener("transitionend", toggleHiddenContent);
50
+ }, [open]);
51
+
52
+ useEffect(() => {
53
+ function handleCloseSidebar(evt) {
54
+ if (evt.key === "Escape") {
55
+ evt.stopPropagation();
56
+ closeSidebar();
57
+ }
58
+ }
59
+
60
+ window.addEventListener("keyup", handleCloseSidebar);
61
+
62
+ return () => window.removeEventListener("keyup", handleCloseSidebar);
63
+ }, [open, onClose]);
64
+
65
+ useEffect(() => {
66
+ if (open) {
67
+ prevFocus.current = document.activeElement as HTMLElement | null;
68
+
69
+ const firstFocusable = sidebar.current?.querySelector(
70
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
71
+ ) as HTMLElement | undefined;
72
+
73
+ if (firstFocusable) {
74
+ firstFocusable.focus();
75
+ }
76
+ } else if (prevFocus.current) {
77
+ prevFocus.current.focus();
78
+ prevFocus.current = null;
79
+ }
80
+
81
+ let prevFocusElem = prevFocus.current;
82
+
83
+ return () => {
84
+ if (open && prevFocusElem) {
85
+ prevFocusElem.focus();
86
+ }
87
+ };
88
+ }, [open]);
89
+
90
+ const { className: overlayClassName, ...overlayOther } = overlayProps;
91
+
92
+ return (
93
+ <>
94
+ <div
95
+ className={clsx(
96
+ "ObSidebar-root",
97
+ open && "Ob-open",
98
+ pullRight && "Ob-right",
99
+ shadow && "ObSidebar-shadow",
100
+ className
101
+ )}
102
+ ref={sidebar}
103
+ tabIndex={-1}
104
+ {...other}
105
+ >
106
+ {(open || !hidden) && children}
107
+ </div>
108
+ <div
109
+ role="presentation"
110
+ tabIndex={-1}
111
+ className={clsx("ObSidebar-overlay", open && "Ob-open", overlayClassName)}
112
+ onClick={closeSidebar}
113
+ {...overlayOther}
114
+ />
115
+ </>
116
+ );
117
+ }
@@ -0,0 +1,71 @@
1
+ $bullet-size: 0.5em;
2
+
3
+ .ObSpinner-root {
4
+ display: inline-block;
5
+ }
6
+
7
+ .ObSpinner-fullPage {
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+
12
+ height: 100vh;
13
+ width: 100vw;
14
+ }
15
+
16
+ .ObSpinner-spinner {
17
+ display: inline-block;
18
+ height: $bullet-size * 1.5;
19
+ position: relative;
20
+ width: $bullet-size * 5;
21
+ }
22
+
23
+ .ObSpinner-bullet {
24
+ animation-timing-function: cubic-bezier(0, 1, 1, 0);
25
+ background: #666;
26
+ border-radius: 50%;
27
+ height: $bullet-size;
28
+ position: absolute;
29
+ top: 0.2rem;
30
+ width: $bullet-size;
31
+
32
+ &:nth-child(1) {
33
+ animation: scaleAnimation 0.6s infinite ease-in-out;
34
+ left: $bullet-size * 0.5;
35
+ }
36
+
37
+ &:nth-child(2) {
38
+ animation: translateAnimation 0.6s infinite ease-in-out;
39
+ left: $bullet-size * 0.5;
40
+ }
41
+
42
+ &:nth-child(3) {
43
+ animation: translateAnimation 0.6s infinite ease-in-out;
44
+ left: $bullet-size * 2.4;
45
+ }
46
+
47
+ &:nth-child(4) {
48
+ animation: scaleAnimation 0.6s infinite ease-in-out reverse;
49
+ left: $bullet-size * 4;
50
+ }
51
+ }
52
+
53
+ @keyframes scaleAnimation {
54
+ from {
55
+ transform: scale(0);
56
+ }
57
+
58
+ to {
59
+ transform: scale(1);
60
+ }
61
+ }
62
+
63
+ @keyframes translateAnimation {
64
+ from {
65
+ transform: translate(0, 0);
66
+ }
67
+
68
+ to {
69
+ transform: translate($bullet-size * 1.65, 0);
70
+ }
71
+ }
@@ -0,0 +1,21 @@
1
+ import "./index.scss";
2
+
3
+ import clsx from "clsx";
4
+ import React from "react";
5
+
6
+ export type SpinnerProps = React.HTMLProps<HTMLDivElement> & {
7
+ fullPage?: boolean;
8
+ };
9
+
10
+ export function Spinner({ className = "", fullPage = false, ...rest }) {
11
+ return (
12
+ <div className={clsx(className, fullPage ? "ObSpinner-fullPage" : "ObSpinner-wrapper")} {...rest}>
13
+ <div className={"ObSpinner-spinner"}>
14
+ <div className={"ObSpinner-bullet"} />
15
+ <div className={"ObSpinner-bullet"} />
16
+ <div className={"ObSpinner-bullet"} />
17
+ <div className={"ObSpinner-bullet"} />
18
+ </div>
19
+ </div>
20
+ );
21
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ Hacky solution to sass output for some reason getting a zero-width space at the beginning, which breaks the first selector
3
+ */
4
+ .😖 {
5
+ display: initial;
6
+ }
7
+
8
+ .ObSplitContainer-root {
9
+ display: flex;
10
+ flex-direction: column;
11
+ height: 100%;
12
+ width: 100%;
13
+
14
+ &.horizontal {
15
+ flex-direction: row;
16
+ }
17
+ }
18
+
19
+ .ObSplitContainer-panel {
20
+ overflow: hidden;
21
+ }
22
+
23
+ .ObSplitContainer-divider {
24
+ flex: 0 0 0.5rem;
25
+ background-color: transparent;
26
+ line-height: 0.75;
27
+ cursor: ns-resize;
28
+
29
+ &:focus {
30
+ background-color: rgba(0, 0, 0, 0.3);
31
+ }
32
+
33
+ &::before {
34
+ content: "•••";
35
+ display: block;
36
+ width: 100%;
37
+ text-align: center;
38
+ }
39
+
40
+ .ObSplitContainer-root.horizontal & {
41
+ cursor: ew-resize;
42
+ }
43
+ }