Skip to content

Commit

Permalink
WIP resize observer component. Did not fit into initial POC, but will…
Browse files Browse the repository at this point in the history
… reevaluate in tables.
  • Loading branch information
dgibson666 committed Dec 19, 2024
1 parent e14a940 commit a89d7f5
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ export const CbpHide = /*@__PURE__*/createReactComponent<JSX.CbpHide, HTMLCbpHid
export const CbpIcon = /*@__PURE__*/createReactComponent<JSX.CbpIcon, HTMLCbpIconElement>('cbp-icon');
export const CbpLink = /*@__PURE__*/createReactComponent<JSX.CbpLink, HTMLCbpLinkElement>('cbp-link');
export const CbpList = /*@__PURE__*/createReactComponent<JSX.CbpList, HTMLCbpListElement>('cbp-list');
export const CbpMulticol = /*@__PURE__*/createReactComponent<JSX.CbpMulticol, HTMLCbpMulticolElement>('cbp-multicol');
export const CbpNavItem = /*@__PURE__*/createReactComponent<JSX.CbpNavItem, HTMLCbpNavItemElement>('cbp-nav-item');
export const CbpNotice = /*@__PURE__*/createReactComponent<JSX.CbpNotice, HTMLCbpNoticeElement>('cbp-notice');
export const CbpPagination = /*@__PURE__*/createReactComponent<JSX.CbpPagination, HTMLCbpPaginationElement>('cbp-pagination');
export const CbpPanel = /*@__PURE__*/createReactComponent<JSX.CbpPanel, HTMLCbpPanelElement>('cbp-panel');
export const CbpRadio = /*@__PURE__*/createReactComponent<JSX.CbpRadio, HTMLCbpRadioElement>('cbp-radio');
export const CbpResizeObserver = /*@__PURE__*/createReactComponent<JSX.CbpResizeObserver, HTMLCbpResizeObserverElement>('cbp-resize-observer');
export const CbpSection = /*@__PURE__*/createReactComponent<JSX.CbpSection, HTMLCbpSectionElement>('cbp-section');
export const CbpSegmentedButtonGroup = /*@__PURE__*/createReactComponent<JSX.CbpSegmentedButtonGroup, HTMLCbpSegmentedButtonGroupElement>('cbp-segmented-button-group');
export const CbpSkipNav = /*@__PURE__*/createReactComponent<JSX.CbpSkipNav, HTMLCbpSkipNavElement>('cbp-skip-nav');
Expand All @@ -52,6 +54,7 @@ export const CbpTable = /*@__PURE__*/createReactComponent<JSX.CbpTable, HTMLCbpT
export const CbpTabs = /*@__PURE__*/createReactComponent<JSX.CbpTabs, HTMLCbpTabsElement>('cbp-tabs');
export const CbpTag = /*@__PURE__*/createReactComponent<JSX.CbpTag, HTMLCbpTagElement>('cbp-tag');
export const CbpToast = /*@__PURE__*/createReactComponent<JSX.CbpToast, HTMLCbpToastElement>('cbp-toast');
export const CbpToggle = /*@__PURE__*/createReactComponent<JSX.CbpToggle, HTMLCbpToggleElement>('cbp-toggle');
export const CbpTooltip = /*@__PURE__*/createReactComponent<JSX.CbpTooltip, HTMLCbpTooltipElement>('cbp-tooltip');
export const CbpTypography = /*@__PURE__*/createReactComponent<JSX.CbpTypography, HTMLCbpTypographyElement>('cbp-typography');
export const CbpUniversalHeader = /*@__PURE__*/createReactComponent<JSX.CbpUniversalHeader, HTMLCbpUniversalHeaderElement>('cbp-universal-header');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cbp-resize-observer {
max-width: 100%;
display: inline-block;
overflow: visible;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Component, Element, Prop, Event, EventEmitter, Host, h } from '@stencil/core';

/**
* @slot - any markup or content may be placed in the default slot.
*/
@Component({
tag: 'cbp-resize-observer',
styleUrl: 'cbp-resize-observer.scss'
})
export class CbpResizeObserver {

private observer: ResizeObserver;
private observedEl: Element
//private parentEl: HTMLElement;
//private childEl: HTMLElement;

@Element() host: HTMLElement;

/** Optionally specify a selector with which to query the closest matching parent of the host tag to observe. */
@Prop() parent: string;

/** Optionally specify a selector with which to query the a child of the host tag to observe. */
@Prop() child: string;

/** A custom event emitted when the click event occurs for either a rendered button or anchor/link. */
@Event() resized!: EventEmitter;


async getCurrentSize() {
return this.getClientRect();
}
getClientRect() {
return this.host.getBoundingClientRect();
}


componentDidLoad() {
// TODO: still need to figure out what comparisons are useful at this level - parent or children
const children = this.host.children;
this.observedEl = this.host; //this.host.querySelector(child) or this.host.closest(parent); ?
/*
ResizeObserver object structure:
Entries[]:
Entries[0]: ResizeObserverEntry (I've never seen more than 1 entry...)
borderBoxSize[]: ResizeObserverSize
contentBoxSize[]: ResizeObserverSize
contentRect: DOMRectReadOnly <- this is what we want
bottom
height
left
right
top
width
x
y
devicePixelContentBoxSize[]: ResizeObserverSize
target
*/
this.observer = new ResizeObserver(([{ contentRect }]) => {
const {width, height, top, bottom, left, right, x, y} = contentRect;
console.log('Resize Observer: ', width, height, children, children[0].getBoundingClientRect());

// TODO: do comparisons, such as to check for overflow (against child? this depends what we're observing)
// When using browser zoom, the numbers reported back are sometimes sub-pixel and trigger a flickering of the controls; adding +1 fixes this.
/*
if (width+1 > this.wrapper.scrollWidth) {
//
}
else {
//
}
*/


// TechDebt: should this be debounced?
this.resized.emit({
width: width,
height: height,
top: top,
bottom: bottom,
left: left,
right: right,
x: x,
y: y
});

});
this.observer.observe(this.observedEl);
}

disconnectedCallback(){
this.observer.disconnect()
}

render() {
return (
<Host>
<slot />
</Host>
);
}

}

0 comments on commit a89d7f5

Please sign in to comment.