mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
Et2VfsPath: Better overflow handling, including arrow buttons when needed
This commit is contained in:
parent
83cf428077
commit
ee5f202f35
@ -3,6 +3,7 @@ import {css} from 'lit';
|
|||||||
export default css`
|
export default css`
|
||||||
|
|
||||||
.form-control-input {
|
.form-control-input {
|
||||||
|
position: relative;
|
||||||
min-width: 15em;
|
min-width: 15em;
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -61,14 +62,31 @@ export default css`
|
|||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Breadcrumb directories */
|
.vfs-path__scroll {
|
||||||
|
|
||||||
sl-breadcrumb {
|
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
min-width: 10em;
|
min-width: 10em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-control-input sl-icon-button[name*="caret"] {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
background: var(--sl-input-background-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control-input sl-icon-button[name*="caret"]:last-of-type {
|
||||||
|
right: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(:hover) .form-control-input.vfs-path__overflow sl-icon-button[name*="caret"] {
|
||||||
|
display: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Breadcrumb directories */
|
||||||
|
|
||||||
|
sl-breadcrumb {
|
||||||
|
}
|
||||||
|
|
||||||
et2-image {
|
et2-image {
|
||||||
flex: none;
|
flex: none;
|
||||||
height: 1.5em;
|
height: 1.5em;
|
||||||
@ -76,8 +94,6 @@ export default css`
|
|||||||
|
|
||||||
sl-breadcrumb::part(base) {
|
sl-breadcrumb::part(base) {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
flex-direction: row-reverse;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sl-breadcrumb-item::part(base) {
|
sl-breadcrumb-item::part(base) {
|
||||||
@ -95,15 +111,15 @@ export default css`
|
|||||||
}
|
}
|
||||||
|
|
||||||
sl-breadcrumb-item:first-of-type {
|
sl-breadcrumb-item:first-of-type {
|
||||||
margin-right: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sl-breadcrumb-item:first-of-type::part(separator) {
|
sl-breadcrumb-item:first-of-type::part(separator) {
|
||||||
display: none;
|
display: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
sl-breadcrumb-item:last-of-type::part(separator) {
|
sl-breadcrumb-item:last-of-type::part(separator) {
|
||||||
display: initial;
|
/* Trailing / */
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sizes */
|
/* Sizes */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
||||||
import {html, LitElement, nothing, TemplateResult} from "lit";
|
import {html, LitElement, nothing, PropertyValues, TemplateResult} from "lit";
|
||||||
import shoelace from "../Styles/shoelace";
|
import shoelace from "../Styles/shoelace";
|
||||||
import styles from "./Et2VfsPath.styles";
|
import styles from "./Et2VfsPath.styles";
|
||||||
import {property} from "lit/decorators/property.js";
|
import {property} from "lit/decorators/property.js";
|
||||||
@ -71,6 +71,13 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
|
|||||||
this.handlePathClick = this.handlePathClick.bind(this);
|
this.handlePathClick = this.handlePathClick.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updated(changedProperties : PropertyValues)
|
||||||
|
{
|
||||||
|
super.updated(changedProperties);
|
||||||
|
|
||||||
|
this.checkPathOverflow();
|
||||||
|
}
|
||||||
|
|
||||||
@property()
|
@property()
|
||||||
set value(_value : string)
|
set value(_value : string)
|
||||||
{
|
{
|
||||||
@ -138,6 +145,30 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected checkPathOverflow()
|
||||||
|
{
|
||||||
|
const wrapper = this.shadowRoot.querySelector(".vfs-path__scroll");
|
||||||
|
const path = wrapper?.querySelector("sl-breadcrumb");
|
||||||
|
const scroll = path?.shadowRoot.querySelector("nav");
|
||||||
|
if(!wrapper || !scroll)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
path.updateComplete.then(() =>
|
||||||
|
{
|
||||||
|
if(wrapper.clientWidth < scroll.scrollWidth)
|
||||||
|
{
|
||||||
|
// Too small
|
||||||
|
wrapper.scrollLeft = scroll.scrollWidth - wrapper.clientWidth;
|
||||||
|
wrapper.parentElement.classList.add("vfs-path__overflow");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wrapper.parentElement.classList.remove("vfs-path__overflow");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected handleLabelClick()
|
protected handleLabelClick()
|
||||||
{
|
{
|
||||||
this.edit();
|
this.edit();
|
||||||
@ -185,7 +216,7 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
const dirs = Array.from(target.parentElement.querySelectorAll('sl-breadcrumb-item')).reverse() ?? [];
|
const dirs = Array.from(target.parentElement.querySelectorAll('sl-breadcrumb-item')) ?? [];
|
||||||
let stopIndex = dirs.indexOf(target) + 1;
|
let stopIndex = dirs.indexOf(target) + 1;
|
||||||
let newPath = dirs.slice(0, stopIndex)
|
let newPath = dirs.slice(0, stopIndex)
|
||||||
// Strip out any extra space
|
// Strip out any extra space
|
||||||
@ -228,7 +259,7 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
|
|||||||
|
|
||||||
protected handleScroll(event : WheelEvent)
|
protected handleScroll(event : WheelEvent)
|
||||||
{
|
{
|
||||||
this.shadowRoot.querySelector("sl-breadcrumb").scrollLeft += event.deltaY;
|
this.shadowRoot.querySelector(".vfs-path__scroll").scrollLeft += event.deltaY;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _getIcon(pathParts)
|
protected _getIcon(pathParts)
|
||||||
@ -242,9 +273,8 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected pathPartTemplate(pathParts, path, i)
|
protected pathPartTemplate(pathParts, path, index)
|
||||||
{
|
{
|
||||||
let index = pathParts.length - 1 - i;
|
|
||||||
let pathName : string | TemplateResult<1> = path.trim();
|
let pathName : string | TemplateResult<1> = path.trim();
|
||||||
if(pathParts.length > 1 && pathParts[1] == "apps")
|
if(pathParts.length > 1 && pathParts[1] == "apps")
|
||||||
{
|
{
|
||||||
@ -310,6 +340,13 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
|
|||||||
</label>
|
</label>
|
||||||
<div part="form-control-input" class="form-control-input"
|
<div part="form-control-input" class="form-control-input"
|
||||||
@click=${() => this.focus()}
|
@click=${() => this.focus()}
|
||||||
|
@mouseout=${(e) =>
|
||||||
|
{
|
||||||
|
if(e.target.classList.contains("form-control-input"))
|
||||||
|
{
|
||||||
|
this.checkPathOverflow();
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<slot part="prefix" name="prefix">
|
<slot part="prefix" name="prefix">
|
||||||
${icon ? html`
|
${icon ? html`
|
||||||
@ -334,14 +371,30 @@ export class Et2VfsPath extends Et2InputWidget(LitElement)
|
|||||||
@keydown=${this.handleKeyDown}
|
@keydown=${this.handleKeyDown}
|
||||||
/>
|
/>
|
||||||
<div class="vfs-path__edit"/>` : html`
|
<div class="vfs-path__edit"/>` : html`
|
||||||
|
<sl-icon-button name="caret-left"
|
||||||
|
@click=${(e) =>
|
||||||
|
{
|
||||||
|
e.stopPropagation();
|
||||||
|
this.handleScroll({deltaY: -20})
|
||||||
|
}}></sl-icon-button>
|
||||||
|
<div class="vfs-path__scroll"
|
||||||
|
@wheel=${this.handleScroll}
|
||||||
|
>
|
||||||
<sl-breadcrumb
|
<sl-breadcrumb
|
||||||
label=${this.label || this.egw().lang("path")}
|
label=${this.label || this.egw().lang("path")}
|
||||||
class="vfs-path__breadcrumb"
|
class="vfs-path__breadcrumb"
|
||||||
@click=${this.handlePathClick}
|
@click=${this.handlePathClick}
|
||||||
>
|
>
|
||||||
<span slot="separator">/</span>
|
<span slot="separator">/</span>
|
||||||
${repeat(pathParts.toReversed(), (part, i) => this.pathPartTemplate(pathParts, part, i))}
|
${repeat(pathParts, (part, i) => this.pathPartTemplate(pathParts, part, i))}
|
||||||
</sl-breadcrumb>
|
</sl-breadcrumb>
|
||||||
|
</div>
|
||||||
|
<sl-icon-button name="caret-right"
|
||||||
|
@click=${(e) =>
|
||||||
|
{
|
||||||
|
e.stopPropagation();
|
||||||
|
this.handleScroll({deltaY: 20})
|
||||||
|
}}></sl-icon-button>
|
||||||
${!isEditable ? nothing : html`
|
${!isEditable ? nothing : html`
|
||||||
<button
|
<button
|
||||||
part="edit-button"
|
part="edit-button"
|
||||||
|
Loading…
Reference in New Issue
Block a user