-
Notifications
You must be signed in to change notification settings - Fork 165
[UEPR-518] Implement in-editor Manual Save Project Thumbnail logic #471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 21 commits
a8dd014
a193715
45c2935
84d2901
942bb59
42dedfc
d858e2c
cc1264b
4c0d824
f4698f8
6c06180
8934776
725e94e
c3addb3
4780722
bb35c3e
5d39186
26759dd
02c594c
68ac1ed
e792842
b8cc0c3
6356ca7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| @import "../../css/colors.css"; | ||
| @import "../../css/units.css"; | ||
|
|
||
| .modal-container { | ||
| display: flex; | ||
| width: 100%; | ||
| padding: 0.75rem; | ||
| flex-direction: column; | ||
| align-items: flex-start; | ||
| border-radius: 0.5rem; | ||
| background: $looks-secondary; | ||
| gap: 0.9375rem; | ||
| box-sizing: border-box; | ||
| } | ||
|
|
||
| .label { | ||
| align-self: stretch; | ||
| color: $ui-white; | ||
| text-align: center; | ||
| font-size: 1rem; | ||
| font-weight: 700; | ||
| line-height: 1.5rem; | ||
| } | ||
|
|
||
| .button-row { | ||
| font-weight: 700; | ||
| display: flex; | ||
| gap: 0.5rem; | ||
| width: 100%; | ||
| } | ||
|
|
||
| .confirm-button, | ||
| .cancel-button { | ||
| all: unset; | ||
KManolov3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| display: flex; | ||
| padding: 0.5rem 1rem; | ||
| justify-content: center; | ||
| align-items: center; | ||
| gap: 0.5rem; | ||
| flex: 1; | ||
| border-radius: 2.5rem; | ||
| background: inherit; | ||
| cursor: pointer; | ||
| color: $ui-white; | ||
| } | ||
|
|
||
| .confirm-button:focus, | ||
| .cancel-button:focus { | ||
| outline: auto; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this needed?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. currently yes because of the earlier all: unset; on the button
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if that's a sign not to use |
||
| } | ||
|
|
||
| .confirm-button span, | ||
| .cancel-button span { | ||
| font-size: 0.75rem; | ||
| font-weight: 700; | ||
| line-height: 1rem; | ||
| } | ||
|
|
||
| .confirm-button { | ||
| background: $ui-white; | ||
| } | ||
|
|
||
| .confirm-button span { | ||
| color: $looks-secondary; | ||
| } | ||
|
|
||
| .cancel-button { | ||
| border: 0.0625rem solid $ui-white; | ||
| } | ||
|
|
||
| .button-icon { | ||
| height: 1.5rem; | ||
| width: 1.5rem; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,184 @@ | ||
| import React from 'react'; | ||
| import PropTypes from 'prop-types'; | ||
| import {defineMessages, FormattedMessage} from 'react-intl'; | ||
|
|
||
| import Box from '../box/box.jsx'; | ||
| import ModalWithArrow from '../modal-with-arrow/modal-with-arrow.jsx'; | ||
|
|
||
| import arrowDownIcon from './icon--arrow-down.svg'; | ||
| import arrowUpIcon from './icon--arrow-up.svg'; | ||
| import arrowLeftIcon from './icon--arrow-left.svg'; | ||
| import arrowRightIcon from './icon--arrow-right.svg'; | ||
|
|
||
| import styles from './confirmation-prompt.css'; | ||
| import {PopupAlign, PopupSide} from '../../lib/calculatePopupPosition.js'; | ||
| import classNames from 'classnames'; | ||
|
|
||
| const messages = defineMessages({ | ||
| defaultConfirmLabel: { | ||
| defaultMessage: 'yes', | ||
| description: 'Label for confirm button in confirmation prompt', | ||
| id: 'gui.confirmationPrompt.confirm' | ||
| }, | ||
| defaultCancelLabel: { | ||
| defaultMessage: 'no', | ||
| description: 'Label for cancel button in confirmation prompt', | ||
| id: 'gui.confirmationPrompt.cancel' | ||
| } | ||
| }); | ||
|
|
||
| const defaultConfig = { | ||
| modalWidth: 200, | ||
| spaceForArrow: 16, | ||
| counterOffset: 7, | ||
| arrowOffsetFromBottom: 2, | ||
| arrowWidth: 29, | ||
| arrowHeight: 13 | ||
| }; | ||
|
|
||
| const arrowConfig = { | ||
| arrowDownIcon, | ||
| arrowUpIcon, | ||
| arrowLeftIcon, | ||
| arrowRightIcon | ||
| }; | ||
|
|
||
| const BUTTON_ORDER = { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally, I'd generalize the props to: But I'm not insisting us do that here, as the confirm/cancel separation fits the current cases |
||
| CANCEL_FIRST: 'cancelFirst', | ||
| CONFIRM_FIRST: 'confirmFirst' | ||
| }; | ||
|
|
||
| const ConfirmationPrompt = ({ | ||
adzhindzhi marked this conversation as resolved.
Show resolved
Hide resolved
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I find slightly confusing about the current implementation is the following structure:
I think what we actually need is a clearer separation of responsibilities:
This structure would simplify the overall design and ensure that each component has a clear, single responsibility. We may still need to refine the naming to better reflect each component's purpose, but this is the general direction I think we should take. |
||
| title, | ||
| message, | ||
| confirmLabel, | ||
| cancelLabel, | ||
| confirmIcon, | ||
|
||
| cancelIcon, | ||
| buttonOrder = BUTTON_ORDER.CANCEL_FIRST, | ||
| onConfirm, | ||
| onCancel, | ||
| isOpen, | ||
| relativeElementRef, | ||
| side, | ||
| align, | ||
| layoutConfig, | ||
| containerClassName, | ||
| messageClassName, | ||
| confirmButtonClassName, | ||
| cancelButtonClassName | ||
| }) => { | ||
| const { | ||
| modalWidth, | ||
| spaceForArrow, | ||
| counterOffset, | ||
| arrowOffsetFromBottom, | ||
| arrowHeight, | ||
| arrowWidth | ||
| } = {...defaultConfig, ...layoutConfig}; | ||
|
|
||
| const memoizedLayoutConfig = React.useMemo(() => ({ | ||
| modalWidth, | ||
| spaceForArrow, | ||
| counterOffset, | ||
| arrowOffsetFromBottom, | ||
| arrowHeight, | ||
| arrowWidth | ||
| }), [modalWidth, | ||
| spaceForArrow, | ||
| counterOffset, | ||
| arrowOffsetFromBottom, | ||
| arrowHeight, | ||
| arrowWidth | ||
| ]); | ||
|
|
||
| const cancelButton = ( | ||
| <button | ||
| onClick={onCancel} | ||
| className={classNames(styles.cancelButton, cancelButtonClassName)} | ||
| > | ||
| {cancelIcon && ( | ||
| <img | ||
| className={styles.buttonIcon} | ||
| src={cancelIcon} | ||
| aria-hidden="true" | ||
| alt="" | ||
| /> | ||
| )} | ||
| {cancelLabel ?? <FormattedMessage {...messages.defaultCancelLabel} />} | ||
| </button> | ||
| ); | ||
|
|
||
| const confirmButton = ( | ||
| <button | ||
| onClick={onConfirm} | ||
| className={classNames(styles.confirmButton, confirmButtonClassName)} | ||
| > | ||
| {confirmIcon && ( | ||
| <img | ||
| className={styles.buttonIcon} | ||
| src={confirmIcon} | ||
| aria-hidden="true" | ||
| alt="" | ||
|
||
| /> | ||
| )} | ||
| {confirmLabel ?? <FormattedMessage {...messages.defaultConfirmLabel} />} | ||
| </button> | ||
| ); | ||
|
|
||
| const buttons = buttonOrder === BUTTON_ORDER.CONFIRM_FIRST ? | ||
| [confirmButton, cancelButton] : [cancelButton, confirmButton]; | ||
|
|
||
| return ( | ||
| <ModalWithArrow | ||
| isOpen={isOpen} | ||
| relativeElementRef={relativeElementRef} | ||
| onRequestClose={onCancel} | ||
| side={side} | ||
| align={align} | ||
| layoutConfig={memoizedLayoutConfig} | ||
| arrowConfig={arrowConfig} | ||
| title={title} | ||
| > | ||
| <Box className={classNames(styles.modalContainer, containerClassName)}> | ||
| <Box className={classNames(styles.label, messageClassName)}> | ||
| {message} | ||
| </Box> | ||
| <Box className={styles.buttonRow}> | ||
| {buttons} | ||
| </Box> | ||
| </Box> | ||
| </ModalWithArrow> | ||
| ); | ||
| }; | ||
|
|
||
| ConfirmationPrompt.propTypes = { | ||
| isOpen: PropTypes.bool.isRequired, | ||
| title: PropTypes.string, | ||
| message: PropTypes.node.isRequired, | ||
| confirmLabel: PropTypes.node, | ||
| cancelLabel: PropTypes.node, | ||
| confirmIcon: PropTypes.string, | ||
| cancelIcon: PropTypes.string, | ||
| buttonOrder: PropTypes.oneOf(Object.values(BUTTON_ORDER)), | ||
| onConfirm: PropTypes.func.isRequired, | ||
| onCancel: PropTypes.func.isRequired, | ||
| relativeElementRef: PropTypes.shape({current: PropTypes.instanceOf(Element)}), | ||
| side: PropTypes.oneOf(Object.values(PopupSide)).isRequired, | ||
| align: PropTypes.oneOf(Object.values(PopupAlign)), | ||
| layoutConfig: PropTypes.shape({ | ||
| modalWidth: PropTypes.number, | ||
| spaceForArrow: PropTypes.number, | ||
| arrowOffsetFromBottom: PropTypes.number, | ||
| counterOffset: PropTypes.number, | ||
| arrowHeight: PropTypes.number, | ||
| arrowWidth: PropTypes.number | ||
| }), | ||
| containerClassName: PropTypes.string, | ||
| messageClassName: PropTypes.string, | ||
| confirmButtonClassName: PropTypes.string, | ||
| cancelButtonClassName: PropTypes.string | ||
| }; | ||
|
|
||
| export {BUTTON_ORDER}; | ||
| export default ConfirmationPrompt; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this one bigger than the others? What method did you use for exporting them from Figma?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was some gap on the originally downloaded one. I wonder if it's worth resolving, since it has the same proportions and same length in the end.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it might be, at least size-wise the stored SVG will be smaller. Though I'm not sure if the difference is significant enough to make a difference. |
Uh oh!
There was an error while loading. Please reload this page.