@aquera/nile-elements 1.7.1 → 1.7.3
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.
- package/README.md +7 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1524 -419
- package/dist/nile-breadcrumb-item/nile-breadcrumb-item.cjs.js +1 -1
- package/dist/nile-breadcrumb-item/nile-breadcrumb-item.cjs.js.map +1 -1
- package/dist/nile-breadcrumb-item/nile-breadcrumb-item.esm.js +8 -6
- package/dist/nile-combobox/group-utils.cjs.js +2 -0
- package/dist/nile-combobox/group-utils.cjs.js.map +1 -0
- package/dist/nile-combobox/group-utils.esm.js +1 -0
- package/dist/nile-combobox/index.cjs.js +2 -0
- package/dist/nile-combobox/index.cjs.js.map +1 -0
- package/dist/nile-combobox/index.esm.js +1 -0
- package/dist/nile-combobox/nile-combobox.cjs.js +2 -0
- package/dist/nile-combobox/nile-combobox.cjs.js.map +1 -0
- package/dist/nile-combobox/nile-combobox.css.cjs.js +2 -0
- package/dist/nile-combobox/nile-combobox.css.cjs.js.map +1 -0
- package/dist/nile-combobox/nile-combobox.css.esm.js +715 -0
- package/dist/nile-combobox/nile-combobox.esm.js +238 -0
- package/dist/nile-combobox/portal-manager.cjs.js +2 -0
- package/dist/nile-combobox/portal-manager.cjs.js.map +1 -0
- package/dist/nile-combobox/portal-manager.esm.js +1 -0
- package/dist/nile-combobox/renderer.cjs.js +2 -0
- package/dist/nile-combobox/renderer.cjs.js.map +1 -0
- package/dist/nile-combobox/renderer.esm.js +147 -0
- package/dist/nile-combobox/search-manager.cjs.js +2 -0
- package/dist/nile-combobox/search-manager.cjs.js.map +1 -0
- package/dist/nile-combobox/search-manager.esm.js +1 -0
- package/dist/nile-combobox/selection-manager.cjs.js +2 -0
- package/dist/nile-combobox/selection-manager.cjs.js.map +1 -0
- package/dist/nile-combobox/selection-manager.esm.js +1 -0
- package/dist/nile-combobox/types.cjs.js +2 -0
- package/dist/nile-combobox/types.cjs.js.map +1 -0
- package/dist/nile-combobox/types.esm.js +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/nile-breadcrumb-item/nile-breadcrumb-item.js +4 -2
- package/dist/src/nile-breadcrumb-item/nile-breadcrumb-item.js.map +1 -1
- package/dist/src/nile-combobox/group-utils.d.ts +26 -0
- package/dist/src/nile-combobox/group-utils.js +140 -0
- package/dist/src/nile-combobox/group-utils.js.map +1 -0
- package/dist/src/nile-combobox/index.d.ts +1 -0
- package/dist/src/nile-combobox/index.js +2 -0
- package/dist/src/nile-combobox/index.js.map +1 -0
- package/dist/src/nile-combobox/nile-combobox.css.d.ts +9 -0
- package/dist/src/nile-combobox/nile-combobox.css.js +724 -0
- package/dist/src/nile-combobox/nile-combobox.css.js.map +1 -0
- package/dist/src/nile-combobox/nile-combobox.d.ts +320 -0
- package/dist/src/nile-combobox/nile-combobox.js +1739 -0
- package/dist/src/nile-combobox/nile-combobox.js.map +1 -0
- package/dist/src/nile-combobox/nile-combobox.test.d.ts +1 -0
- package/dist/src/nile-combobox/nile-combobox.test.js +551 -0
- package/dist/src/nile-combobox/nile-combobox.test.js.map +1 -0
- package/dist/src/nile-combobox/portal-manager.d.ts +26 -0
- package/dist/src/nile-combobox/portal-manager.js +218 -0
- package/dist/src/nile-combobox/portal-manager.js.map +1 -0
- package/dist/src/nile-combobox/renderer.d.ts +24 -0
- package/dist/src/nile-combobox/renderer.js +279 -0
- package/dist/src/nile-combobox/renderer.js.map +1 -0
- package/dist/src/nile-combobox/search-manager.d.ts +15 -0
- package/dist/src/nile-combobox/search-manager.js +41 -0
- package/dist/src/nile-combobox/search-manager.js.map +1 -0
- package/dist/src/nile-combobox/selection-manager.d.ts +12 -0
- package/dist/src/nile-combobox/selection-manager.js +44 -0
- package/dist/src/nile-combobox/selection-manager.js.map +1 -0
- package/dist/src/nile-combobox/types.d.ts +53 -0
- package/dist/src/nile-combobox/types.js +8 -0
- package/dist/src/nile-combobox/types.js.map +1 -0
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -1
- package/src/index.ts +1 -0
- package/src/nile-breadcrumb-item/nile-breadcrumb-item.ts +4 -2
- package/src/nile-combobox/group-utils.ts +157 -0
- package/src/nile-combobox/index.ts +1 -0
- package/src/nile-combobox/nile-combobox.css.ts +726 -0
- package/src/nile-combobox/nile-combobox.test.ts +704 -0
- package/src/nile-combobox/nile-combobox.ts +1816 -0
- package/src/nile-combobox/portal-manager.ts +263 -0
- package/src/nile-combobox/renderer.ts +466 -0
- package/src/nile-combobox/search-manager.ts +53 -0
- package/src/nile-combobox/selection-manager.ts +57 -0
- package/src/nile-combobox/types.ts +63 -0
- package/vscode-html-custom-data.json +311 -4
- package/web-dev-server.config.mjs +9 -0
- package/web-test-runner.config.mjs +11 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Webcomponent nile-elements following open-wc recommendations",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "nile-elements",
|
|
6
|
-
"version": "1.7.
|
|
6
|
+
"version": "1.7.3",
|
|
7
7
|
"main": "dist/src/index.js",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"module": "dist/src/index.js",
|
|
@@ -119,6 +119,7 @@
|
|
|
119
119
|
"./nile-inline-sidebar-item": "./dist/src/nile-inline-sidebar-item/index.js",
|
|
120
120
|
"./nile-lite-tooltip": "./dist/src/nile-lite-tooltip/index.js",
|
|
121
121
|
"./nile-qr-code": "./dist/src/nile-qr-code/index.js",
|
|
122
|
+
"./nile-combobox": "./dist/src/nile-combobox/index.js",
|
|
122
123
|
"./nile-floating-panel": "./dist/src/nile-floating-panel/index.js",
|
|
123
124
|
"./nile-inline-sidebar-item-header": "./dist/src/nile-inline-sidebar-item-header/index.js",
|
|
124
125
|
"./nile-inline-sidebar-item-body": "./dist/src/nile-inline-sidebar-item-body/index.js",
|
|
@@ -154,6 +155,7 @@
|
|
|
154
155
|
"@floating-ui/dom": "^1.2.1",
|
|
155
156
|
"@lit-labs/observers": "^2.0.6",
|
|
156
157
|
"@lit-labs/virtualizer": "^2.0.15",
|
|
158
|
+
"@tanstack/lit-virtual": "^3.13.22",
|
|
157
159
|
"@open-wc/form-control": "^0.5.0",
|
|
158
160
|
"@open-wc/form-helpers": "^0.2.1",
|
|
159
161
|
"@rollup/plugin-commonjs": "^25.0.3",
|
package/src/index.ts
CHANGED
|
@@ -25,6 +25,7 @@ export { NileIconButton } from './nile-icon-button';
|
|
|
25
25
|
export { NileMenuItem } from './nile-menu-item';
|
|
26
26
|
export { NileDropdown } from './nile-dropdown';
|
|
27
27
|
export { NileAutoComplete } from './nile-auto-complete';
|
|
28
|
+
export { NileCombobox } from './nile-combobox';
|
|
28
29
|
export { NileChip } from './nile-chip';
|
|
29
30
|
export { NileTextarea } from './nile-textarea';
|
|
30
31
|
export { NileDatePicker } from './nile-date-picker';
|
|
@@ -53,13 +53,15 @@ export class NileBreadcrumbItem extends NileElement {
|
|
|
53
53
|
|
|
54
54
|
public render(): TemplateResult {
|
|
55
55
|
return html`
|
|
56
|
-
|
|
56
|
+
<div part="item"
|
|
57
57
|
class=${classMap({
|
|
58
58
|
'nile-breadcrumb-item__slot-text': !this.isLast,
|
|
59
59
|
'nile-breadcrumb-item__last-slot-text': this.isLast,
|
|
60
60
|
})}
|
|
61
61
|
@click=${this.handleClick}
|
|
62
|
-
|
|
62
|
+
>
|
|
63
|
+
<slot></slot>
|
|
64
|
+
</div>
|
|
63
65
|
<nile-icon
|
|
64
66
|
name=${this.separator}
|
|
65
67
|
aria-label=${this.separator}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Aquera Inc 2025
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the BSD-3-Clause license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
ComboboxDataItem,
|
|
10
|
+
ComboboxGroupItem,
|
|
11
|
+
ComboboxOptionItem,
|
|
12
|
+
ComboboxRow,
|
|
13
|
+
ComboboxHeaderRow,
|
|
14
|
+
ComboboxOptionRow,
|
|
15
|
+
} from './types';
|
|
16
|
+
|
|
17
|
+
export function isGroup(item: any): item is ComboboxGroupItem {
|
|
18
|
+
return !!item && typeof item === 'object' && item.type === 'group' && Array.isArray(item.options);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function hasGroups(data: any[]): boolean {
|
|
22
|
+
if (!Array.isArray(data)) return false;
|
|
23
|
+
for (const item of data) {
|
|
24
|
+
if (isGroup(item)) return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function countOptionsDeep(group: ComboboxGroupItem): number {
|
|
30
|
+
let n = 0;
|
|
31
|
+
for (const child of group.options) {
|
|
32
|
+
if (isGroup(child)) n += countOptionsDeep(child);
|
|
33
|
+
else n += 1;
|
|
34
|
+
}
|
|
35
|
+
return n;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function flattenRows(data: ComboboxDataItem[]): ComboboxRow[] {
|
|
39
|
+
const rows: ComboboxRow[] = [];
|
|
40
|
+
const walk = (items: ComboboxDataItem[], depth: number, parentIds: string[]) => {
|
|
41
|
+
for (const item of items) {
|
|
42
|
+
if (isGroup(item)) {
|
|
43
|
+
rows.push({
|
|
44
|
+
kind: 'header',
|
|
45
|
+
id: item.id,
|
|
46
|
+
label: item.label,
|
|
47
|
+
prefix: item.prefix,
|
|
48
|
+
depth,
|
|
49
|
+
optionCount: countOptionsDeep(item),
|
|
50
|
+
} as ComboboxHeaderRow);
|
|
51
|
+
walk(item.options, depth + 1, [...parentIds, item.id]);
|
|
52
|
+
} else {
|
|
53
|
+
rows.push({
|
|
54
|
+
kind: 'option',
|
|
55
|
+
item: item as ComboboxOptionItem,
|
|
56
|
+
depth,
|
|
57
|
+
parentIds,
|
|
58
|
+
} as ComboboxOptionRow);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
walk(Array.isArray(data) ? data : [], 0, []);
|
|
63
|
+
return rows;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function getOptionRows(rows: ComboboxRow[]): ComboboxOptionRow[] {
|
|
67
|
+
const out: ComboboxOptionRow[] = [];
|
|
68
|
+
for (const r of rows) if (r.kind === 'option') out.push(r);
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Filter rows by a query.
|
|
74
|
+
*
|
|
75
|
+
* Rules:
|
|
76
|
+
* - An option row is kept if its searchText matches.
|
|
77
|
+
* - If a group's label matches, the entire subtree (header + all descendant
|
|
78
|
+
* options + nested headers) is kept.
|
|
79
|
+
* - Otherwise a header is kept only if at least one descendant option matches.
|
|
80
|
+
* - Empty groups (no surviving descendants) are dropped.
|
|
81
|
+
*/
|
|
82
|
+
export function filterRows(
|
|
83
|
+
data: ComboboxDataItem[],
|
|
84
|
+
query: string,
|
|
85
|
+
getSearchText: (item: any) => string,
|
|
86
|
+
): { rows: ComboboxRow[]; visibleOptionCount: number } {
|
|
87
|
+
const q = (query || '').trim().toLowerCase();
|
|
88
|
+
if (!q) {
|
|
89
|
+
const rows = flattenRows(data);
|
|
90
|
+
return { rows, visibleOptionCount: getOptionRows(rows).length };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const matchedOption = (item: ComboboxOptionItem): boolean => {
|
|
94
|
+
const text = (getSearchText(item) || '').toString().toLowerCase();
|
|
95
|
+
return text.includes(q);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Walk the tree, returning a filtered subtree (or null when nothing survives).
|
|
99
|
+
type FilterResult =
|
|
100
|
+
| { kind: 'option'; item: ComboboxOptionItem }
|
|
101
|
+
| { kind: 'group'; group: ComboboxGroupItem; children: FilterResult[] }
|
|
102
|
+
| null;
|
|
103
|
+
|
|
104
|
+
const walk = (item: ComboboxDataItem, ancestorLabelMatched: boolean): FilterResult => {
|
|
105
|
+
if (isGroup(item)) {
|
|
106
|
+
const labelMatched = item.label.toLowerCase().includes(q);
|
|
107
|
+
const keepAll = labelMatched || ancestorLabelMatched;
|
|
108
|
+
const children: FilterResult[] = [];
|
|
109
|
+
for (const child of item.options) {
|
|
110
|
+
const sub = walk(child, keepAll);
|
|
111
|
+
if (sub) children.push(sub);
|
|
112
|
+
}
|
|
113
|
+
if (children.length === 0 && !keepAll) return null;
|
|
114
|
+
// If keepAll but nothing came back (empty group), still emit so user sees label.
|
|
115
|
+
return { kind: 'group', group: item, children };
|
|
116
|
+
}
|
|
117
|
+
if (ancestorLabelMatched || matchedOption(item as ComboboxOptionItem)) {
|
|
118
|
+
return { kind: 'option', item: item as ComboboxOptionItem };
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const tops: FilterResult[] = [];
|
|
124
|
+
for (const top of data) {
|
|
125
|
+
const r = walk(top, false);
|
|
126
|
+
if (r) tops.push(r);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Materialize back to flat rows.
|
|
130
|
+
const rows: ComboboxRow[] = [];
|
|
131
|
+
const emit = (results: FilterResult[], depth: number, parentIds: string[]) => {
|
|
132
|
+
for (const r of results) {
|
|
133
|
+
if (!r) continue;
|
|
134
|
+
if (r.kind === 'group') {
|
|
135
|
+
rows.push({
|
|
136
|
+
kind: 'header',
|
|
137
|
+
id: r.group.id,
|
|
138
|
+
label: r.group.label,
|
|
139
|
+
prefix: r.group.prefix,
|
|
140
|
+
depth,
|
|
141
|
+
optionCount: countOptionsDeep(r.group),
|
|
142
|
+
});
|
|
143
|
+
emit(r.children, depth + 1, [...parentIds, r.group.id]);
|
|
144
|
+
} else {
|
|
145
|
+
rows.push({
|
|
146
|
+
kind: 'option',
|
|
147
|
+
item: r.item,
|
|
148
|
+
depth,
|
|
149
|
+
parentIds,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
emit(tops, 0, []);
|
|
155
|
+
|
|
156
|
+
return { rows, visibleOptionCount: getOptionRows(rows).length };
|
|
157
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NileCombobox } from './nile-combobox';
|