@jupyter/web-components
Version:
A component library for building extensions in Jupyter frontends.
140 lines (139 loc) • 4.33 kB
JavaScript
// Copyright (c) Jupyter Development Team.
// Copyright (c) Microsoft Corporation.
// Distributed under the terms of the Modified BSD License.
import { __decorate } from "tslib";
import { attr, css } from '@microsoft/fast-element';
import { Combobox, comboboxTemplate as template } from '@microsoft/fast-foundation';
import { heightNumberAsToken } from '../design-tokens.js';
import { comboboxStyles as styles } from './combobox.styles.js';
/**
* Combobox class
*
* @public
* @tagname jp-combobox
*
* @fires input - Fires a custom 'input' event when the value has changed
*/
class JupyterCombobox extends Combobox {
/**
* The connected callback for this FASTElement.
*
* @override
*
* @internal
*/
connectedCallback() {
super.connectedCallback();
this.setAutoWidth();
}
/**
* Synchronize the form-associated proxy and updates the value property of the element.
*
* @param prev - the previous collection of slotted option elements
* @param next - the next collection of slotted option elements
*
* @internal
*/
slottedOptionsChanged(prev, next) {
super.slottedOptionsChanged(prev, next);
this.setAutoWidth();
}
/**
* (Un-)set the width when the autoWidth property changes.
*
* @param prev - the previous autoWidth value
* @param next - the current autoWidth value
*/
autoWidthChanged(prev, next) {
if (next) {
this.setAutoWidth();
}
else {
this.style.removeProperty('width');
}
}
/**
* Compute the listbox width to set the one of the input.
*/
setAutoWidth() {
if (!this.autoWidth || !this.isConnected) {
return;
}
let listWidth = this.listbox.getBoundingClientRect().width;
// If the list has not been displayed yet trick to get its size
if (listWidth === 0 && this.listbox.hidden) {
Object.assign(this.listbox.style, { visibility: 'hidden' });
this.listbox.removeAttribute('hidden');
listWidth = this.listbox.getBoundingClientRect().width;
this.listbox.setAttribute('hidden', '');
this.listbox.style.removeProperty('visibility');
}
if (listWidth > 0) {
Object.assign(this.style, { width: `${listWidth}px` });
}
}
/**
* @internal
*/
maxHeightChanged(prev, next) {
this.updateComputedStylesheet();
}
/**
* Updates an internal stylesheet with calculated CSS custom properties.
*
* @internal
*/
updateComputedStylesheet() {
if (this.computedStylesheet) {
this.$fastController.removeStyles(this.computedStylesheet);
}
const popupMaxHeight = Math.floor(this.maxHeight / heightNumberAsToken.getValueFor(this)).toString();
this.computedStylesheet = css `
:host {
--listbox-max-height: ${popupMaxHeight};
}
`;
this.$fastController.addStyles(this.computedStylesheet);
}
}
__decorate([
attr({ attribute: 'autowidth', mode: 'boolean' })
], JupyterCombobox.prototype, "autoWidth", void 0);
__decorate([
attr({ attribute: 'minimal', mode: 'boolean' })
], JupyterCombobox.prototype, "minimal", void 0);
__decorate([
attr
], JupyterCombobox.prototype, "scale", void 0);
/**
* A function that returns a {@link @microsoft/fast-foundation#Combobox} registration for configuring the component with a DesignSystem.
* Implements {@link @microsoft/fast-foundation#comboboxTemplate}
*
* @public
* @remarks
* Generates HTML Element: `<jp-combobox>`
*
*/
export const jpCombobox = JupyterCombobox.compose({
baseName: 'combobox',
baseClass: Combobox,
template,
styles,
shadowOptions: {
delegatesFocus: true
},
indicator: /* html */ `
<svg
class="select-indicator"
part="select-indicator"
viewBox="0 0 12 7"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.85.65c.2.2.2.5 0 .7L6.4 6.84a.55.55 0 01-.78 0L.14 1.35a.5.5 0 11.71-.7L6 5.8 11.15.65c.2-.2.5-.2.7 0z"
/>
</svg>
`
});
export { JupyterCombobox as Combobox };
export { styles as comboboxStyles };