mirror of
https://github.com/mastodon/mastodon.git
synced 2026-09-15 00:36:22 -05:00
Status redesign: Hashtags (#40466)
This commit is contained in:
@@ -4,6 +4,9 @@
|
||||
--bg: transparent;
|
||||
--bg-hover: color-mix(in srgb, var(--bg) 90%, var(--fg));
|
||||
--fg: var(--color-text-primary);
|
||||
--inline-padding: var(--space-xs);
|
||||
|
||||
@include mixins.type-label-lg;
|
||||
|
||||
background-color: var(--bg);
|
||||
border-radius: var(--radius-round);
|
||||
@@ -19,8 +22,7 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
column-gap: var(--space-2xs);
|
||||
@include mixins.type-label-lg;
|
||||
|
||||
padding-inline: var(--inline-padding);
|
||||
box-sizing: border-box;
|
||||
|
||||
&:hover:not(
|
||||
@@ -68,22 +70,27 @@ a.base {
|
||||
// Sizes
|
||||
|
||||
.xs {
|
||||
padding-inline: var(--space-xs);
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
.sm {
|
||||
padding: var(--space-2xs) var(--space-sm);
|
||||
--inline-padding: var(--space-sm);
|
||||
|
||||
padding-block: var(--space-2xs);
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.md {
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
--inline-padding: var(--space-md);
|
||||
|
||||
padding-block: var(--space-xs);
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.lg {
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
--inline-padding: var(--space-lg);
|
||||
|
||||
padding-block: var(--space-sm);
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
@@ -225,3 +232,7 @@ a.base {
|
||||
.loading {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.clipPadding {
|
||||
margin-inline-start: calc(-1 * var(--inline-padding));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ interface ButtonPropsBase<As extends 'a' | 'button'> {
|
||||
* or `aria-pressed` are used.
|
||||
*/
|
||||
noActiveHighlight?: boolean;
|
||||
/**
|
||||
* Adds a negative margin to a button to align the text
|
||||
* with the starting edge of its parent.
|
||||
*/
|
||||
clipPadding?: boolean;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
@@ -50,6 +55,7 @@ const BaseButton: React.FC<BaseButtonProps> = ({
|
||||
className,
|
||||
onClick,
|
||||
loading,
|
||||
clipPadding,
|
||||
noActiveHighlight,
|
||||
'aria-disabled': ariaDisabled,
|
||||
'aria-live': ariaLive,
|
||||
@@ -85,6 +91,7 @@ const BaseButton: React.FC<BaseButtonProps> = ({
|
||||
classes[size],
|
||||
classes[color],
|
||||
classes[variant],
|
||||
clipPadding && classes.clipPadding,
|
||||
noActiveHighlight && classes.noActiveHighlight,
|
||||
)}
|
||||
onClick={handleClick}
|
||||
|
||||
58
app/javascript/mastodon/components/status/hashtag_bar.tsx
Normal file
58
app/javascript/mastodon/components/status/hashtag_bar.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { useOverflowButton } from '@/mastodon/hooks/useOverflow';
|
||||
import { useToggle } from '@/mastodon/hooks/useToggle';
|
||||
|
||||
import { Button } from '../button/redesign';
|
||||
|
||||
import classes from './styles.module.scss';
|
||||
|
||||
export const StatusHashtagBar: React.FC<{
|
||||
hashtags: string[];
|
||||
accountId: string;
|
||||
}> = ({ hashtags, accountId }) => {
|
||||
const [showOverflow, { onTrue: onShowOverflow }] = useToggle();
|
||||
const { hiddenCount, wrapperRef, listRef, hiddenIndex, maxWidth } =
|
||||
useOverflowButton();
|
||||
|
||||
if (hashtags.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.hashtagsWrapper} ref={wrapperRef}>
|
||||
<div
|
||||
className={classNames(
|
||||
classes.hashtags,
|
||||
showOverflow && classes.hashtagsShowAll,
|
||||
)}
|
||||
ref={listRef}
|
||||
style={{ maxWidth }}
|
||||
>
|
||||
{hashtags.map((hashtag, index) => (
|
||||
<Button
|
||||
key={hashtag}
|
||||
size='xs'
|
||||
as='link'
|
||||
to={`/tags/${hashtag}`}
|
||||
data-menu-hashtag={accountId}
|
||||
inert={hiddenIndex > 0 && index >= hiddenIndex}
|
||||
>
|
||||
#{hashtag}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
{hiddenCount > 0 && !showOverflow && (
|
||||
<Button size='xs' onClick={onShowOverflow}>
|
||||
<FormattedMessage
|
||||
id='featured_tags.more_items'
|
||||
defaultMessage='+{count}'
|
||||
values={{ count: hiddenCount }}
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -10,13 +10,14 @@ import { createAppSelector, useAppSelector } from '@/mastodon/store';
|
||||
|
||||
import { ContentWarning } from '../content_warning';
|
||||
import { FilterWarning } from '../filter_warning';
|
||||
import { computeHashtagBarForStatus, HashtagBar } from '../hashtag_bar';
|
||||
import { computeHashtagBarForStatus } from '../hashtag_bar';
|
||||
import { Hotkeys } from '../hotkeys';
|
||||
import { Poll } from '../poll';
|
||||
|
||||
import { StatusActionBar } from './action_bar';
|
||||
import { StatusAttachments } from './attachments';
|
||||
import { StatusContent } from './content';
|
||||
import { StatusHashtagBar } from './hashtag_bar';
|
||||
import type { StatusHandlers } from './hooks';
|
||||
import {
|
||||
StatusContext,
|
||||
@@ -210,7 +211,7 @@ export const StatusRedesign: React.FC<StatusRedesignProps> = ({
|
||||
{showFooter && (
|
||||
<footer className={classes.footer}>
|
||||
{expanded && hashtagsInBar.length > 0 && (
|
||||
<HashtagBar
|
||||
<StatusHashtagBar
|
||||
hashtags={hashtagsInBar}
|
||||
accountId={status.account.id}
|
||||
/>
|
||||
|
||||
@@ -102,6 +102,36 @@
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.footer {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hashtagsWrapper,
|
||||
.hashtags {
|
||||
display: flex;
|
||||
gap: var(--space-2xs);
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.hashtagsWrapper {
|
||||
padding: var(--space-2xs) 0;
|
||||
}
|
||||
|
||||
.hashtags {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
> button {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.hashtagsShowAll {
|
||||
flex-wrap: wrap;
|
||||
overflow: visible;
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.meta {
|
||||
@include mixins.type-micro;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user