@platformatic/ui-components 0.1.48 → 0.1.50

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 (152) hide show
  1. package/.github/workflows/ci.yml +26 -26
  2. package/.nvmrc +1 -1
  3. package/LICENSE +201 -201
  4. package/README.md +30 -30
  5. package/fonts/Montserrat/README.txt +81 -81
  6. package/index.html +12 -12
  7. package/index.js +71 -71
  8. package/package.json +76 -76
  9. package/postcss.config.cjs +8 -8
  10. package/public/api-icon-closed.svg +6 -6
  11. package/public/api-icon.svg +9 -9
  12. package/src/App.jsx +12 -12
  13. package/src/components/BorderedBox.jsx +18 -18
  14. package/src/components/BorderedBox.module.css +8 -8
  15. package/src/components/BorderedText.jsx +8 -8
  16. package/src/components/BorderedText.module.css +2 -2
  17. package/src/components/Box.jsx +14 -14
  18. package/src/components/Box.module.css +7 -7
  19. package/src/components/Button.jsx +95 -95
  20. package/src/components/Button.module.css +127 -127
  21. package/src/components/ButtonFullRounded.jsx +17 -17
  22. package/src/components/ButtonFullRounded.module.css +28 -28
  23. package/src/components/Checkbox.jsx +11 -11
  24. package/src/components/Checkbox.module.css +18 -18
  25. package/src/components/Common.module.css +28 -28
  26. package/src/components/DetailedMetric.jsx +32 -32
  27. package/src/components/DetailedMetric.module.css +2 -2
  28. package/src/components/DropDown.jsx +36 -36
  29. package/src/components/DropDown.module.css +27 -27
  30. package/src/components/FollowUs.jsx +35 -35
  31. package/src/components/FollowUs.module.css +11 -11
  32. package/src/components/GHLoginButton.jsx +14 -14
  33. package/src/components/HorizontalSeparator.jsx +15 -15
  34. package/src/components/HorizontalSeparator.module.css +26 -26
  35. package/src/components/InfoBox.jsx +50 -50
  36. package/src/components/InfoBox.module.css +5 -5
  37. package/src/components/List.jsx +20 -20
  38. package/src/components/List.module.css +11 -11
  39. package/src/components/ListElement.jsx +23 -23
  40. package/src/components/ListElement.module.css +23 -23
  41. package/src/components/Loadable.jsx +34 -34
  42. package/src/components/Loadable.module.css +13 -13
  43. package/src/components/Loader.jsx +22 -22
  44. package/src/components/Loader.module.css +13 -13
  45. package/src/components/LoginButton.jsx +17 -17
  46. package/src/components/LoginButton.module.css +7 -7
  47. package/src/components/LoginButton.test.jsx +25 -25
  48. package/src/components/Logo.jsx +62 -62
  49. package/src/components/Logo.module.css +5 -5
  50. package/src/components/Main.jsx +33 -33
  51. package/src/components/MetricValue.jsx +15 -15
  52. package/src/components/MetricValue.module.css +9 -9
  53. package/src/components/Modal.jsx +93 -93
  54. package/src/components/Modal.module.css +50 -50
  55. package/src/components/PlatformaticIcon.jsx +57 -57
  56. package/src/components/PlatformaticIcon.module.css +2 -2
  57. package/src/components/Playground.jsx +9 -9
  58. package/src/components/SearchBar.jsx +63 -63
  59. package/src/components/SearchBar.module.css +20 -20
  60. package/src/components/Sidebar.jsx +153 -153
  61. package/src/components/Sidebar.module.css +66 -66
  62. package/src/components/SimpleMetric.jsx +28 -28
  63. package/src/components/SimpleMetric.module.css +6 -6
  64. package/src/components/Status.jsx +26 -26
  65. package/src/components/TabbedWindow.jsx +39 -39
  66. package/src/components/TabbedWindow.module.css +16 -16
  67. package/src/components/TextWithLabel.jsx +11 -11
  68. package/src/components/TextWithLabel.module.css +8 -8
  69. package/src/components/Versions.jsx +9 -9
  70. package/src/components/VerticalSeparator.jsx +5 -5
  71. package/src/components/forms/Field.jsx +53 -20
  72. package/src/components/forms/Field.module.css +23 -17
  73. package/src/components/forms/Input.jsx +80 -87
  74. package/src/components/forms/Input.module.css +28 -28
  75. package/src/components/forms/Preview.jsx +75 -77
  76. package/src/components/forms/Preview.module.css +14 -14
  77. package/src/components/forms/ToggleSwitch.jsx +18 -18
  78. package/src/components/forms/ToggleSwitch.module.css +42 -42
  79. package/src/components/forms/index.js +8 -8
  80. package/src/components/icons/ApiEmptyIcon.jsx +107 -107
  81. package/src/components/icons/ApiIcon.jsx +29 -29
  82. package/src/components/icons/ApiIconClosed.jsx +19 -19
  83. package/src/components/icons/AppEmptyIcon.jsx +94 -94
  84. package/src/components/icons/AppIcon.jsx +38 -38
  85. package/src/components/icons/AppListIcon.jsx +73 -73
  86. package/src/components/icons/Calendar1Icon.jsx +54 -54
  87. package/src/components/icons/Calendar7Icon.jsx +55 -55
  88. package/src/components/icons/CalendarIcon.jsx +56 -56
  89. package/src/components/icons/CircleAddIcon.jsx +40 -40
  90. package/src/components/icons/CircleBackIcon.jsx +51 -51
  91. package/src/components/icons/CircleCheckMarkIcon.jsx +66 -0
  92. package/src/components/icons/CircleCloseHoverIcon.jsx +42 -42
  93. package/src/components/icons/CircleCloseIcon.jsx +32 -32
  94. package/src/components/icons/CircleExclamationIcon.jsx +29 -29
  95. package/src/components/icons/CloseIcon.jsx +31 -31
  96. package/src/components/icons/CopyIcon.jsx +75 -46
  97. package/src/components/icons/CreatedWorkspaceIcon.jsx +70 -70
  98. package/src/components/icons/DynamicWorkspaceIcon.jsx +125 -125
  99. package/src/components/icons/EditIcon.jsx +38 -0
  100. package/src/components/icons/GearIcon.jsx +40 -40
  101. package/src/components/icons/Icons.module.css +29 -29
  102. package/src/components/icons/LiveIcon.jsx +43 -43
  103. package/src/components/icons/MetricsIcon.jsx +52 -52
  104. package/src/components/icons/PlayIcon.jsx +20 -20
  105. package/src/components/icons/PullRequestIcon.jsx +35 -35
  106. package/src/components/icons/StaticWorkspaceIcon.jsx +119 -119
  107. package/src/components/icons/StopIcon.jsx +21 -21
  108. package/src/components/icons/TerminalIcon.jsx +22 -22
  109. package/src/components/icons/TriangleExclamationIcon.jsx +26 -26
  110. package/src/components/icons/UpgradeIcon.jsx +48 -48
  111. package/src/components/icons/index.js +63 -59
  112. package/src/components/layouts/Layout.jsx +11 -11
  113. package/src/components/layouts/TwoColumnsLayout.jsx +12 -12
  114. package/src/components/layouts/TwoColumnsLayout.module.css +9 -9
  115. package/src/hooks/useEscapeKey.js +20 -20
  116. package/src/lib/utils.js +23 -23
  117. package/src/main.jsx +9 -9
  118. package/src/stories/BorderedBox.stories.jsx +33 -33
  119. package/src/stories/BorderedText.stories.jsx +24 -24
  120. package/src/stories/Button.stories.jsx +114 -114
  121. package/src/stories/ButtonFullRounded.stories.jsx +61 -61
  122. package/src/stories/Checkbox.stories.jsx +27 -27
  123. package/src/stories/DetailedMetric.stories.jsx +33 -33
  124. package/src/stories/DropDown.stories.jsx +62 -62
  125. package/src/stories/FollowUs.stories.jsx +14 -14
  126. package/src/stories/GHLoginButton.stories.jsx +14 -14
  127. package/src/stories/HorizontalSeparator.stories.jsx +12 -12
  128. package/src/stories/InfoBox.stories.jsx +46 -46
  129. package/src/stories/Introduction.stories.mdx +211 -211
  130. package/src/stories/List.stories.jsx +29 -29
  131. package/src/stories/ListElement.stories.jsx +15 -15
  132. package/src/stories/Loadable.stories.jsx +75 -75
  133. package/src/stories/Loader.stories.jsx +44 -44
  134. package/src/stories/LoginButton.stories.jsx +15 -15
  135. package/src/stories/Logo.stories.jsx +17 -17
  136. package/src/stories/Modal.stories.jsx +100 -100
  137. package/src/stories/PlatformaticIcon.stories.jsx +51 -35
  138. package/src/stories/SearchBar.stories.jsx +28 -28
  139. package/src/stories/Sidebar.stories.jsx +61 -61
  140. package/src/stories/SimpleMetric.stories.jsx +41 -41
  141. package/src/stories/Status.stories.jsx +31 -31
  142. package/src/stories/TextWithLabel.stories.jsx +25 -25
  143. package/src/stories/TwoColumnsLayout.stories.jsx +42 -42
  144. package/src/stories/forms/Field.stories.jsx +89 -81
  145. package/src/stories/forms/Input.stories.jsx +89 -69
  146. package/src/stories/forms/Preview.stories.jsx +57 -57
  147. package/src/stories/forms/ToggleSwitch.stories.jsx +15 -15
  148. package/src/stories/icons/Icons.stories.jsx +74 -74
  149. package/src/styles/main.css +15 -15
  150. package/tailwind.config.cjs +60 -60
  151. package/vite.config.js +6 -6
  152. package/vitest.config.js +14 -14
