mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-27 21:43:20 +03:00
Position tooltip and edit box in same place. (#1770)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
29058d8c84
commit
e0ea083287
@ -24,7 +24,11 @@
|
||||
|
||||
let modalHTML: HTMLElement
|
||||
let componentInstance: any
|
||||
let show: boolean = false
|
||||
|
||||
let options: {
|
||||
show: boolean
|
||||
direction: string
|
||||
} = { show: false, direction: 'bottom' }
|
||||
|
||||
let component: AnySvelteComponent
|
||||
|
||||
@ -58,7 +62,7 @@
|
||||
|
||||
const fitPopup = (props: PanelProps, contentPanel: HTMLElement): void => {
|
||||
if (modalHTML) {
|
||||
show = fitPopupElement(modalHTML, props.element, contentPanel)
|
||||
options = fitPopupElement(modalHTML, props.element, contentPanel)
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +112,13 @@
|
||||
</div>
|
||||
</div>
|
||||
{#if props.element !== 'content'}
|
||||
<div class="modal-overlay" class:show on:click={() => escapeClose()} on:keydown={() => {}} on:keyup={() => {}} />
|
||||
<div
|
||||
class="modal-overlay"
|
||||
class:show={options.show}
|
||||
on:click={() => escapeClose()}
|
||||
on:keydown={() => {}}
|
||||
on:keyup={() => {}}
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
|
@ -29,9 +29,13 @@
|
||||
|
||||
let modalHTML: HTMLElement
|
||||
let componentInstance: any
|
||||
let show: boolean = false
|
||||
let height: number
|
||||
|
||||
let options: {
|
||||
show: boolean
|
||||
direction: string
|
||||
} = { show: false, direction: 'bottom' }
|
||||
|
||||
function _update (result: any): void {
|
||||
if (onUpdate !== undefined) onUpdate(result)
|
||||
fitPopup()
|
||||
@ -51,7 +55,7 @@
|
||||
|
||||
const fitPopup = (): void => {
|
||||
if (modalHTML) {
|
||||
show = fitPopupElement(modalHTML, element)
|
||||
options = fitPopupElement(modalHTML, element)
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,13 +75,19 @@
|
||||
this={is}
|
||||
bind:this={componentInstance}
|
||||
{...props}
|
||||
direction={options.direction}
|
||||
on:update={(ev) => {
|
||||
_update(ev.detail)
|
||||
}}
|
||||
on:close={(ev) => _close(ev.detail)}
|
||||
/>
|
||||
</div>
|
||||
<div class="modal-overlay" class:antiOverlay={show} style={`z-index: ${zIndex};`} on:click={() => escapeClose()} />
|
||||
<div
|
||||
class="modal-overlay"
|
||||
class:antiOverlay={options.show}
|
||||
style={`z-index: ${zIndex};`}
|
||||
on:click={() => escapeClose()}
|
||||
/>
|
||||
|
||||
<style lang="scss">
|
||||
.popup {
|
||||
|
@ -196,7 +196,7 @@
|
||||
background-color: var(--accent-bg-color);
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: var(--popup-aside-shadow);
|
||||
user-select: none;
|
||||
z-index: 10000;
|
||||
|
||||
@ -285,7 +285,7 @@
|
||||
background-color: var(--accent-bg-color);
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: var(--popup-aside-shadow);
|
||||
user-select: none;
|
||||
z-index: 10000;
|
||||
|
||||
|
@ -117,7 +117,8 @@ export function fitPopupPositionedElement (
|
||||
modalHTML: HTMLElement,
|
||||
alignment: PopupPositionElement,
|
||||
newProps: Record<string, string | number>
|
||||
): boolean {
|
||||
): { show: boolean, direction: string } {
|
||||
let direction: string = ''
|
||||
const rect = alignment.getBoundingClientRect()
|
||||
const rectPopup = modalHTML.getBoundingClientRect()
|
||||
newProps.left = newProps.right = newProps.top = newProps.bottom = ''
|
||||
@ -135,24 +136,30 @@ export function fitPopupPositionedElement (
|
||||
} else if (alignment.position.h === 'left') {
|
||||
newProps.left = `calc(${rect.left - rectPopup.width}px - .125rem)`
|
||||
}
|
||||
direction = alignment.position.v + '|' + alignment.position.h
|
||||
} else {
|
||||
// Vertical
|
||||
if (rect.bottom + rectPopup.height + 28 <= document.body.clientHeight) {
|
||||
newProps.top = `${rect.bottom + 1}px`
|
||||
direction = 'bottom'
|
||||
} else if (rectPopup.height + 28 < rect.top) {
|
||||
newProps.bottom = `${document.body.clientHeight - rect.top + 1}px`
|
||||
direction = 'top'
|
||||
} else {
|
||||
newProps.top = modalHTML.style.bottom = '1rem'
|
||||
direction = 'top'
|
||||
}
|
||||
|
||||
// Horizontal
|
||||
if (rect.left + rectPopup.width + 16 > document.body.clientWidth) {
|
||||
newProps.right = `${document.body.clientWidth - rect.right}px`
|
||||
direction += '|left'
|
||||
} else {
|
||||
newProps.left = `${rect.left}px`
|
||||
direction += '|right'
|
||||
}
|
||||
}
|
||||
return false
|
||||
return { show: false, direction }
|
||||
}
|
||||
|
||||
function applyStyle (values: Record<string, string | number>, modalHTML: HTMLElement): void {
|
||||
@ -171,7 +178,11 @@ function applyStyle (values: Record<string, string | number>, modalHTML: HTMLEle
|
||||
*
|
||||
* return boolean to show or not modal overlay.
|
||||
*/
|
||||
export function fitPopupElement (modalHTML: HTMLElement, element?: PopupAlignment, contentPanel?: HTMLElement): boolean {
|
||||
export function fitPopupElement (
|
||||
modalHTML: HTMLElement,
|
||||
element?: PopupAlignment,
|
||||
contentPanel?: HTMLElement
|
||||
): { show: boolean, direction: string } {
|
||||
let show = true
|
||||
const newProps: Record<string, string | number> = {}
|
||||
if (element != null) {
|
||||
@ -238,7 +249,7 @@ export function fitPopupElement (modalHTML: HTMLElement, element?: PopupAlignmen
|
||||
show = true
|
||||
}
|
||||
applyStyle(newProps, modalHTML)
|
||||
return show
|
||||
return { show, direction: '' }
|
||||
}
|
||||
|
||||
export function eventToHTMLElement (evt: MouseEvent): HTMLElement {
|
||||
|
@ -1,11 +1,11 @@
|
||||
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
|
||||
// It should be published with your NPM package. It should not be tracked by Git.
|
||||
{
|
||||
"tsdocVersion": "0.12",
|
||||
"toolPackages": [
|
||||
{
|
||||
"packageName": "@microsoft/api-extractor",
|
||||
"packageVersion": "7.23.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
|
||||
// It should be published with your NPM package. It should not be tracked by Git.
|
||||
{
|
||||
"tsdocVersion": "0.12",
|
||||
"toolPackages": [
|
||||
{
|
||||
"packageName": "@microsoft/api-extractor",
|
||||
"packageVersion": "7.23.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import { createEventDispatcher, onMount, afterUpdate } from 'svelte'
|
||||
import type { IntlString } from '@anticrm/platform'
|
||||
import { translate } from '@anticrm/platform'
|
||||
import {
|
||||
@ -34,6 +34,7 @@
|
||||
export let placeholder: IntlString
|
||||
export let editable: boolean | undefined = undefined
|
||||
export let openable: boolean = false
|
||||
export let direction: string = 'bottom'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
let input: HTMLInputElement
|
||||
@ -73,11 +74,21 @@
|
||||
$: if (input) {
|
||||
input.addEventListener('focus', updateFocus, { once: true })
|
||||
}
|
||||
|
||||
const vDir = (d: string): string => d.split('|')[0]
|
||||
const fitEditor = (): void => {
|
||||
dir = vDir(direction)
|
||||
}
|
||||
$: dir = vDir(direction)
|
||||
afterUpdate(() => {
|
||||
fitEditor()
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:window on:resize={fitEditor} on:scroll={fitEditor} />
|
||||
<FocusHandler manager={mgr} />
|
||||
{#if editable && editable === true}
|
||||
<div class="editor-container buttons-group xsmall-gap">
|
||||
<div class="editor-container {dir} buttons-group xsmall-gap">
|
||||
<div class="cover-channel" class:show class:copied={label === plugin.string.Copied} data-tooltip={lTraslate}>
|
||||
<input
|
||||
bind:this={input}
|
||||
@ -210,11 +221,47 @@
|
||||
}
|
||||
|
||||
.editor-container {
|
||||
margin-top: 0.25rem;
|
||||
padding: 0.5rem;
|
||||
background-color: var(--accent-bg-color);
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: 0.25rem;
|
||||
box-shadow: var(--popup-panel-shadow);
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: var(--popup-aside-shadow);
|
||||
|
||||
&.top {
|
||||
transform: translate(calc(-50% + 0.75rem), -0.5rem);
|
||||
}
|
||||
&.bottom {
|
||||
transform: translate(calc(-50% + 0.75rem), 0.5rem);
|
||||
}
|
||||
&.top::after,
|
||||
&.top::before,
|
||||
&.bottom::after,
|
||||
&.bottom::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
margin-left: -9px;
|
||||
top: -6px;
|
||||
left: 50%;
|
||||
width: 18px;
|
||||
height: 7px;
|
||||
}
|
||||
&.top::before,
|
||||
&.bottom::before {
|
||||
background-color: var(--accent-bg-color);
|
||||
clip-path: url('#nub-bg');
|
||||
z-index: 1;
|
||||
}
|
||||
&.top::after,
|
||||
&.bottom::after {
|
||||
background-color: var(--divider-color);
|
||||
clip-path: url('#nub-border');
|
||||
z-index: 2;
|
||||
}
|
||||
&.top::after,
|
||||
&.top::before {
|
||||
top: calc(100% - 1px);
|
||||
transform-origin: center center;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user