@geoinsight/react-components 0.1.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.
Files changed (41) hide show
  1. package/.babelrc.json +16 -0
  2. package/.storybook/main.js +11 -0
  3. package/.storybook/preview.js +43 -0
  4. package/README.md +26 -0
  5. package/dist/cjs/index.css +111 -0
  6. package/dist/cjs/index.js +15 -0
  7. package/dist/esm/index.css +111 -0
  8. package/dist/esm/index.js +12 -0
  9. package/package.json +44 -0
  10. package/rollup.config.js +40 -0
  11. package/src/components/accordion/index.css +40 -0
  12. package/src/components/accordion/index.stories.tsx +55 -0
  13. package/src/components/accordion/index.tsx +78 -0
  14. package/src/components/accordion/index.types.ts +44 -0
  15. package/src/components/button/index.css +80 -0
  16. package/src/components/button/index.stories.tsx +46 -0
  17. package/src/components/button/index.tsx +45 -0
  18. package/src/components/button/index.types.ts +41 -0
  19. package/src/components/input/index.css +30 -0
  20. package/src/components/input/index.stories.tsx +34 -0
  21. package/src/components/input/index.tsx +25 -0
  22. package/src/components/input/index.types.ts +29 -0
  23. package/src/components/text-area/index.css +53 -0
  24. package/src/components/text-area/index.stories.tsx +30 -0
  25. package/src/components/text-area/index.tsx +62 -0
  26. package/src/components/text-area/index.types.ts +37 -0
  27. package/src/decorators/withColorScheme.tsx +34 -0
  28. package/src/index.ts +2 -0
  29. package/src/stories/Introduction.stories.mdx +211 -0
  30. package/src/stories/assets/code-brackets.svg +1 -0
  31. package/src/stories/assets/colors.svg +1 -0
  32. package/src/stories/assets/comments.svg +1 -0
  33. package/src/stories/assets/direction.svg +1 -0
  34. package/src/stories/assets/flow.svg +1 -0
  35. package/src/stories/assets/plugin.svg +1 -0
  36. package/src/stories/assets/repo.svg +1 -0
  37. package/src/stories/assets/stackalt.svg +1 -0
  38. package/src/styles/variables.css +100 -0
  39. package/src/types/data-theme.d.ts +5 -0
  40. package/src/utils/themes.ts +1 -0
  41. package/tsconfig.json +21 -0
