Skip to content
Snippets Groups Projects
Select Git revision
  • 8ca8e81fe7fab371ecf4a4b934bd9227378645f0
  • main default protected
  • renovate/lock-file-maintenance
  • demo protected
  • person-select-custom
  • dbp-translation-component
  • icon-set-mapping
  • port-i18next-parser
  • remove-sentry
  • favorites-and-recent-files
  • revert-6c632dc6
  • lit2
  • advertisement
  • wc-part
  • automagic
  • publish
  • wip-cleanup
  • demo-file-handling
18 results

button.js

Blame
  • button.js 4.26 KiB
    import {html, LitElement, css} from 'lit-element';
    import {ScopedElementsMixin} from '@open-wc/scoped-elements';
    import {MiniSpinner} from './mini-spinner.js';
    import * as commonStyles from '../styles.js';
    
    /**
     * dbp-button implements a button with Bulma styles and automatic spinner and
     * disabling if button is clicked
     *
     * Use the attribute "no-spinner-on-click" to disable the spinner, then you can
     * start it with start() and stop it with stop()
     *
     * Type can be is-primary/is-info/is-success/is-warning/is-danger
     */
    export class Button extends ScopedElementsMixin(LitElement) {
        constructor() {
            super();
            this.value = "";
            this.type = "";
            this.spinner = false;
            this.noSpinnerOnClick = false;
            this.disabled = false;
        }
    
        static get scopedElements() {
            return {
                'dbp-mini-spinner': MiniSpinner,
            };
        }
    
        connectedCallback() {
            super.connectedCallback();
        }
    
        static get properties() {
            return {
                value: { type: String },
                type: { type: String },
                spinner: { type: Boolean },
                noSpinnerOnClick: { type: Boolean, attribute: 'no-spinner-on-click' },
                disabled: { type: Boolean, reflect: true },
            };
        }
    
        clickHandler() {
            if (!this.noSpinnerOnClick) {
                this.start();
            }
        }
    
        start() {
            this.spinner = true;
            this.disabled = true;
        }
    
        stop() {
            this.spinner = false;
            this.disabled = false;
        }
    
        isDisabled() {
            return this.disabled;
        }
    
        static get styles() {
            // language=css
            return css`
                ${commonStyles.getThemeCSS()}
                ${commonStyles.getButtonCSS()}
    
                .spinner { margin-left: 0.5em; }
            `;
        }
    
        render() {
            return html`
                <button @click="${this.clickHandler}" class="button ${this.type}" ?disabled="${this.disabled}">
                    ${this.value} <dbp-mini-spinner class="spinner" style="display: ${this.spinner ? "inline" : "none"}"></dbp-mini-spinner>
                </button>
            `;
        }
    }
    
    export class LoadingButton extends ScopedElementsMixin(LitElement) {
        constructor() {
            super();
            this.value = "";
            this.type = "";
            this.loading = false;
            this.disabled = false;
    
            // https://bugs.chromium.org/p/chromium/issues/detail?id=1061240#c12
            this.addEventListener('click', (e) => {
                if (this.disabled) {
                  e.stopImmediatePropagation();
                }
            });
        }
    
        static get scopedElements() {
            return {
                'dbp-mini-spinner': MiniSpinner,
            };
        }
    
        static get properties() {
            return {
                // value is deprecated, use the main slot instead
                value: { type: String },
                type: { type: String },
                loading: { type: Boolean },
                disabled: { type: Boolean, reflect: true },
            };
        }
    
        start() {
            this.loading = true;
            this.disabled = true;
        }
    
        stop() {
            this.loading = false;
            this.disabled = false;
        }
    
        static get styles() {
            // language=css
            return css`
                ${commonStyles.getThemeCSS()}
                ${commonStyles.getButtonCSS()}
    
                .spinner {
                    padding-left: 0.5em;
                    min-width: 16px;
                }
    
                .loading-container {
                    display: flex;
                    align-items: baseline;
                }
    
                .label {
                    white-space: nowrap;
                    overflow: hidden;
                    text-overflow: ellipsis;
                }
    
                :host {
                    display: inline-block;
                }
    
                .is-not-loading .label {
                    padding-left: 12px;
                    padding-right: 12px;
                }
    
                .button {
                    width: 100%;
                }
            `;
        }
    
        render() {
            return html`
                <button class="button ${this.type} loading-container ${!this.loading ? "is-not-loading" : ""}" ?disabled="${this.disabled}">
                   <div class="label"><slot>${this.value}</slot></div> <dbp-mini-spinner class="spinner" style="display: ${this.loading ? "inline" : "none"}"></dbp-mini-spinner>
                </button>
            `;
        }
    }