2022-02-04 09:03:24 +00:00
|
|
|
import { AnySvelteComponent, AnyComponent, PopupAlignment } from './types'
|
|
|
|
import { getResource } from '@anticrm/platform'
|
|
|
|
import { writable } from 'svelte/store'
|
|
|
|
|
|
|
|
interface CompAndProps {
|
|
|
|
id: string
|
|
|
|
is: AnySvelteComponent
|
|
|
|
props: any
|
|
|
|
element?: PopupAlignment
|
|
|
|
onClose?: (result: any) => void
|
2022-03-17 06:07:38 +00:00
|
|
|
onUpdate?: (result: any) => void
|
2022-02-04 09:03:24 +00:00
|
|
|
close: () => void
|
|
|
|
}
|
|
|
|
|
|
|
|
export const popupstore = writable<CompAndProps[]>([])
|
|
|
|
function addPopup (props: CompAndProps): void {
|
|
|
|
popupstore.update((popups) => {
|
|
|
|
popups.push(props)
|
|
|
|
return popups
|
|
|
|
})
|
|
|
|
}
|
|
|
|
let popupId: number = 0
|
|
|
|
export function showPopup (
|
|
|
|
component: AnySvelteComponent | AnyComponent,
|
|
|
|
props: any,
|
|
|
|
element?: PopupAlignment,
|
2022-03-17 06:07:38 +00:00
|
|
|
onClose?: (result: any) => void,
|
|
|
|
onUpdate?: (result: any) => void
|
2022-02-04 09:03:24 +00:00
|
|
|
): () => void {
|
|
|
|
const id = `${popupId++}`
|
|
|
|
const closePopupOp = (): void => {
|
|
|
|
popupstore.update((popups) => {
|
|
|
|
const pos = popups.findIndex(p => p.id === id)
|
|
|
|
if (pos !== -1) {
|
|
|
|
popups.splice(pos, 1)
|
|
|
|
}
|
|
|
|
return popups
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if (typeof component === 'string') {
|
2022-03-17 06:07:38 +00:00
|
|
|
getResource(component).then((resolved) => addPopup({ id, is: resolved, props, element, onClose, onUpdate, close: closePopupOp })).catch((err) => console.log(err))
|
2022-02-04 09:03:24 +00:00
|
|
|
} else {
|
2022-03-17 06:07:38 +00:00
|
|
|
addPopup({ id, is: component, props, element, onClose, onUpdate, close: closePopupOp })
|
2022-02-04 09:03:24 +00:00
|
|
|
}
|
|
|
|
return closePopupOp
|
|
|
|
}
|
|
|
|
|
|
|
|
export function closePopup (): void {
|
|
|
|
popupstore.update((popups) => {
|
|
|
|
popups.pop()
|
|
|
|
return popups
|
|
|
|
})
|
|
|
|
}
|
2022-04-07 10:02:01 +00:00
|
|
|
|
|
|
|
interface IDatePopup {
|
|
|
|
component: AnySvelteComponent | undefined
|
|
|
|
currentDate: Date | undefined
|
|
|
|
anchor: HTMLElement | undefined
|
|
|
|
popup: HTMLElement | undefined
|
|
|
|
frendlyFocus: HTMLElement[] | undefined
|
|
|
|
onClose?: (result: any) => void
|
|
|
|
onChange?: (result: any) => void
|
|
|
|
}
|
|
|
|
|
|
|
|
export const dpstore = writable<IDatePopup>({
|
|
|
|
component: undefined,
|
|
|
|
currentDate: undefined,
|
|
|
|
anchor: undefined,
|
|
|
|
popup: undefined,
|
|
|
|
frendlyFocus: undefined,
|
|
|
|
onClose: undefined,
|
|
|
|
onChange: undefined
|
|
|
|
})
|
|
|
|
|
|
|
|
export function showDatePopup (
|
|
|
|
component: AnySvelteComponent | undefined,
|
|
|
|
currentDate: Date,
|
|
|
|
anchor?: HTMLElement,
|
|
|
|
popup?: HTMLElement,
|
|
|
|
frendlyFocus?: HTMLElement[] | undefined,
|
|
|
|
onClose?: (result: any) => void,
|
|
|
|
onChange?: (result: any) => void
|
|
|
|
): void {
|
|
|
|
dpstore.set({
|
|
|
|
component: component,
|
|
|
|
currentDate: currentDate,
|
|
|
|
anchor: anchor,
|
|
|
|
popup: popup,
|
|
|
|
frendlyFocus: frendlyFocus,
|
|
|
|
onClose: onClose,
|
|
|
|
onChange: onChange
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
export function closeDatePopup (): void {
|
|
|
|
dpstore.set({
|
|
|
|
component: undefined,
|
|
|
|
currentDate: undefined,
|
|
|
|
anchor: undefined,
|
|
|
|
popup: undefined,
|
|
|
|
frendlyFocus: undefined,
|
|
|
|
onClose: undefined,
|
|
|
|
onChange: undefined
|
|
|
|
})
|
|
|
|
}
|
2022-04-09 16:00:48 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @public
|
|
|
|
*
|
|
|
|
* Place element based on position and underline content element.
|
|
|
|
*
|
|
|
|
* return boolean to show or not modal overlay.
|
|
|
|
*/
|
|
|
|
export function fitPopupElement (modalHTML: HTMLElement, element?: PopupAlignment, contentPanel?: HTMLElement): boolean {
|
|
|
|
let show = true
|
|
|
|
if (element != null) {
|
|
|
|
show = false
|
|
|
|
modalHTML.style.left = modalHTML.style.right = modalHTML.style.top = modalHTML.style.bottom = ''
|
|
|
|
modalHTML.style.maxHeight = modalHTML.style.height = ''
|
|
|
|
if (typeof element !== 'string') {
|
|
|
|
const el = element as HTMLElement
|
|
|
|
const rect = el.getBoundingClientRect()
|
|
|
|
const rectPopup = modalHTML.getBoundingClientRect()
|
|
|
|
// Vertical
|
|
|
|
if (rect.bottom + rectPopup.height + 28 <= document.body.clientHeight) {
|
2022-04-14 11:04:24 +00:00
|
|
|
modalHTML.style.top = `calc(${rect.bottom}px + .125rem)`
|
2022-04-09 16:00:48 +00:00
|
|
|
} else if (rectPopup.height + 28 < rect.top) {
|
2022-04-14 11:04:24 +00:00
|
|
|
modalHTML.style.bottom = `calc(${document.body.clientHeight - rect.y}px + .125rem)`
|
2022-04-09 16:00:48 +00:00
|
|
|
} else {
|
|
|
|
modalHTML.style.top = modalHTML.style.bottom = '1rem'
|
|
|
|
}
|
|
|
|
|
|
|
|
// Horizontal
|
|
|
|
if (rect.left + rectPopup.width + 16 > document.body.clientWidth) {
|
|
|
|
modalHTML.style.right = `${document.body.clientWidth - rect.right}px`
|
|
|
|
} else {
|
|
|
|
modalHTML.style.left = `${rect.left}px`
|
|
|
|
}
|
|
|
|
} else if (element === 'right' && contentPanel !== undefined) {
|
|
|
|
const rect = contentPanel.getBoundingClientRect()
|
|
|
|
modalHTML.style.top = `calc(${rect.top}px + 0.5rem)`
|
|
|
|
modalHTML.style.bottom = '0.75rem'
|
|
|
|
modalHTML.style.right = '0.75rem'
|
|
|
|
show = true
|
|
|
|
} else if (element === 'top') {
|
|
|
|
modalHTML.style.top = '15vh'
|
|
|
|
modalHTML.style.left = '50%'
|
|
|
|
modalHTML.style.transform = 'translateX(-50%)'
|
|
|
|
show = true
|
|
|
|
} else if (element === 'account') {
|
|
|
|
modalHTML.style.bottom = '2.75rem'
|
|
|
|
modalHTML.style.left = '5rem'
|
|
|
|
} else if (element === 'full' && contentPanel !== undefined) {
|
|
|
|
const rect = contentPanel.getBoundingClientRect()
|
|
|
|
modalHTML.style.top = `calc(${rect.top}px + 0.25rem)`
|
|
|
|
modalHTML.style.bottom = '0.25rem'
|
|
|
|
modalHTML.style.left = '0.25rem'
|
|
|
|
modalHTML.style.right = '0.25rem'
|
|
|
|
show = true
|
|
|
|
} else if (element === 'content' && contentPanel !== undefined) {
|
|
|
|
const rect = contentPanel.getBoundingClientRect()
|
|
|
|
modalHTML.style.top = `calc(${rect.top}px)`
|
|
|
|
modalHTML.style.height = `${rect.height}px`
|
|
|
|
modalHTML.style.left = `calc(${rect.left}px)`
|
|
|
|
modalHTML.style.width = `${rect.width}px`
|
|
|
|
} else if (element === 'middle') {
|
|
|
|
if (contentPanel !== undefined) {
|
|
|
|
const rect = contentPanel.getBoundingClientRect()
|
|
|
|
modalHTML.style.top = `calc(${rect.top}px)`
|
|
|
|
} else {
|
|
|
|
modalHTML.style.top = '15%'
|
|
|
|
}
|
|
|
|
modalHTML.style.bottom = '0.75rem'
|
|
|
|
modalHTML.style.left = '50%'
|
|
|
|
modalHTML.style.transform = 'translateX(-50%)'
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
modalHTML.style.top = '50%'
|
|
|
|
modalHTML.style.left = '50%'
|
|
|
|
modalHTML.style.transform = 'translate(-50%, -50%)'
|
|
|
|
show = true
|
|
|
|
}
|
|
|
|
return show
|
|
|
|
}
|