diff --git a/packages/pl-fe/src/components/polls/poll.tsx b/packages/pl-fe/src/components/polls/poll.tsx index f7357e276..79237ac33 100644 --- a/packages/pl-fe/src/components/polls/poll.tsx +++ b/packages/pl-fe/src/components/polls/poll.tsx @@ -68,7 +68,7 @@ const Poll: React.FC = ({ id, status, language, truncate }): JSX.Element return ( // eslint-disable-next-line jsx-a11y/no-static-element-interactions -
e.stopPropagation()}> +
e.stopPropagation()}> {!showResults && poll.multiple && ( diff --git a/packages/pl-fe/src/components/status-content.tsx b/packages/pl-fe/src/components/status-content.tsx index 47c7a8362..32622ca17 100644 --- a/packages/pl-fe/src/components/status-content.tsx +++ b/packages/pl-fe/src/components/status-content.tsx @@ -2,10 +2,8 @@ import clsx from 'clsx'; import React, { useState, useRef, useLayoutEffect, useMemo } from 'react'; import { FormattedMessage } from 'react-intl'; -import Icon from '@/components/icon'; -import Button from '@/components/ui/button'; +import Icon from '@/components/ui/icon'; import Stack from '@/components/ui/stack'; -import Text from '@/components/ui/text'; import Emojify from '@/features/emoji/emojify'; import QuotedStatus from '@/features/status/containers/quoted-status-container'; import { useFrontendConfig } from '@/hooks/use-frontend-config'; @@ -35,28 +33,15 @@ const BIG_EMOJI_LIMIT = 10; interface IReadMoreButton { onClick?: React.MouseEventHandler; - quote?: boolean; - poll?: boolean; preview?: boolean; } /** Button to expand a truncated status (due to too much content) */ -const ReadMoreButton: React.FC = ({ onClick, quote, poll, preview }) => ( -
-
+const ReadMoreButton: React.FC = ({ onClick, preview }) => ( +
+
{!preview && ( - @@ -180,8 +165,7 @@ const StatusContent: React.FC = React.memo(({ }, [spoilerText]); const direction = getTextDirection(status.search_index); - const className = useMemo(() => clsx('relative text-ellipsis break-words text-gray-900 focus:outline-none dark:text-gray-100', { - 'cursor-pointer': onClick, + const className = useMemo(() => clsx('⁂-status-content', { 'overflow-hidden': collapsed, 'max-h-[200px]': collapsed && !isQuote && !preview, 'max-h-[120px]': collapsed && isQuote, @@ -190,7 +174,10 @@ const StatusContent: React.FC = React.memo(({ 'max-h-[202px]': collapsable && collapsed === null && isQuote, 'max-h-[82px]': collapsed === null && preview, 'leading-normal big-emoji': onlyEmoji, - '⁂-status-content__expanded': !collapsable, + '⁂-status-content--expanded': !collapsable, + '⁂-status-content--quote': isQuote, + '⁂-status-content--preview': preview, + '⁂-status-content--poll': !!status.poll_id, }), [collapsed, onlyEmoji]); const expandable = !displaySpoilers; @@ -199,41 +186,31 @@ const StatusContent: React.FC = React.memo(({ if (spoilerText) { output.push( - - + {expandable && ( - + )} - , +

, ); } - const hasPoll = !!status.poll_id; - if (!expandable || expanded) { let quote; @@ -283,7 +260,7 @@ const StatusContent: React.FC = React.memo(({ } if (collapsed) { - output.push(); + output.push(); } if (status.poll_id) { @@ -304,7 +281,7 @@ const StatusContent: React.FC = React.memo(({ } if (onClick) { - return {output}; + return
{output}
; } else { return <>{output}; } diff --git a/packages/pl-fe/src/styles/markup.scss b/packages/pl-fe/src/styles/markup.scss index 5881d9f35..796cd307f 100644 --- a/packages/pl-fe/src/styles/markup.scss +++ b/packages/pl-fe/src/styles/markup.scss @@ -150,7 +150,7 @@ $vertical-lr-langs: mn-mong, mnmong; max-height: 209px; // roughly above 500 characters, readable overflow-x: hidden; // read more - &.⁂-status-content__expanded { + &.⁂-status-content--expanded { max-width: unset; max-height: 50vh; overflow-x: auto; diff --git a/packages/pl-fe/src/styles/new/statuses.scss b/packages/pl-fe/src/styles/new/statuses.scss index d98b986d5..5d46451ed 100644 --- a/packages/pl-fe/src/styles/new/statuses.scss +++ b/packages/pl-fe/src/styles/new/statuses.scss @@ -228,4 +228,69 @@ } } } -} \ No newline at end of file +} + +.⁂-read-more-button { + @apply flex items-center border-0 bg-transparent p-0 pt-2 text-gray-900 hover:underline active:underline dark:text-gray-300; + + &__gradient { + @apply pointer-events-none absolute -top-16 h-16 w-full bg-gradient-to-b from-transparent to-white black:to-black dark:to-primary-900; + } + + &__container { + position: relative; + margin-top: -1rem; + } +} + +.⁂-status-content { + @apply relative text-ellipsis break-words text-gray-900 focus:outline-none dark:text-gray-100; + + &:has(button) { + cursor: pointer; + } + + &--preview + .⁂-read-more-button__container { + margin-top: -0.5rem; + } + + &--poll + .⁂-read-more-button__container .⁂-read-more-button__gradient { + @apply to-gray-100 dark:to-primary-800; + } + + &--quote + .⁂-read-more-button__container .⁂-read-more-button__gradient { + @apply group-hover:to-gray-100 black:group-hover:to-gray-800 dark:group-hover:to-gray-800; + } + + &__container { + display: flex; + flex-direction: column; + gap: 1rem; + + &:has(.⁂-poll) { + @apply bg-gray-100 dark:bg-primary-800 rounded-md p-4; + } + } +} + +.⁂-status-title { + @include mixins.text($size: 2xl, $weight: medium); + + &--clamp span:first-child { + @apply line-clamp-3 + } + + button { + @include mixins.button($theme: muted, $size: xs); + margin-left: 0.5rem; + vertical-align: middle; + + svg { + @apply size-4 transition-transform; + } + } + + &[aria-expanded='true'] button svg { + transform: rotate(180deg); + } +}