Context popup

This commit is contained in:
ilya-bkv 2022-12-13 14:10:54 +03:00
parent e067f15f0b
commit e08d72a926
10 changed files with 72 additions and 32 deletions

View File

@ -9,7 +9,7 @@ type SharePopupProps = Omit<PopupProps, 'children'>
export const SharePopup = (props: SharePopupProps) => { export const SharePopup = (props: SharePopupProps) => {
return ( return (
<Popup {...props}> <Popup {...props} variant="bordered">
<ul class="nodash"> <ul class="nodash">
<li> <li>
<a href="#"> <a href="#">

View File

@ -29,7 +29,6 @@ const DialogCard = (props: DialogProps) => {
.join(', ') .join(', ')
) )
console.log('!!! companions:', companions())
return ( return (
<Show when={props.members}> <Show when={props.members}>
<div <div
@ -42,7 +41,7 @@ const DialogCard = (props: DialogProps) => {
> >
<div class={styles.avatar}> <div class={styles.avatar}>
<Switch fallback={<DialogAvatar name={props.members[0].name} url={props.members[0].userpic} />}> <Switch fallback={<DialogAvatar name={props.members[0].name} url={props.members[0].userpic} />}>
<Match when={props.members.length >= 2}> <Match when={props.members.length >= 3}>
<GroupDialogAvatar users={props.members} /> <GroupDialogAvatar users={props.members} />
</Match> </Match>
</Switch> </Switch>

View File

@ -1,4 +1,4 @@
import { Show } from 'solid-js' import { createEffect, createMemo, createSignal, Show } from 'solid-js'
import MarkdownIt from 'markdown-it' import MarkdownIt from 'markdown-it'
import { clsx } from 'clsx' import { clsx } from 'clsx'
import styles from './Message.module.scss' import styles from './Message.module.scss'
@ -25,6 +25,12 @@ const md = new MarkdownIt({
const Message = (props: Props) => { const Message = (props: Props) => {
const isOwn = props.ownId === Number(props.content.author) const isOwn = props.ownId === Number(props.content.author)
const user = props.members?.find((m) => m.id === Number(props.content.author)) const user = props.members?.find((m) => m.id === Number(props.content.author))
const [isPopupVisible, setIsPopupVisible] = createSignal<boolean>(false)
const handleMouseLeave = () => {
if (isPopupVisible()) setIsPopupVisible(false)
}
return ( return (
<div class={clsx(styles.Message, isOwn && styles.own)}> <div class={clsx(styles.Message, isOwn && styles.own)}>
<Show when={!isOwn}> <Show when={!isOwn}>
@ -33,13 +39,17 @@ const Message = (props: Props) => {
<div class={styles.name}>{user.name}</div> <div class={styles.name}>{user.name}</div>
</div> </div>
</Show> </Show>
<div class={styles.body}> <div class={styles.body} onMouseLeave={handleMouseLeave}>
<div class={styles.text}> <div class={styles.text}>
<div class={styles.actions}> <div class={styles.actions}>
<div onClick={props.replyClick}> <div onClick={props.replyClick}>
<Icon name="chat-reply" class={styles.reply} /> <Icon name="chat-reply" class={styles.reply} />
</div> </div>
<MessageActionsPopup trigger={<Icon name="menu" />} /> <MessageActionsPopup
forceHide={!isPopupVisible()}
onVisibilityChange={(isVisible) => setIsPopupVisible(isVisible)}
trigger={<Icon name="menu" />}
/>
</div> </div>
<Show when={props.replyBody}> <Show when={props.replyBody}>
<QuotedMessage body={props.replyBody} variant="inline" /> <QuotedMessage body={props.replyBody} variant="inline" />

View File

@ -5,14 +5,14 @@ type MessageActionsPopup = Omit<PopupProps, 'children'>
export const MessageActionsPopup = (props: MessageActionsPopup) => { export const MessageActionsPopup = (props: MessageActionsPopup) => {
return ( return (
<Popup {...props}> <Popup {...props} variant="tiny">
<ul class="nodash"> <ul class="nodash">
<li>Ответить</li> <li>Ответить</li>
<li>Скопировать</li> <li>Скопировать</li>
<li>Закрепить</li> <li>Закрепить</li>
<li>Переслать</li> <li>Переслать</li>
<li>Выбрать</li> <li>Выбрать</li>
<li>Удалить</li> <li style={{ color: 'red' }}>Удалить</li>
</ul> </ul>
</Popup> </Popup>
) )

View File

@ -10,6 +10,7 @@
.icon { .icon {
width: 40px; width: 40px;
height: 40px; height: 40px;
flex-basis: 40px;
&.cancel { &.cancel {
cursor: pointer; cursor: pointer;

View File

@ -14,7 +14,7 @@ export const ProfilePopup = (props: ProfilePopupProps) => {
} = useSession() } = useSession()
return ( return (
<Popup {...props} horizontalAnchor="right"> <Popup {...props} horizontalAnchor="right" variant="bordered">
{/*TODO: l10n*/} {/*TODO: l10n*/}
<ul class="nodash"> <ul class="nodash">
<li> <li>

View File

@ -255,7 +255,7 @@ export const InboxView = () => {
value={postMessageText()} value={postMessageText()}
rows={1} rows={1}
onInput={(event) => handleChangeMessage(event)} onInput={(event) => handleChangeMessage(event)}
placeholder="Написать сообщение" placeholder={t('Write message')}
/> />
</div> </div>
<button type="submit" disabled={postMessageText().length === 0} onClick={handleSubmit}> <button type="submit" disabled={postMessageText().length === 0} onClick={handleSubmit}>

View File

@ -4,9 +4,49 @@
.popup { .popup {
background: #fff; background: #fff;
border: 2px solid #000;
top: calc(100% + 8px); top: calc(100% + 8px);
opacity: 1; opacity: 1;
color: #000;
position: absolute;
z-index: 10;
min-width: 144px;
ul {
margin-bottom: 0;
li {
position: relative;
&:last-child {
margin-bottom: 0;
}
}
}
&.bordered {
@include font-size(1.6rem);
border: 2px solid #000;
padding: 2.4rem;
ul li {
margin-bottom: 1.6rem;
&:last-child {
margin-bottom: 0;
}
}
}
&.tiny {
@include font-size(1.4rem);
box-shadow: 0 4px 60px rgba(0, 0, 0, 0.1);
padding: 1rem;
ul li {
margin-bottom: 1rem;
&:last-child {
margin-bottom: 0;
}
}
}
&.horizontalAnchorCenter { &.horizontalAnchorCenter {
left: 50%; left: 50%;
@ -17,25 +57,6 @@
right: 0; right: 0;
} }
@include font-size(1.6rem);
padding: 2.4rem;
position: absolute;
z-index: 10;
ul {
margin-bottom: 0;
}
li {
margin-bottom: 1.6rem;
position: relative;
&:last-child {
margin-bottom: 0;
}
}
.topBorderItem { .topBorderItem {
border-top: 2px solid; border-top: 2px solid;
padding-top: 1em; padding-top: 1em;

View File

@ -2,6 +2,7 @@ import { createEffect, createSignal, JSX, Show } from 'solid-js'
import styles from './Popup.module.scss' import styles from './Popup.module.scss'
import { clsx } from 'clsx' import { clsx } from 'clsx'
import { useOutsideClickHandler } from '../../../utils/useOutsideClickHandler' import { useOutsideClickHandler } from '../../../utils/useOutsideClickHandler'
import { set } from 'husky'
type HorizontalAnchor = 'center' | 'right' type HorizontalAnchor = 'center' | 'right'
@ -11,6 +12,8 @@ export type PopupProps = {
children: JSX.Element children: JSX.Element
onVisibilityChange?: (isVisible) => void onVisibilityChange?: (isVisible) => void
horizontalAnchor?: HorizontalAnchor horizontalAnchor?: HorizontalAnchor
variant?: 'bordered' | 'tiny'
forceHide?: boolean
} }
export const Popup = (props: PopupProps) => { export const Popup = (props: PopupProps) => {
@ -31,6 +34,9 @@ export const Popup = (props: PopupProps) => {
handler: () => setIsVisible(false) handler: () => setIsVisible(false)
}) })
createEffect(() => {
if (props.forceHide) setIsVisible(false)
})
const toggle = () => setIsVisible((oldVisible) => !oldVisible) const toggle = () => setIsVisible((oldVisible) => !oldVisible)
return ( return (
@ -40,7 +46,9 @@ export const Popup = (props: PopupProps) => {
<div <div
class={clsx(styles.popup, { class={clsx(styles.popup, {
[styles.horizontalAnchorCenter]: horizontalAnchor === 'center', [styles.horizontalAnchorCenter]: horizontalAnchor === 'center',
[styles.horizontalAnchorRight]: horizontalAnchor === 'right' [styles.horizontalAnchorRight]: horizontalAnchor === 'right',
[styles.bordered]: props.variant === 'bordered',
[styles.tiny]: props.variant === 'tiny'
})} })}
> >
{props.children} {props.children}

View File

@ -204,5 +204,6 @@
"Where": "Откуда", "Where": "Откуда",
"Date of Birth": "Дата рождения", "Date of Birth": "Дата рождения",
"Social networks": "Социальные сети", "Social networks": "Социальные сети",
"Save settings": "Сохранить настройки" "Save settings": "Сохранить настройки",
"Write message": "Написать сообщение"
} }