pl-fe: migrations from tailwind

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2026-01-27 17:43:30 +01:00
parent bb8e713d29
commit ddf88e406e
9 changed files with 151 additions and 61 deletions

View File

@@ -1,10 +1,6 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import Button from 'pl-fe/components/ui/button';
import Stack from 'pl-fe/components/ui/stack';
import Text from 'pl-fe/components/ui/text';
const messages = defineMessages({
title: { id: 'chat_pane.blankslate.title', defaultMessage: 'No messages yet' },
body: { id: 'chat_pane.blankslate.body', defaultMessage: 'Search for someone to chat with.' },
@@ -19,30 +15,21 @@ const Blankslate = ({ onSearch }: IBlankslate) => {
const intl = useIntl();
return (
<Stack
alignItems='center'
justifyContent='center'
className='h-full grow'
data-testid='chat-pane-blankslate'
>
<Stack space={4}>
<Stack space={1} className='mx-auto max-w-[80%]'>
<Text size='lg' weight='bold' align='center'>
{intl.formatMessage(messages.title)}
</Text>
<div className='⁂-chat-widget__blankslate' data-testid='chat-pane-blankslate'>
<div className='⁂-chat-widget__blankslate__text'>
<p className='⁂-chat-widget__blankslate__text__title'>
{intl.formatMessage(messages.title)}
</p>
<Text theme='muted' align='center'>
{intl.formatMessage(messages.body)}
</Text>
</Stack>
<p className='⁂-chat-widget__blankslate__text__body'>
{intl.formatMessage(messages.body)}
</p>
</div>
<div className='mx-auto'>
<Button theme='primary' onClick={onSearch}>
{intl.formatMessage(messages.action)}
</Button>
</div>
</Stack>
</Stack>
<button onClick={onSearch}>
{intl.formatMessage(messages.action)}
</button>
</div>
);
};

View File

@@ -1,7 +1,6 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import Stack from 'pl-fe/components/ui/stack';
import { ChatWidgetScreens, useChatContext } from 'pl-fe/contexts/chat-context';
import { useStatContext } from 'pl-fe/contexts/stat-context';
import { useChats } from 'pl-fe/queries/chats';
@@ -37,9 +36,9 @@ const ChatPane = () => {
const renderBody = () => {
if (Number(chats?.length) > 0 || showShoutbox || isLoading) {
return (
<Stack space={4} className='h-full grow'>
<div className='⁂-chat-widget__list'>
<ChatList onClickChat={handleClickChat} />
</Stack>
</div>
);
} else if (chats?.length === 0) {
return (

View File

@@ -1,9 +1,6 @@
import clsx from 'clsx';
import React, { HTMLAttributes } from 'react';
import HStack from 'pl-fe/components/ui/hstack';
import IconButton from 'pl-fe/components/ui/icon-button';
import Text from 'pl-fe/components/ui/text';
import { useSettings } from 'pl-fe/stores/settings';
interface IChatPaneHeader {
@@ -37,45 +34,40 @@ const ChatPaneHeader = (props: IChatPaneHeader) => {
}
return (
<HStack {...rest} alignItems='center' justifyContent='between' className='h-16 rounded-t-xl px-4 py-3'>
<div {...rest} className='⁂-chat-widget__header'>
<ButtonComp
className='flex h-16 grow flex-row items-center space-x-1'
className='⁂-chat-widget__header__title'
data-testid='title'
{...buttonProps}
>
<Text weight='semibold' tag='div'>
{title}
</Text>
<div>{title}</div>
{(!demetricator && typeof unreadCount !== 'undefined' && unreadCount > 0) && (
<HStack alignItems='center' space={2}>
<Text weight='semibold' data-testid='unread-count'>
{(!demetricator && unreadCount !== undefined && unreadCount > 0) && (
<div className='⁂-chat-widget__header__count'>
<p data-testid='unread-count'>
({unreadCount})
</Text>
</p>
<div className='size-2.5 rounded-full bg-accent-300' />
</HStack>
<div className='⁂-chat-widget__header__count__dot' />
</div>
)}
</ButtonComp>
<HStack space={2} alignItems='center'>
<div className='⁂-chat-widget__header__actions'>
{secondaryAction ? (
<IconButton
onClick={secondaryAction}
src={secondaryActionIcon as string}
iconClassName='h-5 w-5 text-gray-600'
/>
) : null}
<IconButton
onClick={onToggle}
src={require('@phosphor-icons/core/regular/caret-up.svg')}
iconClassName={clsx('size-5 text-gray-600 transition-transform', {
'rotate-180': isOpen,
})}
className='⁂-chat-widget__header__open-button'
/>
</HStack>
</HStack>
</div>
</div>
);
};

View File

@@ -1,7 +1,6 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import HStack from 'pl-fe/components/ui/hstack';
import Icon from 'pl-fe/components/ui/icon';
import Text from 'pl-fe/components/ui/text';
import { ChatWidgetScreens, useChatContext } from 'pl-fe/contexts/chat-context';
@@ -21,7 +20,7 @@ const ChatSearchHeader = () => {
<ChatPaneHeader
data-testid='pane-header'
title={
<HStack alignItems='center' space={2}>
<div className='⁂-chat-widget__search-header'>
<button
onClick={() => {
changeScreen(ChatWidgetScreens.INBOX);
@@ -36,7 +35,7 @@ const ChatSearchHeader = () => {
<Text size='sm' weight='bold' truncate>
{intl.formatMessage(messages.title)}
</Text>
</HStack>
</div>
}
isOpen={isOpen}
isToggleable={false}

View File

@@ -11,10 +11,7 @@ interface IPane {
/** Chat pane UI component for desktop. */
const Pane: React.FC<IPane> = ({ isOpen = false, children }) => (
<div
className={clsx('fixed bottom-0 z-[99] flex w-96 flex-col rounded-t-lg bg-white shadow-3xl black:border black:border-b-0 black:border-gray-800 black:bg-black dark:bg-gray-900 ltr:right-5 rtl:left-5', {
'h-[550px] max-h-[100vh]': isOpen,
'h-16': !isOpen,
})}
className={clsx('⁂-chat-widget', { '⁂-chat-widget--open': isOpen })}
data-testid='pane'
>
{children}

View File

@@ -176,8 +176,8 @@ const UI: React.FC = React.memo(() => {
</Suspense>
{me && features.chats && (
<div className='hidden xl:block'>
<Suspense fallback={<div className='fixed bottom-0 z-[99] flex h-16 w-96 animate-pulse flex-col rounded-t-lg bg-white shadow-3xl dark:bg-gray-900 ltr:right-5 rtl:left-5' />}>
<div className='⁂-chat-widget__container'>
<Suspense fallback={<div className='⁂-chat-widget--placeholder' />}>
<ChatWidget />
</Suspense>
</div>

View File

@@ -1,11 +1,11 @@
import React from 'react';
import { ChatProvider } from 'pl-fe/contexts/chat-context';
import ChatPage from 'pl-fe/features/chats/components/chats-page/chats-page';
import ChatsPage from 'pl-fe/features/chats/components/chats-page/chats-page';
const ChatIndex: React.FC = () => (
<ChatProvider>
<ChatPage />
<ChatsPage />
</ChatProvider>
);

View File

@@ -0,0 +1,115 @@
@use 'mixins';
@use 'variables';
.-chat-widget {
@apply fixed bottom-0 z-[99] flex w-96 flex-col rounded-t-lg bg-white shadow-3xl black:border black:border-b-0 black:border-gray-800 black:bg-black dark:bg-gray-900 ltr:right-5 rtl:left-5 h-16;
&--open {
height: 550px;
max-height: 100vh;
.-chat-widget__header__open-button svg {
transform: rotate(180deg);
}
}
&--placeholder {
@apply fixed bottom-0 z-[99] flex h-16 w-96 animate-pulse flex-col rounded-t-lg bg-white shadow-3xl dark:bg-gray-900 ltr:right-5 rtl:left-5;
}
&__container {
display: none;
@media (min-width: variables.$breakpoint-xl) {
display: block;
}
}
&__header {
display: flex;
align-items: center;
justify-content: space-between;
height: 4rem;
border-top-left-radius: 0.75rem;
border-top-right-radius: 0.75rem;
padding: 0.75rem 1rem;
gap: 0.5rem;
overflow: hidden;
&__title {
display: flex;
height: 4rem;
flex-grow: 1;
flex-direction: row;
align-items: center;
gap: 0.25rem;
}
&__title div:first-child,
&__count p {
@include mixins.text($weight: semibold);
overflow: hidden;
text-overflow: ellipsis;
}
&__count {
display: flex;
align-items: center;
gap: 0.5rem;
&__dot {
height: 0.625rem;
width: 0.625rem;
border-radius: 50%;
background: rgb(var(--color-accent-300));
}
}
&__actions {
display: flex;
align-items: center;
gap: 0.5rem;
svg {
height: 1.25rem;
width: 1.25rem;
color: rgb(var(--color-gray-600));
}
}
&__open-button svg {
transform: rotate(0deg);
transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}
}
&__blankslate {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
flex-grow: 1;
gap: 1rem;
&__text {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25rem;
max-width: 80%;
&__title {
@include mixins.text($size: lg, $weight: bold, $align: center);
}
&__body {
@include mixins.text($theme: muted, $align: center);
}
}
button {
@include mixins.button($theme: primary);
}
}
}

View File

@@ -6,4 +6,5 @@
@use 'timelines';
@use 'compose';
@use 'drive';
@use 'chats';
@use 'events';