From c36f28ba77d784cff6f5dba109e1286b13204221 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 9 Oct 2022 15:55:32 +0200 Subject: [PATCH] [Glitch] Fix intermediary responsive layout, accessibility on navigation in web UI Port 07653246223251052f5150e1e74139bf8ff41ec4 to glitch-soc Co-authored-by: Yamagishi Kazutoshi Signed-off-by: Claire --- .../flavours/glitch/components/avatar.js | 2 + .../flavours/glitch/components/logo.js | 3 +- .../features/ui/components/column_link.js | 24 ++++---- ...link.js => follow_requests_column_link.js} | 24 ++++++-- .../glitch/features/ui/components/header.js | 3 +- .../ui/components/navigation_panel.js | 56 ++++++++++++------- .../glitch/styles/components/columns.scss | 3 + .../styles/components/single_column.scss | 31 ++++++++-- .../flavours/glitch/styles/variables.scss | 2 +- 9 files changed, 104 insertions(+), 44 deletions(-) rename app/javascript/flavours/glitch/features/ui/components/{follow_requests_nav_link.js => follow_requests_column_link.js} (52%) diff --git a/app/javascript/flavours/glitch/components/avatar.js b/app/javascript/flavours/glitch/components/avatar.js index ce91d401d1..1da4a861cb 100644 --- a/app/javascript/flavours/glitch/components/avatar.js +++ b/app/javascript/flavours/glitch/components/avatar.js @@ -70,6 +70,8 @@ export default class Avatar extends React.PureComponent { onMouseLeave={this.handleMouseLeave} style={style} data-avatar-of={account && `@${account.get('acct')}`} + role='img' + aria-label={account.get('acct')} /> ); } diff --git a/app/javascript/flavours/glitch/components/logo.js b/app/javascript/flavours/glitch/components/logo.js index 3570b3644b..ee5c22496c 100644 --- a/app/javascript/flavours/glitch/components/logo.js +++ b/app/javascript/flavours/glitch/components/logo.js @@ -1,7 +1,8 @@ import React from 'react'; const Logo = () => ( - + + Mastodon ); diff --git a/app/javascript/flavours/glitch/features/ui/components/column_link.js b/app/javascript/flavours/glitch/features/ui/components/column_link.js index d04b869b69..1c475d087f 100644 --- a/app/javascript/flavours/glitch/features/ui/components/column_link.js +++ b/app/javascript/flavours/glitch/features/ui/components/column_link.js @@ -1,26 +1,29 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Link } from 'react-router-dom'; +import { NavLink } from 'react-router-dom'; import Icon from 'flavours/glitch/components/icon'; +import classNames from 'classnames'; -const ColumnLink = ({ icon, text, to, onClick, href, method, badge }) => { +const ColumnLink = ({ icon, text, to, onClick, href, method, badge, transparent, ...other }) => { + const className = classNames('column-link', { 'column-link--transparent': transparent }); const badgeElement = typeof badge !== 'undefined' ? {badge} : null; + const iconElement = typeof icon === 'string' ? : icon; if (href) { return ( - - + + {iconElement} {text} {badgeElement} ); } else if (to) { return ( - - + + {iconElement} {text} {badgeElement} - + ); } else { const handleOnClick = (e) => { @@ -29,8 +32,8 @@ const ColumnLink = ({ icon, text, to, onClick, href, method, badge }) => { return onClick(e); } return ( - - + + {iconElement} {text} {badgeElement} @@ -39,13 +42,14 @@ const ColumnLink = ({ icon, text, to, onClick, href, method, badge }) => { }; ColumnLink.propTypes = { - icon: PropTypes.string.isRequired, + icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired, text: PropTypes.string.isRequired, to: PropTypes.string, onClick: PropTypes.func, href: PropTypes.string, method: PropTypes.string, badge: PropTypes.node, + transparent: PropTypes.bool, }; export default ColumnLink; diff --git a/app/javascript/flavours/glitch/features/ui/components/follow_requests_nav_link.js b/app/javascript/flavours/glitch/features/ui/components/follow_requests_column_link.js similarity index 52% rename from app/javascript/flavours/glitch/features/ui/components/follow_requests_nav_link.js rename to app/javascript/flavours/glitch/features/ui/components/follow_requests_column_link.js index c30427896f..301392a52a 100644 --- a/app/javascript/flavours/glitch/features/ui/components/follow_requests_nav_link.js +++ b/app/javascript/flavours/glitch/features/ui/components/follow_requests_column_link.js @@ -2,22 +2,27 @@ import React from 'react'; import PropTypes from 'prop-types'; import { fetchFollowRequests } from 'flavours/glitch/actions/accounts'; import { connect } from 'react-redux'; -import { NavLink, withRouter } from 'react-router-dom'; +import ColumnLink from 'flavours/glitch/features/ui/components/column_link'; import IconWithBadge from 'flavours/glitch/components/icon_with_badge'; import { List as ImmutableList } from 'immutable'; -import { FormattedMessage } from 'react-intl'; +import { injectIntl, defineMessages } from 'react-intl'; + +const messages = defineMessages({ + text: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, +}); const mapStateToProps = state => ({ count: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size, }); -export default @withRouter +export default @injectIntl @connect(mapStateToProps) -class FollowRequestsNavLink extends React.Component { +class FollowRequestsColumnLink extends React.Component { static propTypes = { dispatch: PropTypes.func.isRequired, count: PropTypes.number.isRequired, + intl: PropTypes.object.isRequired, }; componentDidMount () { @@ -27,13 +32,20 @@ class FollowRequestsNavLink extends React.Component { } render () { - const { count } = this.props; + const { count, intl } = this.props; if (count === 0) { return null; } - return ; + return ( + } + text={intl.formatMessage(messages.text)} + /> + ); } } diff --git a/app/javascript/flavours/glitch/features/ui/components/header.js b/app/javascript/flavours/glitch/features/ui/components/header.js index 041bdff051..5fdef0af49 100644 --- a/app/javascript/flavours/glitch/features/ui/components/header.js +++ b/app/javascript/flavours/glitch/features/ui/components/header.js @@ -11,8 +11,7 @@ import { connect } from 'react-redux'; const Account = connect(state => ({ account: state.getIn(['accounts', me]), }))(({ account }) => ( - - {account.get('acct')} + )); diff --git a/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js b/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js index 754c651c2e..0955b3cf82 100644 --- a/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js +++ b/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js @@ -1,17 +1,34 @@ -import PropTypes from 'prop-types'; import React from 'react'; -import { FormattedMessage } from 'react-intl'; -import { Link, NavLink } from 'react-router-dom'; -import Icon from 'flavours/glitch/components/icon'; +import PropTypes from 'prop-types'; +import { defineMessages, injectIntl } from 'react-intl'; +import { Link } from 'react-router-dom'; import TrendsContainer from 'flavours/glitch/features/getting_started/containers/trends_container'; import { showTrends, timelinePreview } from 'flavours/glitch/initial_state'; -import FollowRequestsNavLink from './follow_requests_nav_link'; +import FollowRequestsColumnLink from './follow_requests_column_link'; import ListPanel from './list_panel'; import NotificationsCounterIcon from './notifications_counter_icon'; import SignInBanner from './sign_in_banner'; import { preferencesLink, relationshipsLink } from 'flavours/glitch/utils/backend_links'; +import ColumnLink from 'flavours/glitch/features/ui/components/column_link'; -export default class NavigationPanel extends React.Component { +const messages = defineMessages({ + home: { id: 'tabs_bar.home', defaultMessage: 'Home' }, + notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' }, + explore: { id: 'explore.title', defaultMessage: 'Explore' }, + local: { id: 'tabs_bar.local_timeline', defaultMessage: 'Local' }, + federated: { id: 'tabs_bar.federated_timeline', defaultMessage: 'Federated' }, + direct: { id: 'navigation_bar.direct', defaultMessage: 'Direct messages' }, + favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, + bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' }, + lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, + preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, + followsAndFollowers: { id: 'navigation_bar.follows_and_followers', defaultMessage: 'Follows and followers' }, + about: { id: 'navigation_bar.about', defaultMessage: 'About' }, + app_settings: { id: 'navigation_bar.app_settings', defaultMessage: 'App settings' }, +}); + +export default @injectIntl +class NavigationPanel extends React.Component { static contextTypes = { router: PropTypes.object.isRequired, @@ -23,24 +40,24 @@ export default class NavigationPanel extends React.Component { }; render() { + const { intl, onOpenSettings } = this.props; const { signedIn } = this.context.identity; - const { onOpenSettings } = this.props; return (
{signedIn && ( - - - + + } text={intl.formatMessage(messages.notifications)} /> + )} - + {signedIn || timelinePreview && ( <> - - + + )} @@ -53,17 +70,18 @@ export default class NavigationPanel extends React.Component { {signedIn && ( - - - + + + +
- {!!preferencesLink && } - - {!!relationshipsLink && } + {!!preferencesLink && } + + {!!relationshipsLink && }
)} diff --git a/app/javascript/flavours/glitch/styles/components/columns.scss b/app/javascript/flavours/glitch/styles/components/columns.scss index 6f878f7914..3233506cca 100644 --- a/app/javascript/flavours/glitch/styles/components/columns.scss +++ b/app/javascript/flavours/glitch/styles/components/columns.scss @@ -214,6 +214,9 @@ $ui-header-height: 55px; font-size: 16px; padding: 15px; text-decoration: none; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; &:hover, &:focus, diff --git a/app/javascript/flavours/glitch/styles/components/single_column.scss b/app/javascript/flavours/glitch/styles/components/single_column.scss index 63bebc514e..4a987a131e 100644 --- a/app/javascript/flavours/glitch/styles/components/single_column.scss +++ b/app/javascript/flavours/glitch/styles/components/single_column.scss @@ -275,12 +275,14 @@ } @media screen and (max-width: $no-gap-breakpoint - 1px) { + $sidebar-width: 285px; + .with-fab .scrollable .item-list:last-child { padding-bottom: 5.25rem; } .columns-area__panels__main { - width: calc(100% - 55px); + width: calc(100% - $sidebar-width); } .columns-area__panels { @@ -288,10 +290,10 @@ } .columns-area__panels__pane--navigational { - min-width: 55px; + min-width: $sidebar-width; .columns-area__panels__pane__inner { - width: 55px; + width: $sidebar-width; } .navigation-panel { @@ -301,7 +303,6 @@ height: 100vh; } - .column-link span, .navigation-panel__sign-in-banner, .navigation-panel__logo, .getting-started__trends { @@ -326,11 +327,31 @@ } } +@media screen and (max-width: $no-gap-breakpoint - 285px - 1px) { + $sidebar-width: 55px; + + .columns-area__panels__main { + width: calc(100% - $sidebar-width); + } + + .columns-area__panels__pane--navigational { + min-width: $sidebar-width; + + .columns-area__panels__pane__inner { + width: $sidebar-width; + } + + .column-link span { + display: none; + } + } +} + .explore__search-header { display: none; } -@media screen and (max-width: $no-gap-breakpoint + 285px - 1px) { +@media screen and (max-width: $no-gap-breakpoint - 1px) { .columns-area__panels__pane--compositional { display: none; } diff --git a/app/javascript/flavours/glitch/styles/variables.scss b/app/javascript/flavours/glitch/styles/variables.scss index 4b4f5ffbed..b865b5a2d1 100644 --- a/app/javascript/flavours/glitch/styles/variables.scss +++ b/app/javascript/flavours/glitch/styles/variables.scss @@ -51,7 +51,7 @@ $media-modal-media-max-width: 100%; // put margins on top and bottom of image to avoid the screen covered by image. $media-modal-media-max-height: 80%; -$no-gap-breakpoint: 890px; +$no-gap-breakpoint: 1175px; $font-sans-serif: 'mastodon-font-sans-serif' !default; $font-display: 'mastodon-font-display' !default;