diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx
index 512cdac9..ab6d6b07 100644
--- a/src/components/Article/FullArticle.tsx
+++ b/src/components/Article/FullArticle.tsx
@@ -10,6 +10,7 @@ import { showModal } from '../../stores/ui'
import { useAuthStore } from '../../stores/auth'
import { incrementView } from '../../stores/zine/articles'
import MD from './MD'
+import { SharePopup } from './SharePopup'
const MAX_COMMENT_LEVEL = 6
@@ -126,9 +127,13 @@ export const FullArticle = (props: ArticleProps) => {
{/* */}
{/**/}
{/*FIXME*/}
{/**/}
diff --git a/src/components/Article/SharePopup.tsx b/src/components/Article/SharePopup.tsx
new file mode 100644
index 00000000..851cf599
--- /dev/null
+++ b/src/components/Article/SharePopup.tsx
@@ -0,0 +1,45 @@
+import { Icon } from '../Nav/Icon'
+import styles from '../Nav/Popup.module.scss'
+import { t } from '../../utils/intl'
+import { Popup, PopupProps } from '../Nav/Popup'
+
+type SharePopupProps = Omit
+
+export const SharePopup = (props: SharePopupProps) => {
+ return (
+
+
+
+ )
+}
diff --git a/src/components/Nav/Header.module.scss b/src/components/Nav/Header.module.scss
index 0a34a45e..9078872b 100644
--- a/src/components/Nav/Header.module.scss
+++ b/src/components/Nav/Header.module.scss
@@ -35,18 +35,6 @@
}
}
-.popupShare {
- opacity: 1;
- transition: opacity 0.3s;
- z-index: 1;
-
- .headerScrolledTop & {
- opacity: 0;
- transition: opacity 0.3s, z-index 0s 0.3s;
- z-index: -1;
- }
-}
-
.headerFixed {
position: fixed;
top: 0;
@@ -348,18 +336,16 @@
transform: translateY(-50%);
width: 100%;
- .icon {
+ .control {
+ cursor: pointer;
margin-left: 1.6rem;
- opacity: 0.6;
- transition: opacity 0.3s;
- }
+ border: 0;
- img {
- vertical-align: middle;
- }
+ .icon {
+ opacity: 0.6;
+ transition: opacity 0.3s;
+ }
- a {
- border: none;
&:hover {
background: none;
@@ -370,4 +356,8 @@
}
}
}
+
+ img {
+ vertical-align: middle;
+ }
}
diff --git a/src/components/Nav/Header.tsx b/src/components/Nav/Header.tsx
index ab2d6aeb..8a4e46f8 100644
--- a/src/components/Nav/Header.tsx
+++ b/src/components/Nav/Header.tsx
@@ -3,18 +3,17 @@ import Private from './Private'
import Notifications from './Notifications'
import { Icon } from './Icon'
import { Modal } from './Modal'
-import { Popup } from './Popup'
import AuthModal from './AuthModal'
import { t } from '../../utils/intl'
-import {useModalStore, showModal, useWarningsStore, toggleModal} from '../../stores/ui'
+import { useModalStore, showModal, useWarningsStore } from '../../stores/ui'
import { useAuthStore } from '../../stores/auth'
import { handleClientRouteLinkClick, router, Routes, useRouter } from '../../stores/router'
import styles from './Header.module.scss'
-import stylesPopup from './Popup.module.scss'
import privateStyles from './Private.module.scss'
import { getPagePath } from '@nanostores/router'
import { getLogger } from '../../utils/logger'
import { clsx } from 'clsx'
+import { SharePopup } from '../Article/SharePopup'
const log = getLogger('header')
@@ -39,6 +38,7 @@ export const Header = (props: Props) => {
const [getIsScrolled, setIsScrolled] = createSignal(false)
const [fixed, setFixed] = createSignal(false)
const [visibleWarnings, setVisibleWarnings] = createSignal(false)
+ const [isSharePopupVisible, setIsSharePopupVisible] = createSignal(false)
// stores
const { getWarnings } = useWarningsStore()
const { session } = useAuthStore()
@@ -48,14 +48,11 @@ export const Header = (props: Props) => {
// methods
const toggleWarnings = () => setVisibleWarnings(!visibleWarnings())
- const toggleFixed = () => setFixed(!fixed())
+ const toggleFixed = () => setFixed((oldFixed) => !oldFixed)
// effects
createEffect(() => {
- const isFixed = fixed() || (getModal() && getModal() !== 'share');
-
- document.body.classList.toggle('fixed', isFixed);
- document.body.classList.toggle(styles.fixed, isFixed && !getModal());
- }, [fixed(), getModal()])
+ document.body.classList.toggle('fixed', fixed() || getModal() !== null)
+ })
// derived
const authorized = createMemo(() => session()?.user?.slug)
@@ -90,7 +87,7 @@ export const Header = (props: Props) => {
classList={{
[styles.headerFixed]: props.isHeaderFixed,
[styles.headerScrolledTop]: !getIsScrollingBottom() && getIsScrolled(),
- [styles.headerScrolledBottom]: getIsScrollingBottom() && getIsScrolled(),
+ [styles.headerScrolledBottom]: (getIsScrollingBottom() && getIsScrolled()) || isSharePopupVisible(),
[styles.headerWithTitle]: Boolean(props.title)
}}
>
@@ -99,41 +96,6 @@ export const Header = (props: Props) => {
-
-
diff --git a/src/components/Nav/Popup.module.scss b/src/components/Nav/Popup.module.scss
index 63405563..d62d1c09 100644
--- a/src/components/Nav/Popup.module.scss
+++ b/src/components/Nav/Popup.module.scss
@@ -1,6 +1,13 @@
+.container {
+ position: relative;
+}
+
.popup {
background: #fff;
border: 2px solid #000;
+ top: calc(100% + 8px);
+ transform: translateX(-50%);
+ opacity: 1;
@include font-size(1.6rem);
@@ -24,6 +31,7 @@
a {
border: none;
+ white-space: nowrap;
}
img {
@@ -40,7 +48,15 @@
}
}
-.popupShare {
- right: 1em;
- top: 4.5rem;
-}
+// TODO: animation
+// .popup {
+// opacity: 1;
+// transition: opacity 0.3s;
+// z-index: 1;
+// &.visible {
+// opacity: 0;
+// transition: opacity 0.3s, z-index 0s 0.3s;
+// z-index: -1;
+// }
+// }
+
diff --git a/src/components/Nav/Popup.tsx b/src/components/Nav/Popup.tsx
index 451caf88..a53517cf 100644
--- a/src/components/Nav/Popup.tsx
+++ b/src/components/Nav/Popup.tsx
@@ -1,33 +1,50 @@
-import { createEffect, createSignal, onMount, Show } from 'solid-js'
-import style from './Popup.module.scss'
-import { hideModal, useModalStore } from '../../stores/ui'
-import {clsx} from 'clsx';
+import { createEffect, createSignal, JSX, onCleanup, onMount, Show } from 'solid-js'
+import styles from './Popup.module.scss'
+import { clsx } from 'clsx'
-interface PopupProps {
- name: string
- children: any
- class?: string
+export type PopupProps = {
+ containerCssClass?: string
+ trigger: JSX.Element
+ children: JSX.Element
+ onVisibilityChange?: (isVisible) => void
}
export const Popup = (props: PopupProps) => {
- const { getModal } = useModalStore()
+ const [isVisible, setIsVisible] = createSignal(false)
+
+ createEffect(() => {
+ if (props.onVisibilityChange) {
+ props.onVisibilityChange(isVisible())
+ }
+ })
+
+ let container: HTMLDivElement | undefined
+
+ const handleClickOutside = (event: MouseEvent & { target: Element }) => {
+ if (!isVisible()) {
+ return
+ }
+
+ if (event.target === container || container?.contains(event.target)) {
+ return
+ }
+
+ setIsVisible(false)
+ }
onMount(() => {
- window.addEventListener('keydown', (e: KeyboardEvent) => {
- if (e.key === 'Escape') hideModal()
- })
- })
-
- const [visible, setVisible] = createSignal(false)
- createEffect(() => {
- setVisible(getModal() === props.name)
+ document.addEventListener('click', handleClickOutside, { capture: true })
+ onCleanup(() => document.removeEventListener('click', handleClickOutside, { capture: true }))
})
+ const toggle = () => setIsVisible((oldVisible) => !oldVisible)
+ // class={clsx(styles.popupShare, stylesPopup.popupShare)}
return (
-
-
-
+
+ {props.trigger}
+
+
+
+
)
}
diff --git a/src/stores/ui.ts b/src/stores/ui.ts
index 39d4c717..e36e48c7 100644
--- a/src/stores/ui.ts
+++ b/src/stores/ui.ts
@@ -5,7 +5,7 @@ import { createSignal } from 'solid-js'
//export const locale = persistentAtom('locale', 'ru')
export const [locale, setLocale] = createSignal('ru')
-export type ModalType = 'auth' | 'subscribe' | 'feedback' | 'share' | 'thank' | 'donate' | null
+export type ModalType = 'auth' | 'subscribe' | 'feedback' | 'thank' | 'donate' | null
type WarnKind = 'error' | 'warn' | 'info'
export interface Warning {
@@ -20,7 +20,6 @@ const warnings = atom([])
export const showModal = (modalType: ModalType) => modal.set(modalType)
export const hideModal = () => modal.set(null)
-export const toggleModal = (modalType) => modal.get() ? hideModal() : showModal(modalType)
export const clearWarns = () => warnings.set([])
export const warn = (warning: Warning) => warnings.set([...warnings.get(), warning])