@fluid-topics/ft-wc-utils 2.0.15 → 2.0.17

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.
@@ -16,7 +16,8 @@ export class ClusteringHelper {
16
16
  return results === null || results === void 0 ? void 0 : results.find((result) => { var _a; return ((_a = this.extractResultMetadata({ result }).find((meta) => meta.key == metadataKey)) === null || _a === void 0 ? void 0 : _a.value) == metadataValue; });
17
17
  }
18
18
  static extractResultMetadata(options) {
19
- const metadata = accessResult(options.result).metadata;
19
+ var _a, _b;
20
+ const metadata = (_b = (_a = accessResult(options.result)) === null || _a === void 0 ? void 0 : _a.metadata) !== null && _b !== void 0 ? _b : [];
20
21
  if (options.key == null) {
21
22
  return ClusteringHelper.flattenMetadata(metadata, options.hierarchicalValueTruncatingLevel, options.dateFormatter);
22
23
  }
@@ -14,13 +14,12 @@ const constructorPrototype = Symbol("constructorPrototype");
14
14
  const constructorName = Symbol("constructorName");
15
15
  const exportpartsDebouncer = Symbol("exportpartsDebouncer");
16
16
  const dynamicDependenciesLoaded = Symbol("dynamicDependenciesLoaded");
17
- class ExportpartsUpdatedEvent extends CustomEvent {
17
+ export class ExportpartsUpdatedEvent extends CustomEvent {
18
18
  constructor() {
19
19
  super(ExportpartsUpdatedEvent.eventName, { bubbles: true });
20
20
  }
21
21
  }
22
22
  ExportpartsUpdatedEvent.eventName = "exportparts-updated";
23
- export { ExportpartsUpdatedEvent };
24
23
  export class FtLitElement extends ScopedRegistryLitElement {
25
24
  constructor() {
26
25
  super();
@@ -1,6 +1,7 @@
1
1
  import { FtSearchRequest } from "@fluid-topics/public-api";
2
2
  export interface EnrichedFtSearchRequest extends FtSearchRequest {
3
3
  otherQueryParams?: Record<string, string>;
4
+ changedByConfiguration?: boolean;
4
5
  }
5
6
  /** @deprecated replace with SearchPlaceConverter.serialize */
6
7
  export declare function serializeRequest(baseUrl: string, request: EnrichedFtSearchRequest): string;
@@ -102,7 +102,7 @@ export class SearchPlaceConverter {
102
102
  if (request.scope && request.scope !== "DEFAULT") {
103
103
  params.append(SearchPlaceQueryParams.SCOPE, request.scope.toLowerCase());
104
104
  }
105
- if (request.sortId != undefined) {
105
+ if (request.sortId != undefined && request.sortId !== "relevance") {
106
106
  params.append(SearchPlaceQueryParams.SORT, request.sortId);
107
107
  }
108
108
  if (((_h = request.paging) === null || _h === void 0 ? void 0 : _h.perPage) && ((_k = (_j = request.paging) === null || _j === void 0 ? void 0 : _j.perPage) !== null && _k !== void 0 ? _k : this.defaultPerPage) != this.defaultPerPage) {
@@ -0,0 +1,44 @@
1
+ import { ElementPart } from "lit";
2
+ import { AsyncDirective, PartInfo } from "lit/async-directive.js";
3
+ /**
4
+ * This directive will trap the focus inside the element it's attached to, by creating 2 invisible elements at the top and bottom of it.
5
+ * Once the focus is trapped, it will circle from top to bottom.
6
+ * This accessibility behaviour can be used in modals and other popover elements, but there should always be a mean to quit the trapping element
7
+ * (for example by pressing Escape) which should be handled separately from this directive.
8
+ *
9
+ * Use directly on the container you want to trap the focus inside.
10
+ * <pre><div id="my-container" ${ focusTrap() }>
11
+ * <!-- elements to cycle on... -->
12
+ * <div></pre>
13
+ */
14
+ export declare class FocusTrapDirective extends AsyncDirective {
15
+ private firstTrap?;
16
+ private lastTrap?;
17
+ private part?;
18
+ private get element();
19
+ private readonly onFirstTrapFocus;
20
+ private readonly onLastTrapFocus;
21
+ constructor(partInfo: PartInfo);
22
+ render(): symbol;
23
+ update(part: ElementPart): symbol;
24
+ reconnected(): void;
25
+ disconnected(): void;
26
+ private isElementTrappable;
27
+ private createFocusTrap;
28
+ /**
29
+ * Creates an invisible focusable element
30
+ */
31
+ private createTrap;
32
+ private getChildren;
33
+ private focusFirstDescendant;
34
+ private focusLastDescendant;
35
+ private updateCompleteIfNecessary;
36
+ private isInsideElement;
37
+ /**
38
+ * Try to focus an element if focusable and return true, otherwise return false
39
+ */
40
+ private attemptFocus;
41
+ private isFocusable;
42
+ private isElementDisabled;
43
+ }
44
+ export declare const focusTrap: () => import("lit-html/directive").DirectiveResult<typeof FocusTrapDirective>;
@@ -0,0 +1,169 @@
1
+ import { noChange, } from "lit";
2
+ import { AsyncDirective, directive, } from "lit/async-directive.js";
3
+ import { ReactiveElement } from "lit-element";
4
+ /**
5
+ * This directive will trap the focus inside the element it's attached to, by creating 2 invisible elements at the top and bottom of it.
6
+ * Once the focus is trapped, it will circle from top to bottom.
7
+ * This accessibility behaviour can be used in modals and other popover elements, but there should always be a mean to quit the trapping element
8
+ * (for example by pressing Escape) which should be handled separately from this directive.
9
+ *
10
+ * Use directly on the container you want to trap the focus inside.
11
+ * <pre><div id="my-container" ${ focusTrap() }>
12
+ * <!-- elements to cycle on... -->
13
+ * <div></pre>
14
+ */
15
+ export class FocusTrapDirective extends AsyncDirective {
16
+ get element() {
17
+ var _a;
18
+ return (_a = this.part) === null || _a === void 0 ? void 0 : _a.element;
19
+ }
20
+ constructor(partInfo) {
21
+ super(partInfo);
22
+ this.onFirstTrapFocus = async (event) => {
23
+ if (!this.element || !event.relatedTarget) {
24
+ return;
25
+ }
26
+ const previousFocusedElement = event.relatedTarget; // In case of a focus event, should always be an Element
27
+ const isPreviousFocusInsideOfTrap = this.isInsideElement(previousFocusedElement, this.element);
28
+ if (isPreviousFocusInsideOfTrap) {
29
+ await this.focusLastDescendant(this.element);
30
+ }
31
+ else {
32
+ await this.focusFirstDescendant(this.element);
33
+ }
34
+ };
35
+ this.onLastTrapFocus = async (event) => {
36
+ if (!this.element || !event.relatedTarget) {
37
+ return;
38
+ }
39
+ const previousFocusedElement = event.relatedTarget; // In case of a focus event, should always be an Element
40
+ const isPreviousFocusInsideOfTrap = this.isInsideElement(previousFocusedElement, this.element);
41
+ if (isPreviousFocusInsideOfTrap) {
42
+ await this.focusFirstDescendant(this.element);
43
+ }
44
+ else {
45
+ await this.focusLastDescendant(this.element);
46
+ }
47
+ };
48
+ }
49
+ render() {
50
+ return noChange;
51
+ }
52
+ update(part) {
53
+ this.part = part;
54
+ if (this.isElementTrappable(part.element)) {
55
+ this.createFocusTrap(part.element);
56
+ }
57
+ return noChange;
58
+ }
59
+ reconnected() {
60
+ var _a;
61
+ if (this.isElementTrappable((_a = this.part) === null || _a === void 0 ? void 0 : _a.element)) {
62
+ this.createFocusTrap(this.part.element);
63
+ }
64
+ }
65
+ disconnected() {
66
+ var _a, _b, _c, _d;
67
+ (_a = this.firstTrap) === null || _a === void 0 ? void 0 : _a.removeEventListener("focus", this.onFirstTrapFocus);
68
+ (_b = this.lastTrap) === null || _b === void 0 ? void 0 : _b.removeEventListener("focus", this.onLastTrapFocus);
69
+ (_c = this.firstTrap) === null || _c === void 0 ? void 0 : _c.remove();
70
+ (_d = this.lastTrap) === null || _d === void 0 ? void 0 : _d.remove();
71
+ this.firstTrap = undefined;
72
+ this.lastTrap = undefined;
73
+ }
74
+ isElementTrappable(element) {
75
+ return !!element && (element instanceof HTMLElement) && element.childElementCount > 0;
76
+ }
77
+ createFocusTrap(element) {
78
+ this.firstTrap = this.createTrap();
79
+ this.lastTrap = this.createTrap();
80
+ element.insertBefore(this.firstTrap, element.firstChild);
81
+ element.appendChild(this.lastTrap);
82
+ this.lastTrap.addEventListener("focus", this.onLastTrapFocus);
83
+ this.firstTrap.addEventListener("focus", this.onFirstTrapFocus);
84
+ }
85
+ /**
86
+ * Creates an invisible focusable element
87
+ */
88
+ createTrap() {
89
+ const trapElement = document.createElement("div");
90
+ trapElement.tabIndex = 0;
91
+ return trapElement;
92
+ }
93
+ getChildren(element) {
94
+ if (element instanceof HTMLSlotElement) {
95
+ return element.assignedElements();
96
+ }
97
+ if (element.shadowRoot) {
98
+ return element.shadowRoot.children;
99
+ }
100
+ return element.children;
101
+ }
102
+ async focusFirstDescendant(element) {
103
+ await this.updateCompleteIfNecessary(element);
104
+ const children = this.getChildren(element);
105
+ for (let i = 0; i < children.length; i++) {
106
+ const child = children[i];
107
+ if (child instanceof HTMLElement && (this.attemptFocus(child) || await this.focusFirstDescendant(child))) {
108
+ return true;
109
+ }
110
+ }
111
+ return false;
112
+ }
113
+ async focusLastDescendant(element) {
114
+ await this.updateCompleteIfNecessary(element);
115
+ const children = this.getChildren(element);
116
+ for (let i = children.length - 1; i >= 0; i--) { // We cycle through the list backwards to find the latest element focusable
117
+ const child = children[i];
118
+ if (child instanceof HTMLElement && (this.attemptFocus(child) || await this.focusLastDescendant(child))) {
119
+ return true;
120
+ }
121
+ }
122
+ return false;
123
+ }
124
+ async updateCompleteIfNecessary(element) {
125
+ if (element instanceof ReactiveElement) {
126
+ await element.updateComplete;
127
+ }
128
+ }
129
+ isInsideElement(target, container) {
130
+ for (let node = target; node; node = node.parentNode) {
131
+ if (node === container) {
132
+ return true;
133
+ }
134
+ if (node instanceof ShadowRoot) {
135
+ node = node.host;
136
+ }
137
+ else if (node.assignedSlot) {
138
+ node = node.assignedSlot;
139
+ }
140
+ }
141
+ return false;
142
+ }
143
+ /**
144
+ * Try to focus an element if focusable and return true, otherwise return false
145
+ */
146
+ attemptFocus(element) {
147
+ if (element === this.firstTrap || element === this.lastTrap || !this.isFocusable(element)) {
148
+ return false;
149
+ }
150
+ element.focus();
151
+ return true;
152
+ }
153
+ isFocusable(element) {
154
+ if (!element.checkVisibility() || this.isElementDisabled(element)) {
155
+ return false;
156
+ }
157
+ if (element instanceof HTMLAnchorElement) {
158
+ return !!element.href && element.rel !== "ignore";
159
+ }
160
+ if (element instanceof HTMLInputElement) {
161
+ return element.type !== "hidden";
162
+ }
163
+ return element.tabIndex >= 0;
164
+ }
165
+ isElementDisabled(element) {
166
+ return "disabled" in element && !!element.disabled;
167
+ }
168
+ }
169
+ export const focusTrap = directive(FocusTrapDirective);
@@ -1 +1,2 @@
1
+ export * from "./focusTrap";
1
2
  export * from "./whenSize";
@@ -1 +1,2 @@
1
+ export * from "./focusTrap";
1
2
  export * from "./whenSize";