From f1b1c46aabb23341cb60278c968715a5be5fb152 Mon Sep 17 00:00:00 2001 From: Thijs Louisse Date: Wed, 8 Nov 2023 18:44:33 +0100 Subject: [PATCH] chore: fix for lint-versions script --- .../collapsible/assets/CustomCollapsible.js | 115 ++++++++++++++++++ scripts/lint-versions.js | 4 + 2 files changed, 119 insertions(+) create mode 100644 packages/ui/docs/components/collapsible/assets/CustomCollapsible.js diff --git a/packages/ui/docs/components/collapsible/assets/CustomCollapsible.js b/packages/ui/docs/components/collapsible/assets/CustomCollapsible.js new file mode 100644 index 000000000..a2b736559 --- /dev/null +++ b/packages/ui/docs/components/collapsible/assets/CustomCollapsible.js @@ -0,0 +1,115 @@ +import { LionCollapsible } from '@lion/ui/collapsible.js'; + +const EVENT = { + TRANSITION_END: 'transitionend', + TRANSITION_START: 'transitionstart', +}; +/** + * `CustomCollapsible` is a class for custom collapsible element (`` web component). + * @customElement custom-collapsible + */ +// @ts-expect-error false positive for incompatible static get properties. Lit-element merges super properties already for you. +export class CustomCollapsible extends LionCollapsible { + static get properties() { + return { + transitioning: { + type: Boolean, + reflect: true, + }, + }; + } + + constructor() { + super(); + this.transitioning = false; + } + + connectedCallback() { + super.connectedCallback(); + this._contentNode?.style.setProperty( + 'transition', + 'max-height 0.35s, padding 0.35s, opacity 0.35s', + ); + if (this.opened) { + this._contentNode?.style.setProperty('padding', '12px 0'); + } + } + + /** + * Wait until transition is finished. + * @override + */ + toggle() { + if (!this.transitioning) { + super.toggle(); + } + } + + /** + * Trigger show animation and wait for transition to be finished. + * @param {Object} options - element node and its options + * @param {HTMLElement} options.contentNode + * @override + */ + async _showAnimation({ contentNode }) { + const expectedHeight = await this.__calculateHeight(contentNode); + contentNode.style.setProperty('opacity', '1'); + contentNode.style.setProperty('padding', '12px 0'); + contentNode.style.setProperty('max-height', '0px'); + // eslint-disable-next-line no-promise-executor-return + await new Promise(resolve => requestAnimationFrame(() => resolve(undefined))); + contentNode.style.setProperty('max-height', expectedHeight); + await this._waitForTransition({ contentNode }); + } + + /** + * Trigger hide animation and wait for transition to be finished. + * @param {Object} options - element node and its options + * @param {HTMLElement} options.contentNode + * @override + */ + async _hideAnimation({ contentNode }) { + if (this._contentHeight === '0px') { + return; + } + ['opacity', 'padding', 'max-height'].map(prop => contentNode.style.setProperty(prop, '0')); + await this._waitForTransition({ contentNode }); + } + + /** + * Wait until the transition event is finished. + * @param {Object} options - element node and its options + * @param {HTMLElement} options.contentNode + * @returns {Promise} transition event + */ + _waitForTransition({ contentNode }) { + return new Promise(resolve => { + const transitionStarted = () => { + contentNode.removeEventListener(EVENT.TRANSITION_START, transitionStarted); + this.transitioning = true; + }; + contentNode.addEventListener(EVENT.TRANSITION_START, transitionStarted); + + const transitionEnded = () => { + contentNode.removeEventListener(EVENT.TRANSITION_END, transitionEnded); + this.transitioning = false; + resolve(); + }; + contentNode.addEventListener(EVENT.TRANSITION_END, transitionEnded); + }); + } + + /** + * Calculate total content height after collapsible opens + * @param {HTMLElement} contentNode content node + * @private + */ + async __calculateHeight(contentNode) { + contentNode.style.setProperty('max-height', ''); + // eslint-disable-next-line no-promise-executor-return + await new Promise(resolve => requestAnimationFrame(() => resolve(undefined))); + return this._contentHeight; // Expected height i.e. actual size once collapsed after animation + } +} + +customElements.define('custom-collapsible', CustomCollapsible); diff --git a/scripts/lint-versions.js b/scripts/lint-versions.js index 8b38ecf05..c4914dd4a 100644 --- a/scripts/lint-versions.js +++ b/scripts/lint-versions.js @@ -50,6 +50,10 @@ function compareVersions(versionsA, versionsB) { let output = ''; const newVersions = { ...versionsA }; Object.keys(versionsB).forEach(dep => { + // we accept different versions of glob for node packages + if (dep === 'glob') { + return; + } if (versionsA[dep] && versionsB[dep] && versionsA[dep] !== versionsB[dep]) { if (!semver.satisfies(versionsA[dep], versionsB[dep])) { // if version doesn't satisfy range, check if they are both ranges,