Skip to content

Commit

Permalink
chore: eslint flat config (#2742)
Browse files Browse the repository at this point in the history
* feat(eslint-config)!: flat config

* feat(eslint-plugin)!: flat config

* chore: eslint 9 flat config

* docs: changeset

* fix(tools): update typescript types

* chore: tweak eslint config

* fix(eslint-config): config

* chore: decruft scripts

* style: lint allll the files

* test(card): fix assertions

assertion labels go in the expect call, not in the getComputedStyle call

* test(chip): fix suite setup for keyboard nav

tab to chip group instead of calling focus on it
this may indicate breakage in delegatesFocus

* fix(eslint-config): html plugin

* style: lint html
  • Loading branch information
bennypowers committed Apr 11, 2024
1 parent afac682 commit 65079fb
Show file tree
Hide file tree
Showing 155 changed files with 7,271 additions and 4,720 deletions.
6 changes: 6 additions & 0 deletions .changeset/chilly-plums-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@patternfly/eslint-config-elements": major
"@patternfly/eslint-plugin-elements": major
---

Provide ESLint flat config. Upgrade to ESLint 9.0 to use.
4 changes: 4 additions & 0 deletions .changeset/rude-kiwis-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
"@patternfly/pfe-tools": patch
---
Update typescript types
6 changes: 3 additions & 3 deletions .commitlintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const fs = require("fs");
const path = require("path");
const fs = require('fs');
const path = require('path');
const normalizeWorkspace = x =>
fs.readdirSync(path.join(__dirname, x)).map(x => x.replace('pf-', ''));

Expand All @@ -23,5 +23,5 @@ module.exports = {
...normalizeWorkspace('core'),
...normalizeWorkspace('tools'),
]],
}
},
};
45 changes: 0 additions & 45 deletions .eslintignore

This file was deleted.

13 changes: 0 additions & 13 deletions .eslintrc.json

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ tools/*/test/**/*.png
!scripts/**/*.js

!tools/eslint-plugin/index.js
!tools/eslint-config/**/*.js

*.tgz
custom-elements.json
Expand Down
2 changes: 1 addition & 1 deletion core/pfe-core/controllers/cascade-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class CascadeController<E extends ReactiveElement> implements ReactiveCon

private logger: Logger;

static instances: WeakMap<ReactiveElement, CascadeController<ReactiveElement>> = new WeakMap();
static instances = new WeakMap<ReactiveElement, CascadeController<ReactiveElement>>();

mo = new MutationObserver(this.parse);

Expand Down
2 changes: 1 addition & 1 deletion core/pfe-core/controllers/css-variable-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ export class CssVariableController implements ReactiveController {
return this.style.getPropertyValue(this.parseProperty(name)).trim() || null;
}

hostConnected?(): void
hostConnected?(): void;
}
18 changes: 14 additions & 4 deletions core/pfe-core/controllers/floating-dom-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
offset as offsetMiddleware,
shift as shiftMiddleware,
flip as flipMiddleware,
arrow as arrowMiddleware
arrow as arrowMiddleware,
} from '@floating-ui/dom';

type Lazy<T> = T | (() => T | null | undefined);
Expand Down Expand Up @@ -110,7 +110,12 @@ export class FloatingDOMController implements ReactiveController {
this.#cleanup?.();
}

