@patternfly/pfe-core 2.3.1 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,120 +1,122 @@
1
- var _ScrollSpyController_instances, _ScrollSpyController_tagNames, _ScrollSpyController_activeAttribute, _ScrollSpyController_io, _ScrollSpyController_passedLinks, _ScrollSpyController_force, _ScrollSpyController_intersected, _ScrollSpyController_root, _ScrollSpyController_rootMargin, _ScrollSpyController_threshold, _ScrollSpyController_rootNode, _ScrollSpyController_getHash, _ScrollSpyController_linkChildren_get, _ScrollSpyController_initIo, _ScrollSpyController_markPassed, _ScrollSpyController_setActive, _ScrollSpyController_nextIntersection, _ScrollSpyController_onIo;
2
- import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
3
1
  export class ScrollSpyController {
2
+ #tagNames;
3
+ #activeAttribute;
4
+ #io;
5
+ /** Which link's targets have already scrolled past? */
6
+ #passedLinks = new Set();
7
+ /** Ignore intersections? */
8
+ #force = false;
9
+ /** Has the intersection observer found an element? */
10
+ #intersected = false;
11
+ #root;
12
+ #rootMargin;
13
+ #threshold;
14
+ #rootNode;
15
+ #getHash;
16
+ get #linkChildren() {
17
+ return Array.from(this.host.querySelectorAll(this.#tagNames.join(',')))
18
+ .filter(this.#getHash);
19
+ }
4
20
  get root() {
5
- return __classPrivateFieldGet(this, _ScrollSpyController_root, "f");
21
+ return this.#root;
6
22
  }
7
23
  set root(v) {
8
- __classPrivateFieldSet(this, _ScrollSpyController_root, v, "f");
9
- __classPrivateFieldGet(this, _ScrollSpyController_io, "f")?.disconnect();
10
- __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_initIo).call(this);
24
+ this.#root = v;
25
+ this.#io?.disconnect();
26
+ this.#initIo();
11
27
  }
12
28
  get rootMargin() {
13
- return __classPrivateFieldGet(this, _ScrollSpyController_rootMargin, "f");
29
+ return this.#rootMargin;
14
30
  }
15
31
  set rootMargin(v) {
16
- __classPrivateFieldSet(this, _ScrollSpyController_rootMargin, v, "f");
17
- __classPrivateFieldGet(this, _ScrollSpyController_io, "f")?.disconnect();
18
- __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_initIo).call(this);
32
+ this.#rootMargin = v;
33
+ this.#io?.disconnect();
34
+ this.#initIo();
19
35
  }
20
36
  get threshold() {
21
- return __classPrivateFieldGet(this, _ScrollSpyController_threshold, "f");
37
+ return this.#threshold;
22
38
  }
23
39
  set threshold(v) {
24
- __classPrivateFieldSet(this, _ScrollSpyController_threshold, v, "f");
25
- __classPrivateFieldGet(this, _ScrollSpyController_io, "f")?.disconnect();
26
- __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_initIo).call(this);
40
+ this.#threshold = v;
41
+ this.#io?.disconnect();
42
+ this.#initIo();
27
43
  }
28
44
  constructor(host, options) {
29
- _ScrollSpyController_instances.add(this);
30
45
  this.host = host;
31
- _ScrollSpyController_tagNames.set(this, void 0);
32
- _ScrollSpyController_activeAttribute.set(this, void 0);
33
- _ScrollSpyController_io.set(this, void 0);
34
- /** Which link's targets have already scrolled past? */
35
- _ScrollSpyController_passedLinks.set(this, new Set());
36
- /** Ignore intersections? */
37
- _ScrollSpyController_force.set(this, false);
38
- /** Has the intersection observer found an element? */
39
- _ScrollSpyController_intersected.set(this, false);
40
- _ScrollSpyController_root.set(this, void 0);
41
- _ScrollSpyController_rootMargin.set(this, void 0);
42
- _ScrollSpyController_threshold.set(this, void 0);
43
- _ScrollSpyController_rootNode.set(this, void 0);
44
- _ScrollSpyController_getHash.set(this, void 0);
45
46
  host.addController(this);
46
- __classPrivateFieldSet(this, _ScrollSpyController_tagNames, options.tagNames, "f");
47
- __classPrivateFieldSet(this, _ScrollSpyController_root, options.root, "f");
48
- __classPrivateFieldSet(this, _ScrollSpyController_rootMargin, options.rootMargin, "f");
49
- __classPrivateFieldSet(this, _ScrollSpyController_activeAttribute, options.activeAttribute ?? 'active', "f");
50
- __classPrivateFieldSet(this, _ScrollSpyController_threshold, options.threshold ?? 0.85, "f");
51
- __classPrivateFieldSet(this, _ScrollSpyController_rootNode, options.rootNode ?? host.getRootNode(), "f");
52
- __classPrivateFieldSet(this, _ScrollSpyController_getHash, options?.getHash ?? ((el) => el.getAttribute('href')), "f");
47
+ this.#tagNames = options.tagNames;
48
+ this.#root = options.root;
49
+ this.#rootMargin = options.rootMargin;
50
+ this.#activeAttribute = options.activeAttribute ?? 'active';
51
+ this.#threshold = options.threshold ?? 0.85;
52
+ this.#rootNode = options.rootNode ?? host.getRootNode();
53
+ this.#getHash = options?.getHash ?? ((el) => el.getAttribute('href'));
53
54
  }
54
55
  hostConnected() {
55
- __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_initIo).call(this);
56
+ this.#initIo();
56
57
  }
