From 7d4dd57deeba46d10e2ae2084164785587640884 Mon Sep 17 00:00:00 2001 From: Antonio Sonis Date: Tue, 20 Jun 2023 15:54:11 +0200 Subject: [PATCH 001/649] chore: adding ModalStepsForward as component Signed-off-by: Antonio Sonis --- index.js | 2 + src/components/ModalStepsForward.jsx | 90 +++++++++++++++++++++ src/components/ModalStepsForward.module.css | 34 ++++++++ src/components/constants.js | 2 + src/stories/ModalStepsForward.stories.jsx | 41 ++++++++++ 5 files changed, 169 insertions(+) create mode 100644 src/components/ModalStepsForward.jsx create mode 100644 src/components/ModalStepsForward.module.css create mode 100644 src/stories/ModalStepsForward.stories.jsx diff --git a/index.js b/index.js index b6e846e2..e57b5424 100644 --- a/index.js +++ b/index.js @@ -26,6 +26,7 @@ import Logo from './src/components/Logo' import LogoDropDown from './src/components/LogoDropDown' import Logos from './src/components/logos' import Modal from './src/components/Modal' +import ModalStepsForward from './src/components/ModalStepsForward' import PlatformaticIcon from './src/components/PlatformaticIcon' import Playground from './src/components/Playground' import SearchBar from './src/components/SearchBar' @@ -65,6 +66,7 @@ export { Logo, LogoDropDown, Modal, + ModalStepsForward, PlatformaticIcon, Playground, SearchBar, diff --git a/src/components/ModalStepsForward.jsx b/src/components/ModalStepsForward.jsx new file mode 100644 index 00000000..6f28383e --- /dev/null +++ b/src/components/ModalStepsForward.jsx @@ -0,0 +1,90 @@ +'use strict' +import React from 'react' +import PropTypes from 'prop-types' +import ButtonFullRounded from './ButtonFullRounded' +import useEscapeKey from '../hooks/useEscapeKey' +import Logo from './Logo' +import HorizontalSeparator from './HorizontalSeparator' +import styles from './ModalStepsForward.module.css' +import commonStyles from './Common.module.css' +import { + MODAL_SIZES, + SMALL, + MODAL_LAYOUTS, + MODAL_POPUP, + MAIN_DARK_BLUE, + BACKGROUND_COLOR_OPAQUE, + LARGE, + PROFILES, + MARGIN_0, + OPACITY_20 +} from './constants' + +function ModalStepsForward ({ setIsOpen, right, stepper, left }) { + let buttonFullRoundedClassName = `${styles['close--cover']} ` + buttonFullRoundedClassName += commonStyles['background-color-white'] + + let modalCoverClassName = `${styles.container} ${styles.fullscreen} ` + modalCoverClassName += commonStyles['background-color-light-blue'] + + useEscapeKey(() => setIsOpen(false)) + + return ( +
+
+ + + {stepper} + {left} +
+
+
+ { setIsOpen(false) }} + bordered={false} + alt='Close' + /> +
+ {right} +
+
+ ) +} + +ModalStepsForward.propTypes = { + /** + * setIsOpen + */ + setIsOpen: PropTypes.func, + /** + * layout + */ + layout: PropTypes.oneOf(MODAL_LAYOUTS), + /** + * Size + */ + size: PropTypes.oneOf(MODAL_SIZES), + /** + * profile + */ + profile: PropTypes.oneOf(PROFILES), + /** + * backgroundClassName + */ + backgroundClassName: PropTypes.string +} + +ModalStepsForward.defaultProps = { + setIsOpen: () => {}, + layout: MODAL_POPUP, + size: SMALL, + profile: '', + backgroundClassName: '' +} + +export default ModalStepsForward diff --git a/src/components/ModalStepsForward.module.css b/src/components/ModalStepsForward.module.css new file mode 100644 index 00000000..877ccd43 --- /dev/null +++ b/src/components/ModalStepsForward.module.css @@ -0,0 +1,34 @@ +.container { + @apply z-20 flex; +} +.fullscreen { + @apply fixed top-0 left-0 h-screen w-full min-h-screen min-w-full overflow-y-auto; +} +.headerLeft { + @apply flex justify-between w-full; +} +.headerRight { + @apply flex justify-end; +} +.modal--full-width { + @apply w-screen min-w-full; +} +.close--full-dark, +.header--full-light, +.close--cover { + @apply mt-4 mr-4; +} + +.left { + @apply min-w-[60%] max-w-[60%] w-full; +} +.right { + @apply w-full bg-white; + box-shadow: 0px 0px 10px rgba(0, 40, 61, 0.25); +} + + +.left, +.right { + @apply px-20 py-10 flex flex-col gap-y-5; +} \ No newline at end of file diff --git a/src/components/constants.js b/src/components/constants.js index c329ce37..45455d50 100644 --- a/src/components/constants.js +++ b/src/components/constants.js @@ -50,3 +50,5 @@ export const ROLE_OWNER = 'owner' export const MARGIN_10 = 10 export const MARGIN_0 = 0 + +export const OPACITY_20 = 20 diff --git a/src/stories/ModalStepsForward.stories.jsx b/src/stories/ModalStepsForward.stories.jsx new file mode 100644 index 00000000..bf3dd50c --- /dev/null +++ b/src/stories/ModalStepsForward.stories.jsx @@ -0,0 +1,41 @@ +import React, { useState } from 'react' +import ModalStepsForward from '../components/ModalStepsForward' +import Button from '../components/Button' +import { MAIN_DARK_BLUE, MAIN_GREEN, MODAL_LAYOUTS, MODAL_SIZES } from '../components/constants' +export default { + title: 'Platformatic/ModalStepsForward', + component: ModalStepsForward, + argTypes: { + layout: { + type: 'string', + control: { + type: 'radio', + options: MODAL_LAYOUTS + } + }, + size: { + type: 'string', + control: { + type: 'radio', + options: MODAL_SIZES + } + } + } +} + +const Template = (args) => { + const [isOpen, setIsOpen] = useState(false) + const { text, ...rest } = args + return ( +
+
+ ) +} + +export const Default = Template.bind({}) +Default.args = { + title: 'List Title', + text: 'Hello World' +} From 5cc1aff74706243041196cae78e9fc4286809e3f Mon Sep 17 00:00:00 2001 From: Antonio Sonis Date: Wed, 21 Jun 2023 17:29:42 +0200 Subject: [PATCH 002/649] fix: css Signed-off-by: Antonio Sonis --- src/components/ModalStepsForward.jsx | 4 +--- src/components/ModalStepsForward.module.css | 9 ++------- src/components/forms/Field.module.css | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/components/ModalStepsForward.jsx b/src/components/ModalStepsForward.jsx index 6f28383e..ab98d984 100644 --- a/src/components/ModalStepsForward.jsx +++ b/src/components/ModalStepsForward.jsx @@ -21,9 +21,7 @@ import { } from './constants' function ModalStepsForward ({ setIsOpen, right, stepper, left }) { - let buttonFullRoundedClassName = `${styles['close--cover']} ` - buttonFullRoundedClassName += commonStyles['background-color-white'] - + const buttonFullRoundedClassName = commonStyles['background-color-white'] let modalCoverClassName = `${styles.container} ${styles.fullscreen} ` modalCoverClassName += commonStyles['background-color-light-blue'] diff --git a/src/components/ModalStepsForward.module.css b/src/components/ModalStepsForward.module.css index 877ccd43..61795d0a 100644 --- a/src/components/ModalStepsForward.module.css +++ b/src/components/ModalStepsForward.module.css @@ -8,16 +8,11 @@ @apply flex justify-between w-full; } .headerRight { - @apply flex justify-end; + @apply flex justify-end mb-12; } .modal--full-width { @apply w-screen min-w-full; } -.close--full-dark, -.header--full-light, -.close--cover { - @apply mt-4 mr-4; -} .left { @apply min-w-[60%] max-w-[60%] w-full; @@ -30,5 +25,5 @@ .left, .right { - @apply px-20 py-10 flex flex-col gap-y-5; + @apply px-20 py-10 flex flex-col gap-y-10; } \ No newline at end of file diff --git a/src/components/forms/Field.module.css b/src/components/forms/Field.module.css index 837163e4..420a31b4 100644 --- a/src/components/forms/Field.module.css +++ b/src/components/forms/Field.module.css @@ -2,7 +2,7 @@ @apply flex flex-col w-full; } .title { - @apply text-xl font-semibold; + @apply text-xl font-semibold pb-2; } .text-color-main-dark-blue { @apply text-main-dark-blue; From da9c60e4bbf6922bb1cca9700389d9e433dea269 Mon Sep 17 00:00:00 2001 From: Antonio Sonis Date: Wed, 21 Jun 2023 17:30:18 +0200 Subject: [PATCH 003/649] chore: adding select component Signed-off-by: Antonio Sonis --- src/components/forms/Select.jsx | 81 ++++++++++++++++++ src/components/forms/Select.module.css | 48 +++++++++++ src/components/forms/index.js | 3 +- src/stories/forms/Select.stories.jsx | 110 +++++++++++++++++++++++++ 4 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 src/components/forms/Select.jsx create mode 100644 src/components/forms/Select.module.css create mode 100644 src/stories/forms/Select.stories.jsx diff --git a/src/components/forms/Select.jsx b/src/components/forms/Select.jsx new file mode 100644 index 00000000..5fc7a096 --- /dev/null +++ b/src/components/forms/Select.jsx @@ -0,0 +1,81 @@ +'use strict' +import React from 'react' +import PropTypes from 'prop-types' +import styles from './Select.module.css' +import commonStyles from '../Common.module.css' +import { MAIN_DARK_BLUE, MAIN_GREEN, MEDIUM } from '../constants' +import BorderedBox from '../BorderedBox' +import Icons from '../icons' + +function Select ({ defaultOption, name, options, borderColor, errorMessage, onChange, disabled, focused }) { + const selectClassName = styles.select + ' ' + commonStyles[`bordered--${borderColor}`] + ' ' + commonStyles[`text--${borderColor}`] + const showError = errorMessage.length > 0 + let className = styles.selectContainer + if (showError) className += ' ' + commonStyles['bordered--error-red'] + if (disabled) className += ' ' + commonStyles['apply-opacity-30'] + + const cmp = ( +
+
+ +
+ +
+
+ {showError && {errorMessage}} +
+ ) + + return focused ? ({cmp}) : cmp +} + +Select.propTypes = { + /** + * defaultOption + */ + defaultOption: PropTypes.string, + /** + * name + */ + name: PropTypes.string, + /** + * value + */ + options: PropTypes.arrayOf(PropTypes.shape({ + value: PropTypes.string, + label: PropTypes.string + })), + /** + * color of border + */ + borderColor: PropTypes.oneOf([MAIN_GREEN, MAIN_DARK_BLUE]), + /** + * onChange + */ + onChange: PropTypes.func, + /** + * Disabled + */ + disabled: PropTypes.bool, + /** + * addFocus + */ + focused: PropTypes.bool +} + +Select.defaultProps = { + defaultOption: 'this is the default', + name: '', + id: '', + options: [], + borderColor: MAIN_GREEN, + errorMessage: '', + onChange: () => {}, + disabled: false, + focused: false +} + +export default Select diff --git a/src/components/forms/Select.module.css b/src/components/forms/Select.module.css new file mode 100644 index 00000000..5366fac6 --- /dev/null +++ b/src/components/forms/Select.module.css @@ -0,0 +1,48 @@ +.container { + @apply flex flex-col w-full relative; +} +.selectContainer { + @apply w-full; +} +.select { + @apply pl-2 border border-solid box-border rounded-md h-10 w-full bg-transparent; + appearance: none; + box-sizing: border-box; + /* This will create a positioning context for the list of options; + adding this to .select:focus-within will be a better option when fully supported + */ + position: relative; + + /* This will make our control become part of the text flow and sizable at the same time */ + display: inline-block; +} +.arrowIcon { + @apply absolute top-[50%] right-[0.5rem] translate-y-[-50%]; +} +.color-main-dark-blue { + @apply text-main-dark-blue; +} +.color-error-red{ + @apply text-error-red; +} +.color-white{ + @apply text-white; +} +.paddingFocused { + @apply p-4; +} +.placeholderAPart { + @apply absolute top-[50%] right-0 translate-y-[-50%] left-0 text-main-dark-blue text-opacity-20 ml-2 z-0; +} +[type='select']:focus { + outline: none; +} +.select.active, +.select:focus { + @apply shadow-main-dark-blue outline-none; +} + +.select .options { + @apply absolute left-0; + top: 100%; +} \ No newline at end of file diff --git a/src/components/forms/index.js b/src/components/forms/index.js index 0549c002..48e930f6 100644 --- a/src/components/forms/index.js +++ b/src/components/forms/index.js @@ -2,8 +2,9 @@ import Field from './Field' import Input from './Input' import InputWithSeparator from './InputWithSeparator' import Preview from './Preview' +import Select from './Select' import ToggleSwitch from './ToggleSwitch' export default { - Field, Input, InputWithSeparator, Preview, ToggleSwitch + Field, Input, InputWithSeparator, Preview, Select, ToggleSwitch } diff --git a/src/stories/forms/Select.stories.jsx b/src/stories/forms/Select.stories.jsx new file mode 100644 index 00000000..9c384c24 --- /dev/null +++ b/src/stories/forms/Select.stories.jsx @@ -0,0 +1,110 @@ +'use strict' +import React, { useState } from 'react' +import Select from '../../components/forms/Select' +import { MAIN_DARK_BLUE, MAIN_GREEN } from '../../components/constants' + +const divStyle = { + width: '100%', + height: 'auto', + padding: '20px', + backgroundColor: 'transparent' +} + +export default { + title: 'Platformatic/Forms/Select', + component: Select, + decorators: [ + (Story) => ( +
+ +
+ ) + ] +} + +const Template = (args) => + +export const BorderMainDarkBlue = TemplateBorderMainDarkBlue.bind({}) + +BorderMainDarkBlue.args = { + name: 'test', + defaultOption: 'Defaul option', + options: [{ label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }, { label: 'Option 3', value: '3' }], + borderColor: MAIN_DARK_BLUE +} + +export const DefaultInvalid = Template.bind({}) + +DefaultInvalid.args = { + name: 'test', + defaultOption: 'Platformatic empty select', + options: [{ label: 'Option 1', value: '1' }, { label: 'Option 2', value: '2' }, { label: 'Option 3', value: '3' }], + borderColor: MAIN_GREEN, + errorMessage: 'This is an error message' +} + +const TemplateValuedAndAlertChange = (args) => { + const [value, setValue] = useState('') + + function handleChange (event) { + setValue(event.target.value) + } + + return ( + <> +

Value of the input {value}

+ - - {options.map((option, index) => )} - -
- +
+ +
+ {value?.length > 0 && clearValue()} />} + setShowOptions(!showOptions)} />
+ {showOptions && renderOptions()} {showError && {errorMessage}}
) - - return focused ? ({cmp}) : cmp } Select.propTypes = { /** - * defaultOption + * placeholder */ - defaultOption: PropTypes.string, + placeholder: PropTypes.string, /** * name */ @@ -44,6 +83,10 @@ Select.propTypes = { /** * value */ + value: PropTypes.string, + /** + * options + */ options: PropTypes.arrayOf(PropTypes.shape({ value: PropTypes.string, label: PropTypes.string @@ -57,25 +100,26 @@ Select.propTypes = { */ onChange: PropTypes.func, /** - * Disabled + * onSelect */ - disabled: PropTypes.bool, + onSelect: PropTypes.func, /** - * addFocus + * Disabled */ - focused: PropTypes.bool + disabled: PropTypes.bool } Select.defaultProps = { - defaultOption: 'this is the default', + placeholder: 'this is the default', name: '', + value: '', id: '', options: [], borderColor: MAIN_GREEN, errorMessage: '', onChange: () => {}, - disabled: false, - focused: false + onSelect: () => {}, + disabled: false } export default Select diff --git a/src/components/forms/Select.module.css b/src/components/forms/Select.module.css index 5366fac6..1695f7ef 100644 --- a/src/components/forms/Select.module.css +++ b/src/components/forms/Select.module.css @@ -1,48 +1,23 @@ .container { - @apply flex flex-col w-full relative; + @apply flex flex-col w-full relative z-10; } .selectContainer { - @apply w-full; + @apply w-full flex items-center h-10 relative; } .select { - @apply pl-2 border border-solid box-border rounded-md h-10 w-full bg-transparent; - appearance: none; - box-sizing: border-box; - /* This will create a positioning context for the list of options; - adding this to .select:focus-within will be a better option when fully supported - */ - position: relative; - - /* This will make our control become part of the text flow and sizable at the same time */ - display: inline-block; -} -.arrowIcon { - @apply absolute top-[50%] right-[0.5rem] translate-y-[-50%]; -} -.color-main-dark-blue { - @apply text-main-dark-blue; -} -.color-error-red{ - @apply text-error-red; -} -.color-white{ - @apply text-white; -} -.paddingFocused { - @apply p-4; -} -.placeholderAPart { - @apply absolute top-[50%] right-0 translate-y-[-50%] left-0 text-main-dark-blue text-opacity-20 ml-2 z-0; -} -[type='select']:focus { - outline: none; + @apply px-2 h-full border border-solid box-border rounded-md ; } .select.active, .select:focus { @apply shadow-main-dark-blue outline-none; } - -.select .options { - @apply absolute left-0; - top: 100%; -} \ No newline at end of file +.options { + @apply absolute left-0 top-[42px] bg-white w-full max-h-[216px] overflow-y-scroll; + box-shadow: 0px 0px 10px rgb(0 40 61 / 25%); +} +.option { + @apply w-full px-4 py-2 border-b border-main-dark-blue font-light cursor-pointer hover:bg-main-dark-blue hover:bg-opacity-10 +} +.icons { + @apply absolute top-[50%] right-[0.5rem] translate-y-[-50%] flex gap-x-2; +} diff --git a/src/stories/forms/Select.stories.jsx b/src/stories/forms/Select.stories.jsx index 9c384c24..01dcc26b 100644 --- a/src/stories/forms/Select.stories.jsx +++ b/src/stories/forms/Select.stories.jsx @@ -28,83 +28,44 @@ export const Default = Template.bind({}) Default.args = { name: 'test', - defaultOption: 'Platformatic empty select' + placeholder: 'Platformatic empty select', + borderColor: MAIN_GREEN } -const TemplateBorderMainDarkBlue = (args) =>
- + + {afterIcon &&
} +
+ {showError && {errorMessage}} + + ) +} + +TextArea.propTypes = { + /** + * placeholder + */ + placeholder: PropTypes.string, + /** + * value + */ + value: PropTypes.string, + /** + * name + */ + name: PropTypes.string, + /** + * color of border + */ + borderColor: PropTypes.oneOf([MAIN_GREEN, MAIN_DARK_BLUE]), + /** + * onChange + */ + onChange: PropTypes.func, + /** + * Disabled + */ + disabled: PropTypes.bool, + /** + * afterIcon: PlatformaticIcon props + */ + afterIcon: PropTypes.shape({ + iconName: PropTypes.string, + color: PropTypes.string, + onClick: PropTypes.func + }), + /** + * rows + */ + rows: PropTypes.number, + /** + * cols + */ + cols: PropTypes.number +} + +TextArea.defaultProps = { + placeholder: '', + value: '', + name: '', + borderColor: MAIN_DARK_BLUE, + errorMessage: '', + onChange: () => {}, + disabled: false, + afterIcon: null, + rows: 5, + cols: 20 +} + +export default TextArea diff --git a/src/components/forms/TextArea.module.css b/src/components/forms/TextArea.module.css new file mode 100644 index 00000000..c1ea7e56 --- /dev/null +++ b/src/components/forms/TextArea.module.css @@ -0,0 +1,16 @@ +.container { + @apply flex flex-col w-full relative z-10; +} +.textAreaContainer { + @apply w-full flex items-center relative; +} +.textarea { + @apply p-3 h-full border border-solid box-border rounded-md ; +} +.textarea.active, +.textarea:focus { + @apply shadow-main-dark-blue outline-none; +} +.afterIcon { + @apply absolute top-[1.25rem] right-[1.25rem] +} \ No newline at end of file diff --git a/src/components/forms/index.js b/src/components/forms/index.js index 48e930f6..eb2a663e 100644 --- a/src/components/forms/index.js +++ b/src/components/forms/index.js @@ -3,8 +3,9 @@ import Input from './Input' import InputWithSeparator from './InputWithSeparator' import Preview from './Preview' import Select from './Select' +import TextArea from './TextArea' import ToggleSwitch from './ToggleSwitch' export default { - Field, Input, InputWithSeparator, Preview, Select, ToggleSwitch + Field, Input, InputWithSeparator, Preview, Select, TextArea, ToggleSwitch } diff --git a/src/stories/forms/TextArea.stories.jsx b/src/stories/forms/TextArea.stories.jsx new file mode 100644 index 00000000..034a1fa0 --- /dev/null +++ b/src/stories/forms/TextArea.stories.jsx @@ -0,0 +1,73 @@ +'use strict' +import React, { useState } from 'react' +import TextArea from '../../components/forms/TextArea' + +const divStyle = { + width: '100%', + height: 'auto', + padding: '20px', + backgroundColor: 'white' +} + +export default { + title: 'Platformatic/Forms/TextArea', + component: TextArea, + decorators: [ + (Story) => ( +
+ +
+ ) + ] +} + +const Template = (args) => +