From 5f670e404d1b0959c1633768f9a41f4eaae10018 Mon Sep 17 00:00:00 2001 From: Michael Klein Date: Thu, 6 Oct 2022 16:11:39 +0200 Subject: [PATCH] Create dimensions provider To measure the available space of an element when it should take up the "rest" of the page. This matches what `ListCollection` is doing internally but makes the mechanism available in a composable component. --- .../components/providers/dimension/index.hbs | 4 ++ .../components/providers/dimension/index.js | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 ui/packages/consul-ui/app/components/providers/dimension/index.hbs create mode 100644 ui/packages/consul-ui/app/components/providers/dimension/index.js diff --git a/ui/packages/consul-ui/app/components/providers/dimension/index.hbs b/ui/packages/consul-ui/app/components/providers/dimension/index.hbs new file mode 100644 index 0000000000..4d36322965 --- /dev/null +++ b/ui/packages/consul-ui/app/components/providers/dimension/index.hbs @@ -0,0 +1,4 @@ +
+ {{on-window 'resize' this.handleWindowResize}} + {{yield (hash data=this.data)}} +
\ No newline at end of file diff --git a/ui/packages/consul-ui/app/components/providers/dimension/index.js b/ui/packages/consul-ui/app/components/providers/dimension/index.js new file mode 100644 index 0000000000..ebf47545d3 --- /dev/null +++ b/ui/packages/consul-ui/app/components/providers/dimension/index.js @@ -0,0 +1,53 @@ +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; +import { inject as service } from '@ember/service'; +import { ref } from 'ember-ref-bucket'; +import { htmlSafe } from '@ember/template'; + +export default class DimensionsProvider extends Component { + @service dom; + @ref('element') element; + + @tracked height; + + get data() { + const { height, fillRemainingHeightStyle } = this; + + return { + height, + fillRemainingHeightStyle, + }; + } + + get fillRemainingHeightStyle() { + return htmlSafe(`height: ${this.height}px;`); + } + + get bottomBoundary() { + return this.args.bottomBoundary || this.footer; + } + + get footer() { + return document.querySelector('footer[role="contentinfo"]'); + } + + get viewport() { + return this.dom.viewport(); + } + + @action measureDimensions(element) { + const { viewport, bottomBoundary } = this; + + const height = + viewport.innerHeight - (element.getBoundingClientRect().top + bottomBoundary.clientHeight); + + this.height = height; + } + + @action handleWindowResize() { + const { element } = this; + + this.measureDimensions(element); + } +}