57
- /** Explicitly set the active item */
58
- async setActive(link) {
59
- __classPrivateFieldSet(this, _ScrollSpyController_force, true, "f");
60
- __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_setActive).call(this, link);
61
- let sawActive = false;
62
- for (const child of __classPrivateFieldGet(this, _ScrollSpyController_instances, "a", _ScrollSpyController_linkChildren_get)) {
63
- __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_markPassed).call(this, child, !sawActive);
64
- if (child === link) {
65
- sawActive = true;
66
- }
58
+ #initIo() {
59
+ const rootNode = this.#rootNode;
60
+ if (rootNode instanceof Document || rootNode instanceof ShadowRoot) {
61
+ const { rootMargin, threshold, root } = this;
62
+ this.#io = new IntersectionObserver(r => this.#onIo(r), { root, rootMargin, threshold });
63
+ this.#linkChildren
64
+ .map(x => this.#getHash(x))
65
+ .filter((x) => !!x)
66
+ .map(x => rootNode.getElementById(x.replace('#', '')))
67
+ .filter((x) => !!x)
68
+ .forEach(target => this.#io?.observe(target));
67
69
  }
68
- await __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_nextIntersection).call(this);
69
- __classPrivateFieldSet(this, _ScrollSpyController_force, false, "f");
70
- }
71
- }
72
- _ScrollSpyController_tagNames = new WeakMap(), _ScrollSpyController_activeAttribute = new WeakMap(), _ScrollSpyController_io = new WeakMap(), _ScrollSpyController_passedLinks = new WeakMap(), _ScrollSpyController_force = new WeakMap(), _ScrollSpyController_intersected = new WeakMap(), _ScrollSpyController_root = new WeakMap(), _ScrollSpyController_rootMargin = new WeakMap(), _ScrollSpyController_threshold = new WeakMap(), _ScrollSpyController_rootNode = new WeakMap(), _ScrollSpyController_getHash = new WeakMap(), _ScrollSpyController_instances = new WeakSet(), _ScrollSpyController_linkChildren_get = function _ScrollSpyController_linkChildren_get() {
73
- return Array.from(this.host.querySelectorAll(__classPrivateFieldGet(this, _ScrollSpyController_tagNames, "f").join(',')))
74
- .filter(__classPrivateFieldGet(this, _ScrollSpyController_getHash, "f"));
75
- }, _ScrollSpyController_initIo = function _ScrollSpyController_initIo() {
76
- const rootNode = __classPrivateFieldGet(this, _ScrollSpyController_rootNode, "f");
77
- if (rootNode instanceof Document || rootNode instanceof ShadowRoot) {
78
- const { rootMargin, threshold, root } = this;
79
- __classPrivateFieldSet(this, _ScrollSpyController_io, new IntersectionObserver(r => __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_onIo).call(this, r), { root, rootMargin, threshold }), "f");
80
- __classPrivateFieldGet(this, _ScrollSpyController_instances, "a", _ScrollSpyController_linkChildren_get)
81
- .map(x => __classPrivateFieldGet(this, _ScrollSpyController_getHash, "f").call(this, x))
82
- .filter((x) => !!x)
83
- .map(x => rootNode.getElementById(x.replace('#', '')))
84
- .filter((x) => !!x)
85
- .forEach(target => __classPrivateFieldGet(this, _ScrollSpyController_io, "f")?.observe(target));
86
70
  }
