From a36dfbb2aa53b8ce3e4c88826aeda9f25d98e49a Mon Sep 17 00:00:00 2001 From: Peter Simonsson Date: Wed, 11 Jan 2023 21:58:46 +0100 Subject: [PATCH] [Glitch] Fix dropdown menu positions when scrolling Port fd33bcb3b25d3eaf593ade0aa8709a1184fc254e to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/actions/dropdown_menu.js | 4 +- .../glitch/components/dropdown_menu.js | 100 +++++++----------- .../containers/dropdown_menu_container.js | 5 +- .../containers/dropdown_menu_container.js | 5 +- .../features/compose/components/dropdown.js | 47 +++++--- .../compose/components/dropdown_menu.js | 46 +------- .../components/emoji_picker_dropdown.js | 39 ++++--- .../compose/components/language_dropdown.js | 81 +++++++------- .../features/compose/components/search.js | 47 ++++---- .../flavours/glitch/reducers/dropdown_menu.js | 4 +- .../styles/components/compose_form.scss | 2 - .../glitch/styles/components/index.scss | 85 +++++++++++---- .../glitch/styles/components/modal.scss | 1 - .../glitch/styles/mastodon-light/diff.scss | 18 +--- 14 files changed, 231 insertions(+), 253 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/dropdown_menu.js b/app/javascript/flavours/glitch/actions/dropdown_menu.js index fb6e55612e..023151d4bf 100644 --- a/app/javascript/flavours/glitch/actions/dropdown_menu.js +++ b/app/javascript/flavours/glitch/actions/dropdown_menu.js @@ -1,8 +1,8 @@ export const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN'; export const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE'; -export function openDropdownMenu(id, placement, keyboard, scroll_key) { - return { type: DROPDOWN_MENU_OPEN, id, placement, keyboard, scroll_key }; +export function openDropdownMenu(id, keyboard, scroll_key) { + return { type: DROPDOWN_MENU_OPEN, id, keyboard, scroll_key }; } export function closeDropdownMenu(id) { diff --git a/app/javascript/flavours/glitch/components/dropdown_menu.js b/app/javascript/flavours/glitch/components/dropdown_menu.js index 036e0b9090..7c70f750fd 100644 --- a/app/javascript/flavours/glitch/components/dropdown_menu.js +++ b/app/javascript/flavours/glitch/components/dropdown_menu.js @@ -2,9 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import IconButton from './icon_button'; -import Overlay from 'react-overlays/lib/Overlay'; -import Motion from '../features/ui/util/optional_motion'; -import spring from 'react-motion/lib/spring'; +import Overlay from 'react-overlays/Overlay'; import { supportsPassiveEvents } from 'detect-passive-events'; import classNames from 'classnames'; import { CircularProgress } from 'flavours/glitch/components/loading_indicator'; @@ -24,9 +22,6 @@ class DropdownMenu extends React.PureComponent { scrollable: PropTypes.bool, onClose: PropTypes.func.isRequired, style: PropTypes.object, - placement: PropTypes.string, - arrowOffsetLeft: PropTypes.string, - arrowOffsetTop: PropTypes.string, openedViaKeyboard: PropTypes.bool, renderItem: PropTypes.func, renderHeader: PropTypes.func, @@ -35,11 +30,6 @@ class DropdownMenu extends React.PureComponent { static defaultProps = { style: {}, - placement: 'bottom', - }; - - state = { - mounted: false, }; handleDocumentClick = e => { @@ -56,8 +46,6 @@ class DropdownMenu extends React.PureComponent { if (this.focusedItem && this.props.openedViaKeyboard) { this.focusedItem.focus({ preventScroll: true }); } - - this.setState({ mounted: true }); } componentWillUnmount () { @@ -139,40 +127,28 @@ class DropdownMenu extends React.PureComponent { } render () { - const { items, style, placement, arrowOffsetLeft, arrowOffsetTop, scrollable, renderHeader, loading } = this.props; - const { mounted } = this.state; + const { items, scrollable, renderHeader, loading } = this.props; let renderItem = this.props.renderItem || this.renderItem; return ( - - {({ opacity, scaleX, scaleY }) => ( - // It should not be transformed when mounting because the resulting - // size will be used to determine the coordinate of the menu by - // react-overlays -
-
+
+ {loading && ( + + )} -
- {loading && ( - - )} - - {!loading && renderHeader && ( -
- {renderHeader(items)} -
- )} - - {!loading && ( -
    - {items.map((option, i) => renderItem(option, i, { onClick: this.handleClick, onKeyPress: this.handleItemKeyPress }))} -
- )} -
+ {!loading && renderHeader && ( +
+ {renderHeader(items)}
)} - + + {!loading && ( +
    + {items.map((option, i) => renderItem(option, i, { onClick: this.handleClick, onKeyPress: this.handleItemKeyPress }))} +
+ )} +
); } @@ -197,7 +173,6 @@ export default class Dropdown extends React.PureComponent { isUserTouching: PropTypes.func, onOpen: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired, - dropdownPlacement: PropTypes.string, openDropdownId: PropTypes.number, openedViaKeyboard: PropTypes.bool, renderItem: PropTypes.func, @@ -213,13 +188,11 @@ export default class Dropdown extends React.PureComponent { id: id++, }; - handleClick = ({ target, type }) => { + handleClick = ({ type }) => { if (this.state.id === this.props.openDropdownId) { this.handleClose(); } else { - const { top } = target.getBoundingClientRect(); - const placement = top * 2 < innerHeight ? 'bottom' : 'top'; - this.props.onOpen(this.state.id, this.handleItemClick, placement, type !== 'click'); + this.props.onOpen(this.state.id, this.handleItemClick, type !== 'click'); } } @@ -303,7 +276,6 @@ export default class Dropdown extends React.PureComponent { disabled, loading, scrollable, - dropdownPlacement, openDropdownId, openedViaKeyboard, children, @@ -314,7 +286,6 @@ export default class Dropdown extends React.PureComponent { const open = this.state.id === openDropdownId; const button = children ? React.cloneElement(React.Children.only(children), { - ref: this.setTargetRef, onClick: this.handleClick, onMouseDown: this.handleMouseDown, onKeyDown: this.handleButtonKeyDown, @@ -326,7 +297,6 @@ export default class Dropdown extends React.PureComponent { active={open} disabled={disabled} size={size} - ref={this.setTargetRef} onClick={this.handleClick} onMouseDown={this.handleMouseDown} onKeyDown={this.handleButtonKeyDown} @@ -336,19 +306,27 @@ export default class Dropdown extends React.PureComponent { return ( - {button} - - - + + {button} + + + {({ props, arrowProps, placement }) => ( +
+
+
+ +
+
+ )} ); diff --git a/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js b/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js index 8b73663d44..a1519757de 100644 --- a/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js +++ b/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js @@ -4,7 +4,6 @@ import { fetchHistory } from 'flavours/glitch/actions/history'; import DropdownMenu from 'flavours/glitch/components/dropdown_menu'; const mapStateToProps = (state, { statusId }) => ({ - dropdownPlacement: state.getIn(['dropdown_menu', 'placement']), openDropdownId: state.getIn(['dropdown_menu', 'openId']), openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']), items: state.getIn(['history', statusId, 'items']), @@ -13,9 +12,9 @@ const mapStateToProps = (state, { statusId }) => ({ const mapDispatchToProps = (dispatch, { statusId }) => ({ - onOpen (id, onItemClick, dropdownPlacement, keyboard) { + onOpen (id, onItemClick, keyboard) { dispatch(fetchHistory(statusId)); - dispatch(openDropdownMenu(id, dropdownPlacement, keyboard)); + dispatch(openDropdownMenu(id, keyboard)); }, onClose (id) { diff --git a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js index b2dff63db8..43ce8ca631 100644 --- a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js +++ b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js @@ -5,18 +5,17 @@ import DropdownMenu from 'flavours/glitch/components/dropdown_menu'; import { isUserTouching } from '../is_mobile'; const mapStateToProps = state => ({ - dropdownPlacement: state.getIn(['dropdown_menu', 'placement']), openDropdownId: state.getIn(['dropdown_menu', 'openId']), openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']), }); const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({ - onOpen(id, onItemClick, dropdownPlacement, keyboard) { + onOpen(id, onItemClick, keyboard) { dispatch(isUserTouching() ? openModal('ACTIONS', { status, actions: items, onClick: onItemClick, - }) : openDropdownMenu(id, dropdownPlacement, keyboard, scrollKey)); + }) : openDropdownMenu(id, keyboard, scrollKey)); }, onClose(id) { diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown.js b/app/javascript/flavours/glitch/features/compose/components/dropdown.js index 3de198c452..924618930e 100644 --- a/app/javascript/flavours/glitch/features/compose/components/dropdown.js +++ b/app/javascript/flavours/glitch/features/compose/components/dropdown.js @@ -2,7 +2,7 @@ import classNames from 'classnames'; import PropTypes from 'prop-types'; import React from 'react'; -import Overlay from 'react-overlays/lib/Overlay'; +import Overlay from 'react-overlays/Overlay'; // Components. import IconButton from 'flavours/glitch/components/icon_button'; @@ -45,7 +45,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent { }; // Toggles opening and closing the dropdown. - handleToggle = ({ target, type }) => { + handleToggle = ({ type }) => { const { onModalOpen } = this.props; const { open } = this.state; @@ -59,11 +59,9 @@ export default class ComposerOptionsDropdown extends React.PureComponent { } } } else { - const { top } = target.getBoundingClientRect(); if (this.state.open && this.activeElement) { this.activeElement.focus({ preventScroll: true }); } - this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' }); this.setState({ open: !this.state.open, openedViaKeyboard: type !== 'click' }); } } @@ -158,6 +156,18 @@ export default class ComposerOptionsDropdown extends React.PureComponent { }; } + setTargetRef = c => { + this.target = c; + } + + findTarget = () => { + return this.target; + } + + handleOverlayEnter = (state) => { + this.setState({ placement: state.placement }); + } + // Rendering. render () { const { @@ -179,6 +189,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
- + {({ props, placement }) => ( +
+
+ +
+
+ )}
); diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js index 09e8fc35ae..c4895dfd0d 100644 --- a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js +++ b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js @@ -1,7 +1,6 @@ // Package imports. import PropTypes from 'prop-types'; import React from 'react'; -import spring from 'react-motion/lib/spring'; import ImmutablePureComponent from 'react-immutable-pure-component'; import classNames from 'classnames'; @@ -10,15 +9,8 @@ import Icon from 'flavours/glitch/components/icon'; // Utils. import { withPassive } from 'flavours/glitch/utils/dom_helpers'; -import Motion from '../../ui/util/optional_motion'; import { assignHandlers } from 'flavours/glitch/utils/react_helpers'; -// The spring to use with our motion. -const springMotion = spring(1, { - damping: 35, - stiffness: 400, -}); - // The component. export default class ComposerOptionsDropdownContent extends React.PureComponent { @@ -44,7 +36,6 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent }; state = { - mounted: false, value: this.props.openedViaKeyboard ? this.props.items[0].name : undefined, }; @@ -56,7 +47,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent } // Stores our node in `this.node`. - handleRef = (node) => { + setRef = (node) => { this.node = node; } @@ -69,7 +60,6 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent } else { this.node.firstChild.focus({ preventScroll: true }); } - this.setState({ mounted: true }); } // On unmounting, we remove our listeners. @@ -191,7 +181,6 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent // Rendering. render () { - const { mounted } = this.state; const { items, onChange, @@ -201,36 +190,9 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent // The result. return ( - - {({ opacity, scaleX, scaleY }) => ( - // It should not be transformed when mounting because the resulting - // size will be used to determine the coordinate of the menu by - // react-overlays -
- {!!items && items.map((item, i) => this.renderItem(item, i))} -
- )} -
+
+ {!!items && items.map((item, i) => this.renderItem(item, i))} +
); } diff --git a/app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js b/app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js index 546d398a0b..38c7355514 100644 --- a/app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js +++ b/app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { EmojiPicker as EmojiPickerAsync } from '../../ui/util/async-components'; -import Overlay from 'react-overlays/lib/Overlay'; +import Overlay from 'react-overlays/Overlay'; import classNames from 'classnames'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { supportsPassiveEvents } from 'detect-passive-events'; @@ -155,9 +155,6 @@ class EmojiPickerMenu extends React.PureComponent { onClose: PropTypes.func.isRequired, onPick: PropTypes.func.isRequired, style: PropTypes.object, - placement: PropTypes.string, - arrowOffsetLeft: PropTypes.string, - arrowOffsetTop: PropTypes.string, intl: PropTypes.object.isRequired, skinTone: PropTypes.number.isRequired, onSkinTone: PropTypes.func.isRequired, @@ -326,14 +323,13 @@ class EmojiPickerDropdown extends React.PureComponent { state = { active: false, loading: false, - placement: null, }; setRef = (c) => { this.dropdown = c; } - onShowDropdown = ({ target }) => { + onShowDropdown = () => { this.setState({ active: true }); if (!EmojiPicker) { @@ -348,9 +344,6 @@ class EmojiPickerDropdown extends React.PureComponent { this.setState({ loading: false, active: false }); }); } - - const { top } = target.getBoundingClientRect(); - this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' }); } onHideDropdown = () => { @@ -384,7 +377,7 @@ class EmojiPickerDropdown extends React.PureComponent { render () { const { intl, onPickEmoji, onSkinTone, skinTone, frequentlyUsedEmojis, button } = this.props; const title = intl.formatMessage(messages.emoji); - const { active, loading, placement } = this.state; + const { active, loading } = this.state; return (
@@ -396,16 +389,22 @@ class EmojiPickerDropdown extends React.PureComponent { />}
- - + + {({ props, placement })=> ( +
+
+ +
+
+ )}
); diff --git a/app/javascript/flavours/glitch/features/compose/components/language_dropdown.js b/app/javascript/flavours/glitch/features/compose/components/language_dropdown.js index a3256aa9b0..07d138f52b 100644 --- a/app/javascript/flavours/glitch/features/compose/components/language_dropdown.js +++ b/app/javascript/flavours/glitch/features/compose/components/language_dropdown.js @@ -2,9 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { injectIntl, defineMessages } from 'react-intl'; import TextIconButton from './text_icon_button'; -import Overlay from 'react-overlays/lib/Overlay'; -import Motion from 'flavours/glitch/features/ui/util/optional_motion'; -import spring from 'react-motion/lib/spring'; +import Overlay from 'react-overlays/Overlay'; import { supportsPassiveEvents } from 'detect-passive-events'; import classNames from 'classnames'; import { languages as preloadedLanguages } from 'flavours/glitch/initial_state'; @@ -22,10 +20,8 @@ const listenerOptions = supportsPassiveEvents ? { passive: true } : false; class LanguageDropdownMenu extends React.PureComponent { static propTypes = { - style: PropTypes.object, value: PropTypes.string.isRequired, frequentlyUsedLanguages: PropTypes.arrayOf(PropTypes.string).isRequired, - placement: PropTypes.string.isRequired, onClose: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired, languages: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)), @@ -37,7 +33,6 @@ class LanguageDropdownMenu extends React.PureComponent { }; state = { - mounted: false, searchValue: '', }; @@ -50,7 +45,6 @@ class LanguageDropdownMenu extends React.PureComponent { componentDidMount () { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); - this.setState({ mounted: true }); // Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need // to wait for a frame before focusing @@ -222,29 +216,22 @@ class LanguageDropdownMenu extends React.PureComponent { } render () { - const { style, placement, intl } = this.props; - const { mounted, searchValue } = this.state; + const { intl } = this.props; + const { searchValue } = this.state; const isSearching = searchValue !== ''; const results = this.search(); return ( - - {({ opacity, scaleX, scaleY }) => ( - // It should not be transformed when mounting because the resulting - // size will be used to determine the coordinate of the menu by - // react-overlays -
-
- - -
+
+
+ + +
-
- {results.map(this.renderItem)} -
-
- )} - +
+ {results.map(this.renderItem)} +
+
); } @@ -266,14 +253,11 @@ class LanguageDropdown extends React.PureComponent { placement: 'bottom', }; - handleToggle = ({ target }) => { - const { top } = target.getBoundingClientRect(); - + handleToggle = () => { if (this.state.open && this.activeElement) { this.activeElement.focus({ preventScroll: true }); } - this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' }); this.setState({ open: !this.state.open }); } @@ -293,13 +277,25 @@ class LanguageDropdown extends React.PureComponent { onChange(value); } + setTargetRef = c => { + this.target = c; + } + + findTarget = () => { + return this.target; + } + + handleOverlayEnter = (state) => { + this.setState({ placement: state.placement }); + } + render () { const { value, intl, frequentlyUsedLanguages } = this.props; const { open, placement } = this.state; return ( -
-
+
+
- - + + {({ props, placement }) => ( +
+
+ +
+
+ )}
); diff --git a/app/javascript/flavours/glitch/features/compose/components/search.js b/app/javascript/flavours/glitch/features/compose/components/search.js index 9f90a767d0..e5874de75e 100644 --- a/app/javascript/flavours/glitch/features/compose/components/search.js +++ b/app/javascript/flavours/glitch/features/compose/components/search.js @@ -3,13 +3,12 @@ import classNames from 'classnames'; import PropTypes from 'prop-types'; import React from 'react'; import { connect } from 'react-redux'; -import spring from 'react-motion/lib/spring'; import { injectIntl, FormattedMessage, defineMessages, } from 'react-intl'; -import Overlay from 'react-overlays/lib/Overlay'; +import Overlay from 'react-overlays/Overlay'; // Components. import Icon from 'flavours/glitch/components/icon'; @@ -17,7 +16,6 @@ import Icon from 'flavours/glitch/components/icon'; // Utils. import { focusRoot } from 'flavours/glitch/utils/dom_helpers'; import { searchEnabled } from 'flavours/glitch/initial_state'; -import Motion from '../../ui/util/optional_motion'; const messages = defineMessages({ placeholder: { id: 'search.placeholder', defaultMessage: 'Search' }, @@ -26,31 +24,20 @@ const messages = defineMessages({ class SearchPopout extends React.PureComponent { - static propTypes = { - style: PropTypes.object, - }; - render () { - const { style } = this.props; const extraInformation = searchEnabled ? : ; return ( -
- - {({ opacity, scaleX, scaleY }) => ( -
-

+
+

-
    -
  • #example
  • -
  • @username@domain
  • -
  • URL
  • -
  • URL
  • -
+
    +
  • #example
  • +
  • @username@domain
  • +
  • URL
  • +
  • URL
  • +
- {extraInformation} -
- )} - + {extraInformation}
); } @@ -136,6 +123,10 @@ class Search extends React.PureComponent { } } + findTarget = () => { + return this.searchForm; + } + render () { const { intl, value, submitted } = this.props; const { expanded } = this.state; @@ -161,8 +152,14 @@ class Search extends React.PureComponent {
- - + + {({ props, placement }) => ( +
+
+ +
+
+ )}
); diff --git a/app/javascript/flavours/glitch/reducers/dropdown_menu.js b/app/javascript/flavours/glitch/reducers/dropdown_menu.js index a78a11acca..51bf9375bf 100644 --- a/app/javascript/flavours/glitch/reducers/dropdown_menu.js +++ b/app/javascript/flavours/glitch/reducers/dropdown_menu.js @@ -4,12 +4,12 @@ import { DROPDOWN_MENU_CLOSE, } from '../actions/dropdown_menu'; -const initialState = Immutable.Map({ openId: null, placement: null, keyboard: false, scroll_key: null }); +const initialState = Immutable.Map({ openId: null, keyboard: false, scroll_key: null }); export default function dropdownMenu(state = initialState, action) { switch (action.type) { case DROPDOWN_MENU_OPEN: - return state.merge({ openId: action.id, placement: action.placement, keyboard: action.keyboard, scroll_key: action.scroll_key }); + return state.merge({ openId: action.id, keyboard: action.keyboard, scroll_key: action.scroll_key }); case DROPDOWN_MENU_CLOSE: return state.get('openId') === action.id ? state.set('openId', null).set('scroll_key', null) : state; default: diff --git a/app/javascript/flavours/glitch/styles/components/compose_form.scss b/app/javascript/flavours/glitch/styles/components/compose_form.scss index 72d3aad1d3..aa2d52ed04 100644 --- a/app/javascript/flavours/glitch/styles/components/compose_form.scss +++ b/app/javascript/flavours/glitch/styles/components/compose_form.scss @@ -586,7 +586,6 @@ } .privacy-dropdown__dropdown { - position: absolute; border-radius: 4px; box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); background: $simple-background-color; @@ -653,7 +652,6 @@ .language-dropdown { &__dropdown { - position: absolute; background: $simple-background-color; box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4); border-radius: 4px; diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index b7a54cd2b4..d50316366b 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -346,9 +346,8 @@ } } -.dropdown-menu { - position: absolute; - transform-origin: 50% 0; +body > [data-popper-placement] { + z-index: 3; } .invisible { @@ -532,6 +531,42 @@ } } +.dropdown-animation { + animation: dropdown 300ms cubic-bezier(0.1, 0.7, 0.1, 1); + + @keyframes dropdown { + from { + opacity: 0; + transform: scaleX(0.85) scaleY(0.75); + } + + to { + opacity: 1; + transform: scaleX(1) scaleY(1); + } + } + + &.top { + transform-origin: bottom; + } + + &.right { + transform-origin: left; + } + + &.bottom { + transform-origin: top; + } + + &.left { + transform-origin: right; + } + + .reduce-motion & { + animation: none; + } +} + .dropdown { display: inline-block; } @@ -600,36 +635,42 @@ .dropdown-menu__arrow { position: absolute; - width: 0; - height: 0; - border: 0 solid transparent; - &.left { - right: -5px; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: $ui-secondary-color; + &::before { + content: ''; + display: block; + width: 14px; + height: 5px; + background-color: $ui-secondary-color; + mask-image: url("data:image/svg+xml;utf8,"); } &.top { bottom: -5px; - margin-left: -7px; - border-width: 5px 7px 0; - border-top-color: $ui-secondary-color; + + &::before { + transform: rotate(180deg); + } + } + + &.right { + left: -9px; + + &::before { + transform: rotate(-90deg); + } } &.bottom { top: -5px; - margin-left: -7px; - border-width: 0 7px 5px; - border-bottom-color: $ui-secondary-color; } - &.right { - left: -5px; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: $ui-secondary-color; + &.left { + right: -9px; + + &::before { + transform: rotate(90deg); + } } } diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss index 8ba8bec102..972e01e7d3 100644 --- a/app/javascript/flavours/glitch/styles/components/modal.scss +++ b/app/javascript/flavours/glitch/styles/components/modal.scss @@ -37,7 +37,6 @@ .modal-root__modal { pointer-events: auto; display: flex; - z-index: 9999; } .media-modal__zoom-button { diff --git a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss index 9fc1aed2a2..2ec2da8332 100644 --- a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss +++ b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss @@ -285,22 +285,8 @@ html { .dropdown-menu { background: $white; - &__arrow { - &.left { - border-left-color: $white; - } - - &.top { - border-top-color: $white; - } - - &.bottom { - border-bottom-color: $white; - } - - &.right { - border-right-color: $white; - } + &__arrow::before { + background-color: $white; } &__item {