diff --git a/packages/scratch-gui/src/components/delete-confirmation-prompt/delete-confirmation-prompt.css b/packages/scratch-gui/src/components/delete-confirmation-prompt/delete-confirmation-prompt.css index 295bb6b5c3..060b02df3b 100644 --- a/packages/scratch-gui/src/components/delete-confirmation-prompt/delete-confirmation-prompt.css +++ b/packages/scratch-gui/src/components/delete-confirmation-prompt/delete-confirmation-prompt.css @@ -10,17 +10,32 @@ .arrow-container { display: flex; align-items: center; +} + +[dir="ltr"] .arrow-container { margin-right: -7px; } -.arrow-container-left { +[dir="rtl"] .arrow-container { + margin-left: -7px; +} + +[dir="ltr"] .arrow-container-left { margin-right: -7px; } -.arrow-container-right { +[dir="rtl"] .arrow-container-left { margin-left: -7px; } +[dir="ltr"] .arrow-container-right { + margin-left: -7px; +} + +[dir="rtl"] .arrow-container-right { + margin-right: -7px; +} + .body { padding: 1rem 1.5rem; border-radius: 0.5rem; @@ -55,14 +70,22 @@ margin: auto; } -.button-row button.ok-button { +[dir="ltr"] .button-row button.ok-button { margin-left: 0; } -.button-row button.cancel-button { +[dir="rtl"] .button-row button.ok-button { + margin-right: 0; +} + +[dir="ltr"] .button-row button.cancel-button { margin-right: 0; } +[dir="rtl"] .button-row button.cancel-button { + margin-left: 0; +} + .message { margin-top: 0.25rem; } @@ -71,4 +94,3 @@ height: 1.5rem; width: 1.5rem; } - diff --git a/packages/scratch-gui/src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx b/packages/scratch-gui/src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx index e50d98061d..6ec0ae7b34 100644 --- a/packages/scratch-gui/src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx +++ b/packages/scratch-gui/src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx @@ -84,7 +84,8 @@ const DeleteConfirmationPrompt = ({ onOk, modalPosition, entityType, - relativeElemRef + relativeElemRef, + isRtl }) => { const intl = useIntl(); const modalPositionValues = calculateModalPosition(relativeElemRef, modalPosition); @@ -119,12 +120,15 @@ const DeleteConfirmationPrompt = ({ contentLabel={intl.formatMessage(messages.confirmDeletionHeading)} onRequestClose={onCancel} > - - { modalPosition === 'right' ? + + {((modalPosition === 'right' && !isRtl) || (modalPosition === 'left' && isRtl)) ? : null } @@ -160,11 +164,11 @@ const DeleteConfirmationPrompt = ({ - {modalPosition === 'left' ? + {((modalPosition === 'left' && !isRtl) || (modalPosition === 'right' && isRtl)) ? : null } @@ -176,7 +180,8 @@ DeleteConfirmationPrompt.propTypes = { onCancel: PropTypes.func.isRequired, relativeElemRef: PropTypes.object, entityType: PropTypes.string, - modalPosition: PropTypes.string + modalPosition: PropTypes.string, + isRtl: PropTypes.bool }; export default DeleteConfirmationPrompt; diff --git a/packages/scratch-gui/src/components/sprite-selector/sprite-list.jsx b/packages/scratch-gui/src/components/sprite-selector/sprite-list.jsx index c496bd7325..e7888d3b3d 100644 --- a/packages/scratch-gui/src/components/sprite-selector/sprite-list.jsx +++ b/packages/scratch-gui/src/components/sprite-selector/sprite-list.jsx @@ -30,7 +30,8 @@ const SpriteList = function (props) { ordering, raised, selectedId, - items + items, + isRtl } = props; const isSpriteDrag = draggingType === DragConstants.SPRITE; @@ -95,7 +96,7 @@ const SpriteList = function (props) { onDuplicateButtonClick={onDuplicateSprite} onExportButtonClick={onExportSprite} withDeleteConfirmation - deleteConfirmationModalPosition={'left'} + deleteConfirmationModalPosition={isRtl ? 'right' : 'left'} /> ); @@ -134,7 +135,8 @@ SpriteList.propTypes = { onSelectSprite: PropTypes.func, ordering: PropTypes.arrayOf(PropTypes.number), raised: PropTypes.bool, - selectedId: PropTypes.string + selectedId: PropTypes.string, + isRtl: PropTypes.bool }; export default SortableHOC(SpriteList); diff --git a/packages/scratch-gui/src/components/sprite-selector/sprite-selector.jsx b/packages/scratch-gui/src/components/sprite-selector/sprite-selector.jsx index 7f8a5fc44c..58710b6824 100644 --- a/packages/scratch-gui/src/components/sprite-selector/sprite-selector.jsx +++ b/packages/scratch-gui/src/components/sprite-selector/sprite-selector.jsx @@ -111,6 +111,7 @@ const SpriteSelectorComponent = function (props) { onDuplicateSprite={onDuplicateSprite} onExportSprite={onExportSprite} onSelectSprite={onSelectSprite} + isRtl={isRtl(intl.locale)} /> ( + +); + +DeleteConfirmationPrompt.propTypes = { + isRtl: PropTypes.bool, + onCancel: PropTypes.func.isRequired, + onOk: PropTypes.func.isRequired, + modalPosition: PropTypes.string, + entityType: PropTypes.string.isRequired, + relativeElemRef: PropTypes.object.isRequired +}; + +const mapStateToProps = state => ({ + isRtl: state.locales.isRtl +}); + +export default connect( + mapStateToProps +)(DeleteConfirmationPrompt); diff --git a/packages/scratch-gui/src/containers/sprite-selector-item.jsx b/packages/scratch-gui/src/containers/sprite-selector-item.jsx index 1d7f323e7e..a6c113c69b 100644 --- a/packages/scratch-gui/src/containers/sprite-selector-item.jsx +++ b/packages/scratch-gui/src/containers/sprite-selector-item.jsx @@ -10,7 +10,7 @@ import getCostumeUrl from '../lib/get-costume-url'; import DragRecognizer from '../lib/drag-recognizer'; import {getEventXY} from '../lib/touch-utils'; import {GUIStoragePropType} from '../gui-config'; -import DeleteConfirmationPrompt from '../components/delete-confirmation-prompt/delete-confirmation-prompt.jsx'; +import DeleteConfirmationPrompt from './delete-confirmation-prompt'; import SpriteSelectorItemComponent from '../components/sprite-selector-item/sprite-selector-item.jsx'; @@ -154,6 +154,7 @@ class SpriteSelectorItem extends React.PureComponent { relativeElemRef={this.ref} entityType={this.props.dragType} modalPosition={deleteConfirmationModalPosition} + isRtl={this.props.isRtl} /> : null} ({ @@ -201,7 +203,8 @@ const mapStateToProps = (state, {id}) => ({ dragging: state.scratchGui.assetDrag.dragging, receivedBlocks: state.scratchGui.hoveredTarget.receivedBlocks && state.scratchGui.hoveredTarget.sprite === id, - vm: state.scratchGui.vm + vm: state.scratchGui.vm, + isRtl: state.locales.isRtl }); const mapDispatchToProps = dispatch => ({ dispatchSetHoveredSprite: spriteId => { diff --git a/packages/scratch-gui/test/unit/containers/sprite-selector-item.test.jsx b/packages/scratch-gui/test/unit/containers/sprite-selector-item.test.jsx index 84a0c2dfac..2560cf3056 100644 --- a/packages/scratch-gui/test/unit/containers/sprite-selector-item.test.jsx +++ b/packages/scratch-gui/test/unit/containers/sprite-selector-item.test.jsx @@ -6,7 +6,7 @@ import VM from '@scratch/scratch-vm'; import SpriteSelectorItemContainer from '../../../src/containers/sprite-selector-item'; import {legacyConfig} from '../../../src/legacy-config'; -import DeleteConfirmationPrompt from '../../../src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx'; +import DeleteConfirmationPrompt from '../../../src/containers/delete-confirmation-prompt'; import {screen, fireEvent, waitFor} from '@testing-library/react'; global.MutationObserver = class { @@ -14,7 +14,7 @@ global.MutationObserver = class { observe () { } }; -jest.mock('../../../src/components/delete-confirmation-prompt/delete-confirmation-prompt.jsx', () => jest.fn(() => null)); +jest.mock('../../../src/containers/delete-confirmation-prompt', () => jest.fn(() => null)); describe('SpriteSelectorItem Container', () => { const mockStore = configureStore(); let className; @@ -63,6 +63,9 @@ describe('SpriteSelectorItem Container', () => { hoveredTarget: {receivedBlocks: false, sprite: null}, assetDrag: {dragging: false}, vm + }, + locales: { + isRtl: false } }); });