diff --git a/api/js/etemplate/Et2Button/ButtonMixin.ts b/api/js/etemplate/Et2Button/ButtonMixin.ts index 4d9a56983e..4d668b0b84 100644 --- a/api/js/etemplate/Et2Button/ButtonMixin.ts +++ b/api/js/etemplate/Et2Button/ButtonMixin.ts @@ -130,7 +130,7 @@ export const ButtonMixin = (superclass : T) => class exte /* Override primary styling - we use variant=primary on first dialog button */ .button--standard.button--primary { - background-color: hsl(240deg 5% 96%); + background-color: var(--sl-color-gray-100); border-color: var(--sl-color-gray-400); color: var(--sl-input-color-hover); } diff --git a/api/js/etemplate/Et2Link/Et2LinkAdd.ts b/api/js/etemplate/Et2Link/Et2LinkAdd.ts index f8919c06fe..cdf5b834e9 100644 --- a/api/js/etemplate/Et2Link/Et2LinkAdd.ts +++ b/api/js/etemplate/Et2Link/Et2LinkAdd.ts @@ -1,14 +1,18 @@ import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget"; -import {css, html, LitElement, PropertyValues} from "lit"; +import {css, html, LitElement, nothing} from "lit"; import {Et2LinkAppSelect} from "./Et2LinkAppSelect"; import {LinkInfo} from "./Et2Link"; import {Et2Button} from "../Et2Button/Et2Button"; +import {customElement} from "lit/decorators/custom-element.js"; +import {property} from "lit/decorators/property.js"; +import {classMap} from "lit/directives/class-map.js"; /** * Find and select a single entry using the link system. * * */ +@customElement("et2-link-add") export class Et2LinkAdd extends Et2InputWidget(LitElement) { static get styles() @@ -16,75 +20,34 @@ export class Et2LinkAdd extends Et2InputWidget(LitElement) return [ ...super.styles, css` - :host { - display: block; - border: solid var(--sl-input-border-width) var(--sl-input-border-color); - border-radius: var(--sl-input-border-radius-medium); + .form-control { + display: flex; + align-items: center; + flex-wrap: wrap; + } + + .form-control-input { + display: flex; + flex: 1 1 auto; + position: relative; + max-width: 100%; } ` ]; } - static get properties() - { - return { - ...super.properties, - - /** - * Either an array of LinkInfo (defined in Et2Link.ts) or array with keys to_app and to_id - */ - value: {type: Object}, - /** - * Limit to just this application - hides app selection - */ - application: {type: String}, - /** - * Limit to the listed applications (comma seperated) - */ - applicationList: {type: String} - } - } - - get slots() - { - return { - ...super.slots, - app: () => - { - const app = document.createElement("et2-link-apps"); - app.appIcons = false; - if(this.application) - { - app.onlyApp = this.application; - } - else if(typeof this._value !== "undefined" && this._value.app) - { - app.value = this._value.app; - } - if(this.applicationList) - { - app.applicationList = this.applicationList; - } - return app; - }, - button: () => - { - const button = document.createElement("et2-button"); - button.id = this.id + "_add"; - button.label = this.egw().lang("Add"); - button.noSubmit = true; - - return button; - } - } - } + /** + * Either an array of LinkInfo (defined in Et2Link.ts) or array with keys to_app and to_id + */ + @property({type: Object}) + value : LinkInfo[] & { to_app : string, to_id : string } + /** + * Limit to the listed applications (comma seperated) + */ + @property() + applicationList : string /** - * We only care about this value until render. After the sub-nodes are created, - * we take their "live" values for our value. - * - * N.B.: Single underscore! Otherwise we conflict with parent __value - * * @type {LinkInfo} * @private */ @@ -97,98 +60,35 @@ export class Et2LinkAdd extends Et2InputWidget(LitElement) this.handleButtonClick = this.handleButtonClick.bind(this); } - connectedCallback() - { - super.connectedCallback(); - - // Clear initial value, no longer needed - this._value = undefined; - - this._bindListeners(); - } - - updated(changedProperties : PropertyValues) - { - super.updated(changedProperties); - if(changedProperties.has("readonly")) - { - this._appNode.readonly = this.readonly; - } - // Pass some properties on to app selection - if(changedProperties.has("only_app")) - { - this._appNode.only_app = this.only_app; - } - if(changedProperties.has("applicationList")) - { - this._appNode.applicationList = this.applicationList; - } - if(changedProperties.has("app_icons")) - { - this._appNode.app_icons = this.app_icons; - } - } - + /** + * Limit to just this application - hides app selection + */ + @property() set application(app) { app = app || ""; // If initial value got set before only_app, it still needs app in pre-render value - if(this._value && app) + if(this.value && app) { - this._value.app = app; - } - if(this._appNode) - { - this._appNode.value = app; + this.value.app = app; } + this.requestUpdate("application") } get application() { - if(this._value) - { - return this._value.app; - } - if(this._appNode) - { - return this._appNode.value; - } + return this.value.app; } get _appNode() : Et2LinkAppSelect { - return this.querySelector("[slot='app']"); + return this.shadowRoot.querySelector("et2-link-apps"); } get _buttonNode() : Et2Button { - return this.querySelector("[slot='button']"); - } - - /** - * @return {TemplateResult} - * @protected - */ - _inputGroupInputTemplate() - { - return html` -
- - -
- `; - } - - protected _bindListeners() - { - //this._appNode.addEventListener("change", this._handleAppChange); - this._buttonNode.addEventListener("click", this.handleButtonClick) - } - - protected _unbindListeners() - { - this._buttonNode.removeEventListener("click", this.handleButtonClick) + return this.shadowRoot.querySelector("et2-button"); } /** @@ -199,6 +99,55 @@ export class Et2LinkAdd extends Et2InputWidget(LitElement) { this.egw().open(this.value.to_app + ":" + this.value.to_id, this._appNode.value, 'add'); } -} -customElements.define("et2-link-add", Et2LinkAdd); \ No newline at end of file + render() + { + const hasLabel = this.label ? true : false; + const hasHelpText = this.helpText ? true : false; + const isEditable = !(this.disabled || this.readonly); + + return html` +
+ +
+ + + + +
+
+ `; + } +} \ No newline at end of file diff --git a/api/js/etemplate/Styles/shoelace.ts b/api/js/etemplate/Styles/shoelace.ts index ddd466dffb..4ddca900c1 100644 --- a/api/js/etemplate/Styles/shoelace.ts +++ b/api/js/etemplate/Styles/shoelace.ts @@ -1,4 +1,3 @@ -import sl_css from '@shoelace-style/shoelace/dist/themes/light.styles.js'; import {css} from "lit"; import {registerIconLibrary} from '@shoelace-style/shoelace/dist/utilities/icon-library.js'; @@ -38,26 +37,26 @@ if(typeof egw !== "undefined" && typeof egw.image == "function") * Customise shoelace styles to match our stuff * External CSS & widget styles will override this */ -export default [sl_css, css` +export default [css` :root, :host, .sl-theme-light { - --sl-font-sans: egroupware, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; - --sl-button-font-size-medium: var(--sl-font-size-medium); - --sl-input-help-text-font-size-medium: var(--sl-font-size-medium); - --sl-spacing-small: 0.1rem; - --sl-spacing-medium: 0.5rem; + --sl-font-sans: egroupware, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; + --sl-button-font-size-medium: var(--sl-font-size-medium); + --sl-input-help-text-font-size-medium: var(--sl-font-size-medium); + --sl-spacing-small: 0.1rem; + --sl-spacing-medium: 0.5rem; - --sl-input-border-radius-small: 2px; - --sl-input-border-radius-medium: 3px; - --sl-input-border-color-focus: #E6E6E6; - --indicator-color: #696969; - --sl-input-focus-ring-color: #26537C; - --sl-focus-ring-width: 2px; - --sl-color-gray-150: #f0f0f0; - + --sl-input-border-radius-small: 2px; + --sl-input-border-radius-medium: 3px; + --sl-input-border-color-focus: #E6E6E6; + --indicator-color: #696969; + --sl-input-focus-ring-color: #26537C; + --sl-focus-ring-width: 2px; + --sl-color-gray-150: hsl(240, 4.9%, 92.5%); } - .tab-group--top .tab-group__tabs { + + .tab-group--top .tab-group__tabs { --track-width: 3px; } .form-control--has-label .form-control__label {