@geoinsight/react-components 0.1.0 → 0.2.0
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 +171 -0
- package/dist/cjs/index.js +73 -0
- package/dist/esm/index.css +171 -0
- package/dist/esm/index.js +70 -1
- package/package.json +2 -1
- package/src/components/input/index.css +1 -0
- package/src/components/loading/index.css +8 -0
- package/src/components/loading/index.stories.tsx +20 -0
- package/src/components/loading/index.tsx +14 -0
- package/src/components/loading/index.types.ts +12 -0
- package/src/components/text-area/index.css +1 -0
- package/src/context/loading/index.stories.tsx +37 -0
- package/src/context/loading/index.tsx +111 -0
- package/src/context/themeContext.tsx +93 -0
- package/src/decorators/withColorScheme.tsx +20 -25
- package/src/decorators/withLoading.tsx +31 -0
- package/src/decorators/withWrapper.tsx +9 -0
- package/src/index.ts +5 -0
- package/src/stories/assets/loading.gif +0 -0
- package/src/stories/assets/spinner_2.png +0 -0
- package/src/styles/variables.css +15 -0
- package/src/types/palette-theme.d.ts +5 -0
- package/src/types/data-theme.d.ts +0 -5
package/dist/cjs/index.css
CHANGED
|
@@ -1,3 +1,118 @@
|
|
|
1
|
+
@import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap");
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
font-family: Poppins;
|
|
6
|
+
font-size: var(--font-size-16);
|
|
7
|
+
|
|
8
|
+
--font-size-10: 10px;
|
|
9
|
+
--font-size-12: 12px;
|
|
10
|
+
--font-size-14: 14px;
|
|
11
|
+
--font-size-16: 16px;
|
|
12
|
+
--font-size-18: 18px;
|
|
13
|
+
--font-size-20: 20px;
|
|
14
|
+
--font-size-24: 24px;
|
|
15
|
+
--font-size-32: 32px;
|
|
16
|
+
--font-size-40: 40px;
|
|
17
|
+
|
|
18
|
+
--spacing-4: 0.25rem;
|
|
19
|
+
--spacing-8: 0.5rem;
|
|
20
|
+
--spacing-16: 1rem;
|
|
21
|
+
--spacing-20: 1.25rem;
|
|
22
|
+
--spacing-24: 1.5rem;
|
|
23
|
+
--spacing-32: 2rem;
|
|
24
|
+
--spacing-40: 2.5rem;
|
|
25
|
+
--spacing-48: 3rem;
|
|
26
|
+
--spacing-64: 4rem;
|
|
27
|
+
--spacing-128: 8rem;
|
|
28
|
+
|
|
29
|
+
--color-black: #000000;
|
|
30
|
+
--color-white: #ffffff;
|
|
31
|
+
|
|
32
|
+
--color-neutral-200: #f2f2f2;
|
|
33
|
+
--color-neutral-300: #e0e0e0;
|
|
34
|
+
--color-neutral-400: #afafaf;
|
|
35
|
+
--color-neutral-500: #818181;
|
|
36
|
+
--color-neutral-600: #6c6c6c;
|
|
37
|
+
--color-neutral-700: #403b3a;
|
|
38
|
+
--color-neutral-800: #201e1d;
|
|
39
|
+
|
|
40
|
+
--color-success: #20e52f;
|
|
41
|
+
--color-danger: #e52f20;
|
|
42
|
+
|
|
43
|
+
--transition-bg-cubic-bezier: background-color 500ms
|
|
44
|
+
cubic-bezier(0.1, 0.2, 0.3, 0.4);
|
|
45
|
+
--transition-color-cubic-bezier: color 500ms cubic-bezier(0.1, 0.2, 0.3, 0.4);
|
|
46
|
+
--transition-text-decoration-cubic-bezier: text-decoration 500ms cubic-bezier(0.1, 0.2, 0.3, 0.4);
|
|
47
|
+
--transition-box-shadow-cubic-bezier: box-shadow 500ms cubic-bezier(0.1, 0.2, 0.3, 0.4);
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
[data-theme="dark"] {
|
|
53
|
+
--color-neutral-900: var(--color-black);
|
|
54
|
+
--color-neutral-100: var(--color-white);
|
|
55
|
+
--color-primary: var(--color-primary-500);
|
|
56
|
+
--color-secondary: var(--color-primary-600);
|
|
57
|
+
|
|
58
|
+
color: var(--color-neutral-100) !important;
|
|
59
|
+
background-color: var(--color-neutral-900) !important;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[data-theme="light"] {
|
|
63
|
+
--color-neutral-900: var(--color-white);
|
|
64
|
+
--color-neutral-100: var(--color-black);
|
|
65
|
+
--color-primary: var(--color-primary-600);
|
|
66
|
+
--color-secondary: var(--color-primary-500);
|
|
67
|
+
color: var(--color-neutral-900) !important;
|
|
68
|
+
background-color: var(--color-neutral-100) !important;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (prefers-color-scheme: dark) {
|
|
72
|
+
html {
|
|
73
|
+
color-scheme: dark;
|
|
74
|
+
}
|
|
75
|
+
body {
|
|
76
|
+
color: var(--color-neutral-100);
|
|
77
|
+
background-color: var(--color-neutral-900);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[palette-theme="water"] {
|
|
82
|
+
--color-primary-100: #d6efff;
|
|
83
|
+
--color-primary-200: #ade0ff;
|
|
84
|
+
--color-primary-300: #85d0ff;
|
|
85
|
+
--color-primary-400: #5cc0ff;
|
|
86
|
+
--color-primary-500: #33b1ff;
|
|
87
|
+
--color-primary-600: #009eff;
|
|
88
|
+
--color-primary-700: #008ae0;
|
|
89
|
+
--color-primary-800: #0071b8;
|
|
90
|
+
--color-primary-900: #00588f;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[palette-theme="earth"]{
|
|
94
|
+
--color-primary-100: #f6e3cb;
|
|
95
|
+
--color-primary-200: #edc897;
|
|
96
|
+
--color-primary-300: #eabe86;
|
|
97
|
+
--color-primary-400: #e3ac63;
|
|
98
|
+
--color-primary-500: #dd9940;
|
|
99
|
+
--color-primary-600: #ca8323;
|
|
100
|
+
--color-primary-700: #ad701f;
|
|
101
|
+
--color-primary-800: #8b5918;
|
|
102
|
+
--color-primary-900: #684312;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
[palette-theme="forest"] {
|
|
106
|
+
--color-primary-100: #bee8b0;
|
|
107
|
+
--color-primary-200: #a4df90;
|
|
108
|
+
--color-primary-300: #8ad671;
|
|
109
|
+
--color-primary-400: #70cd51;
|
|
110
|
+
--color-primary-500: #54b435;
|
|
111
|
+
--color-primary-600: #4a9e2e;
|
|
112
|
+
--color-primary-700: #3b7e25;
|
|
113
|
+
--color-primary-800: #2c5f1c;
|
|
114
|
+
--color-primary-900: #1e3f12;
|
|
115
|
+
}
|
|
1
116
|
.button {
|
|
2
117
|
align-items: center;
|
|
3
118
|
border-radius: var(--spacing-32);
|
|
@@ -86,6 +201,7 @@
|
|
|
86
201
|
}
|
|
87
202
|
|
|
88
203
|
.input {
|
|
204
|
+
background-color: var(--color-white);
|
|
89
205
|
border-radius: var(--spacing-8);
|
|
90
206
|
border: 2px solid var(--color-primary);
|
|
91
207
|
color: var(--color-black);
|
|
@@ -109,3 +225,58 @@
|
|
|
109
225
|
font-size: 12px;
|
|
110
226
|
color: var(--color-danger);
|
|
111
227
|
}
|
|
228
|
+
|
|
229
|
+
.textarea {
|
|
230
|
+
margin-bottom: var(--spacing-8);
|
|
231
|
+
position: relative;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.textarea__input {
|
|
235
|
+
background-color: var(--color-white);
|
|
236
|
+
box-sizing: border-box;
|
|
237
|
+
border-radius: var(--spacing-8);
|
|
238
|
+
border: 2px solid var(--color-primary);
|
|
239
|
+
cursor: text;
|
|
240
|
+
color: var(--color-black);
|
|
241
|
+
outline: none;
|
|
242
|
+
padding: var(--spacing-8) var(--spacing-16);
|
|
243
|
+
resize: vertical;
|
|
244
|
+
width: 100%;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.textarea__input:hover {
|
|
248
|
+
border: 3px solid var(--color-primary-700);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.textarea__button {
|
|
252
|
+
background: var(--color-primary);
|
|
253
|
+
border: 2px solid var(--color-secondary);
|
|
254
|
+
box-shadow: 2px 4px 2px 1px rgba(0, 0, 0, 0.25);
|
|
255
|
+
border-radius: 0px 0px var(--spacing-8) var(--spacing-8);
|
|
256
|
+
bottom: 0;
|
|
257
|
+
cursor: pointer;
|
|
258
|
+
left: 0;
|
|
259
|
+
padding-bottom: -20px;
|
|
260
|
+
position: absolute;
|
|
261
|
+
width: 100%;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.textarea__button > svg {
|
|
265
|
+
color: var(--color-neutral-100);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.textarea__button:disabled {
|
|
269
|
+
cursor: unset;
|
|
270
|
+
opacity: 0.5;
|
|
271
|
+
pointer-events: none;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.textarea__button:hover {
|
|
275
|
+
background: var(--color-secondary);
|
|
276
|
+
color: var(--color-neutral-100);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.textarea__button--show {
|
|
280
|
+
background: var(--color-primary-700);
|
|
281
|
+
color: var(--color-neutral-100);
|
|
282
|
+
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var clsx = require('clsx');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var tb = require('react-icons/tb');
|
|
5
7
|
|
|
6
8
|
function Button({ children = "Click me", className = "", icon = undefined, isNewWindow = false, mode = "primary", size = "medium", as = "button", ...rest }) {
|
|
7
9
|
return as === "link" ? (jsxRuntime.jsxs("a", { ...(isNewWindow && { target: "_blank" }), className: clsx(className, "button", mode === "secondary" ? `button button__${mode}` : "button__link", `button__${size}`), ...rest, children: [children, icon] })) : (jsxRuntime.jsxs("button", { className: clsx(className, "button", `button__${mode}`, `button__${size}`), ...rest, children: [children, icon] }));
|
|
@@ -11,5 +13,76 @@ function Input({ className = "", classNameGroup = "", errorMessage = "", inputRe
|
|
|
11
13
|
return (jsxRuntime.jsxs("div", { className: `input-group ${classNameGroup}`, style: styleGroup, children: [jsxRuntime.jsx("input", { ref: inputRef, className: `input ${errorMessage ? "input--error" : ""} ${className}`, ...rest }), errorMessage && jsxRuntime.jsx("span", { className: "error", children: errorMessage })] }));
|
|
12
14
|
}
|
|
13
15
|
|
|
16
|
+
function TextArea({ className = "", disabled = true, hasToggleButton = true, hideHeight = "5rem", placeholder = "", showHeight = "10rem", style = {}, textareaClassName = "", ...rest }) {
|
|
17
|
+
const ref = react.useRef();
|
|
18
|
+
const [isShow, setIsShow] = react.useState(false);
|
|
19
|
+
const handleClickToggle = () => {
|
|
20
|
+
if (ref && ref.current) {
|
|
21
|
+
if (isShow) {
|
|
22
|
+
ref.current.style.height = hideHeight;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
ref.current.style.height = showHeight; //(48 + ref.current.scrollHeight) + 'px';
|
|
26
|
+
}
|
|
27
|
+
setIsShow((prev) => !prev);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
return (jsxRuntime.jsxs("div", { className: clsx("textarea", className), style: style, children: [jsxRuntime.jsx("textarea", { ref: ref, className: clsx("textarea__input", textareaClassName), style: {
|
|
31
|
+
height: hasToggleButton ? hideHeight : showHeight,
|
|
32
|
+
}, placeholder: placeholder, disabled: disabled, ...rest }), hasToggleButton && (jsxRuntime.jsx("button", { className: clsx("textarea__button", isShow && "textarea__button--show"), onClick: handleClickToggle, disabled: disabled, children: jsxRuntime.jsx(tb.TbArrowsDiagonal2, { size: "1.5rem" }) }))] }));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const ThemeContext = react.createContext(undefined);
|
|
36
|
+
function ThemeProvider({ children }) {
|
|
37
|
+
const [dataTheme, setDataTheme] = react.useState();
|
|
38
|
+
const [paletteTheme, setPaletteTheme] = react.useState();
|
|
39
|
+
react.useEffect(() => {
|
|
40
|
+
if (window.matchMedia) {
|
|
41
|
+
if (localStorage.getItem("data-theme")) {
|
|
42
|
+
document.documentElement.setAttribute("data-theme", localStorage.getItem("data-theme"));
|
|
43
|
+
setDataTheme(localStorage.getItem("data-theme"));
|
|
44
|
+
}
|
|
45
|
+
else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
46
|
+
document.documentElement.setAttribute("data-theme", "dark");
|
|
47
|
+
setDataTheme("dark");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, []);
|
|
51
|
+
const switchDataTheme = (mode) => {
|
|
52
|
+
document.documentElement.setAttribute("data-theme", mode);
|
|
53
|
+
setDataTheme(mode);
|
|
54
|
+
localStorage.setItem("data-theme", mode);
|
|
55
|
+
};
|
|
56
|
+
const switchPaletteTheme = (mode) => {
|
|
57
|
+
document.documentElement.setAttribute("palette-theme", mode);
|
|
58
|
+
setPaletteTheme(mode);
|
|
59
|
+
localStorage.setItem("palette-theme", mode);
|
|
60
|
+
};
|
|
61
|
+
return (jsxRuntime.jsx(ThemeContext.Provider, { value: { dataTheme, switchDataTheme, paletteTheme, switchPaletteTheme }, children: children }));
|
|
62
|
+
}
|
|
63
|
+
function useTheme({ dataTheme = undefined, paletteTheme = "water", } = {}) {
|
|
64
|
+
const context = react.useContext(ThemeContext);
|
|
65
|
+
// only happens if there is an initial mode value.
|
|
66
|
+
react.useEffect(() => {
|
|
67
|
+
if (dataTheme && !localStorage.getItem("data-theme")) {
|
|
68
|
+
context?.switchDataTheme(dataTheme);
|
|
69
|
+
}
|
|
70
|
+
else if (!dataTheme && localStorage.getItem("data-theme")) {
|
|
71
|
+
localStorage.removeItem("data-theme");
|
|
72
|
+
}
|
|
73
|
+
}, []);
|
|
74
|
+
react.useEffect(() => {
|
|
75
|
+
context?.switchPaletteTheme(paletteTheme);
|
|
76
|
+
}, []);
|
|
77
|
+
if (context === undefined) {
|
|
78
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
79
|
+
}
|
|
80
|
+
return context;
|
|
81
|
+
}
|
|
82
|
+
|
|
14
83
|
exports.Button = Button;
|
|
15
84
|
exports.Input = Input;
|
|
85
|
+
exports.TextArea = TextArea;
|
|
86
|
+
exports.ThemeContext = ThemeContext;
|
|
87
|
+
exports.ThemeProvider = ThemeProvider;
|
|
88
|
+
exports.useTheme = useTheme;
|
package/dist/esm/index.css
CHANGED
|
@@ -1,3 +1,118 @@
|
|
|
1
|
+
@import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap");
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
font-family: Poppins;
|
|
6
|
+
font-size: var(--font-size-16);
|
|
7
|
+
|
|
8
|
+
--font-size-10: 10px;
|
|
9
|
+
--font-size-12: 12px;
|
|
10
|
+
--font-size-14: 14px;
|
|
11
|
+
--font-size-16: 16px;
|
|
12
|
+
--font-size-18: 18px;
|
|
13
|
+
--font-size-20: 20px;
|
|
14
|
+
--font-size-24: 24px;
|
|
15
|
+
--font-size-32: 32px;
|
|
16
|
+
--font-size-40: 40px;
|
|
17
|
+
|
|
18
|
+
--spacing-4: 0.25rem;
|
|
19
|
+
--spacing-8: 0.5rem;
|
|
20
|
+
--spacing-16: 1rem;
|
|
21
|
+
--spacing-20: 1.25rem;
|
|
22
|
+
--spacing-24: 1.5rem;
|
|
23
|
+
--spacing-32: 2rem;
|
|
24
|
+
--spacing-40: 2.5rem;
|
|
25
|
+
--spacing-48: 3rem;
|
|
26
|
+
--spacing-64: 4rem;
|
|
27
|
+
--spacing-128: 8rem;
|
|
28
|
+
|
|
29
|
+
--color-black: #000000;
|
|
30
|
+
--color-white: #ffffff;
|
|
31
|
+
|
|
32
|
+
--color-neutral-200: #f2f2f2;
|
|
33
|
+
--color-neutral-300: #e0e0e0;
|
|
34
|
+
--color-neutral-400: #afafaf;
|
|
35
|
+
--color-neutral-500: #818181;
|
|
36
|
+
--color-neutral-600: #6c6c6c;
|
|
37
|
+
--color-neutral-700: #403b3a;
|
|
38
|
+
--color-neutral-800: #201e1d;
|
|
39
|
+
|
|
40
|
+
--color-success: #20e52f;
|
|
41
|
+
--color-danger: #e52f20;
|
|
42
|
+
|
|
43
|
+
--transition-bg-cubic-bezier: background-color 500ms
|
|
44
|
+
cubic-bezier(0.1, 0.2, 0.3, 0.4);
|
|
45
|
+
--transition-color-cubic-bezier: color 500ms cubic-bezier(0.1, 0.2, 0.3, 0.4);
|
|
46
|
+
--transition-text-decoration-cubic-bezier: text-decoration 500ms cubic-bezier(0.1, 0.2, 0.3, 0.4);
|
|
47
|
+
--transition-box-shadow-cubic-bezier: box-shadow 500ms cubic-bezier(0.1, 0.2, 0.3, 0.4);
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
[data-theme="dark"] {
|
|
53
|
+
--color-neutral-900: var(--color-black);
|
|
54
|
+
--color-neutral-100: var(--color-white);
|
|
55
|
+
--color-primary: var(--color-primary-500);
|
|
56
|
+
--color-secondary: var(--color-primary-600);
|
|
57
|
+
|
|
58
|
+
color: var(--color-neutral-100) !important;
|
|
59
|
+
background-color: var(--color-neutral-900) !important;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[data-theme="light"] {
|
|
63
|
+
--color-neutral-900: var(--color-white);
|
|
64
|
+
--color-neutral-100: var(--color-black);
|
|
65
|
+
--color-primary: var(--color-primary-600);
|
|
66
|
+
--color-secondary: var(--color-primary-500);
|
|
67
|
+
color: var(--color-neutral-900) !important;
|
|
68
|
+
background-color: var(--color-neutral-100) !important;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (prefers-color-scheme: dark) {
|
|
72
|
+
html {
|
|
73
|
+
color-scheme: dark;
|
|
74
|
+
}
|
|
75
|
+
body {
|
|
76
|
+
color: var(--color-neutral-100);
|
|
77
|
+
background-color: var(--color-neutral-900);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[palette-theme="water"] {
|
|
82
|
+
--color-primary-100: #d6efff;
|
|
83
|
+
--color-primary-200: #ade0ff;
|
|
84
|
+
--color-primary-300: #85d0ff;
|
|
85
|
+
--color-primary-400: #5cc0ff;
|
|
86
|
+
--color-primary-500: #33b1ff;
|
|
87
|
+
--color-primary-600: #009eff;
|
|
88
|
+
--color-primary-700: #008ae0;
|
|
89
|
+
--color-primary-800: #0071b8;
|
|
90
|
+
--color-primary-900: #00588f;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[palette-theme="earth"]{
|
|
94
|
+
--color-primary-100: #f6e3cb;
|
|
95
|
+
--color-primary-200: #edc897;
|
|
96
|
+
--color-primary-300: #eabe86;
|
|
97
|
+
--color-primary-400: #e3ac63;
|
|
98
|
+
--color-primary-500: #dd9940;
|
|
99
|
+
--color-primary-600: #ca8323;
|
|
100
|
+
--color-primary-700: #ad701f;
|
|
101
|
+
--color-primary-800: #8b5918;
|
|
102
|
+
--color-primary-900: #684312;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
[palette-theme="forest"] {
|
|
106
|
+
--color-primary-100: #bee8b0;
|
|
107
|
+
--color-primary-200: #a4df90;
|
|
108
|
+
--color-primary-300: #8ad671;
|
|
109
|
+
--color-primary-400: #70cd51;
|
|
110
|
+
--color-primary-500: #54b435;
|
|
111
|
+
--color-primary-600: #4a9e2e;
|
|
112
|
+
--color-primary-700: #3b7e25;
|
|
113
|
+
--color-primary-800: #2c5f1c;
|
|
114
|
+
--color-primary-900: #1e3f12;
|
|
115
|
+
}
|
|
1
116
|
.button {
|
|
2
117
|
align-items: center;
|
|
3
118
|
border-radius: var(--spacing-32);
|
|
@@ -86,6 +201,7 @@
|
|
|
86
201
|
}
|
|
87
202
|
|
|
88
203
|
.input {
|
|
204
|
+
background-color: var(--color-white);
|
|
89
205
|
border-radius: var(--spacing-8);
|
|
90
206
|
border: 2px solid var(--color-primary);
|
|
91
207
|
color: var(--color-black);
|
|
@@ -109,3 +225,58 @@
|
|
|
109
225
|
font-size: 12px;
|
|
110
226
|
color: var(--color-danger);
|
|
111
227
|
}
|
|
228
|
+
|
|
229
|
+
.textarea {
|
|
230
|
+
margin-bottom: var(--spacing-8);
|
|
231
|
+
position: relative;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.textarea__input {
|
|
235
|
+
background-color: var(--color-white);
|
|
236
|
+
box-sizing: border-box;
|
|
237
|
+
border-radius: var(--spacing-8);
|
|
238
|
+
border: 2px solid var(--color-primary);
|
|
239
|
+
cursor: text;
|
|
240
|
+
color: var(--color-black);
|
|
241
|
+
outline: none;
|
|
242
|
+
padding: var(--spacing-8) var(--spacing-16);
|
|
243
|
+
resize: vertical;
|
|
244
|
+
width: 100%;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.textarea__input:hover {
|
|
248
|
+
border: 3px solid var(--color-primary-700);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.textarea__button {
|
|
252
|
+
background: var(--color-primary);
|
|
253
|
+
border: 2px solid var(--color-secondary);
|
|
254
|
+
box-shadow: 2px 4px 2px 1px rgba(0, 0, 0, 0.25);
|
|
255
|
+
border-radius: 0px 0px var(--spacing-8) var(--spacing-8);
|
|
256
|
+
bottom: 0;
|
|
257
|
+
cursor: pointer;
|
|
258
|
+
left: 0;
|
|
259
|
+
padding-bottom: -20px;
|
|
260
|
+
position: absolute;
|
|
261
|
+
width: 100%;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.textarea__button > svg {
|
|
265
|
+
color: var(--color-neutral-100);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.textarea__button:disabled {
|
|
269
|
+
cursor: unset;
|
|
270
|
+
opacity: 0.5;
|
|
271
|
+
pointer-events: none;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.textarea__button:hover {
|
|
275
|
+
background: var(--color-secondary);
|
|
276
|
+
color: var(--color-neutral-100);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.textarea__button--show {
|
|
280
|
+
background: var(--color-primary-700);
|
|
281
|
+
color: var(--color-neutral-100);
|
|
282
|
+
}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
+
import { useRef, useState, createContext, useEffect, useContext } from 'react';
|
|
4
|
+
import { TbArrowsDiagonal2 } from 'react-icons/tb';
|
|
3
5
|
|
|
4
6
|
function Button({ children = "Click me", className = "", icon = undefined, isNewWindow = false, mode = "primary", size = "medium", as = "button", ...rest }) {
|
|
5
7
|
return as === "link" ? (jsxs("a", { ...(isNewWindow && { target: "_blank" }), className: clsx(className, "button", mode === "secondary" ? `button button__${mode}` : "button__link", `button__${size}`), ...rest, children: [children, icon] })) : (jsxs("button", { className: clsx(className, "button", `button__${mode}`, `button__${size}`), ...rest, children: [children, icon] }));
|
|
@@ -9,4 +11,71 @@ function Input({ className = "", classNameGroup = "", errorMessage = "", inputRe
|
|
|
9
11
|
return (jsxs("div", { className: `input-group ${classNameGroup}`, style: styleGroup, children: [jsx("input", { ref: inputRef, className: `input ${errorMessage ? "input--error" : ""} ${className}`, ...rest }), errorMessage && jsx("span", { className: "error", children: errorMessage })] }));
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
function TextArea({ className = "", disabled = true, hasToggleButton = true, hideHeight = "5rem", placeholder = "", showHeight = "10rem", style = {}, textareaClassName = "", ...rest }) {
|
|
15
|
+
const ref = useRef();
|
|
16
|
+
const [isShow, setIsShow] = useState(false);
|
|
17
|
+
const handleClickToggle = () => {
|
|
18
|
+
if (ref && ref.current) {
|
|
19
|
+
if (isShow) {
|
|
20
|
+
ref.current.style.height = hideHeight;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
ref.current.style.height = showHeight; //(48 + ref.current.scrollHeight) + 'px';
|
|
24
|
+
}
|
|
25
|
+
setIsShow((prev) => !prev);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return (jsxs("div", { className: clsx("textarea", className), style: style, children: [jsx("textarea", { ref: ref, className: clsx("textarea__input", textareaClassName), style: {
|
|
29
|
+
height: hasToggleButton ? hideHeight : showHeight,
|
|
30
|
+
}, placeholder: placeholder, disabled: disabled, ...rest }), hasToggleButton && (jsx("button", { className: clsx("textarea__button", isShow && "textarea__button--show"), onClick: handleClickToggle, disabled: disabled, children: jsx(TbArrowsDiagonal2, { size: "1.5rem" }) }))] }));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const ThemeContext = createContext(undefined);
|
|
34
|
+
function ThemeProvider({ children }) {
|
|
35
|
+
const [dataTheme, setDataTheme] = useState();
|
|
36
|
+
const [paletteTheme, setPaletteTheme] = useState();
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (window.matchMedia) {
|
|
39
|
+
if (localStorage.getItem("data-theme")) {
|
|
40
|
+
document.documentElement.setAttribute("data-theme", localStorage.getItem("data-theme"));
|
|
41
|
+
setDataTheme(localStorage.getItem("data-theme"));
|
|
42
|
+
}
|
|
43
|
+
else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
44
|
+
document.documentElement.setAttribute("data-theme", "dark");
|
|
45
|
+
setDataTheme("dark");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}, []);
|
|
49
|
+
const switchDataTheme = (mode) => {
|
|
50
|
+
document.documentElement.setAttribute("data-theme", mode);
|
|
51
|
+
setDataTheme(mode);
|
|
52
|
+
localStorage.setItem("data-theme", mode);
|
|
53
|
+
};
|
|
54
|
+
const switchPaletteTheme = (mode) => {
|
|
55
|
+
document.documentElement.setAttribute("palette-theme", mode);
|
|
56
|
+
setPaletteTheme(mode);
|
|
57
|
+
localStorage.setItem("palette-theme", mode);
|
|
58
|
+
};
|
|
59
|
+
return (jsx(ThemeContext.Provider, { value: { dataTheme, switchDataTheme, paletteTheme, switchPaletteTheme }, children: children }));
|
|
60
|
+
}
|
|
61
|
+
function useTheme({ dataTheme = undefined, paletteTheme = "water", } = {}) {
|
|
62
|
+
const context = useContext(ThemeContext);
|
|
63
|
+
// only happens if there is an initial mode value.
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (dataTheme && !localStorage.getItem("data-theme")) {
|
|
66
|
+
context?.switchDataTheme(dataTheme);
|
|
67
|
+
}
|
|
68
|
+
else if (!dataTheme && localStorage.getItem("data-theme")) {
|
|
69
|
+
localStorage.removeItem("data-theme");
|
|
70
|
+
}
|
|
71
|
+
}, []);
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
context?.switchPaletteTheme(paletteTheme);
|
|
74
|
+
}, []);
|
|
75
|
+
if (context === undefined) {
|
|
76
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
77
|
+
}
|
|
78
|
+
return context;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { Button, Input, TextArea, ThemeContext, ThemeProvider, useTheme };
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geoinsight/react-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "This library is the main UI component library for geoinsight",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
7
8
|
"author": "Geoinsight",
|
|
8
9
|
"license": "MIT",
|
|
9
10
|
"scripts": {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
|
|
3
|
+
import { Loading } from "./index";
|
|
4
|
+
import { withColorScheme } from "../../decorators/withColorScheme";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Loading> = {
|
|
7
|
+
title: "Example/Loading",
|
|
8
|
+
component: Loading,
|
|
9
|
+
decorators: [withColorScheme]
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
|
|
14
|
+
type Story = StoryObj<typeof Loading>;
|
|
15
|
+
|
|
16
|
+
export const Primary: Story = {
|
|
17
|
+
args: {
|
|
18
|
+
img: ""
|
|
19
|
+
},
|
|
20
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Loading as LoadingProps } from "./index.types";
|
|
2
|
+
import "./index.css";
|
|
3
|
+
import loading from "../../stories/assets/loading.gif";
|
|
4
|
+
|
|
5
|
+
export function Loading({ img, children }: LoadingProps) {
|
|
6
|
+
return (
|
|
7
|
+
<div className="loading">
|
|
8
|
+
<img src={img ? img : loading} />
|
|
9
|
+
{children}
|
|
10
|
+
</div>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default Loading;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
|
|
3
|
+
import { LoadingProvider } from ".";
|
|
4
|
+
import { withColorScheme } from "../../decorators/withColorScheme";
|
|
5
|
+
import { withLoading } from "../../decorators/withLoading";
|
|
6
|
+
import spinner from "../../stories/assets/spinner_2.png";
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof LoadingProvider> = {
|
|
9
|
+
title: "Context/Loading",
|
|
10
|
+
component: () => <div></div>,
|
|
11
|
+
decorators: [withColorScheme, withLoading],
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
|
|
16
|
+
type Story = StoryObj<typeof LoadingProvider>;
|
|
17
|
+
|
|
18
|
+
export const Basic: Story = {};
|
|
19
|
+
|
|
20
|
+
export const CustomMessage: Story = {
|
|
21
|
+
parameters: {
|
|
22
|
+
loadingOptions: {
|
|
23
|
+
message: "Updating form",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const CustomImage: Story = {
|
|
29
|
+
parameters: {
|
|
30
|
+
loadingOptions: {
|
|
31
|
+
isRef: true,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
args: {
|
|
35
|
+
img: spinner,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
ReactNode,
|
|
3
|
+
RefObject,
|
|
4
|
+
createContext,
|
|
5
|
+
useContext,
|
|
6
|
+
useEffect,
|
|
7
|
+
useReducer,
|
|
8
|
+
} from "react";
|
|
9
|
+
import Loading from "../../components/loading";
|
|
10
|
+
|
|
11
|
+
type Action = {
|
|
12
|
+
type: "set_ref" | "start_loading" | "stop_loading" | "set_message";
|
|
13
|
+
ref?: RefObject<ReactNode>;
|
|
14
|
+
message?: string;
|
|
15
|
+
};
|
|
16
|
+
type State = {
|
|
17
|
+
isLoading: boolean;
|
|
18
|
+
message?: string | React.ReactNode;
|
|
19
|
+
ref?: RefObject<ReactNode>;
|
|
20
|
+
};
|
|
21
|
+
type Context = {
|
|
22
|
+
state: State;
|
|
23
|
+
setRef: (ref: RefObject<ReactNode>) => void;
|
|
24
|
+
setMessage: (message: string) => void;
|
|
25
|
+
startLoading: () => void;
|
|
26
|
+
stopLoading: () => void;
|
|
27
|
+
};
|
|
28
|
+
type LoadingProviderProps = { children: React.ReactNode };
|
|
29
|
+
type UseLoadingProps = {
|
|
30
|
+
ref?: RefObject<ReactNode>;
|
|
31
|
+
message?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const LoadingContext = createContext<Context | undefined>(undefined);
|
|
35
|
+
|
|
36
|
+
function loadingReducer(state: State, action: Action) {
|
|
37
|
+
switch (action.type) {
|
|
38
|
+
case "set_ref": {
|
|
39
|
+
return { ...state, ref: action.ref };
|
|
40
|
+
}
|
|
41
|
+
case "start_loading": {
|
|
42
|
+
return { ...state, isLoading: true };
|
|
43
|
+
}
|
|
44
|
+
case "stop_loading": {
|
|
45
|
+
return { ...state, isLoading: false };
|
|
46
|
+
}
|
|
47
|
+
case "set_message": {
|
|
48
|
+
return { ...state, message: action.message };
|
|
49
|
+
}
|
|
50
|
+
default: {
|
|
51
|
+
throw new Error(`Unhandled action type: ${action.type}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function LoadingProvider({ children }: LoadingProviderProps) {
|
|
57
|
+
const [{ isLoading, message, ref }, dispatch] = useReducer(loadingReducer, {
|
|
58
|
+
isLoading: false,
|
|
59
|
+
message: "Loading",
|
|
60
|
+
ref: undefined,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const setRef = (ref: RefObject<ReactNode>) => {
|
|
64
|
+
dispatch({ type: "set_ref", ref });
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const setMessage = (message: string) => {
|
|
68
|
+
dispatch({ type: "set_message", message });
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const startLoading = () => {
|
|
72
|
+
dispatch({ type: "start_loading" });
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const stopLoading = () => {
|
|
76
|
+
dispatch({ type: "stop_loading" });
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<LoadingContext.Provider
|
|
81
|
+
value={{
|
|
82
|
+
state: { ref, message, isLoading },
|
|
83
|
+
setMessage,
|
|
84
|
+
setRef,
|
|
85
|
+
startLoading,
|
|
86
|
+
stopLoading,
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
{!ref && <Loading>{message}</Loading>}
|
|
90
|
+
{children}
|
|
91
|
+
</LoadingContext.Provider>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function useLoading({ ref, message }: UseLoadingProps = {}) {
|
|
96
|
+
const context = useContext(LoadingContext);
|
|
97
|
+
|
|
98
|
+
// only happens if there is an initial mode value.
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
ref && context?.setRef(ref);
|
|
101
|
+
message && context?.setMessage(message);
|
|
102
|
+
}, []);
|
|
103
|
+
|
|
104
|
+
if (context === undefined) {
|
|
105
|
+
throw new Error("useLoading must be used within a LoadingProvider");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return context;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export { LoadingContext, LoadingProvider, useLoading };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { PaletteTheme } from "palette-theme";
|
|
2
|
+
import React, {
|
|
3
|
+
Dispatch,
|
|
4
|
+
SetStateAction,
|
|
5
|
+
createContext,
|
|
6
|
+
useContext,
|
|
7
|
+
useEffect,
|
|
8
|
+
useState,
|
|
9
|
+
} from "react";
|
|
10
|
+
|
|
11
|
+
type DataTheme = "light" | "dark";
|
|
12
|
+
|
|
13
|
+
type State = {
|
|
14
|
+
dataTheme?: DataTheme;
|
|
15
|
+
switchDataTheme: (mode: DataTheme) => void;
|
|
16
|
+
paletteTheme?: PaletteTheme;
|
|
17
|
+
switchPaletteTheme: (mode: PaletteTheme) => void;
|
|
18
|
+
};
|
|
19
|
+
type ThemeProviderProps = { children: React.ReactNode };
|
|
20
|
+
type UseThemeProps = {
|
|
21
|
+
dataTheme?: DataTheme;
|
|
22
|
+
paletteTheme?: PaletteTheme;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const ThemeContext = createContext<State | undefined>(undefined);
|
|
26
|
+
|
|
27
|
+
function ThemeProvider({ children }: ThemeProviderProps) {
|
|
28
|
+
const [dataTheme, setDataTheme] = useState<DataTheme>();
|
|
29
|
+
const [paletteTheme, setPaletteTheme] = useState<PaletteTheme>();
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (window.matchMedia) {
|
|
33
|
+
if (localStorage.getItem("data-theme")) {
|
|
34
|
+
document.documentElement.setAttribute(
|
|
35
|
+
"data-theme",
|
|
36
|
+
localStorage.getItem("data-theme") as string
|
|
37
|
+
);
|
|
38
|
+
setDataTheme(localStorage.getItem("data-theme") as DataTheme);
|
|
39
|
+
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
40
|
+
document.documentElement.setAttribute("data-theme", "dark");
|
|
41
|
+
setDataTheme("dark");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
46
|
+
const switchDataTheme = (mode: DataTheme) => {
|
|
47
|
+
document.documentElement.setAttribute("data-theme", mode);
|
|
48
|
+
setDataTheme(mode);
|
|
49
|
+
localStorage.setItem("data-theme", mode);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const switchPaletteTheme = (mode: PaletteTheme) => {
|
|
53
|
+
document.documentElement.setAttribute("palette-theme", mode);
|
|
54
|
+
setPaletteTheme(mode);
|
|
55
|
+
localStorage.setItem("palette-theme", mode);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<ThemeContext.Provider
|
|
60
|
+
value={{ dataTheme, switchDataTheme, paletteTheme, switchPaletteTheme }}
|
|
61
|
+
>
|
|
62
|
+
{children}
|
|
63
|
+
</ThemeContext.Provider>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function useTheme({
|
|
68
|
+
dataTheme = undefined,
|
|
69
|
+
paletteTheme = "water",
|
|
70
|
+
}: UseThemeProps = {}) {
|
|
71
|
+
const context = useContext(ThemeContext);
|
|
72
|
+
|
|
73
|
+
// only happens if there is an initial mode value.
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (dataTheme && !localStorage.getItem("data-theme")) {
|
|
76
|
+
context?.switchDataTheme(dataTheme);
|
|
77
|
+
} else if (!dataTheme && localStorage.getItem("data-theme")) {
|
|
78
|
+
localStorage.removeItem("data-theme");
|
|
79
|
+
}
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
context?.switchPaletteTheme(paletteTheme);
|
|
84
|
+
}, []);
|
|
85
|
+
|
|
86
|
+
if (context === undefined) {
|
|
87
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return context;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { ThemeContext, ThemeProvider, useTheme };
|
|
@@ -1,34 +1,29 @@
|
|
|
1
1
|
import { StoryContext, StoryFn } from "@storybook/react";
|
|
2
|
+
import { ThemeProvider, useTheme } from "../context/themeContext";
|
|
3
|
+
import "../styles/variables.css";
|
|
4
|
+
import { useEffect } from "react";
|
|
2
5
|
|
|
3
6
|
export const withColorScheme = (Story: StoryFn, context: StoryContext) => {
|
|
7
|
+
return (
|
|
8
|
+
<ThemeProvider>
|
|
9
|
+
<Wrapped Story={Story} context={context} />
|
|
10
|
+
</ThemeProvider>
|
|
11
|
+
);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const Wrapped = ({ Story, context } : { Story: StoryFn, context: StoryContext}) => {
|
|
4
15
|
const { theme, palette } = context.globals;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}}
|
|
15
|
-
>
|
|
16
|
-
<Story />
|
|
17
|
-
</div>
|
|
18
|
-
);
|
|
19
|
-
}
|
|
16
|
+
const switchTheme = useTheme();
|
|
17
|
+
|
|
18
|
+
useEffect (()=> {
|
|
19
|
+
switchTheme.switchDataTheme(theme)
|
|
20
|
+
}, [theme]);
|
|
21
|
+
|
|
22
|
+
useEffect (()=> {
|
|
23
|
+
switchTheme.switchPaletteTheme(palette)
|
|
24
|
+
}, [palette]);
|
|
20
25
|
|
|
21
26
|
return (
|
|
22
|
-
<div
|
|
23
|
-
data-theme="dark"
|
|
24
|
-
palette-theme={palette}
|
|
25
|
-
style={{
|
|
26
|
-
background: "var(--color-black)",
|
|
27
|
-
height: "150px",
|
|
28
|
-
padding: "16px",
|
|
29
|
-
}}
|
|
30
|
-
>
|
|
31
27
|
<Story />
|
|
32
|
-
</div>
|
|
33
28
|
);
|
|
34
29
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { StoryContext, StoryFn } from "@storybook/react";
|
|
3
|
+
import { LoadingProvider, useLoading } from "../context/loading";
|
|
4
|
+
|
|
5
|
+
const LoadingProviderMock = ({ Story, loadingOptions, loadingArgs }) => {
|
|
6
|
+
const ref = useRef();
|
|
7
|
+
const loading = useLoading({
|
|
8
|
+
...(loadingOptions?.isRef && { ref: ref }),
|
|
9
|
+
...(loadingOptions?.message && { message: loadingOptions.message }),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
// initialize stuff here
|
|
13
|
+
return (
|
|
14
|
+
<>
|
|
15
|
+
{loading.state.ref && <img ref={ref} src={loadingArgs.img} />}
|
|
16
|
+
<Story />
|
|
17
|
+
</>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const withLoading = (Story: StoryFn, context: StoryContext) => {
|
|
22
|
+
return (
|
|
23
|
+
<LoadingProvider>
|
|
24
|
+
<LoadingProviderMock
|
|
25
|
+
Story={Story}
|
|
26
|
+
loadingOptions={context.parameters.loadingOptions}
|
|
27
|
+
loadingArgs={context.args}
|
|
28
|
+
/>
|
|
29
|
+
</LoadingProvider>
|
|
30
|
+
);
|
|
31
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
import "../src/styles/variables.css";
|
|
2
|
+
|
|
1
3
|
export { Button } from "./components/button";
|
|
2
4
|
export { Input } from "./components/input";
|
|
5
|
+
export { TextArea } from "./components/text-area";
|
|
6
|
+
|
|
7
|
+
export { ThemeContext, ThemeProvider, useTheme } from "./context/themeContext";
|
|
Binary file
|
|
Binary file
|
package/src/styles/variables.css
CHANGED
|
@@ -54,6 +54,9 @@
|
|
|
54
54
|
--color-neutral-100: var(--color-white);
|
|
55
55
|
--color-primary: var(--color-primary-500);
|
|
56
56
|
--color-secondary: var(--color-primary-600);
|
|
57
|
+
|
|
58
|
+
color: var(--color-neutral-100) !important;
|
|
59
|
+
background-color: var(--color-neutral-900) !important;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
[data-theme="light"] {
|
|
@@ -61,6 +64,18 @@
|
|
|
61
64
|
--color-neutral-100: var(--color-black);
|
|
62
65
|
--color-primary: var(--color-primary-600);
|
|
63
66
|
--color-secondary: var(--color-primary-500);
|
|
67
|
+
color: var(--color-neutral-900) !important;
|
|
68
|
+
background-color: var(--color-neutral-100) !important;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (prefers-color-scheme: dark) {
|
|
72
|
+
html {
|
|
73
|
+
color-scheme: dark;
|
|
74
|
+
}
|
|
75
|
+
body {
|
|
76
|
+
color: var(--color-neutral-100);
|
|
77
|
+
background-color: var(--color-neutral-900);
|
|
78
|
+
}
|
|
64
79
|
}
|
|
65
80
|
|
|
66
81
|
[palette-theme="water"] {
|