async #update(placement: Placement = 'top', offset?: Offset, flip = true, fallbackPlacements?: Placement[]) {
async #update(
placement: Placement = 'top',
offset?: Offset,
flip = true,
fallbackPlacements?: Placement[],
) {
const { padding, shift } = this.#options;

const invoker = this.#invoker;
Expand All @@ -119,15 +124,20 @@ export class FloatingDOMController implements ReactiveController {
if (!invoker || !content) {
return;
}
const { x, y, placement: _placement, middlewareData } = await computePosition(invoker, content, {
const {
x,
y,
placement: _placement,
middlewareData,
} = await computePosition(invoker, content, {
strategy: 'absolute',
placement,
middleware: [
offsetMiddleware(offset),
shift && shiftMiddleware({ padding }),
arrow && arrowMiddleware({ element: arrow, padding: arrow.offsetHeight / 2 }),
flip && flipMiddleware({ padding, fallbackPlacements }),
].filter(Boolean)
].filter(Boolean),
});

if (arrow) {
Expand Down
33 changes: 21 additions & 12 deletions core/pfe-core/controllers/internals-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ function isARIAMixinProp(key: string): key is keyof ARIAMixin {
return key === 'role' || key.startsWith('aria');
}

type FACE = HTMLElement & {
formDisabledCallback?(disabled: boolean): void;
};

const protos = new WeakMap();

let constructingAllowed = false;
Expand Down Expand Up @@ -38,7 +42,7 @@ function aria(
// @ts-expect-error: shamone!
this.attach()[key] = value;
this.host.requestUpdate();
}
},
});
protos.get(target).add(key);
}
Expand All @@ -63,14 +67,17 @@ export class InternalsController implements ReactiveController, ARIAMixin {
declare readonly willValidate: ElementInternals['willValidate'];
declare readonly validationMessage: ElementInternals['validationMessage'];

public static of(host: ReactiveControllerHost, options?: InternalsControllerOptions): InternalsController {
public static of(
host: ReactiveControllerHost,
options?: InternalsControllerOptions,
): InternalsController {
constructingAllowed = true;
// implement the singleton pattern
// using a public static constructor method is much easier to manage,
// due to the quirks of our typescript config
const instance: InternalsController =
InternalsController.instances.get(host) ??
new InternalsController(host, options);
InternalsController.instances.get(host)
?? new InternalsController(host, options);
instance.initializeOptions(options);
constructingAllowed = false;
return instance;
Expand Down Expand Up @@ -152,10 +159,10 @@ export class InternalsController implements ReactiveController, ARIAMixin {

/** A best-attempt based on observed behaviour in FireFox 115 on fedora 38 */
get computedLabelText() {
return this.internals.ariaLabel ||
Array.from(this.internals.labels as NodeListOf<HTMLElement>)
.reduce((acc, label) =>
`${acc}${getLabelText(label)}`, '');
return this.internals.ariaLabel
|| Array.from(this.internals.labels as NodeListOf<HTMLElement>)
.reduce((acc, label) =>
`${acc}${getLabelText(label)}`, '');
}

private get element() {
Expand All @@ -174,7 +181,9 @@ export class InternalsController implements ReactiveController, ARIAMixin {
throw new Error('InternalsController must be constructed with `InternalsController.for()`');
}
if (!this.element) {
throw new Error('InternalsController must be instantiated with an HTMLElement or a `getHTMLElement` function');
throw new Error(
`InternalsController must be instantiated with an HTMLElement or a \`getHTMLElement\` function`,
);
}
this.attach();
this.initializeOptions(options);
Expand All @@ -190,8 +199,8 @@ export class InternalsController implements ReactiveController, ARIAMixin {
// START polyfill-disabled
// We need to polyfill :disabled
// see https://github.com/calebdwilliams/element-internals-polyfill/issues/88
const orig = (this.element as HTMLElement & { formDisabledCallback?(disabled: boolean): void }).formDisabledCallback;
(this.element as HTMLElement & { formDisabledCallback?(disabled: boolean): void }).formDisabledCallback = disabled => {
const orig = (this.element as FACE).formDisabledCallback;
(this.element as FACE).formDisabledCallback = disabled => {
this._formDisabled = disabled;
orig?.call(this.host, disabled);
// END polyfill-disabled
Expand Down Expand Up @@ -223,7 +232,7 @@ export class InternalsController implements ReactiveController, ARIAMixin {
}
}

hostConnected?(): void
hostConnected?(): void;

setFormValue(...args: Parameters<ElementInternals['setFormValue']>) {
return this.internals.setFormValue(...args);
Expand Down
4 changes: 2 additions & 2 deletions core/pfe-core/controllers/light-dom-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ export class LightDOMController implements ReactiveController {
*/
hasLightDOM(): boolean {
return !!(
this.host.children.length > 0 ||
(this.host.textContent ?? '').trim().length > 0
this.host.children.length > 0
|| (this.host.textContent ?? '').trim().length > 0
);
}
}
33 changes: 25 additions & 8 deletions core/pfe-core/controllers/listbox-controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { ReactiveController, ReactiveControllerHost } from 'lit';

export interface ListboxAccessibilityController<Item extends HTMLElement> extends ReactiveController {
export interface ListboxAccessibilityController<
Item extends HTMLElement
> extends ReactiveController {
items: Item[];
activeItem?: Item;
nextItem?: Item;
Expand Down Expand Up @@ -55,10 +57,14 @@ export class ListboxController<Item extends HTMLElement> implements ReactiveCont
throw new Error('ListboxController must be constructed with `ListboxController.of()`');
}
if (!(host instanceof HTMLElement) && typeof _options.getHTMLElement !== 'function') {
throw new Error('ListboxController requires the host to be an HTMLElement, or for the initializer to include a `getHTMLElement()` function');
throw new Error(
`ListboxController requires the host to be an HTMLElement, or for the initializer to include a \`getHTMLElement()\` function`,
);
}
if (!_options.a11yController) {
throw new Error('ListboxController requires an additional keyboard accessibility controller. Provide either a RovingTabindexController or an ActiveDescendantController');
throw new Error(
`ListboxController requires an additional keyboard accessibility controller. Provide either a RovingTabindexController or an ActiveDescendantController`,
);
}
ListboxController.instances.set(host, this);
this.host.addController(this);
Expand Down Expand Up @@ -145,7 +151,9 @@ export class ListboxController<Item extends HTMLElement> implements ReactiveCont
}

#getEventOption(event: Event): Item | undefined {
return event.composedPath().find(node => this.#items.includes(node as Item)) as Item | undefined;
return event
.composedPath()
.find(node => this.#items.includes(node as Item)) as Item | undefined;
}


Expand Down Expand Up @@ -258,7 +266,8 @@ export class ListboxController<Item extends HTMLElement> implements ReactiveCont
*/
#optionsChanged(oldOptions: Item[]) {
const setSize = this.#items.length;
if (setSize !== oldOptions.length || !oldOptions.every((element, index) => element === this.#items[index])) {
if (setSize !== oldOptions.length
|| !oldOptions.every((element, index) => element === this.#items[index])) {
this._options.a11yController.updateItems(this.options);
}
}
Expand All @@ -269,7 +278,11 @@ export class ListboxController<Item extends HTMLElement> implements ReactiveCont
#updateSingleselect() {
if (!this._options.multi && !this.disabled) {
this.#getEnabledOptions()
.forEach(option => this._options.requestSelect(option, option === this._options.a11yController.activeItem));
.forEach(option =>
this._options.requestSelect(
option,
option === this._options.a11yController.activeItem,
));
}
}

Expand All @@ -284,12 +297,16 @@ export class ListboxController<Item extends HTMLElement> implements ReactiveCont
) {
if (referenceItem && this._options.multi && !this.disabled && currentItem) {
// select all options between active descendant and target
const [start, end] = [this.options.indexOf(referenceItem), this.options.indexOf(currentItem)].sort();
const [start, end] = [
this.options.indexOf(referenceItem),
this.options.indexOf(currentItem),
].sort();
const options = [...this.options].slice(start, end + 1);

// by default CTRL+A will select all options
// if all options are selected, CTRL+A will deselect all options
const allSelected = this.#getEnabledOptions(options).filter(option => !this._options.isSelected(option))?.length === 0;
const allSelected = this.#getEnabledOptions(options)
.filter(option => !this._options.isSelected(option))?.length === 0;

// whether options will be selected (true) or deselected (false)
const selected = ctrlA ? !allSelected : this._options.isSelected(referenceItem);
Expand Down

0 comments on commit 65079fb

Please sign in to comment.