@@ -0,0 +1,80 @@
1
+ .button {
2
+ align-items: center;
3
+ border-radius: var(--spacing-32);
4
+ border: none;
5
+ cursor: pointer;
6
+ display: flex;
7
+ justify-content: center;
8
+ gap: var(--spacing-8);
9
+ font-size: var(--font-size-16);
10
+ }
11
+
12
+ /*
13
+ .button--active {
14
+ background-color: var(--color-neutral-500) !important;
15
+ } */
16
+
17
+ .button:disabled {
18
+ cursor: unset;
19
+ opacity: 0.5;
20
+ pointer-events: none;
21
+ }
22
+
23
+ .button:hover {
24
+ background-color: var(--color-primary);
25
+ transition: var(--transition-bg-cubic-bezier);
26
+ }
27
+
28
+ .button__link {
29
+ background-color: unset !important;
30
+ color: var(--color-neutral-100);
31
+ text-decoration: underline transparent;
32
+ }
33
+
34
+ .button__link:hover {
35
+ color: var(--color-primary);
36
+ text-decoration: underline 0.1rem var(--color-primary);
37
+ text-underline-offset: var(--spacing-8);
38
+ transition: var(--transition-color-cubic-bezier),
39
+ var(--transition-text-decoration-cubic-bezier);
40
+ }
41
+
42
+ .button__primary {
43
+ background-color: var(--color-secondary);
44
+ border: 3px solid var(--color-primary);
45
+ }
46
+
47
+ .button__primary:hover {
48
+ box-shadow: 0 4px 4px 0 var(--color-neutral-400);
49
+ transition: var(--transition-bg-cubic-bezier), var(--transition-box-shadow-cubic-bezier);
50
+ }
51
+
52
+ .button__secondary {
53
+ background-color: var(--color-neutral-900);
54
+ border: 3px solid var(--color-primary);
55
+ color: var(--color-neutral-100);
56
+ }
57
+
58
+ .button__secondary:hover {
59
+ background-color: var(--color-primary);
60
+ }
61
+
62
+ .button__icon {
63
+ background-color: unset;
64
+ }
65
+
66
+ .button__icon:hover {
67
+ box-shadow: unset;
68
+ }
69
+
70
+ .button__small {
71
+ padding: var(--spacing-4);
72
+ }
73
+
74
+ .button__medium {
75
+ padding: var(--spacing-8) var(--spacing-24);
76
+ }
77
+
78
+ .button__large {
79
+ padding: var(--spacing-16);
80
+ }
@@ -0,0 +1,46 @@
1
+ import { StoryObj, Meta } from "@storybook/react";
2
+
3
+ import { Button } from "./index";
4
+ import { withColorScheme } from "../../decorators/withColorScheme";
5
+
6
+ // More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
7
+ const meta: Meta<typeof Button> = {
8
+ title: "Example/Button",
9
+ component: Button,
10
+ // More on argTypes: https://storybook.js.org/docs/react/api/argtypes
11
+ argTypes: {
12
+ backgroundColor: { control: "color" },
13
+ mode: {
14
+ options: ["primary", "secondary", "icon"],
15
+ control: {
16
+ type: "select",
17
+ },
18
+ },
19
+ size: {
20
+ options: ["small", "medium", "large"],
21
+ control: {
22
+ type: "select",
23
+ },
24
+ },
25
+ },
26
+ decorators: [withColorScheme],
27
+ };
28
+
29
+ export default meta;
30
+
31
+ type Story = StoryObj<typeof Button>;
32
+
33
+ export const Primary: Story = {
34
+ args: {
35
+ children: "Click here",
36
+ mode: "primary",
37
+ size: "medium",
38
+ as: "button",
39
+ },
40
+ };
41
+
42
+ export const Secondary: Story = {
43
+ args: {
44
+ mode: "secondary",
45
+ },
46
+ };
@@ -0,0 +1,45 @@
1
+ import clsx from "clsx";
2
+ import { ButtonAsButton, ButtonAsLink } from "./index.types";
3
+ import "./index.css";
4
+
5
+ export function Button({
6
+ children = "Click me",
7
+ className = "",
8
+ icon = undefined,
9
+ isNewWindow = false,
10
+ mode = "primary",
11
+ size = "medium",
12
+ as = "button",
13
+ ...rest
14
+ }: ButtonAsButton | ButtonAsLink): JSX.Element {
15
+ return as === "link" ? (
16
+ <a
17
+ {...(isNewWindow && { target: "_blank" })}
18
+ className={clsx(
19
+ className,
20
+ "button",
21
+ mode === "secondary" ? `button button__${mode}` : "button__link",
22
+ `button__${size}`
23
+ )}
24
+ {...(rest as React.AnchorHTMLAttributes<HTMLAnchorElement>)}
25
+ >
26
+ {children}
27
+ {icon}
28
+ </a>
29
+ ) : (
30
+ <button
31
+ className={clsx(
32
+ className,
33
+ "button",
34
+ `button__${mode}`,
35
+ `button__${size}`
36
+ )}
37
+ {...(rest as React.ButtonHTMLAttributes<HTMLButtonElement>)}
38
+ >
39
+ {children}
40
+ {icon}
41
+ </button>
42
+ );
43
+ }
44
+
45
+ export default Button;
@@ -0,0 +1,41 @@
1
+ type Mode = "primary" | "secondary" | "icon";
2
+ type Size = "small" | "medium" | "large";
3
+ export type ButtonAsButton = Base &
4
+ Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof Base> & {
5
+ as?: "button";
6
+ };
7
+ export type ButtonAsLink = Base &
8
+ Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof Base> & {
9
+ as?: "link";
10
+ };
11
+
12
+ export interface Base {
13
+ /**
14
+ * What to put inside the button (string or html elements)
15
+ */
16
+ children?: JSX.Element | string;
17
+ /**
18
+ * Custom css class name
19
+ */
20
+ className?: string;
21
+ /**
22
+ * If you want to add an icon image next to the children. Needs to be an react html element.
23
+ */
24
+ icon?: JSX.Element;
25
+ /**
26
+ * If you want to open a new window on the browser when you click the button. Only applies to html anchor elements.
27
+ */
28
+ isNewWindow?: boolean;
29
+ /**
30
+ * Css mode used to style the button.
31
+ */
32
+ mode?: Mode;
33
+ /**
34
+ * Button size.
35
+ */
36
+ size?: Size;
37
+ /**
38
+ * Button type.
39
+ */
40
+ as?: "button" | "link";
41
+ }
@@ -0,0 +1,30 @@
1
+ .input-group {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: flex-start;
5
+ }
6
+
7
+ .input {
8
+ border-radius: var(--spacing-8);
9
+ border: 2px solid var(--color-primary);
10
+ color: var(--color-black);
11
+ padding: var(--spacing-16) var(--spacing-24);
12
+ }
13
+
14
+ .input:hover {
15
+ border: 3px solid var(--color-primary-700);
16
+ }
17
+
18
+ .input:focus {
19
+ border: 3px solid var(--color-primary-700);
20
+ outline: none;
21
+ }
22
+
23
+ .input--error {
24
+ border: 3px solid var(--color-danger);
25
+ }
26
+
27
+ .error {
28
+ font-size: 12px;
29
+ color: var(--color-danger);
30
+ }
@@ -0,0 +1,34 @@
1
+ import { Meta, StoryObj } from "@storybook/react";
2
+
3
+ import { Input } from "./index";
4
+ import { withColorScheme } from "../../decorators/withColorScheme";
5
+
6
+ const meta: Meta<typeof Input> = {
7
+ title: "Example/Input",
8
+ component: Input,
9
+ argTypes: {
10
+ backgroundColor: { control: "color" },
11
+ },
12
+ decorators: [withColorScheme]
13
+ };
14
+
15
+ export default meta;
16
+
17
+ type Story = StoryObj<typeof Input>;
18
+
19
+ export const Primary: Story = {
20
+ args: {
21
+ className: "",
22
+ classNameGroup: "",
23
+ placeholder: "Insert a value",
24
+ errorMessage: "",
25
+ },
26
+ };
27
+
28
+ export const Error: Story = {
29
+ args: {
30
+ className: "",
31
+ classNameGroup: "",
32
+ errorMessage: "Insert a value",
33
+ },
34
+ };
@@ -0,0 +1,25 @@
1
+ import { Input as InputProps } from "./index.types";
2
+ import "./index.css";
3
+
4
+ export function Input({
5
+ className = "",
6
+ classNameGroup = "",
7
+ errorMessage = "" ,
8
+ inputRef,
9
+ styleGroup,
10
+ ...rest
11
+ }: InputProps) {
12
+ return (
13
+ <div className={`input-group ${classNameGroup}`}
14
+ style={styleGroup}>
15
+ <input
16
+ ref={inputRef}
17
+ className={`input ${errorMessage ? "input--error" : ""} ${className}`}
18
+ {...rest}
19
+ />
20
+ {errorMessage && <span className="error">{errorMessage}</span>}
21
+ </div>
22
+ );
23
+ }
24
+
25
+ export default Input;
@@ -0,0 +1,29 @@
1
+ import { dataTheme } from "data-theme";
2
+ import { CSSProperties, Ref } from "react";
3
+
4
+ export interface Input extends React.InputHTMLAttributes<HTMLInputElement> {
5
+ /**
6
+ * Custom css class name.
7
+ */
8
+ className?: string;
9
+ /**
10
+ * Custom css class name for group wrapper.
11
+ */
12
+ classNameGroup?: string;
13
+ /**
14
+ * Data theme for the html. `${themes}`
15
+ */
16
+ paletteTheme?: dataTheme;
17
+ /**
18
+ * Error message to show when input has an error.
19
+ */
20
+ errorMessage?: string;
21
+ /**
22
+ * Ref react elemnt to use
23
+ */
24
+ inputRef?: Ref<HTMLInputElement>;
25
+ /**
26
+ * Style input group wrapper
27
+ */
28
+ styleGroup?: CSSProperties;
29
+ }
@@ -0,0 +1,53 @@
1
+ .textarea {
2
+ margin-bottom: var(--spacing-8);
3
+ position: relative;
4
+ }
5
+
6
+ .textarea__input {
7
+ box-sizing: border-box;
8
+ border-radius: var(--spacing-8);
9
+ border: 2px solid var(--color-primary);
10
+ cursor: text;
11
+ color: var(--color-black);
12
+ outline: none;
13
+ padding: var(--spacing-8) var(--spacing-16);
14
+ resize: vertical;
15
+ width: 100%;
16
+ }
17
+
18
+ .textarea__input:hover {
19
+ border: 3px solid var(--color-primary-700);
20
+ }
21
+
22
+ .textarea__button {
23
+ background: var(--color-primary);
24
+ border: 2px solid var(--color-secondary);
25
+ box-shadow: 2px 4px 2px 1px rgba(0, 0, 0, 0.25);
26
+ border-radius: 0px 0px var(--spacing-8) var(--spacing-8);
27
+ bottom: 0;
28
+ cursor: pointer;
29
+ left: 0;
30
+ padding-bottom: -20px;
31
+ position: absolute;
32
+ width: 100%;
33
+ }
34
+
35
+ .textarea__button > svg {
36
+ color: var(--color-neutral-100);
37
+ }
38
+
39
+ .textarea__button:disabled {
40
+ cursor: unset;
41
+ opacity: 0.5;
42
+ pointer-events: none;
43
+ }
44
+
45
+ .textarea__button:hover {
46
+ background: var(--color-secondary);
47
+ color: var(--color-neutral-100);
48
+ }
49
+
50
+ .textarea__button--show {
51
+ background: var(--color-primary-700);
52
+ color: var(--color-neutral-100);
53
+ }
@@ -0,0 +1,30 @@
1
+ import { Meta, StoryObj } from "@storybook/react";
2
+
3
+ import { TextArea } from "./index";
4
+ import { withColorScheme } from "../../decorators/withColorScheme";
5
+
6
+ const meta: Meta<typeof TextArea> = {
7
+ title: "Example/TextArea",
8
+ component: TextArea,
9
+ argTypes: {
10
+ backgroundColor: { control: "color" },
11
+ },
12
+ decorators: [withColorScheme]
13
+ };
14
+
15
+ export default meta;
16
+
17
+ type Story = StoryObj<typeof TextArea>;
18
+
19
+ export const Active: Story = {
20
+ args: {
21
+ placeholder: "Insert a value",
22
+ disabled: false
23
+ },
24
+ };
25
+
26
+ export const Disabled: Story = {
27
+ args: {
28
+ placeholder: "Insert a value",
29
+ },
30
+ };
@@ -0,0 +1,62 @@
1
+ import React, { MutableRefObject, useRef, useState } from "react";
2
+ import clsx from "clsx";
3
+ import { TbArrowsDiagonal2 } from "react-icons/tb";
4
+ import { TextArea as TextAreaProps } from "./index.types";
5
+ import "./index.css";
6
+
7
+ export function TextArea({
8
+ className = "",
9
+ disabled = true,
10
+ hasToggleButton = true,
11
+ hideHeight = "5rem",
12
+ placeholder = "",
13
+ showHeight = "10rem",
14
+ style = {},
15
+ textareaClassName = "",
16
+ ...rest
17
+ }: TextAreaProps): JSX.Element {
18
+ const ref = useRef() as MutableRefObject<HTMLTextAreaElement>;
19
+ const [isShow, setIsShow] = useState<boolean>(false);
20
+
21
+ const handleClickToggle = () => {
22
+ if (ref && ref.current) {
23
+ if (isShow) {
24
+ ref.current.style.height = hideHeight;
25
+ } else {
26
+ ref.current.style.height = showHeight; //(48 + ref.current.scrollHeight) + 'px';
27
+ }
28
+ setIsShow((prev) => !prev);
29
+ }
30
+ };
31
+
32
+ return (
33
+ <div className={clsx("textarea", className)} style={style}>
34
+ <textarea
35
+ ref={ref}
36
+ className={clsx("textarea__input", textareaClassName)}
37
+ style={
38
+ {
39
+ height: hasToggleButton ? hideHeight : showHeight,
40
+ } as React.CSSProperties
41
+ }
42
+ placeholder={placeholder}
43
+ disabled={disabled}
44
+ {...rest}
45
+ />
46
+ {hasToggleButton && (
47
+ <button
48
+ className={clsx(
49
+ "textarea__button",
50
+ isShow && "textarea__button--show"
51
+ )}
52
+ onClick={handleClickToggle}
53
+ disabled={disabled}
54
+ >
55
+ <TbArrowsDiagonal2 size="1.5rem" />
56
+ </button>
57
+ )}
58
+ </div>
59
+ );
60
+ }
61
+
62
+ export default TextArea;
@@ -0,0 +1,37 @@
1
+ import { dataTheme } from "data-theme";
2
+ import { CSSProperties, Ref } from "react";
3
+
4
+ export interface TextArea extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
5
+ /**
6
+ * Custom css class name textarea wrapper.
7
+ */
8
+ className?: string;
9
+ /**
10
+ * Disable prop
11
+ */
12
+ disabled?: boolean;
13
+ /**
14
+ * Check if there is a toggle button
15
+ */
16
+ hasToggleButton?: boolean;
17
+ /**
18
+ * Minimum height if toggle button is true
19
+ */
20
+ hideHeight?: string;
21
+ /**
22
+ * Placeholder for textarea html tag
23
+ */
24
+ placeholder?: string;
25
+ /**
26
+ * Maximum height if toggle button is false
27
+ */
28
+ showHeight?: string;
29
+ /**
30
+ * Style textarea group wrapper
31
+ */
32
+ style?: CSSProperties;
33
+ /**
34
+ * Classname of the textarea
35
+ */
36
+ textareaClassName?: string;
37
+ }
@@ -0,0 +1,34 @@
1
+ import { StoryContext, StoryFn } from "@storybook/react";
2
+
3
+ export const withColorScheme = (Story: StoryFn, context: StoryContext) => {
4
+ const { theme, palette } = context.globals;
5
+ if (theme === "light") {
6
+ return (
7
+ <div
8
+ data-theme="light"
9
+ palette-theme={palette}
10
+ style={{
11
+ background: "var(--color-white)",
12
+ height: "150px",
13
+ padding: "16px",
14
+ }}
15
+ >
16
+ <Story />
17
+ </div>
18
+ );
19
+ }
20
+
21
+ 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
+ <Story />
32
+ </div>
33
+ );
34
+ };
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { Button } from "./components/button";
2
+ export { Input } from "./components/input";