mirror of
https://github.com/mastodon/mastodon.git
synced 2026-09-28 01:40:06 -05:00
Redesign: Implement new navigation in advanced (multi-column) layout (#40522)
This commit is contained in:
@@ -5,9 +5,11 @@ import classNames from 'classnames';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
import { getColumnSkipLinkId } from '@/mastodon/features/ui/components/skip_links';
|
||||
import { isRedesignEnabled } from '@/mastodon/utils/environment';
|
||||
import { scrollTop } from 'mastodon/scroll';
|
||||
|
||||
import { ColumnContext, useColumnIndexContext } from './context';
|
||||
import classes from './styles.module.scss';
|
||||
|
||||
interface ColumnProps {
|
||||
children?: React.ReactNode;
|
||||
@@ -66,7 +68,10 @@ export const Column: React.FC<ColumnProps> = ({
|
||||
role='region'
|
||||
ref={nodeRef}
|
||||
onScroll={handleScroll}
|
||||
className={classNames('column', className)}
|
||||
className={classNames(
|
||||
isRedesignEnabled() ? classes.root : 'column',
|
||||
className,
|
||||
)}
|
||||
aria-label={label}
|
||||
aria-labelledby={
|
||||
label === undefined ? getColumnSkipLinkId(columnIndex) : undefined
|
||||
|
||||
19
app/javascript/mastodon/components/column/styles.module.scss
Normal file
19
app/javascript/mastodon/components/column/styles.module.scss
Normal file
@@ -0,0 +1,19 @@
|
||||
:global(.layout-multiple-columns) .root {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 0 auto;
|
||||
|
||||
--available-width: calc(
|
||||
100% - var(--multi-column-navigation-width) - var(--multi-column-gap)
|
||||
);
|
||||
|
||||
width: clamp(
|
||||
360px,
|
||||
(var(--available-width) / 4 - var(--multi-column-gap)),
|
||||
400px
|
||||
);
|
||||
padding: 0;
|
||||
background: var(--color-bg-primary);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import type { List, Record } from 'immutable';
|
||||
|
||||
import { ColumnIndexContext } from '@/mastodon/components/column/context';
|
||||
import { useAppSelector } from '@/mastodon/store';
|
||||
import { isRedesignEnabled } from '@/mastodon/utils/environment';
|
||||
|
||||
import {
|
||||
Compose,
|
||||
@@ -76,6 +77,10 @@ export const MultiColumnContent: React.FC<{
|
||||
const uuid = column.get('uuid');
|
||||
const id = column.get('id');
|
||||
|
||||
if (isRedesignEnabled() && id === 'COMPOSE') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ColumnIndexContext.Provider value={index} key={uuid}>
|
||||
<Bundle
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
--navigation-max-width: 320px;
|
||||
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 100vh;
|
||||
@@ -33,6 +32,19 @@
|
||||
--navigation-min-width: 0;
|
||||
}
|
||||
|
||||
.multiColumnRoot {
|
||||
--multi-column-navigation-width: 320px;
|
||||
--multi-column-gap: var(--space-xs);
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
justify-content: flex-start;
|
||||
gap: var(--multi-column-gap);
|
||||
padding-inline-end: var(--multi-column-gap);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.navigationWrapper {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
@@ -41,6 +53,14 @@
|
||||
height: 100dvh;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.multiColumnRoot & {
|
||||
height: initial;
|
||||
min-width: var(--multi-column-navigation-width);
|
||||
inset-inline-start: 0;
|
||||
z-index: 100;
|
||||
background: var(--color-bg-blend);
|
||||
}
|
||||
|
||||
@media (max-width: ($mobile-menu-breakpoint - 1)) {
|
||||
display: none;
|
||||
}
|
||||
@@ -58,12 +78,6 @@
|
||||
color: var(--color-text-primary);
|
||||
background-color: var(--color-bg-primary);
|
||||
|
||||
:global(.column) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:global(.scrollable) {
|
||||
contain: content;
|
||||
overflow: visible;
|
||||
|
||||
@@ -3,13 +3,13 @@ import classNames from 'classnames';
|
||||
import { ComposeRedesignButton } from '@/mastodon/features/compose/redesign/trigger';
|
||||
import { RedesignNavigationPanel } from '@/mastodon/features/navigation_panel/redesign';
|
||||
import { RedesignMobileNavigation } from '@/mastodon/features/navigation_panel/redesign/mobile_nav';
|
||||
import { useAppSelector } from '@/mastodon/store';
|
||||
import { Footer } from 'mastodon/features/custom_homepage/components/footer';
|
||||
|
||||
import { useBreakpoint } from '../../hooks/useBreakpoint';
|
||||
|
||||
import { MultiColumnContent } from './multi_column_content';
|
||||
import classes from './redesign.module.scss';
|
||||
import multiColClasses from './redesign_multicol.module.scss';
|
||||
|
||||
export const ColumnsAreaRedesign: React.FC<{
|
||||
singleColumn?: boolean;
|
||||
@@ -17,14 +17,11 @@ export const ColumnsAreaRedesign: React.FC<{
|
||||
children: React.ReactElement | React.ReactElement[];
|
||||
ref?: React.Ref<HTMLDivElement>;
|
||||
}> = ({ children, minimalShell, singleColumn, ref }) => {
|
||||
const isModalOpen = useAppSelector(
|
||||
(state) => !state.modal.get('stack').isEmpty(),
|
||||
);
|
||||
const isMobile = useBreakpoint('openable');
|
||||
|
||||
if (minimalShell) {
|
||||
return (
|
||||
<div className={classNames(classes.root, classes.rootMinimal)}>
|
||||
<div ref={ref} className={classNames(classes.root, classes.rootMinimal)}>
|
||||
{isMobile && <RedesignMobileNavigation />}
|
||||
<div className={classes.main}>
|
||||
<div>{children}</div>
|
||||
@@ -37,7 +34,7 @@ export const ColumnsAreaRedesign: React.FC<{
|
||||
|
||||
if (singleColumn) {
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<div ref={ref} className={classes.root}>
|
||||
<div className={classes.navigationWrapper}>
|
||||
<RedesignNavigationPanel />
|
||||
</div>
|
||||
@@ -49,11 +46,11 @@ export const ColumnsAreaRedesign: React.FC<{
|
||||
}
|
||||
|
||||
return (
|
||||
<main
|
||||
className={classNames('columns-area', { unscrollable: isModalOpen })}
|
||||
ref={ref}
|
||||
tabIndex={isModalOpen ? undefined : 0}
|
||||
>
|
||||
<main ref={ref} className={multiColClasses.root}>
|
||||
<div className={multiColClasses.navigationWrapper}>
|
||||
<RedesignNavigationPanel />
|
||||
</div>
|
||||
<ComposeRedesignButton />
|
||||
<MultiColumnContent>{children}</MultiColumnContent>
|
||||
</main>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
@use '@/styles/mastodon/variables' as *;
|
||||
|
||||
.root {
|
||||
--multi-column-navigation-width: 320px;
|
||||
--multi-column-gap: var(--space-xs);
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
justify-content: flex-start;
|
||||
gap: var(--multi-column-gap);
|
||||
padding-inline-end: var(--multi-column-gap);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.navigationWrapper {
|
||||
position: sticky;
|
||||
inset-inline-start: 0;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
min-width: var(--multi-column-navigation-width);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
background: var(--color-bg-blend);
|
||||
|
||||
@media (max-width: ($mobile-menu-breakpoint - 1)) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user