@@ -1,93 +1,93 @@
1
- import React, { useState } from 'react'
2
- import useEscapeKey from '../hooks/useEscapeKey'
3
- import CloseIcon from './icons/CloseIcon'
4
- import CircleCloseIcon from './icons/CircleCloseIcon'
5
- import CircleCloseHoverIcon from './icons/CircleCloseHoverIcon'
6
- import Logo from './Logo'
7
- import styles from './Modal.module.css'
8
-
9
- export default function Modal (props) {
10
- const { setIsOpen, title, layout = 'info' } = props
11
- const [isHoverCloseModal, setIsHoverCloseModal] = useState(false)
12
- useEscapeKey(() => setIsOpen(false))
13
- let whichModal = <></>
14
-
15
- switch (layout) {
16
- case 'info':
17
- whichModal = (
18
- <>
19
- <div className={styles.blur} onClick={() => setIsOpen(false)} />
20
- <div className={`${styles.container} ${styles.centered}`}>
21
- <div className={`${styles.modal} ${styles.modalInfo}`}>
22
- <div className={styles.header}>
23
- <div className={styles.title}>{title}</div>
24
- <div className={styles.close} onClick={() => setIsOpen(false)}>
25
- <CloseIcon />
26
- </div>
27
- </div>
28
- <div>
29
- {props.children}
30
- </div>
31
- </div>
32
- </div>
33
- </>
34
- )
35
- break
36
-
37
- case 'invite':
38
- whichModal = (
39
- <>
40
- <div className={styles.blur} onClick={() => setIsOpen(false)} />
41
- <div className={`${styles.container} ${styles.centered}`}>
42
- <div className={`${styles.modal} ${styles.modalInvite}`}>
43
- <div className={styles.headerInvite}>
44
- <div
45
- className={styles.close}
46
- onClick={() => setIsOpen(false)}
47
- onMouseEnter={() => setIsHoverCloseModal(true)}
48
- onMouseLeave={() => setIsHoverCloseModal(false)}
49
- >
50
- {isHoverCloseModal ? <CircleCloseHoverIcon /> : <CircleCloseIcon />}
51
- </div>
52
- </div>
53
- <p className={styles.titleInvite}>{title}</p>
54
- <div>{props.children}</div>
55
- </div>
56
- </div>
57
- </>
58
- )
59
- break
60
-
61
- case 'fullscreen':
62
- whichModal = (
63
- <>
64
- <div className={`${styles.container} ${styles.fullscreen}`}>
65
- <div className={styles.modalFullscreen}>
66
- <div className={styles.headerInvite}>
67
- <div
68
- className={styles.close}
69
- onClick={() => setIsOpen(false)}
70
- onMouseEnter={() => setIsHoverCloseModal(true)}
71
- onMouseLeave={() => setIsHoverCloseModal(false)}
72
- >
73
- {isHoverCloseModal ? <CircleCloseHoverIcon color='main-dark-blue' /> : <CircleCloseIcon color='main-dark-blue' />}
74
- </div>
75
- </div>
76
- <div className={styles.contentFullscreen}>
77
- <div className={styles.titleFullscreen}>
78
- <Logo width={100} heigth={80} color='main-dark-blue' />
79
- <h3>PLATFORMATIC</h3>
80
- </div>
81
- <div>{props.children}</div>
82
- </div>
83
- </div>
84
- </div>
85
- </>
86
- )
87
- break
88
-
89
- default:
90
- break
91
- }
92
- return whichModal
93
- }
1
+ import React, { useState } from 'react'
2
+ import useEscapeKey from '../hooks/useEscapeKey'
3
+ import CloseIcon from './icons/CloseIcon'
4
+ import CircleCloseIcon from './icons/CircleCloseIcon'
5
+ import CircleCloseHoverIcon from './icons/CircleCloseHoverIcon'
6
+ import Logo from './Logo'
7
+ import styles from './Modal.module.css'
8
+
9
+ export default function Modal (props) {
10
+ const { setIsOpen, title, layout = 'info' } = props
11
+ const [isHoverCloseModal, setIsHoverCloseModal] = useState(false)
12
+ useEscapeKey(() => setIsOpen(false))
13
+ let whichModal = <></>
14
+
15
+ switch (layout) {
16
+ case 'info':
17
+ whichModal = (
18
+ <>
19
+ <div className={styles.blur} onClick={() => setIsOpen(false)} />
20
+ <div className={`${styles.container} ${styles.centered}`}>
21
+ <div className={`${styles.modal} ${styles.modalInfo}`}>
22
+ <div className={styles.header}>
23
+ <div className={styles.title}>{title}</div>
24
+ <div className={styles.close} onClick={() => setIsOpen(false)}>
25
+ <CloseIcon />
26
+ </div>
27
+ </div>
28
+ <div>
29
+ {props.children}
30
+ </div>
31
+ </div>
32
+ </div>
33
+ </>
34
+ )
35
+ break
36
+
37
+ case 'invite':
38
+ whichModal = (
39
+ <>
40
+ <div className={styles.blur} onClick={() => setIsOpen(false)} />
41
+ <div className={`${styles.container} ${styles.centered}`}>
42
+ <div className={`${styles.modal} ${styles.modalInvite}`}>
43
+ <div className={styles.headerInvite}>
44
+ <div
45
+ className={styles.close}
46
+ onClick={() => setIsOpen(false)}
47
+ onMouseEnter={() => setIsHoverCloseModal(true)}
48
+ onMouseLeave={() => setIsHoverCloseModal(false)}
49
+ >
50
+ {isHoverCloseModal ? <CircleCloseHoverIcon /> : <CircleCloseIcon />}
51
+ </div>
52
+ </div>
53
+ <p className={styles.titleInvite}>{title}</p>
54
+ <div>{props.children}</div>
55
+ </div>
56
+ </div>
57
+ </>
58
+ )
59
+ break
60
+
61
+ case 'fullscreen':
62
+ whichModal = (
63
+ <>
64
+ <div className={`${styles.container} ${styles.fullscreen}`}>
65
+ <div className={styles.modalFullscreen}>
66
+ <div className={styles.headerInvite}>
67
+ <div
68
+ className={styles.close}
69
+ onClick={() => setIsOpen(false)}
70
+ onMouseEnter={() => setIsHoverCloseModal(true)}
71
+ onMouseLeave={() => setIsHoverCloseModal(false)}
72
+ >
73
+ {isHoverCloseModal ? <CircleCloseHoverIcon color='main-dark-blue' /> : <CircleCloseIcon color='main-dark-blue' />}
74
+ </div>
75
+ </div>
76
+ <div className={styles.contentFullscreen}>
77
+ <div className={styles.titleFullscreen}>
78
+ <Logo width={100} heigth={80} color='main-dark-blue' />
79
+ <h3>PLATFORMATIC</h3>
80
+ </div>
81
+ <div>{props.children}</div>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </>
86
+ )
87
+ break
88
+
89
+ default:
90
+ break
91
+ }
92
+ return whichModal
93
+ }
@@ -1,50 +1,50 @@
1
- .blur {
2
- @apply fixed top-[50%] left-[50%] w-full h-screen translate-x-[-50%] translate-y-[-50%] z-10;
3
- background-color: rgba(0, 0, 0, 0.75);
4
- }
5
- .container {
6
- @apply z-20;
7
- }
8
- .centered {
9
- @apply fixed top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]
10
- }
11
- .modal {
12
- @apply p-4 rounded-md mx-auto my-auto min-w-[480px] max-h-[85vh] overflow-y-auto;
13
- }
14
- .modalInfo {
15
- @apply bg-light-blue max-w-[480px];
16
- }
17
- .modalInvite {
18
- @apply bg-main-dark-blue border-light-green border shadow-wrap shadow-main-green max-w-[480px] max-h-[300px];
19
- }
20
- .fullscreen {
21
- @apply fixed top-0 left-0 bg-light-blue h-screen w-full min-h-screen min-w-full py-4 pl-20 pr-4 overflow-y-auto;
22
- }
23
- .header {
24
- @apply flex justify-between items-center;
25
- }
26
- .headerInvite {
27
- @apply flex justify-end;
28
- }
29
- .close {
30
- @apply hover:cursor-pointer;
31
- }
32
- .hr {
33
- @apply text-[#00283D] my-2 opacity-20;
34
- }
35
- .title {
36
- @apply font-bold text-lg;
37
- }
38
- .titleInvite {
39
- @apply font-bold text-lg text-main-green text-center;
40
- }
41
- .contentFullscreen {
42
- @apply h-auto w-full pt-4;
43
- }
44
- .titleFullscreen {
45
- @apply inline-flex items-center;
46
- }
47
- .titleFullscreen h3 {
48
- @apply text-[22px] text-dark-blue font-bold tracking-widest mx-3;
49
- }
50
-
1
+ .blur {
2
+ @apply fixed top-[50%] left-[50%] w-full h-screen translate-x-[-50%] translate-y-[-50%] z-10;
3
+ background-color: rgba(0, 0, 0, 0.75);
4
+ }
5
+ .container {
6
+ @apply z-20;
7
+ }
8
+ .centered {
9
+ @apply fixed top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]
10
+ }
11
+ .modal {
12
+ @apply p-4 rounded-md mx-auto my-auto min-w-[480px] max-h-[85vh] overflow-y-auto;
13
+ }
14
+ .modalInfo {
15
+ @apply bg-light-blue max-w-[480px];
16
+ }
17
+ .modalInvite {
18
+ @apply bg-main-dark-blue border-light-green border shadow-wrap shadow-main-green max-w-[480px] max-h-[300px];
19
+ }
20
+ .fullscreen {
21
+ @apply fixed top-0 left-0 bg-light-blue h-screen w-full min-h-screen min-w-full py-4 pl-20 pr-4 overflow-y-auto;
22
+ }
23
+ .header {
24
+ @apply flex justify-between items-center;
25
+ }
26
+ .headerInvite {
27
+ @apply flex justify-end;
28
+ }
29
+ .close {
30
+ @apply hover:cursor-pointer;
31
+ }
32
+ .hr {
33
+ @apply text-[#00283D] my-2 opacity-20;
34
+ }
35
+ .title {
36
+ @apply font-bold text-lg;
37
+ }
38
+ .titleInvite {
39
+ @apply font-bold text-lg text-main-green text-center;
40
+ }
41
+ .contentFullscreen {
42
+ @apply h-auto w-full pt-4;
43
+ }
44
+ .titleFullscreen {
45
+ @apply inline-flex items-center;
46
+ }
47
+ .titleFullscreen h3 {
48
+ @apply text-[22px] text-dark-blue font-bold tracking-widest mx-3;
49
+ }
50
+
@@ -1,57 +1,57 @@
1
- 'use strict'
2
- import React from 'react'
3
- import PropTypes from 'prop-types'
4
- import Icons from './icons'
5
- import styles from './PlatformaticIcon.module.css'
6
-
7
- function PlatformaticIcon ({ iconName, color, onClick, size, classes, tip }) {
8
- let icon = React.createElement(Icons[`${iconName}`], {
9
- color,
10
- size,
11
- tip
12
- })
13
- if (onClick) {
14
- let className = styles.cursorPointer
15
- if (classes) className += ` ${classes}`
16
- icon = (<span className={className} onClick={onClick}>{icon}</span>)
17
- }
18
- return icon
19
- }
20
-
21
- PlatformaticIcon.propTypes = {
22
- /**
23
- * iconName
24
- */
25
- iconName: PropTypes.string.isRequired,
26
- /**
27
- * color
28
- */
29
- color: PropTypes.string,
30
- /**
31
- * size
32
- */
33
- size: PropTypes.string,
34
- /**
35
- * onClick
36
- */
37
- onClick: PropTypes.func,
38
- /**
39
- * classes
40
- */
41
- classes: PropTypes.string,
42
- /**
43
- * tip
44
- */
45
- tip: PropTypes.string
46
- }
47
-
48
- PlatformaticIcon.defaultProps = {
49
- iconName: null,
50
- color: 'green',
51
- size: 'small',
52
- onClick: () => {},
53
- classes: null,
54
- tip: null
55
- }
56
-
57
- export default PlatformaticIcon
1
+ 'use strict'
2
+ import React from 'react'
3
+ import PropTypes from 'prop-types'
4
+ import Icons from './icons'
5
+ import styles from './PlatformaticIcon.module.css'
6
+
7
+ function PlatformaticIcon ({ iconName, color, onClick, size, classes, tip }) {
8
+ let icon = React.createElement(Icons[`${iconName}`], {
9
+ color,
10
+ size,
11
+ tip
12
+ })
13
+ if (onClick) {
14
+ let className = styles.cursorPointer
15
+ if (classes) className += ` ${classes}`
16
+ icon = (<span className={className} onClick={onClick}>{icon}</span>)
17
+ }
18
+ return icon
19
+ }
20
+
21
+ PlatformaticIcon.propTypes = {
22
+ /**
23
+ * iconName
24
+ */
25
+ iconName: PropTypes.string.isRequired,
26
+ /**
27
+ * color
28
+ */
29
+ color: PropTypes.string,
30
+ /**
31
+ * size
32
+ */
33
+ size: PropTypes.string,
34
+ /**
35
+ * onClick
36
+ */
37
+ onClick: PropTypes.func,
38
+ /**
39
+ * classes
40
+ */
41
+ classes: PropTypes.string,
42
+ /**
43
+ * tip
44
+ */
45
+ tip: PropTypes.string
46
+ }
47
+
48
+ PlatformaticIcon.defaultProps = {
49
+ iconName: null,
50
+ color: 'green',
51
+ size: 'small',
52
+ onClick: () => {},
53
+ classes: null,
54
+ tip: null
55
+ }
56
+
57
+ export default PlatformaticIcon
@@ -1,3 +1,3 @@
1
- .cursorPointer {
2
- @apply cursor-pointer;
1
+ .cursorPointer {
2
+ @apply cursor-pointer;
3
3
  }
@@ -1,9 +1,9 @@
1
- 'use strict'
2
- import React from 'react'
3
- import BorderedBox from './BorderedBox'
4
-
5
- export default function Playground () {
6
- return (
7
- <BorderedBox color='green'>Playground</BorderedBox>
8
- )
9
- }
1
+ 'use strict'
2
+ import React from 'react'
3
+ import BorderedBox from './BorderedBox'
4
+
5
+ export default function Playground () {
6
+ return (
7
+ <BorderedBox color='green'>Playground</BorderedBox>
8
+ )
9
+ }
@@ -1,63 +1,63 @@
1
- 'use strict'
2
- import React, { useRef, useState } from 'react'
3
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
4
- import { faSearch } from '@fortawesome/free-solid-svg-icons'
5
- import styles from './SearchBar.module.css'
6
- import commonStyles from './Common.module.css'
7
- export default function SearchBar (props) {
8
- const inputRef = useRef()
9
- const [wrapperClassName, setWrapperClassName] = useState(normalClassName())
10
- const [isOnFocus, setIsOnFocus] = useState(false)
11
- const { onSubmit, onChange, title } = props
12
-
13
- function handleSearch () {
14
- if (onSubmit) {
15
- const value = inputRef.current.value
16
- return onSubmit(value)
17
- }
18
- }
19
-
20
- function handleChange () {
21
- if (onChange) {
22
- const value = inputRef.current.value
23
- return onChange(value)
24
- }
25
- }
26
-
27
- function onFocus () {
28
- if (!isOnFocus) {
29
- setIsOnFocus(true)
30
- setWrapperClassName(onFocusClassName())
31
- }
32
- }
33
-
34
- function onBlur () {
35
- setIsOnFocus(false)
36
- setWrapperClassName(normalClassName())
37
- }
38
-
39
- function onFocusClassName () {
40
- return `${styles.input} ${commonStyles.padded} ${styles.onFocus}`
41
- }
42
-
43
- function normalClassName () {
44
- return `${styles.input} ${commonStyles.padded} ${styles.onBlur}`
45
- }
46
-
47
- function iconClassName () {
48
- return isOnFocus ? 'text-main-green' : 'text-white'
49
- }
50
-
51
- return (
52
- <div>
53
- {title && <h1 className={styles.title}>{title}</h1>}
54
- <div className={wrapperClassName}>
55
- <input type='text' placeholder='Search' className='grow' ref={inputRef} onChange={handleChange} onFocus={onFocus} onBlur={onBlur} />
56
- <button onClick={handleSearch} onFocus={onFocus} onBlur={onBlur}>
57
- <FontAwesomeIcon className={iconClassName()} icon={faSearch} />
58
- </button>
59
- </div>
60
- </div>
61
-
62
- )
63
- }
1
+ 'use strict'
2
+ import React, { useRef, useState } from 'react'
3
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
4
+ import { faSearch } from '@fortawesome/free-solid-svg-icons'
5
+ import styles from './SearchBar.module.css'
6
+ import commonStyles from './Common.module.css'
7
+ export default function SearchBar (props) {
8
+ const inputRef = useRef()
9
+ const [wrapperClassName, setWrapperClassName] = useState(normalClassName())
10
+ const [isOnFocus, setIsOnFocus] = useState(false)
11
+ const { onSubmit, onChange, title } = props
12
+
13
+ function handleSearch () {
14
+ if (onSubmit) {
15
+ const value = inputRef.current.value
16
+ return onSubmit(value)
17
+ }
18
+ }
19
+
20
+ function handleChange () {
21
+ if (onChange) {
22
+ const value = inputRef.current.value
23
+ return onChange(value)
24
+ }
25
+ }
26
+
27
+ function onFocus () {
28
+ if (!isOnFocus) {
29
+ setIsOnFocus(true)
30
+ setWrapperClassName(onFocusClassName())
31
+ }
32
+ }
33
+
34
+ function onBlur () {
35
+ setIsOnFocus(false)
36
+ setWrapperClassName(normalClassName())
37
+ }
38
+
39
+ function onFocusClassName () {
40
+ return `${styles.input} ${commonStyles.padded} ${styles.onFocus}`
41
+ }
42
+
43
+ function normalClassName () {
44
+ return `${styles.input} ${commonStyles.padded} ${styles.onBlur}`
45
+ }
46
+
47
+ function iconClassName () {
48
+ return isOnFocus ? 'text-main-green' : 'text-white'
49
+ }
50
+
51
+ return (
52
+ <div>
53
+ {title && <h1 className={styles.title}>{title}</h1>}
54
+ <div className={wrapperClassName}>
55
+ <input type='text' placeholder='Search' className='grow' ref={inputRef} onChange={handleChange} onFocus={onFocus} onBlur={onBlur} />
56
+ <button onClick={handleSearch} onFocus={onFocus} onBlur={onBlur}>
57
+ <FontAwesomeIcon className={iconClassName()} icon={faSearch} />
58
+ </button>
59
+ </div>
60
+ </div>
61
+
62
+ )
63
+ }
@@ -1,21 +1,21 @@
1
- .input {
2
- @apply flex justify-between w-full h-10 text-white border border-solid box-border rounded-md;
3
- }
4
- .onFocus {
5
- @apply border-main-green;
6
- }
7
- .onBlur {
8
- @apply border-white;
9
- }
10
- .fillGreen {
11
- @apply fill-main-green;
12
- }
13
- .fillWhite {
14
- @apply fill-white;
15
- }
16
- .input > input:focus {
17
- @apply outline-none;
18
- }
19
- .title {
20
- @apply font-semibold text-white text-3xl pb-4;
1
+ .input {
2
+ @apply flex justify-between w-full h-10 text-white border border-solid box-border rounded-md;
3
+ }
4
+ .onFocus {
5
+ @apply border-main-green;
6
+ }
7
+ .onBlur {
8
+ @apply border-white;
9
+ }
10
+ .fillGreen {
11
+ @apply fill-main-green;
12
+ }
13
+ .fillWhite {
14
+ @apply fill-white;
15
+ }
16
+ .input > input:focus {
17
+ @apply outline-none;
18
+ }
19
+ .title {
20
+ @apply font-semibold text-white text-3xl pb-4;
21
21
  }