@platformatic/ui-components 0.1.40 → 0.1.42
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/index.js +3 -3
- package/package.json +1 -1
- package/src/components/BorderedBox.jsx +4 -2
- package/src/components/BorderedBox.module.css +7 -1
- package/src/components/Button.module.css +1 -1
- package/src/components/Common.module.css +4 -1
- package/src/components/DropDown.module.css +1 -1
- package/src/components/Modal.jsx +5 -3
- package/src/components/Modal.module.css +9 -4
- package/src/components/Sidebar.jsx +153 -0
- package/src/components/Sidebar.module.css +66 -0
- package/src/components/forms/Input.jsx +37 -5
- package/src/components/forms/Input.module.css +13 -0
- package/src/components/icons/AppEmptyIcon.jsx +94 -0
- package/src/components/icons/AppIcon.jsx +38 -0
- package/src/components/icons/GearIcon.jsx +40 -0
- package/src/components/icons/PuzzleDynamicIcon.jsx +69 -0
- package/src/components/icons/PuzzleIcon.jsx +20 -20
- package/src/components/icons/index.js +8 -0
- package/src/stories/{SideBar.stories.jsx → Sidebar.stories.jsx} +21 -15
- package/src/stories/forms/Input.stories.jsx +13 -0
- package/tailwind.config.cjs +4 -4
- package/src/components/SideBar.jsx +0 -61
- package/src/components/SideBar.module.css +0 -43
package/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import GHLoginButton from './src/components/GHLoginButton'
|
|
|
13
13
|
import HorizontalSeparator from './src/components/HorizontalSeparator'
|
|
14
14
|
import Forms from './src/components/forms'
|
|
15
15
|
import Icons from './src/components/icons'
|
|
16
|
-
import
|
|
16
|
+
import Sidebar from './src/components/Sidebar'
|
|
17
17
|
import Layout from './src/components/layouts/Layout'
|
|
18
18
|
import List from './src/components/List'
|
|
19
19
|
import ListElement from './src/components/ListElement'
|
|
@@ -46,7 +46,7 @@ export {
|
|
|
46
46
|
GHLoginButton,
|
|
47
47
|
Forms,
|
|
48
48
|
Icons,
|
|
49
|
-
|
|
49
|
+
Sidebar,
|
|
50
50
|
Layout,
|
|
51
51
|
List,
|
|
52
52
|
ListElement,
|
|
@@ -63,5 +63,5 @@ export {
|
|
|
63
63
|
TextWithLabel,
|
|
64
64
|
TwoColumnsLayout,
|
|
65
65
|
Versions,
|
|
66
|
-
VerticalSeparator
|
|
66
|
+
VerticalSeparator
|
|
67
67
|
}
|
package/package.json
CHANGED
|
@@ -5,11 +5,13 @@ import styles from './BorderedBox.module.css'
|
|
|
5
5
|
import commonStyles from './Common.module.css'
|
|
6
6
|
import React from 'react'
|
|
7
7
|
export default function BorderedBox (props) {
|
|
8
|
-
const { classes, color, children } = props
|
|
8
|
+
const { classes, color, children, backgroundColor = 'dark-blue' } = props
|
|
9
9
|
const borderColor = getColor('border', color)
|
|
10
|
+
const styledBackgroundColor = styles[`background-color-${backgroundColor}`]
|
|
11
|
+
const className = `${styles.borderedBox} ${commonStyles.bordered} ${classes} ${borderColor} ${styledBackgroundColor}`
|
|
10
12
|
|
|
11
13
|
return (
|
|
12
|
-
<div className={
|
|
14
|
+
<div className={className}>
|
|
13
15
|
{children}
|
|
14
16
|
</div>
|
|
15
17
|
)
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
.borderedBox {
|
|
2
|
-
@apply rounded-md p-5
|
|
2
|
+
@apply rounded-md p-5 text-white flex-1 gap-y-4;
|
|
3
|
+
}
|
|
4
|
+
.background-color-dark-blue{
|
|
5
|
+
@apply bg-dark-blue !important;
|
|
6
|
+
}
|
|
7
|
+
.background-color-transparent{
|
|
8
|
+
@apply bg-transparent ;
|
|
3
9
|
}
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
@apply border border-solid box-border rounded-md;
|
|
3
3
|
}
|
|
4
4
|
.bordered--main-green {
|
|
5
|
-
@apply border-main-green
|
|
5
|
+
@apply border-main-green;
|
|
6
6
|
}
|
|
7
7
|
.bordered--main-dark-blue {
|
|
8
8
|
@apply border-main-dark-blue;
|
|
9
9
|
}
|
|
10
|
+
.bordered--error-red {
|
|
11
|
+
@apply border-error-red;
|
|
12
|
+
}
|
|
10
13
|
|
|
11
14
|
.error-message {
|
|
12
15
|
@apply absolute -bottom-5 text-error-red text-xs px-2;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
@apply border border-transparent rounded-full mr-2;
|
|
20
20
|
}
|
|
21
21
|
.menu {
|
|
22
|
-
@apply absolute border-solid border border-white px-0 py-1 bg-light-blue mt-8 rounded-md z-
|
|
22
|
+
@apply absolute border-solid border border-white px-0 py-1 bg-light-blue mt-8 rounded-md z-10 text-sm min-w-[175px];
|
|
23
23
|
}
|
|
24
24
|
.item {
|
|
25
25
|
@apply py-3 px-3 text-main-dark-blue first:border-t-0 text-sm uppercase hover:font-semibold hover:cursor-pointer tracking-more-widest;
|
package/src/components/Modal.jsx
CHANGED
|
@@ -8,11 +8,13 @@ import HorizontalSeparator from './HorizontalSeparator'
|
|
|
8
8
|
import styles from './Modal.module.css'
|
|
9
9
|
|
|
10
10
|
export default function Modal (props) {
|
|
11
|
-
const { setIsOpen, title, layout = 'info' } = props
|
|
11
|
+
const { setIsOpen, title, layout = 'info', maxWidth = 50 } = props
|
|
12
12
|
const [isHoverCloseModal, setIsHoverCloseModal] = useState(false)
|
|
13
13
|
useEscapeKey(() => setIsOpen(false))
|
|
14
|
-
|
|
14
|
+
const styledMaxWidth = styles[`maxW${maxWidth}`]
|
|
15
|
+
const classNameFullScreen = `${styles.contentFullscreen} ${styledMaxWidth}`
|
|
15
16
|
let whichModal = <></>
|
|
17
|
+
|
|
16
18
|
switch (layout) {
|
|
17
19
|
case 'info':
|
|
18
20
|
whichModal = (
|
|
@@ -74,7 +76,7 @@ export default function Modal (props) {
|
|
|
74
76
|
{isHoverCloseModal ? <RoundCloseHoverIcon color='main-dark-blue' /> : <RoundCloseIcon color='main-dark-blue' />}
|
|
75
77
|
</div>
|
|
76
78
|
</div>
|
|
77
|
-
<div className={
|
|
79
|
+
<div className={classNameFullScreen}>
|
|
78
80
|
<div className={styles.titleFullscreen}>
|
|
79
81
|
<Logo width={100} heigth={80} color='main-dark-blue' />
|
|
80
82
|
<h3>PLATFORMATIC</h3>
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
@apply p-4 rounded-md mx-auto my-auto min-w-[480px] max-h-[85vh] overflow-y-auto;
|
|
13
13
|
}
|
|
14
14
|
.modalInfo {
|
|
15
|
-
@apply bg-light-blue;
|
|
15
|
+
@apply bg-light-blue max-w-[480px];
|
|
16
16
|
}
|
|
17
17
|
.modalInvite {
|
|
18
|
-
@apply bg-main-dark-blue border-light-green border shadow-wrap shadow-main-green max-w-[
|
|
18
|
+
@apply bg-main-dark-blue border-light-green border shadow-wrap shadow-main-green max-w-[480px] max-h-[300px];
|
|
19
19
|
}
|
|
20
20
|
.fullscreen {
|
|
21
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;
|
|
@@ -39,9 +39,14 @@
|
|
|
39
39
|
@apply font-bold text-lg text-main-green text-center;
|
|
40
40
|
}
|
|
41
41
|
.contentFullscreen {
|
|
42
|
-
@apply h-auto
|
|
42
|
+
@apply h-auto w-full pt-4;
|
|
43
|
+
}
|
|
44
|
+
.maxW50 {
|
|
45
|
+
@apply max-w-[50%];
|
|
46
|
+
}
|
|
47
|
+
.maxW70 {
|
|
48
|
+
@apply max-w-[70%];
|
|
43
49
|
}
|
|
44
|
-
|
|
45
50
|
.titleFullscreen {
|
|
46
51
|
@apply inline-flex items-center;
|
|
47
52
|
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import Icons from './icons'
|
|
3
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
4
|
+
import { faChevronLeft, faPlusCircle } from '@fortawesome/free-solid-svg-icons'
|
|
5
|
+
import styles from './Sidebar.module.css'
|
|
6
|
+
import ReactTooltip from 'react-tooltip'
|
|
7
|
+
import HorizontalSeparator from './HorizontalSeparator'
|
|
8
|
+
import PropTypes from 'prop-types'
|
|
9
|
+
|
|
10
|
+
function Sidebar (props) {
|
|
11
|
+
const {
|
|
12
|
+
title,
|
|
13
|
+
defaultSelected,
|
|
14
|
+
onClickItemSelectedParent,
|
|
15
|
+
items,
|
|
16
|
+
onClickAdd,
|
|
17
|
+
addTitle,
|
|
18
|
+
onClickSettings
|
|
19
|
+
} = props
|
|
20
|
+
const [collapsed, setCollapsed] = useState(false)
|
|
21
|
+
const [selectedItem, setSelectedItem] = useState(defaultSelected)
|
|
22
|
+
|
|
23
|
+
function onClickItemSelected (index) {
|
|
24
|
+
setSelectedItem(index)
|
|
25
|
+
onClickItemSelectedParent(index)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function renderItemIcon (iconName, title, isSelected) {
|
|
29
|
+
if (iconName) {
|
|
30
|
+
return React.createElement(Icons[`${iconName}`], {
|
|
31
|
+
size: 'small',
|
|
32
|
+
color: isSelected ? 'green' : 'white',
|
|
33
|
+
tip: title
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
return (<></>)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div className={`${styles.container} ${collapsed && styles.collapsed}`}>
|
|
41
|
+
{collapsed
|
|
42
|
+
? (
|
|
43
|
+
<>
|
|
44
|
+
<button type='button' className={styles.buttonExpand} onClick={() => { setCollapsed(false) }}>
|
|
45
|
+
<Icons.PuzzleIcon color='white' />
|
|
46
|
+
</button>
|
|
47
|
+
<div className={styles.titleCollapsed} data-testid='lateral-bar-title'>
|
|
48
|
+
{title}
|
|
49
|
+
</div>
|
|
50
|
+
<HorizontalSeparator marginBottom={2} marginTop={2} />
|
|
51
|
+
<div className={styles.bottom}>
|
|
52
|
+
<button type='button' className={styles.buttonSettings} onClick={onClickSettings}>
|
|
53
|
+
<Icons.GearIcon color='white' />
|
|
54
|
+
</button>
|
|
55
|
+
<div className={styles.titleCollapsed} data-testid='lateral-bar-title'>
|
|
56
|
+
Settings
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</>
|
|
60
|
+
)
|
|
61
|
+
: (
|
|
62
|
+
<>
|
|
63
|
+
<button type='button' className={styles.buttonCollapse} onClick={() => { setCollapsed(true) }}>
|
|
64
|
+
<FontAwesomeIcon icon={faChevronLeft} size='1x' color='white' />
|
|
65
|
+
</button>
|
|
66
|
+
<div className={styles.title} data-testid='lateral-bar-title'>
|
|
67
|
+
{title}
|
|
68
|
+
</div>
|
|
69
|
+
<div className={styles.items} data-test-id='lateral-bar-items'>
|
|
70
|
+
{items.map((item, index) => {
|
|
71
|
+
const isSelected = selectedItem === index
|
|
72
|
+
return (
|
|
73
|
+
<React.Fragment key={index}>
|
|
74
|
+
<button className={`${styles.buttonItem} ${collapsed && styles.buttonItemCollapsed}`} type='button' onClick={() => onClickItemSelected(index)}>
|
|
75
|
+
{renderItemIcon(item.iconName, item.title, isSelected)}
|
|
76
|
+
<div className={`${styles.item} ${isSelected ? styles.itemSelected : ''}`}>
|
|
77
|
+
<span className={styles.itemSubTitle}>{item.subTitle}</span>
|
|
78
|
+
<span className={styles.itemTitle}>{item.title}</span>
|
|
79
|
+
</div>
|
|
80
|
+
</button>
|
|
81
|
+
<ReactTooltip />
|
|
82
|
+
</React.Fragment>
|
|
83
|
+
)
|
|
84
|
+
})}
|
|
85
|
+
{/* <Button label='Add' buttonClass='transparent' icon={faPlus} color='white' size='small' inClick={onClickAdd}/> */}
|
|
86
|
+
<button className={`${styles.buttonItem} ${collapsed && styles.buttonItemCollapsed}`} onClick={onClickAdd}>
|
|
87
|
+
<FontAwesomeIcon color='white' icon={faPlusCircle} data-tip={addTitle} />
|
|
88
|
+
{!collapsed && <span className={styles.item}>{addTitle}</span>}
|
|
89
|
+
</button>
|
|
90
|
+
</div>
|
|
91
|
+
<HorizontalSeparator marginBottom='2' marginTop='2' />
|
|
92
|
+
|
|
93
|
+
<div className={styles.bottom}>
|
|
94
|
+
<button type='button' className={`${styles.buttonSettings} ${styles.buttonSettingsExpanded}`} onClick={onClickSettings}>
|
|
95
|
+
<Icons.GearIcon color='white' size='small' /> <span className={styles.titleSettings}>Settings</span>
|
|
96
|
+
</button>
|
|
97
|
+
</div>
|
|
98
|
+
</>
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
Sidebar.propTypes = {
|
|
105
|
+
/**
|
|
106
|
+
* title
|
|
107
|
+
*/
|
|
108
|
+
title: PropTypes.string,
|
|
109
|
+
/**
|
|
110
|
+
* defaultSelected
|
|
111
|
+
*/
|
|
112
|
+
defaultSelected: PropTypes.number,
|
|
113
|
+
/**
|
|
114
|
+
* addTitle
|
|
115
|
+
*/
|
|
116
|
+
addTitle: PropTypes.string,
|
|
117
|
+
/**
|
|
118
|
+
* items: array with keys
|
|
119
|
+
* title: name to display
|
|
120
|
+
* subtitle: secondary title
|
|
121
|
+
* icon: what Icon
|
|
122
|
+
*/
|
|
123
|
+
items: PropTypes.arrayOf(PropTypes.shape({
|
|
124
|
+
title: PropTypes.string,
|
|
125
|
+
subtitle: PropTypes.string,
|
|
126
|
+
iconName: PropTypes.string
|
|
127
|
+
})),
|
|
128
|
+
/**
|
|
129
|
+
* Apply onClickItemSelectedParent
|
|
130
|
+
*/
|
|
131
|
+
onClickItemSelectedParent: PropTypes.func,
|
|
132
|
+
/**
|
|
133
|
+
* Apply onClickAdd: function called clicking on plus button
|
|
134
|
+
*/
|
|
135
|
+
onClickAdd: PropTypes.func,
|
|
136
|
+
/**
|
|
137
|
+
* Apply onClickSettings: function called clicking on Settings button
|
|
138
|
+
*/
|
|
139
|
+
onClickSettings: PropTypes.func
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
Sidebar.defaultProps = {
|
|
144
|
+
title: '',
|
|
145
|
+
defaultSelected: 0,
|
|
146
|
+
onClickItemSelectedParent: () => {},
|
|
147
|
+
items: [],
|
|
148
|
+
onClickAdd: () => {},
|
|
149
|
+
addTitle: 'Add',
|
|
150
|
+
onClickSettings: () => {}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export default Sidebar
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
@apply max-w-[216px] w-full p-4 border border-white rounded-md h-auto relative;
|
|
3
|
+
transition: max-width 0.2s linear;
|
|
4
|
+
}
|
|
5
|
+
.collapsed {
|
|
6
|
+
@apply max-w-[96px] text-center;
|
|
7
|
+
}
|
|
8
|
+
.buttonExpand {
|
|
9
|
+
@apply border rounded-md p-1 border-white;
|
|
10
|
+
}
|
|
11
|
+
.buttonSettings {
|
|
12
|
+
@apply border rounded-md p-1 border-white;
|
|
13
|
+
}
|
|
14
|
+
.buttonCollapse {
|
|
15
|
+
@apply absolute border border-white rounded-full h-6 w-6 right-[-0.875rem];
|
|
16
|
+
/* Override tailwind dist button[type='button]: background: transparent*/
|
|
17
|
+
@apply bg-main-dark-blue !important;
|
|
18
|
+
top: 1rem;
|
|
19
|
+
}
|
|
20
|
+
.title {
|
|
21
|
+
@apply text-white font-bold py-3;
|
|
22
|
+
}
|
|
23
|
+
.titleCollapsed {
|
|
24
|
+
@apply text-white text-[10px];
|
|
25
|
+
}
|
|
26
|
+
.buttonItem {
|
|
27
|
+
@apply flex items-center justify-start border-0 w-full;
|
|
28
|
+
}
|
|
29
|
+
.buttonItemCollapsed {
|
|
30
|
+
@apply w-auto;
|
|
31
|
+
}
|
|
32
|
+
.item {
|
|
33
|
+
@apply text-white ml-2 grow-0 text-left flex flex-col;
|
|
34
|
+
width: calc(100% - 28px)
|
|
35
|
+
}
|
|
36
|
+
.itemSubTitle {
|
|
37
|
+
@apply text-[10px] leading-[10px];
|
|
38
|
+
}
|
|
39
|
+
.itemTitle{
|
|
40
|
+
@apply text-xs text-ellipsis overflow-hidden whitespace-nowrap;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.itemSelected {
|
|
44
|
+
@apply text-light-green;
|
|
45
|
+
}
|
|
46
|
+
.items {
|
|
47
|
+
@apply flex flex-col gap-y-3 py-2;
|
|
48
|
+
}
|
|
49
|
+
.bottom {
|
|
50
|
+
@apply absolute left-0 bottom-[1rem] w-full px-4;
|
|
51
|
+
}
|
|
52
|
+
.titleSettings {
|
|
53
|
+
@apply text-white font-semibold ml-3;
|
|
54
|
+
}
|
|
55
|
+
.buttonSettingsExpanded {
|
|
56
|
+
@apply flex items-center justify-center w-full;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@keyframes fadeIn {
|
|
60
|
+
0% {
|
|
61
|
+
opacity: 0;
|
|
62
|
+
}
|
|
63
|
+
100% {
|
|
64
|
+
opacity: 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -3,14 +3,21 @@ import React from 'react'
|
|
|
3
3
|
import PropTypes from 'prop-types'
|
|
4
4
|
import styles from './Input.module.css'
|
|
5
5
|
import commonStyles from '../Common.module.css'
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
7
|
+
|
|
8
|
+
function Input ({ placeholder, value, name, borderColor, errorMessage, onChange, disabled, beforeInputIcon, beforeInputIconColor, afterInputIcon, afterInputIconColor, onClickBeforeIcon }) {
|
|
9
|
+
let className = styles.inputContainer + ' ' + commonStyles[`bordered--${borderColor}`] + ' ' + commonStyles[`text--${borderColor}`] + ' ' + commonStyles.padded
|
|
10
|
+
const showError = errorMessage.length > 0
|
|
11
|
+
if (showError) className += ' ' + commonStyles['bordered--error-red']
|
|
12
|
+
const classNameBeforeInput = `${styles.beforeInputIcon} ` + styles[`color-${beforeInputIconColor}`]
|
|
8
13
|
return (
|
|
9
14
|
<div className={styles.container}>
|
|
10
15
|
<div className={className}>
|
|
16
|
+
{beforeInputIcon && <FontAwesomeIcon icon={beforeInputIcon} className={classNameBeforeInput} data-testid='before-icon' color='white' onClick={() => onClickBeforeIcon()} />}
|
|
11
17
|
<input type='text' name={name} value={value} placeholder={placeholder} className={styles.fullWidth} onChange={onChange} disabled={disabled} />
|
|
18
|
+
{afterInputIcon && <FontAwesomeIcon icon={afterInputIcon} className={styles[`color-${afterInputIconColor}`]} data-testid='after-icon' />}
|
|
12
19
|
</div>
|
|
13
|
-
{
|
|
20
|
+
{showError && <span className={commonStyles['error-message']}>{errorMessage}</span>}
|
|
14
21
|
</div>
|
|
15
22
|
)
|
|
16
23
|
}
|
|
@@ -39,7 +46,27 @@ Input.propTypes = {
|
|
|
39
46
|
/**
|
|
40
47
|
* Disabled
|
|
41
48
|
*/
|
|
42
|
-
disabled: PropTypes.bool
|
|
49
|
+
disabled: PropTypes.bool,
|
|
50
|
+
/**
|
|
51
|
+
* beforeInputIcon
|
|
52
|
+
*/
|
|
53
|
+
beforeInputIcon: PropTypes.object,
|
|
54
|
+
/**
|
|
55
|
+
* beforeInputIconColor
|
|
56
|
+
*/
|
|
57
|
+
beforeInputIconColor: PropTypes.oneOf(['error-red', 'main-dark-blue', 'white']),
|
|
58
|
+
/**
|
|
59
|
+
* afterInputIcon
|
|
60
|
+
*/
|
|
61
|
+
afterInputIcon: PropTypes.object,
|
|
62
|
+
/**
|
|
63
|
+
* afterInputIconColor
|
|
64
|
+
*/
|
|
65
|
+
afterInputIconColor: PropTypes.oneOf(['error-red', 'main-dark-blue', 'white']),
|
|
66
|
+
/**
|
|
67
|
+
* onClickBeforeIcon
|
|
68
|
+
*/
|
|
69
|
+
onClickBeforeIcon: PropTypes.func
|
|
43
70
|
}
|
|
44
71
|
|
|
45
72
|
Input.defaultProps = {
|
|
@@ -49,7 +76,12 @@ Input.defaultProps = {
|
|
|
49
76
|
borderColor: 'main-green',
|
|
50
77
|
errorMessage: '',
|
|
51
78
|
onChange: () => {},
|
|
52
|
-
disabled: false
|
|
79
|
+
disabled: false,
|
|
80
|
+
beforeInputIcon: null,
|
|
81
|
+
beforeInputIconColor: 'main-dark-blue',
|
|
82
|
+
afterInputIcon: null,
|
|
83
|
+
onClickBeforeIcon: () => {},
|
|
84
|
+
afterInputIconColor: 'main-dark-blue'
|
|
53
85
|
}
|
|
54
86
|
|
|
55
87
|
export default Input
|
|
@@ -10,6 +10,19 @@
|
|
|
10
10
|
.input {
|
|
11
11
|
@apply focus:outline-none focus-within:outline-none focus-visible:outline-none;
|
|
12
12
|
}
|
|
13
|
+
.beforeInputIcon {
|
|
14
|
+
@apply ml-1 mr-3 cursor-pointer;
|
|
15
|
+
}
|
|
16
|
+
.color-main-dark-blue {
|
|
17
|
+
@apply text-main-dark-blue;
|
|
18
|
+
}
|
|
19
|
+
.color-error-red{
|
|
20
|
+
@apply text-error-red;
|
|
21
|
+
}
|
|
22
|
+
.color-white{
|
|
23
|
+
@apply text-white;
|
|
24
|
+
}
|
|
25
|
+
|
|
13
26
|
[type='text']:focus {
|
|
14
27
|
outline: none;
|
|
15
28
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
export default function AppEmptyIcon () {
|
|
3
|
+
return (
|
|
4
|
+
<svg
|
|
5
|
+
width={81}
|
|
6
|
+
height={80}
|
|
7
|
+
viewBox='0 0 81 80'
|
|
8
|
+
fill='none'
|
|
9
|
+
xmlns='http://www.w3.org/2000/svg'
|
|
10
|
+
>
|
|
11
|
+
<path
|
|
12
|
+
d='M34.8199 45.5671H24.4589C23.9066 45.5671 23.4589 46.0149 23.4589 46.5671V66.3802C23.4589 66.9324 23.9066 67.3802 24.4589 67.3802H56.5418C57.0941 67.3802 57.5418 66.9324 57.5418 66.3802V46.5671C57.5418 46.0149 57.0941 45.5671 56.5418 45.5671H46.1808'
|
|
13
|
+
stroke='#21FA90'
|
|
14
|
+
strokeWidth={3}
|
|
15
|
+
strokeLinecap='round'
|
|
16
|
+
/>
|
|
17
|
+
<rect
|
|
18
|
+
x={34.8199}
|
|
19
|
+
y={67.3799}
|
|
20
|
+
width={11.3609}
|
|
21
|
+
height={5.45325}
|
|
22
|
+
stroke='#21FA90'
|
|
23
|
+
strokeWidth={3}
|
|
24
|
+
/>
|
|
25
|
+
<path
|
|
26
|
+
d='M29.1394 73.8333C29.1394 73.281 29.5871 72.8333 30.1394 72.8333H50.8613C51.4136 72.8333 51.8613 73.281 51.8613 73.8333V76.9232H29.1394V73.8333Z'
|
|
27
|
+
stroke='#21FA90'
|
|
28
|
+
strokeWidth={3}
|
|
29
|
+
/>
|
|
30
|
+
<path
|
|
31
|
+
d='M40.5004 42.8403L43.051 50.3765L51.3053 50.3765L44.6275 55.0342L47.1782 62.5704L40.5004 57.9128L33.8226 62.5704L36.3732 55.0342L29.6954 50.3765L37.9497 50.3765L40.5004 42.8403Z'
|
|
32
|
+
stroke='#21FA90'
|
|
33
|
+
strokeWidth={3}
|
|
34
|
+
strokeLinejoin='round'
|
|
35
|
+
/>
|
|
36
|
+
<path
|
|
37
|
+
d='M19.1982 57.0413H9.25739V37.1597'
|
|
38
|
+
stroke='#21FA90'
|
|
39
|
+
strokeWidth={3}
|
|
40
|
+
strokeLinecap='round'
|
|
41
|
+
strokeLinejoin='round'
|
|
42
|
+
/>
|
|
43
|
+
<path
|
|
44
|
+
d='M29.139 39.9999V14.4377'
|
|
45
|
+
stroke='#21FA90'
|
|
46
|
+
strokeWidth={3}
|
|
47
|
+
strokeLinecap='round'
|
|
48
|
+
strokeLinejoin='round'
|
|
49
|
+
/>
|
|
50
|
+
<path
|
|
51
|
+
d='M61.8018 57.0414H71.7426V45.6804'
|
|
52
|
+
stroke='#21FA90'
|
|
53
|
+
strokeWidth={3}
|
|
54
|
+
strokeLinecap='round'
|
|
55
|
+
strokeLinejoin='round'
|
|
56
|
+
/>
|
|
57
|
+
<path
|
|
58
|
+
d='M49.0207 41.4201V32.8994H58.9615V17.2781'
|
|
59
|
+
stroke='#21FA90'
|
|
60
|
+
strokeWidth={3}
|
|
61
|
+
strokeLinecap='round'
|
|
62
|
+
strokeLinejoin='round'
|
|
63
|
+
/>
|
|
64
|
+
<circle
|
|
65
|
+
cx={9.25738}
|
|
66
|
+
cy={31.4793}
|
|
67
|
+
r={5.68047}
|
|
68
|
+
stroke='#21FA90'
|
|
69
|
+
strokeWidth={3}
|
|
70
|
+
/>
|
|
71
|
+
<circle
|
|
72
|
+
cx={29.139}
|
|
73
|
+
cy={8.75738}
|
|
74
|
+
r={5.68047}
|
|
75
|
+
stroke='#21FA90'
|
|
76
|
+
strokeWidth={3}
|
|
77
|
+
/>
|
|
78
|
+
<circle
|
|
79
|
+
cx={58.9615}
|
|
80
|
+
cy={11.5977}
|
|
81
|
+
r={5.68047}
|
|
82
|
+
stroke='#21FA90'
|
|
83
|
+
strokeWidth={3}
|
|
84
|
+
/>
|
|
85
|
+
<circle
|
|
86
|
+
cx={71.7426}
|
|
87
|
+
cy={40.0001}
|
|
88
|
+
r={5.68047}
|
|
89
|
+
stroke='#21FA90'
|
|
90
|
+
strokeWidth={3}
|
|
91
|
+
/>
|
|
92
|
+
</svg>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
export default function AppEmptyIcon () {
|
|
3
|
+
return (
|
|
4
|
+
<svg
|
|
5
|
+
width={32}
|
|
6
|
+
height={33}
|
|
7
|
+
viewBox='0 0 32 33'
|
|
8
|
+
fill='none'
|
|
9
|
+
xmlns='http://www.w3.org/2000/svg'
|
|
10
|
+
>
|
|
11
|
+
<path
|
|
12
|
+
d='M12 6.75317H5C4.44772 6.75317 4 7.20089 4 7.75317V21.1132C4 21.6655 4.44772 22.1132 5 22.1132H27C27.5523 22.1132 28 21.6655 28 21.1132V7.75317C28 7.20089 27.5523 6.75317 27 6.75317H20'
|
|
13
|
+
stroke='#00283D'
|
|
14
|
+
strokeWidth={2}
|
|
15
|
+
strokeLinecap='round'
|
|
16
|
+
/>
|
|
17
|
+
<rect
|
|
18
|
+
x={12}
|
|
19
|
+
y={22.1133}
|
|
20
|
+
width={8}
|
|
21
|
+
height={3.84}
|
|
22
|
+
stroke='#00283D'
|
|
23
|
+
strokeWidth={2}
|
|
24
|
+
/>
|
|
25
|
+
<path
|
|
26
|
+
d='M8 26.9534C8 26.4011 8.44772 25.9534 9 25.9534H23C23.5523 25.9534 24 26.4011 24 26.9534V28.8334H8V26.9534Z'
|
|
27
|
+
stroke='#00283D'
|
|
28
|
+
strokeWidth={2}
|
|
29
|
+
/>
|
|
30
|
+
<path
|
|
31
|
+
d='M16 4.83325L17.7961 10.14H23.6085L18.9062 13.4198L20.7023 18.7265L16 15.4468L11.2977 18.7265L13.0938 13.4198L8.39155 10.14H14.2039L16 4.83325Z'
|
|
32
|
+
stroke='#00283D'
|
|
33
|
+
strokeWidth={2}
|
|
34
|
+
strokeLinejoin='round'
|
|
35
|
+
/>
|
|
36
|
+
</svg>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import styles from './Icons.module.css'
|
|
3
|
+
const GearIcon = ({ color = 'green', size = 'normal' }) => {
|
|
4
|
+
const className = styles[`${color}`]
|
|
5
|
+
let dimension = 33
|
|
6
|
+
switch (size) {
|
|
7
|
+
case 'small':
|
|
8
|
+
dimension = 16
|
|
9
|
+
break
|
|
10
|
+
default:
|
|
11
|
+
break
|
|
12
|
+
}
|
|
13
|
+
return (
|
|
14
|
+
<svg
|
|
15
|
+
width={dimension}
|
|
16
|
+
height={dimension}
|
|
17
|
+
viewBox='0 0 33 32'
|
|
18
|
+
fill='none'
|
|
19
|
+
xmlns='http://www.w3.org/2000/svg'
|
|
20
|
+
className={className}
|
|
21
|
+
>
|
|
22
|
+
<path
|
|
23
|
+
d='M16.5016 20.6575C19.011 20.6575 21.0452 18.6574 21.0452 16.1901C21.0452 13.7228 19.011 11.7227 16.5016 11.7227C13.9922 11.7227 11.958 13.7228 11.958 16.1901C11.958 18.6574 13.9922 20.6575 16.5016 20.6575Z'
|
|
24
|
+
stroke='none'
|
|
25
|
+
strokeWidth={1.5}
|
|
26
|
+
strokeLinecap='round'
|
|
27
|
+
strokeLinejoin='round'
|
|
28
|
+
/>
|
|
29
|
+
<path
|
|
30
|
+
d='M18.9391 4.69606V6.21219C18.9391 6.50074 19.1219 6.76144 19.3974 6.86269L21.3641 7.59418C21.6318 7.69289 21.9356 7.62455 22.1312 7.417L23.076 6.41974C23.354 6.12613 23.8277 6.1236 24.1083 6.41721L26.3891 8.79139C26.6439 9.05716 26.6465 9.46973 26.3968 9.73803L25.1818 11.0491C24.9887 11.2567 24.9423 11.5579 25.0633 11.811L25.8871 13.5575C26.003 13.803 26.2552 13.9625 26.5307 13.9625H27.7921C28.1834 13.9625 28.5 14.2738 28.5 14.6585V17.5895C28.5 17.9743 28.1834 18.2856 27.7921 18.2856H26.4663C26.16 18.2856 25.8871 18.4805 25.7919 18.7665L25.1225 20.7838C25.0427 21.0217 25.0994 21.2824 25.2719 21.4672L26.3608 22.6492C26.6259 22.9378 26.6002 23.3858 26.3016 23.6414L23.7916 25.8005C23.5033 26.0485 23.0657 26.0257 22.8057 25.7498L21.9304 24.8235C21.7399 24.621 21.4439 24.5476 21.1788 24.6387L19.351 25.2664C19.0653 25.3651 18.8748 25.6283 18.8748 25.9245V27.3039C18.8748 27.6887 18.5581 28 18.1668 28H14.8306C14.4393 28 14.1227 27.6887 14.1227 27.3039V25.9245C14.1227 25.6283 13.9322 25.3651 13.6464 25.2664L11.8187 24.6387C11.5535 24.5476 11.2575 24.6184 11.067 24.8235L10.1917 25.7498C9.93173 26.0257 9.4941 26.0485 9.20578 25.8005L6.69586 23.6414C6.39724 23.3858 6.3715 22.9378 6.63665 22.6492L7.72557 21.4672C7.89547 21.2824 7.95211 21.0217 7.87488 20.7838L7.20557 18.7665C7.11032 18.4805 6.83745 18.2856 6.53111 18.2856H5.20793C4.81664 18.2856 4.5 17.9743 4.5 17.5895V14.6585C4.5 14.2738 4.81664 13.9625 5.20793 13.9625H6.46932C6.74477 13.9625 6.99705 13.8055 7.11289 13.5575L7.93666 11.811C8.05765 11.5554 8.00874 11.2567 7.81825 11.0491L6.60319 9.73803C6.35348 9.46973 6.35605 9.05463 6.61091 8.79139L8.89172 6.41721C9.17232 6.12613 9.64598 6.12613 9.92401 6.41974L10.8688 7.417C11.0644 7.62455 11.3682 7.69289 11.6359 7.59418L13.6026 6.86269C13.8781 6.76144 14.0609 6.50074 14.0609 6.21219V4.69606C14.0609 4.31133 14.3775 4 14.7688 4H18.2312C18.6225 4 18.9391 4.31133 18.9391 4.69606Z'
|
|
31
|
+
stroke='none'
|
|
32
|
+
strokeWidth={1.5}
|
|
33
|
+
strokeLinecap='round'
|
|
34
|
+
strokeLinejoin='round'
|
|
35
|
+
/>
|
|
36
|
+
</svg>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default GearIcon
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import styles from './Icons.module.css'
|
|
3
|
+
const PuzzleDynamicIcon = ({ color = 'green', size = 'normal' }) => {
|
|
4
|
+
const className = `${styles.noShrinkForFlex} ` + styles[`${color}`]
|
|
5
|
+
let dimension = 33
|
|
6
|
+
switch (size) {
|
|
7
|
+
case 'small':
|
|
8
|
+
dimension = 24
|
|
9
|
+
break
|
|
10
|
+
default:
|
|
11
|
+
break
|
|
12
|
+
}
|
|
13
|
+
return (
|
|
14
|
+
<svg
|
|
15
|
+
width={dimension}
|
|
16
|
+
height={dimension}
|
|
17
|
+
viewBox='0 0 32 33'
|
|
18
|
+
fill='none'
|
|
19
|
+
xmlns='http://www.w3.org/2000/svg'
|
|
20
|
+
className={className}
|
|
21
|
+
>
|
|
22
|
+
<rect
|
|
23
|
+
x={4}
|
|
24
|
+
y={4.83325}
|
|
25
|
+
width={8}
|
|
26
|
+
height={10.0699}
|
|
27
|
+
rx={1}
|
|
28
|
+
stroke='none'
|
|
29
|
+
strokeWidth={1.5}
|
|
30
|
+
/>
|
|
31
|
+
<path
|
|
32
|
+
d='M16 4.83325L22 9.83325L16 14.8333V4.83325Z'
|
|
33
|
+
stroke='none'
|
|
34
|
+
strokeWidth={2}
|
|
35
|
+
strokeLinecap='round'
|
|
36
|
+
strokeLinejoin='round'
|
|
37
|
+
/>
|
|
38
|
+
<rect
|
|
39
|
+
x={28}
|
|
40
|
+
y={28.8333}
|
|
41
|
+
width={8}
|
|
42
|
+
height={10.0699}
|
|
43
|
+
rx={1}
|
|
44
|
+
transform='rotate(-180 28 28.8333)'
|
|
45
|
+
stroke='none'
|
|
46
|
+
strokeWidth={1.5}
|
|
47
|
+
/>
|
|
48
|
+
<rect
|
|
49
|
+
x={16}
|
|
50
|
+
y={28.8333}
|
|
51
|
+
width={12}
|
|
52
|
+
height={10.0699}
|
|
53
|
+
rx={1}
|
|
54
|
+
transform='rotate(-180 16 28.8333)'
|
|
55
|
+
stroke='none'
|
|
56
|
+
strokeWidth={1.5}
|
|
57
|
+
/>
|
|
58
|
+
<path
|
|
59
|
+
d='M22 12.8333V14.8333L28 9.83325L22 4.83325V6.83325'
|
|
60
|
+
stroke='none'
|
|
61
|
+
strokeWidth={1.5}
|
|
62
|
+
strokeLinecap='round'
|
|
63
|
+
strokeLinejoin='round'
|
|
64
|
+
/>
|
|
65
|
+
</svg>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default PuzzleDynamicIcon
|
|
@@ -2,7 +2,7 @@ import * as React from 'react'
|
|
|
2
2
|
import styles from './Icons.module.css'
|
|
3
3
|
const PuzzleIcon = ({ color = 'green', size = 'normal', tip = '' }) => {
|
|
4
4
|
const className = `${styles.noShrinkForFlex} ` + styles[`${color}`]
|
|
5
|
-
let dimension =
|
|
5
|
+
let dimension = 33
|
|
6
6
|
switch (size) {
|
|
7
7
|
case 'small':
|
|
8
8
|
dimension = 24
|
|
@@ -14,47 +14,47 @@ const PuzzleIcon = ({ color = 'green', size = 'normal', tip = '' }) => {
|
|
|
14
14
|
<svg
|
|
15
15
|
width={dimension}
|
|
16
16
|
height={dimension}
|
|
17
|
-
viewBox='0 0
|
|
17
|
+
viewBox='0 0 33 32'
|
|
18
18
|
fill='none'
|
|
19
19
|
xmlns='http://www.w3.org/2000/svg'
|
|
20
20
|
className={className}
|
|
21
21
|
data-tip={tip}
|
|
22
22
|
>
|
|
23
23
|
<rect
|
|
24
|
-
x={5}
|
|
25
|
-
y={
|
|
26
|
-
width={
|
|
27
|
-
height={
|
|
24
|
+
x={4.5}
|
|
25
|
+
y={4}
|
|
26
|
+
width={8}
|
|
27
|
+
height={10.0699}
|
|
28
28
|
rx={1}
|
|
29
29
|
stroke='none'
|
|
30
30
|
strokeWidth={1.5}
|
|
31
31
|
/>
|
|
32
32
|
<rect
|
|
33
|
-
x={
|
|
34
|
-
y={
|
|
35
|
-
width={
|
|
36
|
-
height={
|
|
33
|
+
x={16.5}
|
|
34
|
+
y={4}
|
|
35
|
+
width={12}
|
|
36
|
+
height={10.0699}
|
|
37
37
|
rx={1}
|
|
38
38
|
stroke='none'
|
|
39
39
|
strokeWidth={1.5}
|
|
40
40
|
/>
|
|
41
41
|
<rect
|
|
42
|
-
x={
|
|
43
|
-
y={
|
|
44
|
-
width={
|
|
45
|
-
height={
|
|
42
|
+
x={28.5}
|
|
43
|
+
y={28}
|
|
44
|
+
width={8}
|
|
45
|
+
height={10.0699}
|
|
46
46
|
rx={1}
|
|
47
|
-
transform='rotate(-180
|
|
47
|
+
transform='rotate(-180 28.5 28)'
|
|
48
48
|
stroke='none'
|
|
49
49
|
strokeWidth={1.5}
|
|
50
50
|
/>
|
|
51
51
|
<rect
|
|
52
|
-
x={
|
|
53
|
-
y={
|
|
54
|
-
width={
|
|
55
|
-
height={
|
|
52
|
+
x={16.5}
|
|
53
|
+
y={28}
|
|
54
|
+
width={12}
|
|
55
|
+
height={10.0699}
|
|
56
56
|
rx={1}
|
|
57
|
-
transform='rotate(-180
|
|
57
|
+
transform='rotate(-180 16.5 28)'
|
|
58
58
|
stroke='none'
|
|
59
59
|
strokeWidth={1.5}
|
|
60
60
|
/>
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import ApiIcon from './ApiIcon'
|
|
2
2
|
import ApiIconClosed from './ApiIconClosed'
|
|
3
3
|
import ApiEmptyIcon from './ApiEmptyIcon'
|
|
4
|
+
import AppIcon from './AppIcon'
|
|
5
|
+
import AppEmptyIcon from './AppEmptyIcon'
|
|
4
6
|
import CloseModalIcon from './CloseModalIcon'
|
|
7
|
+
import GearIcon from './GearIcon'
|
|
5
8
|
import RoundCloseIcon from './RoundCloseIcon'
|
|
6
9
|
import RoundCloseHoverIcon from './RoundCloseHoverIcon'
|
|
7
10
|
import MetricsIcon from './MetricsIcon'
|
|
11
|
+
import PuzzleDynamicIcon from './PuzzleDynamicIcon'
|
|
8
12
|
import PuzzleIcon from './PuzzleIcon'
|
|
9
13
|
import PullRequestIcon from './PullRequestIcon'
|
|
10
14
|
|
|
@@ -12,10 +16,14 @@ export default {
|
|
|
12
16
|
ApiIcon,
|
|
13
17
|
ApiIconClosed,
|
|
14
18
|
ApiEmptyIcon,
|
|
19
|
+
AppIcon,
|
|
20
|
+
AppEmptyIcon,
|
|
15
21
|
CloseModalIcon,
|
|
22
|
+
GearIcon,
|
|
16
23
|
RoundCloseIcon,
|
|
17
24
|
RoundCloseHoverIcon,
|
|
18
25
|
MetricsIcon,
|
|
26
|
+
PuzzleDynamicIcon,
|
|
19
27
|
PuzzleIcon,
|
|
20
28
|
PullRequestIcon
|
|
21
29
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
import { useState } from 'react'
|
|
3
|
-
import
|
|
3
|
+
import Sidebar from '../components/Sidebar'
|
|
4
4
|
import BorderedBox from '../components/BorderedBox'
|
|
5
5
|
|
|
6
6
|
const divStyle = {
|
|
@@ -11,8 +11,8 @@ const divStyle = {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export default {
|
|
14
|
-
title: 'Platformatic/
|
|
15
|
-
component:
|
|
14
|
+
title: 'Platformatic/Sidebar',
|
|
15
|
+
component: Sidebar,
|
|
16
16
|
decorators: [
|
|
17
17
|
(Story) => (
|
|
18
18
|
<div style={divStyle}>
|
|
@@ -23,18 +23,23 @@ export default {
|
|
|
23
23
|
]
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const Template = (args) => <
|
|
26
|
+
const Template = (args) => <Sidebar {...args} />
|
|
27
27
|
|
|
28
|
-
export const
|
|
28
|
+
export const EmptySidebar = Template.bind({})
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
title: '
|
|
30
|
+
EmptySidebar.args = {
|
|
31
|
+
title: 'Sidebar bar empty',
|
|
32
32
|
addTitle: 'Create',
|
|
33
|
-
onClickAdd: () => alert('clicked on add
|
|
33
|
+
onClickAdd: () => alert('clicked on add EmptySidebar'),
|
|
34
|
+
onClickSettings: () => alert('settings')
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
const
|
|
37
|
-
const [items, setItems] = useState([
|
|
37
|
+
const FullSidebarTemplate = (args) => {
|
|
38
|
+
const [items, setItems] = useState([
|
|
39
|
+
{ iconName: 'PuzzleIcon', subTitle: 'Subtitle', title: 'a very very very very very long title 1' },
|
|
40
|
+
{ title: 'Title number 2', subTitle: 'Subtitle 2' },
|
|
41
|
+
{ title: 'Another Title', subTitle: 'Subtitle 3', iconName: 'PuzzleDynamicIcon' }
|
|
42
|
+
])
|
|
38
43
|
function onClickAdd () {
|
|
39
44
|
const tmpItem = items.map(item => item)
|
|
40
45
|
tmpItem.push('Title number ' + (items.length + 1))
|
|
@@ -42,14 +47,15 @@ const FullSideBarTemplate = (args) => {
|
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
return (
|
|
45
|
-
<
|
|
50
|
+
<Sidebar items={items} onClickAdd={() => onClickAdd()} {...args} />
|
|
46
51
|
)
|
|
47
52
|
}
|
|
48
53
|
|
|
49
|
-
export const
|
|
54
|
+
export const FullSidebar = FullSidebarTemplate.bind({})
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
title: '
|
|
56
|
+
FullSidebar.args = {
|
|
57
|
+
title: 'Sidebar bar Full',
|
|
53
58
|
addTitle: 'Create',
|
|
54
|
-
onClickItemSelected: (index) => alert('selected: ' + index)
|
|
59
|
+
onClickItemSelected: (index) => alert('selected: ' + index),
|
|
60
|
+
onClickSettings: () => alert('settings')
|
|
55
61
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
import React, { useState } from 'react'
|
|
3
3
|
import Input from '../../components/forms/Input'
|
|
4
|
+
import { faAdd, faCheckCircle } from '@fortawesome/free-solid-svg-icons'
|
|
5
|
+
|
|
4
6
|
export default {
|
|
5
7
|
title: 'Platformatic/Forms/Input',
|
|
6
8
|
component: Input
|
|
@@ -30,6 +32,7 @@ export const DefaultInvalid = Template.bind({})
|
|
|
30
32
|
DefaultInvalid.args = {
|
|
31
33
|
name: 'test',
|
|
32
34
|
placeholder: 'Platformatic',
|
|
35
|
+
borderColor: 'main-dark-blue',
|
|
33
36
|
errorMessage: 'This is an error message'
|
|
34
37
|
}
|
|
35
38
|
|
|
@@ -54,3 +57,13 @@ ValuedAndAlertChange.args = {
|
|
|
54
57
|
name: 'test',
|
|
55
58
|
placeholder: 'Platformatic'
|
|
56
59
|
}
|
|
60
|
+
|
|
61
|
+
export const IconBeforeAndAfter = Template.bind({})
|
|
62
|
+
|
|
63
|
+
IconBeforeAndAfter.args = {
|
|
64
|
+
name: 'test',
|
|
65
|
+
placeholder: 'Platformatic',
|
|
66
|
+
beforeInputIcon: faAdd,
|
|
67
|
+
afterInputIcon: faCheckCircle,
|
|
68
|
+
afterInputIconColor: 'error-red'
|
|
69
|
+
}
|
package/tailwind.config.cjs
CHANGED
|
@@ -7,11 +7,11 @@ module.exports = {
|
|
|
7
7
|
},
|
|
8
8
|
extend: {
|
|
9
9
|
screens: {
|
|
10
|
-
|
|
10
|
+
lg: '1440px'
|
|
11
11
|
// => @media (min-width: 1440px) { ... }
|
|
12
12
|
},
|
|
13
13
|
boxShadow: {
|
|
14
|
-
|
|
14
|
+
wrap: '0px 0px 20px rgba(0, 0, 0, 0.6)'
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
colors: {
|
|
@@ -24,7 +24,7 @@ module.exports = {
|
|
|
24
24
|
white: '#FFFFFF',
|
|
25
25
|
'error-red': '#FA2121',
|
|
26
26
|
'tertiary-blue': '#2588E4',
|
|
27
|
-
|
|
27
|
+
transparent: 'transparent'
|
|
28
28
|
},
|
|
29
29
|
fontFamily: {
|
|
30
30
|
sans: ['Montserrat']
|
|
@@ -37,7 +37,7 @@ module.exports = {
|
|
|
37
37
|
wider: '.05em',
|
|
38
38
|
widest: '.1em',
|
|
39
39
|
'more-widest': '.15em',
|
|
40
|
-
'super-widest': '.25em'
|
|
40
|
+
'super-widest': '.25em'
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
safelist: [
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
2
|
-
import PuzzleIcon from './icons/PuzzleIcon'
|
|
3
|
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
4
|
-
import { faChevronLeft, faPlus } from '@fortawesome/free-solid-svg-icons'
|
|
5
|
-
import styles from './SideBar.module.css'
|
|
6
|
-
import ReactTooltip from 'react-tooltip'
|
|
7
|
-
import HorizontalSeparator from './HorizontalSeparator'
|
|
8
|
-
export default function SideBar (props) {
|
|
9
|
-
const { title, defaultSelected = 0, onClickItemSelectedParent = () => {}, items = [], onClickAdd = () => {}, addTitle = 'Add' } = props
|
|
10
|
-
const [collapsed, setCollapsed] = useState(false)
|
|
11
|
-
const [selectedItem, setSelectedItem] = useState(defaultSelected)
|
|
12
|
-
|
|
13
|
-
function onClickItemSelected (index) {
|
|
14
|
-
setSelectedItem(index)
|
|
15
|
-
onClickItemSelectedParent(index)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return (
|
|
19
|
-
<div className={`${styles.container} ${collapsed && styles.collapsed}`}>
|
|
20
|
-
{collapsed
|
|
21
|
-
? (
|
|
22
|
-
<>
|
|
23
|
-
<button type='button' className={styles.buttonPuzzle} onClick={() => { setCollapsed(false) }}>
|
|
24
|
-
<PuzzleIcon tip='expand' />
|
|
25
|
-
</button>
|
|
26
|
-
<ReactTooltip />
|
|
27
|
-
</>
|
|
28
|
-
)
|
|
29
|
-
: (
|
|
30
|
-
<>
|
|
31
|
-
<button type='button' className={styles.buttonCollapse} onClick={() => { setCollapsed(true) }}>
|
|
32
|
-
<FontAwesomeIcon icon={faChevronLeft} size='1x' color='white' />
|
|
33
|
-
</button>
|
|
34
|
-
<div className={styles.title} data-testid='lateral-bar-title'>
|
|
35
|
-
{title}
|
|
36
|
-
</div>
|
|
37
|
-
<div className={styles.items} data-test-id='lateral-bar-items'>
|
|
38
|
-
{items.map((item, index) => {
|
|
39
|
-
const isSelected = selectedItem === index
|
|
40
|
-
return (
|
|
41
|
-
<React.Fragment key={index}>
|
|
42
|
-
<button className={`${styles.buttonItem} ${collapsed && styles.buttonItemCollapsed}`} type='button' onClick={() => onClickItemSelected(index)}>
|
|
43
|
-
<PuzzleIcon size='small' color={isSelected ? 'green' : 'white'} tip={item} />
|
|
44
|
-
<span className={`${styles.item} ${isSelected ? styles.itemSelected : ''}`}>{item}</span>
|
|
45
|
-
</button>
|
|
46
|
-
<ReactTooltip />
|
|
47
|
-
</React.Fragment>
|
|
48
|
-
)
|
|
49
|
-
})}
|
|
50
|
-
{/* <Button label='Add' buttonClass='transparent' icon={faPlus} color='white' size='small' inClick={onClickAdd}/> */}
|
|
51
|
-
<button className={`${styles.buttonItem} ${collapsed && styles.buttonItemCollapsed}`} onClick={onClickAdd}>
|
|
52
|
-
<FontAwesomeIcon color='white' icon={faPlus} data-tip={addTitle} />
|
|
53
|
-
{!collapsed && <span className={styles.item}>{addTitle}</span>}
|
|
54
|
-
</button>
|
|
55
|
-
</div>
|
|
56
|
-
</>
|
|
57
|
-
)}
|
|
58
|
-
<HorizontalSeparator marginBottom={2} marginTop={2} />
|
|
59
|
-
</div>
|
|
60
|
-
)
|
|
61
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
.container {
|
|
2
|
-
@apply max-w-[216px] w-full p-4 border border-white rounded-md h-auto relative;
|
|
3
|
-
transition: max-width 0.2s linear;
|
|
4
|
-
}
|
|
5
|
-
.collapsed {
|
|
6
|
-
@apply max-w-[96px] text-center;
|
|
7
|
-
}
|
|
8
|
-
.buttonPuzzle {
|
|
9
|
-
@apply border-0;
|
|
10
|
-
}
|
|
11
|
-
.buttonCollapse {
|
|
12
|
-
@apply absolute border border-white rounded-full h-6 w-6 right-[-0.875rem];
|
|
13
|
-
/* Override tailwind dist button[type='button]: background: transparent*/
|
|
14
|
-
@apply bg-main-dark-blue !important;
|
|
15
|
-
top: 1rem;
|
|
16
|
-
}
|
|
17
|
-
.title {
|
|
18
|
-
@apply text-white font-bold py-3;
|
|
19
|
-
}
|
|
20
|
-
.buttonItem {
|
|
21
|
-
@apply flex items-center border-0 w-full mx-auto;
|
|
22
|
-
}
|
|
23
|
-
.buttonItemCollapsed {
|
|
24
|
-
@apply w-auto
|
|
25
|
-
}
|
|
26
|
-
.item {
|
|
27
|
-
@apply text-sm text-white ml-2 grow-0;
|
|
28
|
-
}
|
|
29
|
-
.itemSelected {
|
|
30
|
-
@apply text-light-green;
|
|
31
|
-
}
|
|
32
|
-
.items {
|
|
33
|
-
@apply flex flex-col gap-y-3 py-2;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
@keyframes fadeIn {
|
|
37
|
-
0% {
|
|
38
|
-
opacity: 0;
|
|
39
|
-
}
|
|
40
|
-
100% {
|
|
41
|
-
opacity: 1;
|
|
42
|
-
}
|
|
43
|
-
}
|