@platformatic/ui-components 0.1.68 → 0.1.70

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/index.html CHANGED
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Platformatic UI Components</title>
7
- <script type="module" crossorigin src="/assets/index.de7e435d.js"></script>
7
+ <script type="module" crossorigin src="/assets/index.e049ed0f.js"></script>
8
8
  <link rel="stylesheet" href="/assets/index.611cc270.css">
9
9
  </head>
10
10
  <body>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@platformatic/ui-components",
3
3
  "description": "Platformatic UI Components",
4
- "version": "0.1.68",
4
+ "version": "0.1.70",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -7,7 +7,7 @@ import PlatformaticIcon from './PlatformaticIcon'
7
7
  import { COLORS_ICON, SIZES, BACKGROUND_COLOR_OPAQUE, PADDING_SIZES, SMALL, WHITE, NONE } from './constants'
8
8
  function ButtonFullRounded ({ className, iconName, iconSize, iconColor, disabled, paddingSize, alt, onClick, hoverEffect, bordered }) {
9
9
  const padding = commonStyles[`padding--${paddingSize}`]
10
- const containerClassName = `${className} ${styles.roundedFull} ` + commonStyles['background-color-main-dark-blue']
10
+ const containerClassName = `${className} ${styles.roundedFull}`
11
11
  let buttonClassName = `${styles.roundedFull} ${styles.buttonRoundedFull} ${padding}`
12
12
  if (bordered) buttonClassName += ' ' + commonStyles[`bordered--${iconColor}`]
13
13
  if (disabled) {
@@ -1,5 +1,5 @@
1
1
  .buttonRoundedFull {
2
- @apply flex justify-center cursor-pointer bg-main-dark-blue border items-center;
2
+ @apply flex justify-center cursor-pointer border-0 items-center;
3
3
  }
4
4
  .disabled {
5
5
  @apply bg-opacity-30 cursor-default;
@@ -1,32 +1,49 @@
1
- import React, { useState } from 'react'
1
+ 'use strict'
2
+ import React from 'react'
3
+ import PropTypes from 'prop-types'
4
+ import ButtonFullRounded from './ButtonFullRounded'
2
5
  import useEscapeKey from '../hooks/useEscapeKey'
3
6
  import CloseIcon from './icons/CloseIcon'
4
- import CircleCloseIcon from './icons/CircleCloseIcon'
5
- import CircleCloseHoverIcon from './icons/CircleCloseHoverIcon'
6
7
  import Logo from './Logo'
7
8
  import styles from './Modal.module.css'
9
+ import commonStyles from './Common.module.css'
10
+ import { MODAL_SIZES, SMALL, MODAL_LAYOUTS, MODAL_COVER, MODAL_POPUP, MAIN_DARK_BLUE, BACKGROUND_COLOR_OPAQUE, LARGE } from './constants'
11
+
12
+ function Modal ({ setIsOpen, title, layout, children, size }) {
13
+ let contentFullscreen
14
+ let titleFullscreen
15
+ let modalClassName = `${styles.modal}`
16
+ modalClassName += ' ' + styles[`modal--${layout}`]
17
+ modalClassName += ' ' + styles[`modal--${size}`]
18
+
19
+ let buttonFullRoundedClassName
20
+
21
+ const headerClassName = styles[`header--${layout}`]
22
+ if (MODAL_COVER === layout) {
23
+ contentFullscreen = styles[`content--${layout}`]
24
+ titleFullscreen = styles[`title--${layout}`]
25
+ buttonFullRoundedClassName = `${styles['close--cover']} `
26
+ buttonFullRoundedClassName += commonStyles['background-color-light-blue']
27
+ }
8
28
 
9
- export default function Modal (props) {
10
- const { setIsOpen, title, layout = 'info' } = props
11
- const [isHoverCloseModal, setIsHoverCloseModal] = useState(false)
12
29
  useEscapeKey(() => setIsOpen(false))
13
30
  let whichModal = <></>
14
31
 
15
32
  switch (layout) {
16
- case 'info':
33
+ case MODAL_POPUP:
17
34
  whichModal = (
18
35
  <>
19
36
  <div className={styles.blur} onClick={() => setIsOpen(false)} />
20
37
  <div className={`${styles.container} ${styles.centered}`}>
21
- <div className={`${styles.modal} ${styles.modalInfo}`}>
22
- <div className={styles.header}>
38
+ <div className={modalClassName}>
39
+ <div className={headerClassName}>
23
40
  <div className={styles.title}>{title}</div>
24
41
  <div className={styles.close} onClick={() => setIsOpen(false)}>
25
- <CloseIcon size='small' />
42
+ <CloseIcon size={SMALL} />
26
43
  </div>
27
44
  </div>
28
45
  <div>
29
- {props.children}
46
+ {children}
30
47
  </div>
31
48
  </div>
32
49
  </div>
@@ -34,55 +51,29 @@ export default function Modal (props) {
34
51
  )
35
52
  break
36
53
 
37
- case 'invite':
54
+ case MODAL_COVER:
38
55
  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 color='main-green' /> : <CircleCloseIcon color='main-green' />}
51
- </div>
52
- </div>
53
- <p className={styles.titleInvite}>{title}</p>
54
- <div>{props.children}</div>
55
- </div>
56
+ <div className={`${styles.container} ${styles.fullscreen}`}>
57
+ <div className={headerClassName}>
58
+ <ButtonFullRounded
59
+ className={buttonFullRoundedClassName}
60
+ iconName='CircleCloseIcon'
61
+ iconSize={LARGE}
62
+ iconColor={MAIN_DARK_BLUE}
63
+ hoverEffect={BACKGROUND_COLOR_OPAQUE}
64
+ onClick={() => { setIsOpen(false) }}
65
+ bordered={false}
66
+ alt='Close'
67
+ />
56
68
  </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>
69
+ <div className={contentFullscreen}>
70
+ <div className={titleFullscreen}>
71
+ <Logo width={100} heigth={80} color={MAIN_DARK_BLUE} />
72
+ <h3>PLATFORMATIC</h3>
83
73
  </div>
74
+ <div>{children}</div>
84
75
  </div>
85
- </>
76
+ </div>
86
77
  )
87
78
  break
88
79
 
@@ -91,3 +82,36 @@ export default function Modal (props) {
91
82
  }
92
83
  return whichModal
93
84
  }
85
+
86
+ Modal.propTypes = {
87
+ /**
88
+ * children
89
+ */
90
+ children: PropTypes.node,
91
+ /**
92
+ * setIsOpen
93
+ */
94
+ setIsOpen: PropTypes.func,
95
+ /**
96
+ * title
97
+ */
98
+ title: PropTypes.string,
99
+ /**
100
+ * layout
101
+ */
102
+ layout: PropTypes.oneOf(MODAL_LAYOUTS),
103
+ /**
104
+ * Size
105
+ */
106
+ size: PropTypes.oneOf(MODAL_SIZES)
107
+ }
108
+
109
+ Modal.defaultProps = {
110
+ children: null,
111
+ setIsOpen: () => {},
112
+ title: '',
113
+ layout: MODAL_POPUP,
114
+ size: SMALL
115
+ }
116
+
117
+ export default Modal
@@ -9,42 +9,45 @@
9
9
  @apply fixed top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]
10
10
  }
11
11
  .modal {
12
- @apply p-4 rounded-md mx-auto my-auto min-w-[480px] max-h-[85vh] overflow-y-auto;
12
+ @apply p-4 rounded-md mx-auto my-auto max-h-[85vh] overflow-y-auto;
13
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];
14
+ .modal--popup {
15
+ @apply bg-light-blue;
19
16
  }
20
17
  .fullscreen {
21
18
  @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
19
  }
23
- .header {
20
+ .header--popup {
24
21
  @apply flex justify-between items-center;
25
22
  }
26
- .headerInvite {
23
+ .header--cover {
27
24
  @apply flex justify-end;
28
25
  }
29
- .close {
30
- @apply hover:cursor-pointer;
31
- }
32
26
  .hr {
33
27
  @apply text-[#00283D] my-2 opacity-20;
34
28
  }
35
29
  .title {
36
30
  @apply font-bold text-lg;
37
31
  }
38
- .titleInvite {
39
- @apply font-bold text-lg text-main-green text-center;
40
- }
41
- .contentFullscreen {
32
+ .content--cover {
42
33
  @apply h-auto w-full pt-4;
43
34
  }
44
- .titleFullscreen {
35
+ .title--cover {
45
36
  @apply inline-flex items-center;
46
37
  }
47
- .titleFullscreen h3 {
38
+ .title--cover h3 {
48
39
  @apply text-[22px] text-dark-blue font-bold tracking-widest mx-3;
49
40
  }
41
+ .modal--small {
42
+ @apply min-w-[480px] max-w-[480px];
43
+ }
44
+ .modal--medium {
45
+ @apply min-w-[880px] max-w-[880px];
46
+ }
47
+ .modal--full-width {
48
+ @apply w-screen min-w-full;
49
+ }
50
+ .close--cover {
51
+ @apply mt-4 mr-4;
52
+ }
50
53
 
@@ -1,13 +1,14 @@
1
1
  import React, { useEffect, useState } from 'react'
2
2
  import Icons from './icons'
3
3
  import Button from './Button'
4
+ import ButtonFullRounded from './ButtonFullRounded'
5
+ import commonStyles from './Common.module.css'
4
6
  import styles from './Sidebar.module.css'
5
7
  import ReactTooltip from 'react-tooltip'
6
8
  import HorizontalSeparator from './HorizontalSeparator'
7
9
  import PlatformaticIcon from './PlatformaticIcon'
8
10
  import PropTypes from 'prop-types'
9
11
  import { BACKGROUND_COLOR_OPAQUE, MEDIUM, WHITE } from './constants'
10
- import ButtonFullRounded from './ButtonFullRounded'
11
12
 
12
13
  function Sidebar (props) {
13
14
  const {
@@ -24,6 +25,8 @@ function Sidebar (props) {
24
25
  const [collapsed, setCollapsed] = useState(false)
25
26
  const [selectedItem, setSelectedItem] = useState(null)
26
27
  const disabledCreateButton = disableClickAdd ? styles.disabled : ''
28
+ let buttonFullRoundedClassName = `${styles.buttonCollapse} `
29
+ buttonFullRoundedClassName += commonStyles['background-color-main-dark-blue']
27
30
 
28
31
  function onClickItemSelected (item) {
29
32
  setSelectedItem(item.id)
@@ -40,7 +43,7 @@ function Sidebar (props) {
40
43
  ? (
41
44
  <>
42
45
  <ButtonFullRounded
43
- className={styles.buttonCollapse}
46
+ className={buttonFullRoundedClassName}
44
47
  iconName='CircleArrowRightIcon'
45
48
  iconSize={MEDIUM}
46
49
  iconColor={WHITE}
@@ -65,7 +68,7 @@ function Sidebar (props) {
65
68
  : (
66
69
  <>
67
70
  <ButtonFullRounded
68
- className={styles.buttonCollapse}
71
+ className={buttonFullRoundedClassName}
69
72
  iconName='CircleArrowLeftIcon'
70
73
  iconSize={MEDIUM}
71
74
  iconColor={WHITE}
@@ -14,4 +14,10 @@ export const PADDING_SIZES = [NONE, ...SIZES]
14
14
  export const BOX_SHADOW = 'box-shadow'
15
15
  export const BACKGROUND_COLOR_OPAQUE = 'background-color-opaque'
16
16
  export const UNDERLINE = 'underline'
17
+ export const FULL_WIDTH = 'full-width'
17
18
  export const HOVER_EFFECTS_BUTTONS = [BOX_SHADOW, BACKGROUND_COLOR_OPAQUE, UNDERLINE]
19
+ export const MODAL_SIZES = [SMALL, MEDIUM, FULL_WIDTH]
20
+
21
+ export const MODAL_POPUP = 'popup'
22
+ export const MODAL_COVER = 'cover'
23
+ export const MODAL_LAYOUTS = [MODAL_POPUP, MODAL_COVER]
@@ -1,13 +1,18 @@
1
1
  'use strict'
2
2
  import React from 'react'
3
+ import PropTypes from 'prop-types'
3
4
  import styles from './ToggleSwitch.module.css'
4
5
  import commonStyles from '../Common.module.css'
5
- export default function ToggleSwitch ({ name, label, errorMessage = '', onChange = () => {} }) {
6
+
7
+ function ToggleSwitch ({ name, label, errorMessage, onChange, checked, disabled }) {
8
+ let className = `${styles.switch} `
9
+ if (disabled) className += styles.disabled
10
+
6
11
  return (
7
12
  <>
8
13
  <div className={styles.container}>
9
- <label className={styles.switch}>
10
- <input type='checkbox' name={name} onChange={onChange} />
14
+ <label className={className}>
15
+ <input type='checkbox' name={name} onChange={onChange} checked={checked} disabled={disabled} />
11
16
  <span className={`${styles.slider} ${styles.round}`} />
12
17
  </label>
13
18
  <span className={styles.label}>{label}</span>
@@ -16,3 +21,41 @@ export default function ToggleSwitch ({ name, label, errorMessage = '', onChange
16
21
  </>
17
22
  )
18
23
  }
24
+
25
+ ToggleSwitch.propTypes = {
26
+ /**
27
+ * name
28
+ */
29
+ name: PropTypes.string,
30
+ /**
31
+ * label
32
+ */
33
+ label: PropTypes.string,
34
+ /**
35
+ * errorMessage
36
+ */
37
+ errorMessage: PropTypes.string,
38
+ /**
39
+ * checked
40
+ */
41
+ checked: PropTypes.bool,
42
+ /**
43
+ * disabled
44
+ */
45
+ disabled: PropTypes.bool,
46
+ /**
47
+ * onChange of border
48
+ */
49
+ onChange: PropTypes.func
50
+ }
51
+
52
+ ToggleSwitch.defaultProps = {
53
+ name: '',
54
+ label: '',
55
+ errorMessage: '',
56
+ checked: false,
57
+ disabled: false,
58
+ onChange: () => {}
59
+ }
60
+
61
+ export default ToggleSwitch
@@ -2,13 +2,13 @@
2
2
  @apply flex w-full h-10 items-center;
3
3
  }
4
4
  .switch {
5
- @apply relative inline-block w-[50px] h-[24px];
5
+ @apply relative inline-block w-[50px] h-[24px] cursor-pointer;
6
6
  }
7
7
  .switch input {
8
8
  @apply opacity-0 w-0 h-0;
9
9
  }
10
10
  .slider {
11
- @apply absolute cursor-pointer top-0 left-0 right-0 bottom-0 h-full;
11
+ @apply absolute top-0 left-0 right-0 bottom-0 h-full;
12
12
  background-color: #707070;
13
13
  -webkit-transition: .4s;
14
14
  transition: .4s;
@@ -40,4 +40,8 @@ input:checked + .slider:before {
40
40
 
41
41
  .slider.round:before {
42
42
  @apply rounded-full;
43
+ }
44
+
45
+ .disabled {
46
+ @apply opacity-30 cursor-default;
43
47
  }
@@ -18,7 +18,7 @@ const CircleCloseIcon = ({ color, size }) => {
18
18
  xmlns='http://www.w3.org/2000/svg'
19
19
  className={className}
20
20
  >
21
- <circle cx={12} cy={12} r={11.5} stroke='none' />
21
+ <circle cx={12} cy={12} r={11.5} stroke='none' strokeWidth={1.5} />
22
22
  <path
23
23
  d='M6 6L18 18'
24
24
  stroke='none'
@@ -34,6 +34,23 @@ const CircleCloseIcon = ({ color, size }) => {
34
34
  </svg>
35
35
  )
36
36
  break
37
+ case 'large':
38
+ icon = (
39
+ <svg
40
+ width={40}
41
+ height={40}
42
+ className={className}
43
+ viewBox='0 0 40 40'
44
+ fill='none'
45
+ xmlns='http://www.w3.org/2000/svg'
46
+ >
47
+ <circle cx='20' cy='20' r='19.25' stroke='none' strokeWidth={1.5} />
48
+ <path d='M10 10L30 30' stroke='none' strokeWidth={2} strokeLinecap='round' strokeLinejoin='round' />
49
+ <path d='M10 30L30 10' stroke='none' strokeWidth={2} strokeLinecap='round' strokeLinejoin='round' />
50
+ </svg>
51
+
52
+ )
53
+ break
37
54
  default:
38
55
  break
39
56
  }
@@ -4,6 +4,7 @@ import Button from '../components/Button'
4
4
  import BorderedBox from '../components/BorderedBox'
5
5
  import DropDown from '../components/DropDown'
6
6
  import HorizontalSeparator from '../components/HorizontalSeparator'
7
+ import { FULL_WIDTH, MAIN_DARK_BLUE, MAIN_GREEN, MODAL_COVER, MODAL_LAYOUTS, MODAL_SIZES } from '../components/constants'
7
8
  export default {
8
9
  title: 'Platformatic/Modal',
9
10
  component: Modal,
@@ -12,7 +13,14 @@ export default {
12
13
  type: 'string',
13
14
  control: {
14
15
  type: 'radio',
15
- options: ['info', 'invite', 'fullscreen']
16
+ options: MODAL_LAYOUTS
17
+ }
18
+ },
19
+ size: {
20
+ type: 'string',
21
+ control: {
22
+ type: 'radio',
23
+ options: MODAL_SIZES
16
24
  }
17
25
  }
18
26
  }
@@ -25,24 +33,12 @@ const Template = (args) => {
25
33
  <main>
26
34
  <BorderedBox>This Is another Content</BorderedBox>
27
35
  <ContentThatLoads />
28
- <Button color='main-green' buttonClass='primary' onClick={() => setIsOpen(true)} label='Open Modal' />
36
+ <Button color={MAIN_GREEN} backgroundColor={MAIN_DARK_BLUE} onClick={() => setIsOpen(true)} label='Open Modal' />
29
37
  {isOpen && <Modal setIsOpen={setIsOpen} {...rest}>{text}</Modal>}
30
38
  </main>
31
39
  )
32
40
  }
33
41
 
34
- const TemplateInvite = (args) => {
35
- const [isOpen, setIsOpen] = useState(false)
36
- return (
37
- <main>
38
- <BorderedBox>This Is another Content</BorderedBox>
39
- <ContentThatLoads />
40
- <Button color='main-green' buttonClass='primary' onClick={() => setIsOpen(true)} label='Open Modal' />
41
- {isOpen && <Modal setIsOpen={setIsOpen} {...args}><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed</p><Button buttonClass='primary' onClick={() => setIsOpen(false)} label='Discard invite' /></Modal>}
42
- </main>
43
- )
44
- }
45
-
46
42
  const ContentThatLoads = () => {
47
43
  const [content, setContent] = useState(null)
48
44
  setTimeout(() => {
@@ -55,8 +51,7 @@ const ContentThatLoads = () => {
55
51
  export const Default = Template.bind({})
56
52
  Default.args = {
57
53
  title: 'List Title',
58
- text: 'Hello World',
59
- layout: 'info'
54
+ text: 'Hello World'
60
55
  }
61
56
 
62
57
  export const WithLongText = Template.bind({})
@@ -87,14 +82,9 @@ const MenuTemplate = () => {
87
82
  }
88
83
  export const WithDropDown = MenuTemplate.bind({})
89
84
 
90
- export const InviteLayout = TemplateInvite.bind({})
91
- InviteLayout.args = {
92
- title: 'Give me an invite',
93
- layout: 'invite'
94
- }
95
-
96
85
  export const FullscreenLayout = Template.bind({})
97
86
  FullscreenLayout.args = {
98
87
  title: 'Give me an invite',
99
- layout: 'fullscreen'
88
+ size: FULL_WIDTH,
89
+ layout: MODAL_COVER
100
90
  }
@@ -1,11 +1,18 @@
1
1
  'use strict'
2
+ import React, { useState } from 'react'
2
3
  import ToggleSwitch from '../../components/forms/ToggleSwitch'
3
4
  export default {
4
5
  title: 'Platformatic/Forms/ToggleSwitch',
5
6
  component: ToggleSwitch
6
7
  }
7
8
 
8
- const Template = (args) => <ToggleSwitch {...args} />
9
+ const Template = ({ checked, ...args }) => {
10
+ const [localChecked, setLocalChecked] = useState(checked)
11
+ const onChange = () => { setLocalChecked(!localChecked) }
12
+ return (
13
+ <ToggleSwitch {...args} checked={localChecked} onChange={() => onChange()} />
14
+ )
15
+ }
9
16
 
10
17
  export const Default = Template.bind({})
11
18
 
@@ -13,3 +20,22 @@ Default.args = {
13
20
  name: 'test',
14
21
  label: 'This is a label'
15
22
  }
23
+
24
+ export const Checked = Template.bind({})
25
+
26
+ Checked.args = {
27
+ name: 'test',
28
+ label: 'This is a label',
29
+ checked: true,
30
+ onChange: () => { alert('checked') }
31
+ }
32
+
33
+ export const Disabled = Template.bind({})
34
+
35
+ Disabled.args = {
36
+ name: 'test',
37
+ label: 'This is a label',
38
+ checked: true,
39
+ onChange: () => { alert('checked') },
40
+ disabled: true
41
+ }