From 737d465c22b8bc1695cac9bcade086e47d86d3e2 Mon Sep 17 00:00:00 2001 From: Kaloyan Manolov Date: Wed, 16 Oct 2024 13:10:37 +0300 Subject: [PATCH 1/3] chore: uepr-72: uepr-65: migrate monorepo changes --- .../delete-button/delete-button.css | 4 + .../delete-button/delete-button.jsx | 7 +- .../delete-confirmation-prompt.css | 74 + .../delete-confirmation-prompt.jsx | 185 +++ .../icon--arrow-left.svg | 3 + .../icon--arrow-right.svg | 3 + .../icon--delete.svg | 18 + .../delete-confirmation-prompt/icon--undo.svg | 12 + src/components/library/library.css | 18 + src/components/library/library.jsx | 102 +- .../sprite-selector-item.jsx | 4 +- .../sprite-selector/sprite-list.jsx | 2 + src/containers/sprite-selector-item.jsx | 47 +- src/containers/tips-library.jsx | 1 + src/lib/libraries/decks/index.jsx | 1308 +++++++++-------- test/integration/how-tos.test.js | 4 +- test/integration/menu-bar.test.js | 1 + test/integration/sprites.test.js | 2 + test/integration/stage-size.test.js | 6 +- .../sprite-selector-item.test.jsx.snap | 4 +- .../containers/sprite-selector-item.test.jsx | 36 +- 21 files changed, 1154 insertions(+), 687 deletions(-) create mode 100644 src/components/delete-confirmation-prompt/delete-confirmation-prompt.css create mode 100644 src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx create mode 100644 src/components/delete-confirmation-prompt/icon--arrow-left.svg create mode 100644 src/components/delete-confirmation-prompt/icon--arrow-right.svg create mode 100644 src/components/delete-confirmation-prompt/icon--delete.svg create mode 100644 src/components/delete-confirmation-prompt/icon--undo.svg diff --git a/src/components/delete-button/delete-button.css b/src/components/delete-button/delete-button.css index 692a9d35200..5f7f422c66d 100644 --- a/src/components/delete-button/delete-button.css +++ b/src/components/delete-button/delete-button.css @@ -28,6 +28,10 @@ transition: all 0.15s ease-out; } +.delete-button-clicked { + background-color: $data-primary; +} + .delete-icon { position: relative; margin: 0.25rem; diff --git a/src/components/delete-button/delete-button.jsx b/src/components/delete-button/delete-button.jsx index 6e84fb983f3..bdd16c7349d 100644 --- a/src/components/delete-button/delete-button.jsx +++ b/src/components/delete-button/delete-button.jsx @@ -16,7 +16,11 @@ const DeleteButton = props => ( tabIndex={props.tabIndex} onClick={props.onClick} > -
+
( DeleteButton.propTypes = { className: PropTypes.string, onClick: PropTypes.func.isRequired, + isConfirmationModalOpened: PropTypes.bool, tabIndex: PropTypes.number }; diff --git a/src/components/delete-confirmation-prompt/delete-confirmation-prompt.css b/src/components/delete-confirmation-prompt/delete-confirmation-prompt.css new file mode 100644 index 00000000000..295bb6b5c34 --- /dev/null +++ b/src/components/delete-confirmation-prompt/delete-confirmation-prompt.css @@ -0,0 +1,74 @@ +@import "../../css/colors.css"; +@import "../../css/units.css"; + +.modal-container { + display: flex; + flex-direction: row; + border: none; +} + +.arrow-container { + display: flex; + align-items: center; + margin-right: -7px; +} + +.arrow-container-left { + margin-right: -7px; +} + +.arrow-container-right { + margin-left: -7px; +} + +.body { + padding: 1rem 1.5rem; + border-radius: 0.5rem; + background: $looks-secondary; +} + +.label { + color: $ui-white; + font-size: 1.25rem; + font-weight: 700; + margin: 1rem 0 1.5rem; +} + +.button-row { + font-weight: bolder; + display: flex; +} + +.button-row button { + display: flex; + gap: 0.5rem; + justify-content: center; + width: 47%; + padding: 0.75rem 1rem; + border-radius: 2rem; + border: 1px solid $ui-black-transparent; + color: $looks-secondary; + background: $ui-white; + font-weight: 600; + font-size: 0.85rem; + cursor: pointer; + margin: auto; +} + +.button-row button.ok-button { + margin-left: 0; +} + +.button-row button.cancel-button { + margin-right: 0; +} + +.message { + margin-top: 0.25rem; +} + +.delete-icon { + height: 1.5rem; + width: 1.5rem; +} + diff --git a/src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx b/src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx new file mode 100644 index 00000000000..2a6eea9525f --- /dev/null +++ b/src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx @@ -0,0 +1,185 @@ +import {defineMessages, FormattedMessage, injectIntl, intlShape} from 'react-intl'; +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +import Box from '../box/box.jsx'; +import ReactModal from 'react-modal'; +import deleteIcon from './icon--delete.svg'; +import undoIcon from './icon--undo.svg'; +import arrowLeftIcon from './icon--arrow-left.svg'; +import arrowRightIcon from './icon--arrow-right.svg'; + +import styles from './delete-confirmation-prompt.css'; + +// TODO: Parametrize from outside if we want more custom messaging +const messages = defineMessages({ + shouldDeleteSpriteMessage: { + defaultMessage: 'Are you sure you want to delete this sprite?', + description: 'Message to indicate whether selected sprite should be deleted.', + id: 'gui.gui.shouldDeleteSprite' + }, + shouldDeleteCostumeMessage: { + defaultMessage: 'Are you sure you want to delete this costume?', + description: 'Message to indicate whether selected costume should be deleted.', + id: 'gui.gui.shouldDeleteCostume' + }, + shouldDeleteSoundMessage: { + defaultMessage: 'Are you sure you want to delete this sound?', + description: 'Message to indicate whether selected sound should be deleted.', + id: 'gui.gui.shouldDeleteSound' + }, + confirmOption: { + defaultMessage: 'yes', + description: 'Yes - should delete the sprite', + id: 'gui.gui.confirm' + }, + cancelOption: { + defaultMessage: 'no', + description: 'No - cancel deletion', + id: 'gui.gui.cancel' + }, + confirmDeletionHeading: { + defaultMessage: 'Confirm Asset Deletion', + description: 'Heading of confirmation prompt to delete asset', + id: 'gui.gui.deleteAssetHeading' + } +}); + +const modalWidth = 300; +const calculateModalPosition = (relativeElemRef, modalPosition) => { + const refPosition = relativeElemRef.getBoundingClientRect(); + + if (modalPosition === 'left') { + return { + top: refPosition.top - refPosition.height, + left: refPosition.left - modalWidth - 25 + }; + } + + if (modalPosition === 'right') { + return { + top: refPosition.top - refPosition.height, + left: refPosition.right + 25 + }; + } + + return {}; +}; + +const getMessage = entityType => { + if (entityType === 'COSTUME') { + return messages.shouldDeleteCostumeMessage; + } + + if (entityType === 'SOUND') { + return messages.shouldDeleteSoundMessage; + } + + return messages.shouldDeleteSpriteMessage; +}; + +const DeleteConfirmationPrompt = ({ + intl, + onCancel, + onOk, + modalPosition, + entityType, + relativeElemRef +}) => { + const modalPositionValues = calculateModalPosition(relativeElemRef, modalPosition); + + return ( + + { modalPosition === 'right' ? + + + : null } + + + + + + + + + + {modalPosition === 'left' ? + + + : null } + + ); +}; + +DeleteConfirmationPrompt.propTypes = { + onOk: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, + relativeElemRef: PropTypes.object, + entityType: PropTypes.string, + modalPosition: PropTypes.string, + intl: intlShape.isRequired +}; + +const DeleteConfirmationPromptIntl = injectIntl(DeleteConfirmationPrompt); + +export default DeleteConfirmationPromptIntl; diff --git a/src/components/delete-confirmation-prompt/icon--arrow-left.svg b/src/components/delete-confirmation-prompt/icon--arrow-left.svg new file mode 100644 index 00000000000..0712a6f88b8 --- /dev/null +++ b/src/components/delete-confirmation-prompt/icon--arrow-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/delete-confirmation-prompt/icon--arrow-right.svg b/src/components/delete-confirmation-prompt/icon--arrow-right.svg new file mode 100644 index 00000000000..cc59340dc3f --- /dev/null +++ b/src/components/delete-confirmation-prompt/icon--arrow-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/delete-confirmation-prompt/icon--delete.svg b/src/components/delete-confirmation-prompt/icon--delete.svg new file mode 100644 index 00000000000..4be0a2a3caf --- /dev/null +++ b/src/components/delete-confirmation-prompt/icon--delete.svg @@ -0,0 +1,18 @@ + + + + Sound/General/Delete + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/delete-confirmation-prompt/icon--undo.svg b/src/components/delete-confirmation-prompt/icon--undo.svg new file mode 100644 index 00000000000..44c9517b707 --- /dev/null +++ b/src/components/delete-confirmation-prompt/icon--undo.svg @@ -0,0 +1,12 @@ + + + + undo + Created with Sketch. + + + + + + + diff --git a/src/components/library/library.css b/src/components/library/library.css index df13ec5f71a..1419380c103 100644 --- a/src/components/library/library.css +++ b/src/components/library/library.css @@ -19,6 +19,24 @@ height: calc(100% - $library-header-height - $library-filter-bar-height - 2rem); } +.library-category { + display: flex; + flex-direction: column; +} + +.library-category-title { + padding-Left: .5rem; + font-weight: bold; + font-size: 2rem; + color: $text-primary; +} + +.library-category-items { + display: flex; + flex-wrap: wrap; + padding-bottom: 1rem; +} + .filter-bar { display: flex; flex-direction: row; diff --git a/src/components/library/library.jsx b/src/components/library/library.jsx index 48a1de5541d..8e4ac86f15a 100644 --- a/src/components/library/library.jsx +++ b/src/components/library/library.jsx @@ -10,6 +10,7 @@ import Divider from '../divider/divider.jsx'; import Filter from '../filter/filter.jsx'; import TagButton from '../../containers/tag-button.jsx'; import Spinner from '../spinner/spinner.jsx'; +import {CATEGORIES} from '../../../src/lib/libraries/decks/index.jsx'; import styles from './library.css'; @@ -23,6 +24,28 @@ const messages = defineMessages({ id: 'gui.library.allTag', defaultMessage: 'All', description: 'Label for library tag to revert to all items after filtering by tag.' + }, + // Strings here need to be defined statically + // https://formatjs.io/docs/getting-started/message-declaration/#pre-declaring-using-definemessage-for-later-consumption-less-recommended + [CATEGORIES.gettingStarted]: { + id: `gui.library.gettingStarted`, + defaultMessage: 'Getting Started', + description: 'Label for getting started category' + }, + [CATEGORIES.basics]: { + id: `gui.library.basics`, + defaultMessage: 'Basics', + description: 'Label for basics category' + }, + [CATEGORIES.intermediate]: { + id: `gui.library.intermediate`, + defaultMessage: 'Intermediate', + description: 'Label for intermediate category' + }, + [CATEGORIES.prompts]: { + id: `gui.library.prompts`, + defaultMessage: 'Prompts', + description: 'Label for prompts category' } }); @@ -128,7 +151,7 @@ class LibraryComponent extends React.Component { this.setState({filterQuery: ''}); } getFilteredData () { - if (this.state.selectedTag === 'all') { + if (this.state.selectedTag === ALL_TAG.tag) { if (!this.state.filterQuery) return this.props.data; return this.props.data.filter(dataItem => ( (dataItem.tags || []) @@ -157,6 +180,58 @@ class LibraryComponent extends React.Component { setFilteredDataRef (ref) { this.filteredDataRef = ref; } + renderElement (data, index) { + return (