Skip to content

Commit

Permalink
merge collect 3.0 changes (#2679)
Browse files Browse the repository at this point in the history
* feat(tabs): implement tabs controller

feat(tabs): implement tabs controller

* fix(tabs): remove BaseTab from test

* fix(tabs): correct disabled test to check child button

* fix(tabs): dispatch event when active property changes on tab

* fix(tabs): dispatch  event only when changing from false to true

* fix(tabs): add dynamic tab demo

* fix(tabs): update RTI if tab is disabled

* refactor(tabs): mutation observer

* fix(tabs): demo js link

* fix(tabs): add TabsController to exports remove Base classes

* fix(tabs): update active tab onTabExpand

* fix(core): update overflow when childList updates

* fix(tabs): reduce mutation observer scope

* fix(tabs): add missing activeIndex getter

* fix(tabs): fix bug with tab button before styles on box variant

* chore(tabs): remove whitespace

* fix(core): undo uneeded change to RTI controller

* chore(tabs): add changeset

* chore(core): add changeset

* fix(tabs): remove base styles files

* docs(tabs): add additional documentation

* chore(tabs): update changeset

* docs(tabs): add set activeIndex jsDoc

* fix(tabs): refactor mutations callback

* fix(tabs): add override keyword

* fix(tabs): add override keyword to panel

* test(tabs): improve disabled tab testing

* refactor(tabs): check event instanceof type in static method

* docs(tabs): add active state to nested demo

* refactor(tabs): making validation methods required

* fix(tabs): additional public api

* test(tabs): refactor tab tests using nested describes

* feat(core): add tabs-controller

* fix(tabs): relink tabs controller from core

* fix(tabs): remove TabsController

* chore(tabs): update changeset

* chore(core): update changeset

* fix(tabs): remove TabsController from element package exports

* fix(core): add tabs-controller to package exports

* chore(tabs): update changeset

* fix(tabs): revert removal of base classes

* fix(tabs): re-add isExpandEvent

* chore(tabs): add changeset

* docs: update changesets

* feat(core): loosen logger host type

* docs: changeset

* docs(tabs): split up demos

* fix(tabs): loosen type of host for tabscontroller

* refactor(tabs): docs and ordering

* chore(tabs): remove commented out code

* test(tabs): remove unused aTimeout

* docs(tabs): fix inset demo

* fix(tabs): linting no aria- on slots

* docs(tabs): unify demo styles, fixing overflow

---------

Co-authored-by: Benny Powers <[email protected]>
  • Loading branch information
zeroedin and bennypowers authored Jan 22, 2024
1 parent 52076cb commit fa50164
Show file tree
Hide file tree
Showing 29 changed files with 1,233 additions and 237 deletions.
5 changes: 5 additions & 0 deletions .changeset/hip-bags-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@patternfly/elements": minor
---

`<pf-tabs>`: improved overflow handling, added dynamic tab creation support
4 changes: 4 additions & 0 deletions .changeset/logger-host-loose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
"@patternfly/pfe-core": minor
---
`Logger`: loosen the type of allowed controller hosts
5 changes: 5 additions & 0 deletions .changeset/overflow-controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@patternfly/core": minor
---

`OverflowController`: recalculate overflow when the window size changes and when tabs are dynamically created.
15 changes: 15 additions & 0 deletions .changeset/tabs-controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@patternfly/core": minor
---

`TabsController`: Added TabsController. This controller is used to manage the state of the tabs and panels.

```ts
#tabs = new TabsController(this, {
isTab: (x: Node): x is PfTab => x instanceof PfTab,
isPanel: (x: Node): x is PfTabPanel => x instanceof PfTabPanel,
});
```

Please review the [Tabs 2.4 to 3.0 migration guide](https://patternflyelements.org/migration/3.0/tabs) for more
information.
57 changes: 49 additions & 8 deletions core/pfe-core/controllers/overflow-controller.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
import type { ReactiveController, ReactiveControllerHost } from 'lit';
import type { ReactiveController, ReactiveElement } from 'lit';

import { isElementInView } from '@patternfly/pfe-core/functions/isElementInView.js';

export interface Options {
/**
* Force hide the scroll buttons regardless of overflow
*/
hideOverflowButtons?: boolean;
/**
* Delay in ms to wait before checking for overflow
*/
scrollTimeoutDelay?: number;
}

export class OverflowController implements ReactiveController {
static #instances = new Set<OverflowController>();

static {
// on resize check for overflows to add or remove scroll buttons
window.addEventListener('resize', () => {
for (const instance of this.#instances) {
instance.onScroll();
}
}, { capture: false });
}

#host: ReactiveElement;
/** Overflow container */
#container?: HTMLElement;
/** Children that can overflow */
#items: HTMLElement[] = [];

#scrollTimeoutDelay = 0;
#scrollTimeoutDelay: number;
#scrollTimeout?: ReturnType<typeof setTimeout>;

/** Default state */
#hideOverflowButtons = false;
#hideOverflowButtons: boolean;

#mo = new MutationObserver(this.#mutationsCallback.bind(this));

showScrollButtons = false;
overflowLeft = false;
overflowRight = false;
Expand All @@ -29,17 +51,32 @@ export class OverflowController implements ReactiveController {
return this.#items.at(-1);
}

constructor(public host: ReactiveControllerHost & Element, private options?: Options) {
this.host.addController(this);
if (options?.hideOverflowButtons) {
this.#hideOverflowButtons = options?.hideOverflowButtons;
constructor(public host: ReactiveElement, private options?: Options) {
this.#hideOverflowButtons = options?.hideOverflowButtons ?? false;
this.#scrollTimeoutDelay = options?.scrollTimeoutDelay ?? 0;
if (host.isConnected) {
OverflowController.#instances.add(this);
}
(this.#host = host).addController(this);
this.#mo.observe(host, { attributes: false, childList: true, subtree: true });
}

async #mutationsCallback(mutations: MutationRecord[]): Promise<void> {
for (const mutation of mutations) {
if (mutation.type === 'childList') {
this.#setOverflowState();
this.#host.requestUpdate();
}
}
}

#setOverflowState(): void {
if (!this.firstItem || !this.lastItem || !this.#container) {
return;
}
const prevLeft = this.overflowLeft;
const prevRight = this.overflowRight;

this.overflowLeft = !this.#hideOverflowButtons && !isElementInView(this.#container, this.firstItem);
this.overflowRight = !this.#hideOverflowButtons && !isElementInView(this.#container, this.lastItem);
let scrollButtonsWidth = 0;
Expand All @@ -48,7 +85,11 @@ export class OverflowController implements ReactiveController {
}
this.showScrollButtons = !this.#hideOverflowButtons &&
this.#container.scrollWidth > (this.#container.clientWidth + scrollButtonsWidth);
this.host.requestUpdate();

// only request update if there has been a change
if ((prevLeft !== this.overflowLeft) || (prevRight !== this.overflowRight)) {
this.host.requestUpdate();
}
}

init(container: HTMLElement, items: HTMLElement[]) {
Expand Down
Loading

0 comments on commit fa50164

Please sign in to comment.