Update design of Collections list page (#38822)

This commit is contained in:
diondiondion authored and GitHub committed 2026-04-28 11:32:27 +00:00
1 parent 1f1653e039
commit 3d5cb624ba
13 files changed
+305 -122

No files matched your search

@@ -276,9 +276,11 @@ export const ColumnHeader: React.FC<Props> = ({
</>
);
const HeadingElement = hasTitle ? 'h1' : 'div';
const component = (
<div className={wrapperClassName}>
<h1 className={buttonClassName}>
<HeadingElement className={buttonClassName}>
{hasTitle && (
<>
{backButton}
@@ -311,7 +313,7 @@ export const ColumnHeader: React.FC<Props> = ({
{extraButton}
{collapseButton}
</div>
</h1>
</HeadingElement>
<div
className={collapsibleClassName}
@@ -1,8 +1,10 @@
import type { ComponentPropsWithoutRef } from 'react';
import { Children, forwardRef } from 'react';
import { forwardRef } from 'react';
import classNames from 'classnames';
import { hasReactChildren } from '@/mastodon/utils/has_react_children';
import { LoadingIndicator } from '../loading_indicator';
export const Scrollable = forwardRef<
@@ -36,7 +38,7 @@ export const ItemList = forwardRef<
emptyMessage?: React.ReactNode;
}
>(({ isLoading, emptyMessage, className, children, ...otherProps }, ref) => {
if (!isLoading && Children.count(children) === 0 && emptyMessage) {
if (!isLoading && !hasReactChildren(children) && emptyMessage) {
return (
<div className='empty-column-indicator'>
<span>{emptyMessage}</span>
@@ -0,0 +1,51 @@
import type { ComponentPropsWithoutRef, FC } from 'react';
import classNames from 'classnames';
import type { NavLinkProps } from 'react-router-dom';
import { NavLink } from 'react-router-dom';
import classes from './styles.module.scss';
interface TabListProps {
/**
* Setting this will remove the default border and
* horizontal padding from the component
*/
plain?: boolean;
}
/**
* Display a simple row of links as tabs.
* The current page will be highlighted automatically based on the link destination.
*/
export const TabList: FC<TabListProps & ComponentPropsWithoutRef<'div'>> = ({
plain,
className,
children,
...otherProps
}) => {
return (
<div
{...otherProps}
className={classNames(
className,
classes.tabList,
!plain && classes.withSpaceAndBorder,
)}
>
{children}
</div>
);
};
export const TabLink: FC<NavLinkProps> = ({
className,
children,
...otherProps
}) => {
return (
<NavLink className={classNames(classes.tab, className)} {...otherProps}>
{children}
</NavLink>
);
};
@@ -0,0 +1,39 @@
.tabList {
display: flex;
gap: 16px;
}
.withSpaceAndBorder {
padding-inline: 16px;
border-bottom: 1px solid var(--color-border-primary);
}
.tab {
display: block;
padding: 18px 0;
color: var(--color-text-primary);
font-size: 15px;
font-weight: 500;
text-decoration: none;
border-radius: 0;
transition: color 0.2s ease-in-out;
@container (width < 500px) {
flex: 1 1 0px;
text-align: center;
}
&:hover {
text-decoration: none;
}
&:not(:global(.active)):is(:hover, :focus) {
color: var(--color-text-brand-soft);
}
&:global(.active) {
color: var(--color-text-brand);
border-bottom: 4px solid var(--color-border-brand);
padding-bottom: 14px;
}
}
@@ -0,0 +1,33 @@
import type { Meta, StoryObj } from '@storybook/react-vite';
import { TabList, TabLink } from './index';
const meta = {
title: 'Components/TabList',
component: TabList,
subcomponents: { TabLink },
} satisfies Meta<typeof TabList>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
render: () => (
<TabList>
<TabLink to='/'>Activity</TabLink>
<TabLink to='/media'>Media</TabLink>
<TabLink to='/featured'>Featured</TabLink>
</TabList>
),
};
export const Plain: Story = {
render: () => (
<TabList plain>
<TabLink to='/'>Activity</TabLink>
<TabLink to='/media'>Media</TabLink>
<TabLink to='/featured'>Featured</TabLink>
</TabList>
),
};