87
- }, _ScrollSpyController_markPassed = function _ScrollSpyController_markPassed(link, force) {
88
- if (force) {
89
- __classPrivateFieldGet(this, _ScrollSpyController_passedLinks, "f").add(link);
71
+ #markPassed(link, force) {
72
+ if (force) {
73
+ this.#passedLinks.add(link);
74
+ }
75
+ else {
76
+ this.#passedLinks.delete(link);
77
+ }
90
78
  }
91
- else {
92
- __classPrivateFieldGet(this, _ScrollSpyController_passedLinks, "f").delete(link);
79
+ #setActive(link) {
80
+ for (const child of this.#linkChildren) {
81
+ child.toggleAttribute(this.#activeAttribute, child === link);
82
+ }
93
83
  }
94
- }, _ScrollSpyController_setActive = function _ScrollSpyController_setActive(link) {
95
- for (const child of __classPrivateFieldGet(this, _ScrollSpyController_instances, "a", _ScrollSpyController_linkChildren_get)) {
96
- child.toggleAttribute(__classPrivateFieldGet(this, _ScrollSpyController_activeAttribute, "f"), child === link);
84
+ async #nextIntersection() {
85
+ this.#intersected = false;
86
+ // safeguard the loop
87
+ setTimeout(() => this.#intersected = false, 3000);
88
+ while (!this.#intersected) {
89
+ await new Promise(requestAnimationFrame);
90
+ }
97
91
  }
98
- }, _ScrollSpyController_nextIntersection = async function _ScrollSpyController_nextIntersection() {
99
- __classPrivateFieldSet(this, _ScrollSpyController_intersected, false, "f");
100
- // safeguard the loop
101
- setTimeout(() => __classPrivateFieldSet(this, _ScrollSpyController_intersected, false, "f"), 3000);
102
- while (!__classPrivateFieldGet(this, _ScrollSpyController_intersected, "f")) {
103
- await new Promise(requestAnimationFrame);
92
+ async #onIo(entries) {
93
+ if (!this.#force) {
94
+ for (const { target, boundingClientRect, intersectionRect } of entries) {
95
+ const selector = `:is(${this.#tagNames.join(',')})[href="#${target.id}"]`;
96
+ const link = this.host.querySelector(selector);
97
+ if (link) {
98
+ this.#markPassed(link, boundingClientRect.top < intersectionRect.top);
99
+ }
100
+ }
101
+ const link = [...this.#passedLinks];
102
+ const last = link.at(-1);
103
+ this.#setActive(last ?? this.#linkChildren.at(0));
104
+ }
105
+ this.#intersected = true;
104
106
  }
105
- }, _ScrollSpyController_onIo = async function _ScrollSpyController_onIo(entries) {
106
- if (!__classPrivateFieldGet(this, _ScrollSpyController_force, "f")) {
107
- for (const { target, boundingClientRect, intersectionRect } of entries) {
108
- const selector = `:is(${__classPrivateFieldGet(this, _ScrollSpyController_tagNames, "f").join(',')})[href="#${target.id}"]`;
109
- const link = this.host.querySelector(selector);
110
- if (link) {
111
- __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_markPassed).call(this, link, boundingClientRect.top < intersectionRect.top);
107
+ /** Explicitly set the active item */
108
+ async setActive(link) {
109
+ this.#force = true;
110
+ this.#setActive(link);
111
+ let sawActive = false;
112
+ for (const child of this.#linkChildren) {
113
+ this.#markPassed(child, !sawActive);
114
+ if (child === link) {
115
+ sawActive = true;
112
116
  }
113
117
  }
114
- const link = [...__classPrivateFieldGet(this, _ScrollSpyController_passedLinks, "f")];
115
- const last = link.at(-1);
116
- __classPrivateFieldGet(this, _ScrollSpyController_instances, "m", _ScrollSpyController_setActive).call(this, last ?? __classPrivateFieldGet(this, _ScrollSpyController_instances, "a", _ScrollSpyController_linkChildren_get).at(0));
118
+ await this.#nextIntersection();
119
+ this.#force = false;
117
120
  }
118
- __classPrivateFieldSet(this, _ScrollSpyController_intersected, true, "f");
119
- };
121
+ }
120
122
  //# sourceMappingURL=scroll-spy-controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-spy-controller.js","sourceRoot":"","sources":["scroll-spy-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit';\n\nexport interface ScrollSpyControllerOptions extends IntersectionObserverInit {\n /**\n * Tag names of legal link children.\n * Legal children must have an `href` property/attribute pair, like `<a>`.\n */\n tagNames: string[];\n\n /**\n * Attribute to set on the active link element.\n * @default 'active'\n */\n activeAttribute?: string;\n\n /**\n * The root node to query content for\n * @default the host's root node\n */\n rootNode?: Node;\n /**\n * function to call on link children to get their URL hash (i.e. id to scroll to)\n * @default el => el.getAttribute('href');\n */\n getHash?: (el: Element) => string | null;\n}\n\nexport class ScrollSpyController implements ReactiveController {\n #tagNames: string[];\n #activeAttribute: string;\n\n #io?: IntersectionObserver;\n\n /** Which link's targets have already scrolled past? */\n #passedLinks = new Set<Element>();\n\n /** Ignore intersections? */\n #force = false;\n\n /** Has the intersection observer found an element? */\n #intersected = false;\n\n #root: ScrollSpyControllerOptions['root'];\n #rootMargin?: string;\n #threshold: number | number[];\n\n #rootNode: Node;\n #getHash: (el: Element) => string | null;\n\n get #linkChildren(): Element[] {\n return Array.from(this.host.querySelectorAll(this.#tagNames.join(',')))\n .filter(this.#getHash);\n }\n\n get root() {\n return this.#root;\n }\n\n set root(v) {\n this.#root = v;\n this.#io?.disconnect();\n this.#initIo();\n }\n\n get rootMargin() {\n return this.#rootMargin;\n }\n\n set rootMargin(v) {\n this.#rootMargin = v;\n this.#io?.disconnect();\n this.#initIo();\n }\n\n get threshold() {\n return this.#threshold;\n }\n\n set threshold(v) {\n this.#threshold = v;\n this.#io?.disconnect();\n this.#initIo();\n }\n\n constructor(\n private host: ReactiveControllerHost & HTMLElement,\n options: ScrollSpyControllerOptions,\n ) {\n host.addController(this);\n this.#tagNames = options.tagNames;\n this.#root = options.root;\n this.#rootMargin = options.rootMargin;\n this.#activeAttribute = options.activeAttribute ?? 'active';\n this.#threshold = options.threshold ?? 0.85;\n this.#rootNode = options.rootNode ?? host.getRootNode();\n this.#getHash = options?.getHash ?? ((el: Element) => el.getAttribute('href'));\n }\n\n hostConnected() {\n this.#initIo();\n }\n\n #initIo() {\n const rootNode = this.#rootNode;\n if (rootNode instanceof Document || rootNode instanceof ShadowRoot) {\n const { rootMargin, threshold, root } = this;\n this.#io = new IntersectionObserver(r => this.#onIo(r), { root, rootMargin, threshold });\n this.#linkChildren\n .map(x => this.#getHash(x))\n .filter((x): x is string => !!x)\n .map(x => rootNode.getElementById(x.replace('#', '')))\n .filter((x): x is HTMLElement => !!x)\n .forEach(target => this.#io?.observe(target));\n }\n }\n\n #markPassed(link: Element, force: boolean) {\n if (force) {\n this.#passedLinks.add(link);\n } else {\n this.#passedLinks.delete(link);\n }\n }\n\n #setActive(link?: EventTarget | null) {\n for (const child of this.#linkChildren) {\n child.toggleAttribute(this.#activeAttribute, child === link);\n }\n }\n\n async #nextIntersection() {\n this.#intersected = false;\n // safeguard the loop\n setTimeout(() => this.#intersected = false, 3000);\n while (!this.#intersected) {\n await new Promise(requestAnimationFrame);\n }\n }\n\n async #onIo(entries: IntersectionObserverEntry[]) {\n if (!this.#force) {\n for (const { target, boundingClientRect, intersectionRect } of entries) {\n const selector = `:is(${this.#tagNames.join(',')})[href=\"#${target.id}\"]`;\n const link = this.host.querySelector(selector);\n if (link) {\n this.#markPassed(link, boundingClientRect.top < intersectionRect.top);\n }\n }\n const link = [...this.#passedLinks];\n const last = link.at(-1);\n this.#setActive(last ?? this.#linkChildren.at(0));\n }\n this.#intersected = true;\n }\n\n /** Explicitly set the active item */\n public async setActive(link: EventTarget | null) {\n this.#force = true;\n this.#setActive(link);\n let sawActive = false;\n for (const child of this.#linkChildren) {\n this.#markPassed(child, !sawActive);\n if (child === link) {\n sawActive = true;\n }\n }\n await this.#nextIntersection();\n this.#force = false;\n }\n}\n"]}
1
+ {"version":3,"file":"scroll-spy-controller.js","sourceRoot":"","sources":["scroll-spy-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit';\n\nexport interface ScrollSpyControllerOptions extends IntersectionObserverInit {\n /**\n * Tag names of legal link children.\n * Legal children must have an `href` property/attribute pair, like `<a>`.\n */\n tagNames: string[];\n\n /**\n * Attribute to set on the active link element.\n * @default 'active'\n */\n activeAttribute?: string;\n\n /**\n * The root node to query content for\n * @default the host's root node\n */\n rootNode?: Node;\n /**\n * function to call on link children to get their URL hash (i.e. id to scroll to)\n * @default el => el.getAttribute('href');\n */\n getHash?: (el: Element) => string | null;\n}\n\nexport class ScrollSpyController implements ReactiveController {\n #tagNames: string[];\n #activeAttribute: string;\n\n #io?: IntersectionObserver;\n\n /** Which link's targets have already scrolled past? */\n #passedLinks = new Set<Element>();\n\n /** Ignore intersections? */\n #force = false;\n\n /** Has the intersection observer found an element? */\n #intersected = false;\n\n #root: ScrollSpyControllerOptions['root'];\n #rootMargin?: string;\n #threshold: number | number[];\n\n #rootNode: Node;\n #getHash: (el: Element) => string | null;\n\n get #linkChildren(): Element[] {\n return Array.from(this.host.querySelectorAll(this.#tagNames.join(',')))\n .filter(this.#getHash);\n }\n\n get root() {\n return this.#root;\n }\n\n set root(v) {\n this.#root = v;\n this.#io?.disconnect();\n this.#initIo();\n }\n\n get rootMargin() {\n return this.#rootMargin;\n }\n\n set rootMargin(v) {\n this.#rootMargin = v;\n this.#io?.disconnect();\n this.#initIo();\n }\n\n get threshold() {\n return this.#threshold;\n }\n\n set threshold(v) {\n this.#threshold = v;\n this.#io?.disconnect();\n this.#initIo();\n }\n\n constructor(\n private host: ReactiveControllerHost & HTMLElement,\n options: ScrollSpyControllerOptions,\n ) {\n host.addController(this);\n this.#tagNames = options.tagNames;\n this.#root = options.root;\n this.#rootMargin = options.rootMargin;\n this.#activeAttribute = options.activeAttribute ?? 'active';\n this.#threshold = options.threshold ?? 0.85;\n this.#rootNode = options.rootNode ?? host.getRootNode();\n this.#getHash = options?.getHash ?? ((el: Element) => el.getAttribute('href'));\n }\n\n hostConnected() {\n this.#initIo();\n }\n\n #initIo() {\n const rootNode = this.#rootNode;\n if (rootNode instanceof Document || rootNode instanceof ShadowRoot) {\n const { rootMargin, threshold, root } = this;\n this.#io = new IntersectionObserver(r => this.#onIo(r), { root, rootMargin, threshold });\n this.#linkChildren\n .map(x => this.#getHash(x))\n .filter((x): x is string => !!x)\n .map(x => rootNode.getElementById(x.replace('#', '')))\n .filter((x): x is HTMLElement => !!x)\n .forEach(target => this.#io?.observe(target));\n }\n }\n\n #markPassed(link: Element, force: boolean) {\n if (force) {\n this.#passedLinks.add(link);\n } else {\n this.#passedLinks.delete(link);\n }\n }\n\n #setActive(link?: EventTarget | null) {\n for (const child of this.#linkChildren) {\n child.toggleAttribute(this.#activeAttribute, child === link);\n }\n }\n\n async #nextIntersection() {\n this.#intersected = false;\n // safeguard the loop\n setTimeout(() => this.#intersected = false, 3000);\n while (!this.#intersected) {\n await new Promise(requestAnimationFrame);\n }\n }\n\n async #onIo(entries: IntersectionObserverEntry[]) {\n if (!this.#force) {\n for (const { target, boundingClientRect, intersectionRect } of entries) {\n const selector = `:is(${this.#tagNames.join(',')})[href=\"#${target.id}\"]`;\n const link = this.host.querySelector(selector);\n if (link) {\n this.#markPassed(link, boundingClientRect.top < intersectionRect.top);\n }\n }\n const link = [...this.#passedLinks];\n const last = link.at(-1);\n this.#setActive(last ?? this.#linkChildren.at(0));\n }\n this.#intersected = true;\n }\n\n /** Explicitly set the active item */\n public async setActive(link: EventTarget | null) {\n this.#force = true;\n this.#setActive(link);\n let sawActive = false;\n for (const child of this.#linkChildren) {\n this.#markPassed(child, !sawActive);\n if (child === link) {\n sawActive = true;\n }\n }\n await this.#nextIntersection();\n this.#force = false;\n }\n}\n"]}
@@ -26,16 +26,11 @@ export interface SlotsConfig {
26
26
  deprecations?: Record<string, string>;
27
27
  }
28
28
  export declare class SlotController implements ReactiveController {
29
+ #private;
29
30
  host: ReactiveElement;
30
31
  static anonymous: symbol;
31
- private nodes;
32
- private logger;
33
- private firstUpdated;
34
- private mo;
35
- private slotNames;
36
- private deprecations;
37
32
  constructor(host: ReactiveElement, ...config: ([SlotsConfig] | (string | null)[]));
38
- hostConnected(): void;
33
+ hostConnected(): Promise<void>;
39
34
  hostUpdated(): void;
40
35
  hostDisconnected(): void;
41
36
  /**
@@ -65,13 +60,5 @@ export declare class SlotController implements ReactiveController {
65
60
  * ```
66
61
  */
67
62
  getSlotted<T extends Element = Element>(...slotNames: string[]): T[];
68
- private onSlotChange;
69
- private onMutation;
70
- private getChildrenForSlot;
71
- private initSlot;
72
- /**
73
- * Maps the defined slots into an object that is easier to query
74
- */
75
- private init;
76
63
  }
77
64
  export {};
@@ -1,5 +1,3 @@
1
- import { __decorate } from "tslib";
2
- import { bound } from '../decorators/bound.js';
3
1
  import { Logger } from './logger.js';
4
2
  function isObjectConfigSpread(config) {
5
3
  return config.length === 1 && typeof config[0] === 'object' && config[0] !== null;
@@ -11,41 +9,52 @@ function isObjectConfigSpread(config) {
11
9
  const isSlot = (n) => (child) => n === SlotController.anonymous ? !child.hasAttribute('slot')
12
10
  : child.getAttribute('slot') === n;
13
11
  class SlotController {
12
+ static { this.anonymous = Symbol('anonymous slot'); }
13
+ #nodes = new Map();
14
+ #logger;
15
+ #firstUpdated = false;
16
+ #mo = new MutationObserver(records => this.#onMutation(records));
17
+ #slotNames;
18
+ #deprecations = {};
14
19
  constructor(host, ...config) {
15
20
  this.host = host;
16
- this.nodes = new Map();
17
- this.firstUpdated = false;
18
- this.mo = new MutationObserver(this.onMutation);
19
- this.deprecations = {};
20
- this.logger = new Logger(this.host);
21
+ this.#logger = new Logger(this.host);
21
22
  if (isObjectConfigSpread(config)) {
22
23
  const [{ slots, deprecations }] = config;
23
- this.slotNames = slots;
24
- this.deprecations = deprecations ?? {};
24
+ this.#slotNames = slots;
25
+ this.#deprecations = deprecations ?? {};
25
26
  }
26
27
  else if (config.length >= 1) {
27
- this.slotNames = config;
28
- this.deprecations = {};
28
+ this.#slotNames = config;
29
+ this.#deprecations = {};
29
30
  }
30
31
  else {
31
- this.slotNames = [null];
32
+ this.#slotNames = [null];
32
33
  }
33
34
  host.addController(this);
34
35
  }
35
- hostConnected() {
36
- this.host.addEventListener('slotchange', this.onSlotChange);
37
- this.firstUpdated = false;
38
- this.mo.observe(this.host, { childList: true });
39
- this.init();
36
+ async hostConnected() {
37
+ this.host.addEventListener('slotchange', this.#onSlotChange);
38
+ this.#firstUpdated = false;
39
+ this.#mo.observe(this.host, { childList: true });
40
+ // Map the defined slots into an object that is easier to query
41
+ this.#nodes.clear();
42
+ // Loop over the properties provided by the schema
43
+ this.#slotNames.forEach(this.#initSlot);
44
+ Object.values(this.#deprecations).forEach(this.#initSlot);
45
+ this.host.requestUpdate();
46
+ // insurance for framework integrations
47
+ await this.host.updateComplete;
48
+ this.host.requestUpdate();
40
49
  }
41
50
  hostUpdated() {
42
- if (!this.firstUpdated) {
43
- this.slotNames.forEach(this.initSlot);
44
- this.firstUpdated = true;
51
+ if (!this.#firstUpdated) {
52
+ this.#slotNames.forEach(this.#initSlot);
53
+ this.#firstUpdated = true;
45
54
  }
46
55
  }
47
56
  hostDisconnected() {
48
- this.mo.disconnect();
57
+ this.#mo.disconnect();
49
58
  }
50
59
  /**
51
60
  * Returns a boolean statement of whether or not any of those slots exists in the light DOM.
@@ -55,11 +64,11 @@ class SlotController {
55
64
  */
56
65
  hasSlotted(...names) {
57
66
  if (!names.length) {
58
- this.logger.warn(`Please provide at least one slot name for which to search.`);
67
+ this.#logger.warn(`Please provide at least one slot name for which to search.`);
59
68
  return false;
60
69
  }
61
70
  else {
62
- return names.some(x => this.nodes.get(x)?.hasContent ?? false);
71
+ return names.some(x => this.#nodes.get(x)?.hasContent ?? false);
63
72
  }
64
73
  }
65
74
  /**
@@ -83,67 +92,42 @@ class SlotController {
83
92
  */
84
93
  getSlotted(...slotNames) {
85
94
  if (!slotNames.length) {
86
- return (this.nodes.get(SlotController.anonymous)?.elements ?? []);
95
+ return (this.#nodes.get(SlotController.anonymous)?.elements ?? []);
87
96
  }
88
97
  else {
89
- return slotNames.flatMap(slotName => this.nodes.get(slotName)?.elements ?? []);
98
+ return slotNames.flatMap(slotName => this.#nodes.get(slotName)?.elements ?? []);
90
99
  }
91
100
  }
92
- onSlotChange(event) {
101
+ #onSlotChange = (event) => {
93
102
  const slotName = event.target.name;
94
- this.initSlot(slotName);
103
+ this.#initSlot(slotName);
95
104
  this.host.requestUpdate();
96
- }
97
- async onMutation(records) {
105
+ };
106
+ #onMutation = async (records) => {
98
107
  const changed = [];
99
108
  for (const { addedNodes, removedNodes } of records) {
100
109
  for (const node of [...addedNodes, ...removedNodes]) {
101
110
  if (node instanceof HTMLElement && node.slot) {
102
- this.initSlot(node.slot);
111
+ this.#initSlot(node.slot);
103
112
  changed.push(node.slot);
104
113
  }
105
114
  }
106
115
  }
107
- if (changed.length) {
108
- this.host.requestUpdate();
109
- }
110
- }
111
- getChildrenForSlot(name) {
116
+ this.host.requestUpdate();
117
+ };
118
+ #getChildrenForSlot(name) {
112
119
  const children = Array.from(this.host.children);
113
120
  return children.filter(isSlot(name));
114
121
  }
115
- initSlot(slotName) {
122
+ #initSlot = (slotName) => {
116
123
  const name = slotName || SlotController.anonymous;
117
- const elements = this.nodes.get(name)?.slot?.assignedElements?.() ?? this.getChildrenForSlot(name);
124
+ const elements = this.#nodes.get(name)?.slot?.assignedElements?.() ?? this.#getChildrenForSlot(name);
118
125
  const selector = slotName ? `slot[name="${slotName}"]` : 'slot:not([name])';
119
126
  const slot = this.host.shadowRoot?.querySelector?.(selector) ?? null;
120
127
  const hasContent = !!elements.length;
121
- this.nodes.set(name, { elements, name: slotName ?? '', hasContent, slot });
122
- this.logger.log(slotName, hasContent);
123
- }
124
- /**
125
- * Maps the defined slots into an object that is easier to query
126
- */
127
- init() {
128
- this.nodes.clear();
129
- // Loop over the properties provided by the schema
130
- this.slotNames.forEach(this.initSlot);
131
- Object.values(this.deprecations).forEach(this.initSlot);
132
- this.host.requestUpdate();
133
- }
128
+ this.#nodes.set(name, { elements, name: slotName ?? '', hasContent, slot });
129
+ this.#logger.log(slotName, hasContent);
130
+ };
134
131
  }
135
- SlotController.anonymous = Symbol('anonymous slot');
136
- __decorate([
137
- bound
138
- ], SlotController.prototype, "onSlotChange", null);
139
- __decorate([
140
- bound
141
- ], SlotController.prototype, "onMutation", null);
142
- __decorate([
143
- bound
144
- ], SlotController.prototype, "initSlot", null);
145
- __decorate([
146
- bound
147
- ], SlotController.prototype, "init", null);
148
132
  export { SlotController };
149
133
  //# sourceMappingURL=slot-controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"slot-controller.js","sourceRoot":"","sources":["slot-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController, ReactiveElement } from 'lit';\n\nimport { bound } from '../decorators/bound.js';\nimport { Logger } from './logger.js';\n\ninterface AnonymousSlot {\n hasContent: boolean;\n elements: Element[];\n slot: HTMLSlotElement | null;\n}\n\ninterface NamedSlot extends AnonymousSlot {\n name: string;\n initialized: true;\n}\n\nexport type Slot = NamedSlot | AnonymousSlot;\n\nexport interface SlotsConfig {\n slots: (string | null)[];\n /**\n * Object mapping new slot name keys to deprecated slot name values\n * @example `pf-modal--header` is deprecated in favour of `header`\n * ```js\n * new SlotController(this, {\n * slots: ['header'],\n * deprecations: {\n * 'header': 'pf-modal--header'\n * }\n * })\n * ```\n */\n deprecations?: Record<string, string>;\n}\n\nfunction isObjectConfigSpread(config: ([SlotsConfig] | (string | null)[])): config is [SlotsConfig] {\n return config.length === 1 && typeof config[0] === 'object' && config[0] !== null;\n}\n\n/**\n * If it's a named slot, return its children,\n * for the default slot, look for direct children not assigned to a slot\n */\nconst isSlot =\n <T extends Element = Element>(n: string | typeof SlotController.anonymous) =>\n (child: Element): child is T =>\n n === SlotController.anonymous ? !child.hasAttribute('slot')\n : child.getAttribute('slot') === n;\n\nexport class SlotController implements ReactiveController {\n public static anonymous = Symbol('anonymous slot');\n\n private nodes = new Map<string | typeof SlotController.anonymous, Slot>();\n\n private logger: Logger;\n\n private firstUpdated = false;\n\n private mo = new MutationObserver(this.onMutation);\n\n private slotNames: (string | null)[];\n\n private deprecations: Record<string, string> = {};\n\n constructor(public host: ReactiveElement, ...config: ([SlotsConfig] | (string | null)[])) {\n this.logger = new Logger(this.host);\n\n if (isObjectConfigSpread(config)) {\n const [{ slots, deprecations }] = config;\n this.slotNames = slots;\n this.deprecations = deprecations ?? {};\n } else if (config.length >= 1) {\n this.slotNames = config;\n this.deprecations = {};\n } else {\n this.slotNames = [null];\n }\n\n\n host.addController(this);\n }\n\n hostConnected() {\n this.host.addEventListener('slotchange', this.onSlotChange as EventListener);\n this.firstUpdated = false;\n this.mo.observe(this.host, { childList: true });\n this.init();\n }\n\n hostUpdated() {\n if (!this.firstUpdated) {\n this.slotNames.forEach(this.initSlot);\n this.firstUpdated = true;\n }\n }\n\n hostDisconnected() {\n this.mo.disconnect();\n }\n\n /**\n * Returns a boolean statement of whether or not any of those slots exists in the light DOM.\n *\n * @param {String|Array} name The slot name.\n * @example this.hasSlotted(\"header\");\n */\n hasSlotted(...names: string[]): boolean {\n if (!names.length) {\n this.logger.warn(`Please provide at least one slot name for which to search.`);\n return false;\n } else {\n return names.some(x =>\n this.nodes.get(x)?.hasContent ?? false);\n }\n }\n\n /**\n * Given a slot name or slot names, returns elements assigned to the requested slots as an array.\n * If no value is provided, it returns all children not assigned to a slot (without a slot attribute).\n *\n * @example Get header-slotted elements\n * ```js\n * this.getSlotted('header')\n * ```\n *\n * @example Get header- and footer-slotted elements\n * ```js\n * this.getSlotted('header', 'footer')\n * ```\n *\n * @example Get default-slotted elements\n * ```js\n * this.getSlotted();\n * ```\n */\n getSlotted<T extends Element = Element>(...slotNames: string[]): T[] {\n if (!slotNames.length) {\n return (this.nodes.get(SlotController.anonymous)?.elements ?? []) as T[];\n } else {\n return slotNames.flatMap(slotName =>\n this.nodes.get(slotName)?.elements ?? []) as T[];\n }\n }\n\n @bound private onSlotChange(event: Event & { target: HTMLSlotElement }) {\n const slotName = event.target.name;\n this.initSlot(slotName);\n this.host.requestUpdate();\n }\n\n @bound private async onMutation(records: MutationRecord[]) {\n const changed = [];\n for (const { addedNodes, removedNodes } of records) {\n for (const node of [...addedNodes, ...removedNodes]) {\n if (node instanceof HTMLElement && node.slot) {\n this.initSlot(node.slot);\n changed.push(node.slot);\n }\n }\n }\n if (changed.length) {\n this.host.requestUpdate();\n }\n }\n\n private getChildrenForSlot<T extends Element = Element>(name: string | typeof SlotController.anonymous): T[] {\n const children = Array.from(this.host.children) as T[];\n return children.filter(isSlot(name));\n }\n\n @bound private initSlot(slotName: string | null) {\n const name = slotName || SlotController.anonymous;\n const elements = this.nodes.get(name)?.slot?.assignedElements?.() ?? this.getChildrenForSlot(name);\n const selector = slotName ? `slot[name=\"${slotName}\"]` : 'slot:not([name])';\n const slot = this.host.shadowRoot?.querySelector?.<HTMLSlotElement>(selector) ?? null;\n const hasContent = !!elements.length;\n this.nodes.set(name, { elements, name: slotName ?? '', hasContent, slot });\n this.logger.log(slotName, hasContent);\n }\n\n /**\n * Maps the defined slots into an object that is easier to query\n */\n @bound private init() {\n this.nodes.clear();\n // Loop over the properties provided by the schema\n this.slotNames.forEach(this.initSlot);\n Object.values(this.deprecations).forEach(this.initSlot);\n this.host.requestUpdate();\n }\n}\n"]}
1
+ {"version":3,"file":"slot-controller.js","sourceRoot":"","sources":["slot-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController, ReactiveElement } from 'lit';\n\nimport { Logger } from './logger.js';\n\ninterface AnonymousSlot {\n hasContent: boolean;\n elements: Element[];\n slot: HTMLSlotElement | null;\n}\n\ninterface NamedSlot extends AnonymousSlot {\n name: string;\n initialized: true;\n}\n\nexport type Slot = NamedSlot | AnonymousSlot;\n\nexport interface SlotsConfig {\n slots: (string | null)[];\n /**\n * Object mapping new slot name keys to deprecated slot name values\n * @example `pf-modal--header` is deprecated in favour of `header`\n * ```js\n * new SlotController(this, {\n * slots: ['header'],\n * deprecations: {\n * 'header': 'pf-modal--header'\n * }\n * })\n * ```\n */\n deprecations?: Record<string, string>;\n}\n\nfunction isObjectConfigSpread(config: ([SlotsConfig] | (string | null)[])): config is [SlotsConfig] {\n return config.length === 1 && typeof config[0] === 'object' && config[0] !== null;\n}\n\n/**\n * If it's a named slot, return its children,\n * for the default slot, look for direct children not assigned to a slot\n */\nconst isSlot =\n <T extends Element = Element>(n: string | typeof SlotController.anonymous) =>\n (child: Element): child is T =>\n n === SlotController.anonymous ? !child.hasAttribute('slot')\n : child.getAttribute('slot') === n;\n\nexport class SlotController implements ReactiveController {\n public static anonymous = Symbol('anonymous slot');\n\n #nodes = new Map<string | typeof SlotController.anonymous, Slot>();\n\n #logger: Logger;\n\n #firstUpdated = false;\n\n #mo = new MutationObserver(records => this.#onMutation(records));\n\n #slotNames: (string | null)[];\n\n #deprecations: Record<string, string> = {};\n\n constructor(public host: ReactiveElement, ...config: ([SlotsConfig] | (string | null)[])) {\n this.#logger = new Logger(this.host);\n\n if (isObjectConfigSpread(config)) {\n const [{ slots, deprecations }] = config;\n this.#slotNames = slots;\n this.#deprecations = deprecations ?? {};\n } else if (config.length >= 1) {\n this.#slotNames = config;\n this.#deprecations = {};\n } else {\n this.#slotNames = [null];\n }\n\n\n host.addController(this);\n }\n\n async hostConnected() {\n this.host.addEventListener('slotchange', this.#onSlotChange as EventListener);\n this.#firstUpdated = false;\n this.#mo.observe(this.host, { childList: true });\n // Map the defined slots into an object that is easier to query\n this.#nodes.clear();\n // Loop over the properties provided by the schema\n this.#slotNames.forEach(this.#initSlot);\n Object.values(this.#deprecations).forEach(this.#initSlot);\n this.host.requestUpdate();\n // insurance for framework integrations\n await this.host.updateComplete;\n this.host.requestUpdate();\n }\n\n hostUpdated() {\n if (!this.#firstUpdated) {\n this.#slotNames.forEach(this.#initSlot);\n this.#firstUpdated = true;\n }\n }\n\n hostDisconnected() {\n this.#mo.disconnect();\n }\n\n /**\n * Returns a boolean statement of whether or not any of those slots exists in the light DOM.\n *\n * @param {String|Array} name The slot name.\n * @example this.hasSlotted(\"header\");\n */\n hasSlotted(...names: string[]): boolean {\n if (!names.length) {\n this.#logger.warn(`Please provide at least one slot name for which to search.`);\n return false;\n } else {\n return names.some(x =>\n this.#nodes.get(x)?.hasContent ?? false);\n }\n }\n\n /**\n * Given a slot name or slot names, returns elements assigned to the requested slots as an array.\n * If no value is provided, it returns all children not assigned to a slot (without a slot attribute).\n *\n * @example Get header-slotted elements\n * ```js\n * this.getSlotted('header')\n * ```\n *\n * @example Get header- and footer-slotted elements\n * ```js\n * this.getSlotted('header', 'footer')\n * ```\n *\n * @example Get default-slotted elements\n * ```js\n * this.getSlotted();\n * ```\n */\n getSlotted<T extends Element = Element>(...slotNames: string[]): T[] {\n if (!slotNames.length) {\n return (this.#nodes.get(SlotController.anonymous)?.elements ?? []) as T[];\n } else {\n return slotNames.flatMap(slotName =>\n this.#nodes.get(slotName)?.elements ?? []) as T[];\n }\n }\n\n #onSlotChange = (event: Event & { target: HTMLSlotElement }) => {\n const slotName = event.target.name;\n this.#initSlot(slotName);\n this.host.requestUpdate();\n };\n\n #onMutation = async (records: MutationRecord[]) => {\n const changed = [];\n for (const { addedNodes, removedNodes } of records) {\n for (const node of [...addedNodes, ...removedNodes]) {\n if (node instanceof HTMLElement && node.slot) {\n this.#initSlot(node.slot);\n changed.push(node.slot);\n }\n }\n }\n this.host.requestUpdate();\n };\n\n #getChildrenForSlot<T extends Element = Element>(name: string | typeof SlotController.anonymous): T[] {\n const children = Array.from(this.host.children) as T[];\n return children.filter(isSlot(name));\n }\n\n #initSlot = (slotName: string | null) => {\n const name = slotName || SlotController.anonymous;\n const elements = this.#nodes.get(name)?.slot?.assignedElements?.() ?? this.#getChildrenForSlot(name);\n const selector = slotName ? `slot[name=\"${slotName}\"]` : 'slot:not([name])';\n const slot = this.host.shadowRoot?.querySelector?.<HTMLSlotElement>(selector) ?? null;\n const hasContent = !!elements.length;\n this.#nodes.set(name, { elements, name: slotName ?? '', hasContent, slot });\n this.#logger.log(slotName, hasContent);\n };\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import type { ReactiveController, ReactiveControllerHost } from 'lit';
2
+ export type DateTimeFormat = 'full' | 'long' | 'medium' | 'short';
3
+ export interface TimestampOptions {
4
+ dateFormat?: DateTimeFormat;
5
+ timeFormat?: DateTimeFormat;
6
+ customFormat?: Intl.DateTimeFormatOptions;
7
+ displaySuffix: string;
8
+ locale: Intl.LocalesArgument;
9
+ relative: boolean;
10
+ utc: boolean;
11
+ hour12: boolean;
12
+ }
13
+ export declare class TimestampController implements ReactiveController {
14
+ #private;
15
+ get localeString(): string;
16
+ get date(): Date;
17
+ set date(string: Date);
18
+ get isoString(): string;
19
+ get time(): string;
20
+ constructor(host: ReactiveControllerHost, options?: Partial<TimestampOptions>);
21
+ hostConnected?(): void;
22
+ set(prop: PropertyKey, value: unknown): void;
23
+ }