@dodlhuat/basix 1.2.8 → 1.3.0
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 +1 -1
- package/package.json +4 -3
- package/svg-icons/icons.svg +284 -0
- package/js/bottom-sheet.ts +0 -224
- package/js/calendar.ts +0 -774
- package/js/carousel.ts +0 -222
- package/js/chart.ts +0 -694
- package/js/code-viewer.ts +0 -188
- package/js/context-menu.ts +0 -252
- package/js/datepicker.ts +0 -640
- package/js/dropdown.ts +0 -180
- package/js/editor.ts +0 -492
- package/js/file-uploader.ts +0 -361
- package/js/flyout-menu.ts +0 -255
- package/js/gallery.ts +0 -237
- package/js/group-picker.ts +0 -451
- package/js/lightbox.ts +0 -333
- package/js/modal.ts +0 -171
- package/js/popover.ts +0 -221
- package/js/position.ts +0 -111
- package/js/push-menu.ts +0 -286
- package/js/range-slider.ts +0 -33
- package/js/scroll.ts +0 -47
- package/js/scrollbar.ts +0 -335
- package/js/select.ts +0 -235
- package/js/sidebar-nav.ts +0 -66
- package/js/stepper.ts +0 -109
- package/js/table.ts +0 -459
- package/js/tabs.ts +0 -280
- package/js/theme.ts +0 -235
- package/js/timepicker.ts +0 -202
- package/js/toast.ts +0 -134
- package/js/tooltip.ts +0 -196
- package/js/tree.ts +0 -244
- package/js/tsconfig.json +0 -19
- package/js/utils.ts +0 -119
- package/js/virtual-dropdown.ts +0 -396
package/js/tree.ts
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
type NodeType = 'file' | 'folder';
|
|
2
|
-
|
|
3
|
-
interface TreeOptions {
|
|
4
|
-
onSelect?: (node: TreeNode) => void;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
class TreeNode {
|
|
8
|
-
public label: string;
|
|
9
|
-
public type: NodeType;
|
|
10
|
-
public children: TreeNode[];
|
|
11
|
-
public expanded: boolean;
|
|
12
|
-
public selected: boolean;
|
|
13
|
-
public element: HTMLDivElement | null;
|
|
14
|
-
public childrenContainer: HTMLUListElement | null;
|
|
15
|
-
|
|
16
|
-
constructor(label: string, type: NodeType = 'file', children: TreeNode[] = []) {
|
|
17
|
-
this.label = label;
|
|
18
|
-
this.type = type;
|
|
19
|
-
this.children = children;
|
|
20
|
-
this.expanded = false;
|
|
21
|
-
this.selected = false;
|
|
22
|
-
this.element = null;
|
|
23
|
-
this.childrenContainer = null;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
class TreeComponent {
|
|
28
|
-
private container: HTMLElement;
|
|
29
|
-
private data: TreeNode[];
|
|
30
|
-
private selectedNode: TreeNode | null;
|
|
31
|
-
private readonly options: TreeOptions;
|
|
32
|
-
|
|
33
|
-
constructor(elementOrSelector: string | HTMLElement, data: TreeNode[], options: TreeOptions = {}) {
|
|
34
|
-
const container = typeof elementOrSelector === 'string'
|
|
35
|
-
? document.querySelector<HTMLElement>(elementOrSelector)
|
|
36
|
-
: elementOrSelector;
|
|
37
|
-
|
|
38
|
-
if (!container) {
|
|
39
|
-
throw new Error(`TreeComponent: Element not found for selector "${elementOrSelector}"`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
this.container = container;
|
|
43
|
-
this.data = data;
|
|
44
|
-
this.selectedNode = null;
|
|
45
|
-
this.options = options;
|
|
46
|
-
this.init();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private init(): void {
|
|
50
|
-
this.render();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public render(): void {
|
|
54
|
-
this.container.innerHTML = '';
|
|
55
|
-
this.data.forEach(node => {
|
|
56
|
-
this.renderNode(node, this.container);
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private renderNode(node: TreeNode, parentElement: HTMLElement): void {
|
|
61
|
-
const li = document.createElement('li');
|
|
62
|
-
li.className = 'tree-node';
|
|
63
|
-
|
|
64
|
-
const itemDiv = document.createElement('div');
|
|
65
|
-
itemDiv.className = `tree-item ${node.type}`;
|
|
66
|
-
|
|
67
|
-
if (node.selected) itemDiv.classList.add('selected');
|
|
68
|
-
if (node.expanded) itemDiv.classList.add('expanded');
|
|
69
|
-
|
|
70
|
-
const iconDiv = this.createIconElement(node.type);
|
|
71
|
-
const labelSpan = this.createLabelElement(node.label);
|
|
72
|
-
|
|
73
|
-
itemDiv.append(iconDiv, labelSpan);
|
|
74
|
-
li.appendChild(itemDiv);
|
|
75
|
-
|
|
76
|
-
node.element = itemDiv;
|
|
77
|
-
|
|
78
|
-
if (node.type === 'folder' && node.children.length > 0) {
|
|
79
|
-
const childrenUl = this.createChildrenContainer(node);
|
|
80
|
-
li.appendChild(childrenUl);
|
|
81
|
-
node.childrenContainer = childrenUl;
|
|
82
|
-
|
|
83
|
-
itemDiv.addEventListener('click', (e) => {
|
|
84
|
-
e.stopPropagation();
|
|
85
|
-
this.toggleNode(node);
|
|
86
|
-
});
|
|
87
|
-
} else {
|
|
88
|
-
itemDiv.addEventListener('click', (e) => {
|
|
89
|
-
e.stopPropagation();
|
|
90
|
-
this.selectNode(node);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
parentElement.appendChild(li);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private createIconElement(type: NodeType): HTMLDivElement {
|
|
98
|
-
const iconDiv = document.createElement('div');
|
|
99
|
-
iconDiv.className = 'tree-icon';
|
|
100
|
-
|
|
101
|
-
if (type === 'folder') {
|
|
102
|
-
iconDiv.innerHTML = `
|
|
103
|
-
<svg class="chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
104
|
-
<path d="M9 18l6-6-6-6" stroke-linecap="round" stroke-linejoin="round"/>
|
|
105
|
-
</svg>
|
|
106
|
-
`;
|
|
107
|
-
} else {
|
|
108
|
-
iconDiv.innerHTML = `
|
|
109
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
110
|
-
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z" stroke-linecap="round" stroke-linejoin="round"/>
|
|
111
|
-
<path d="M13 2v7h7" stroke-linecap="round" stroke-linejoin="round"/>
|
|
112
|
-
</svg>
|
|
113
|
-
`;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return iconDiv;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private createLabelElement(label: string): HTMLSpanElement {
|
|
120
|
-
const labelSpan = document.createElement('span');
|
|
121
|
-
labelSpan.className = 'tree-label';
|
|
122
|
-
labelSpan.textContent = label;
|
|
123
|
-
return labelSpan;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private createChildrenContainer(node: TreeNode): HTMLUListElement {
|
|
127
|
-
const childrenUl = document.createElement('ul');
|
|
128
|
-
childrenUl.className = 'tree-children';
|
|
129
|
-
|
|
130
|
-
if (node.expanded) {
|
|
131
|
-
childrenUl.classList.add('expanded');
|
|
132
|
-
childrenUl.style.height = 'auto';
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
node.children.forEach(child => {
|
|
136
|
-
this.renderNode(child, childrenUl);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
return childrenUl;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private toggleNode(node: TreeNode): void {
|
|
143
|
-
node.expanded = !node.expanded;
|
|
144
|
-
node.element?.classList.toggle('expanded', node.expanded);
|
|
145
|
-
|
|
146
|
-
if (node.childrenContainer) {
|
|
147
|
-
if (node.expanded) {
|
|
148
|
-
this.expandChildren(node.childrenContainer);
|
|
149
|
-
} else {
|
|
150
|
-
this.collapseChildren(node.childrenContainer);
|
|
151
|
-
}
|
|
152
|
-
node.childrenContainer.classList.toggle('expanded', node.expanded);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private expandChildren(container: HTMLUListElement): void {
|
|
157
|
-
container.style.height = container.scrollHeight + 'px';
|
|
158
|
-
container.addEventListener('transitionend', () => {
|
|
159
|
-
container.style.height = 'auto';
|
|
160
|
-
}, { once: true });
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private collapseChildren(container: HTMLUListElement): void {
|
|
164
|
-
container.style.height = container.offsetHeight + 'px';
|
|
165
|
-
requestAnimationFrame(() => {
|
|
166
|
-
container.style.height = '0';
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
public selectNode(node: TreeNode): void {
|
|
171
|
-
if (this.selectedNode?.element) {
|
|
172
|
-
this.selectedNode.element.classList.remove('selected');
|
|
173
|
-
this.selectedNode.selected = false;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
node.selected = true;
|
|
177
|
-
node.element?.classList.add('selected');
|
|
178
|
-
this.selectedNode = node;
|
|
179
|
-
|
|
180
|
-
this.options.onSelect?.(node);
|
|
181
|
-
this.container.dispatchEvent(new CustomEvent('tree-select', {
|
|
182
|
-
detail: { node },
|
|
183
|
-
bubbles: true,
|
|
184
|
-
}));
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
public expandAll(): void {
|
|
188
|
-
this.traverseNodes(this.data, (node) => {
|
|
189
|
-
if (node.type === 'folder' && node.childrenContainer) {
|
|
190
|
-
node.expanded = true;
|
|
191
|
-
node.element?.classList.add('expanded');
|
|
192
|
-
node.childrenContainer.classList.add('expanded');
|
|
193
|
-
node.childrenContainer.style.height = 'auto';
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
public collapseAll(): void {
|
|
199
|
-
this.traverseNodes(this.data, (node) => {
|
|
200
|
-
if (node.type === 'folder' && node.childrenContainer) {
|
|
201
|
-
node.expanded = false;
|
|
202
|
-
node.element?.classList.remove('expanded');
|
|
203
|
-
node.childrenContainer.classList.remove('expanded');
|
|
204
|
-
node.childrenContainer.style.height = '0';
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
private traverseNodes(nodes: TreeNode[], callback: (node: TreeNode) => void): void {
|
|
210
|
-
nodes.forEach(node => {
|
|
211
|
-
callback(node);
|
|
212
|
-
if (node.children.length > 0) {
|
|
213
|
-
this.traverseNodes(node.children, callback);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
public destroy(): void {
|
|
219
|
-
this.container.innerHTML = '';
|
|
220
|
-
this.selectedNode = null;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
public getSelectedNode(): TreeNode | null {
|
|
224
|
-
return this.selectedNode;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
public findNodeByLabel(label: string): TreeNode | null {
|
|
228
|
-
return this.findNode(this.data, label);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
private findNode(nodes: TreeNode[], label: string): TreeNode | null {
|
|
232
|
-
for (const node of nodes) {
|
|
233
|
-
if (node.label === label) return node;
|
|
234
|
-
if (node.children.length > 0) {
|
|
235
|
-
const found = this.findNode(node.children, label);
|
|
236
|
-
if (found) return found;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
return null;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
export { TreeComponent, TreeNode };
|
|
244
|
-
export type { NodeType, TreeOptions };
|
package/js/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"outDir": ".",
|
|
6
|
-
"rootDir": ".",
|
|
7
|
-
"strict": true,
|
|
8
|
-
"declaration": true,
|
|
9
|
-
"types": [],
|
|
10
|
-
},
|
|
11
|
-
"include": [
|
|
12
|
-
"*.ts"
|
|
13
|
-
],
|
|
14
|
-
"exclude": [
|
|
15
|
-
"dist",
|
|
16
|
-
"node_modules",
|
|
17
|
-
"../node_modules"
|
|
18
|
-
]
|
|
19
|
-
}
|
package/js/utils.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility functions for DOM manipulation and element handling
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
interface Utils {
|
|
6
|
-
ready(fn: () => void): void;
|
|
7
|
-
value(element: HTMLElement): string;
|
|
8
|
-
text(element: HTMLElement): string;
|
|
9
|
-
attribute(element: HTMLElement, attribute: string): string | undefined;
|
|
10
|
-
isList(element: HTMLElement | NodeList): boolean;
|
|
11
|
-
isHidden(element: HTMLElement): boolean;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const utils: Utils = {
|
|
15
|
-
/**
|
|
16
|
-
* Execute a function when the DOM is ready
|
|
17
|
-
* @param fn - Callback function to execute
|
|
18
|
-
*/
|
|
19
|
-
ready(fn: () => void): void {
|
|
20
|
-
if (document.readyState === "complete" || document.readyState === "interactive") {
|
|
21
|
-
setTimeout(fn, 1);
|
|
22
|
-
} else {
|
|
23
|
-
document.addEventListener("DOMContentLoaded", fn);
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Get the value of an element from various sources
|
|
29
|
-
* Priority: value attribute > data-value attribute > innerText
|
|
30
|
-
* @param element - HTML element to get value from
|
|
31
|
-
* @returns The element's value as a string
|
|
32
|
-
*/
|
|
33
|
-
value(element: HTMLElement): string {
|
|
34
|
-
if (element.hasAttribute('value')) {
|
|
35
|
-
return element.getAttribute('value') || '';
|
|
36
|
-
}
|
|
37
|
-
if (element.hasAttribute('data-value')) {
|
|
38
|
-
return element.getAttribute('data-value') || '';
|
|
39
|
-
}
|
|
40
|
-
return element.innerText;
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Get the text content of an element
|
|
45
|
-
* @param element - HTML element to get text from
|
|
46
|
-
* @returns The element's inner text
|
|
47
|
-
*/
|
|
48
|
-
text(element: HTMLElement): string {
|
|
49
|
-
return element.innerText;
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Get an attribute value from an element
|
|
54
|
-
* @param element - HTML element to get attribute from
|
|
55
|
-
* @param attribute - Name of the attribute to retrieve
|
|
56
|
-
* @returns The attribute value or undefined if not present
|
|
57
|
-
*/
|
|
58
|
-
attribute(element: HTMLElement, attribute: string): string | undefined {
|
|
59
|
-
if (element.hasAttribute(attribute)) {
|
|
60
|
-
return element.getAttribute(attribute) || undefined;
|
|
61
|
-
}
|
|
62
|
-
return undefined;
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Check if an element is a NodeList
|
|
67
|
-
* @param element - Element or NodeList to check
|
|
68
|
-
* @returns True if the element is a NodeList
|
|
69
|
-
*/
|
|
70
|
-
isList(element: HTMLElement | NodeList): element is NodeList {
|
|
71
|
-
return NodeList.prototype.isPrototypeOf(element);
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Check if an element is hidden
|
|
76
|
-
* @param element - HTML element to check
|
|
77
|
-
* @returns True if the element is hidden
|
|
78
|
-
*/
|
|
79
|
-
isHidden(element: HTMLElement): boolean {
|
|
80
|
-
return element.offsetParent === null;
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Escape a plain-text string so it is safe to inject into innerHTML.
|
|
86
|
-
* Use this whenever inserting user-controlled strings into HTML templates.
|
|
87
|
-
*/
|
|
88
|
-
function escapeHtml(text: string): string {
|
|
89
|
-
const div = document.createElement('div');
|
|
90
|
-
div.textContent = text;
|
|
91
|
-
return div.innerHTML;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Sanitize an HTML string by removing dangerous elements and attributes
|
|
96
|
-
* (script, iframe, on* handlers, javascript: hrefs) while preserving safe markup.
|
|
97
|
-
* Use this when a component intentionally accepts rich HTML from callers.
|
|
98
|
-
*/
|
|
99
|
-
function sanitizeHtml(html: string): string {
|
|
100
|
-
const parser = new DOMParser();
|
|
101
|
-
const doc = parser.parseFromString(html, 'text/html');
|
|
102
|
-
|
|
103
|
-
doc.querySelectorAll('script, style, iframe, object, embed').forEach(el => el.remove());
|
|
104
|
-
|
|
105
|
-
doc.querySelectorAll('*').forEach(el => {
|
|
106
|
-
for (const attr of Array.from(el.attributes)) {
|
|
107
|
-
if (
|
|
108
|
-
attr.name.startsWith('on') ||
|
|
109
|
-
attr.value.trim().toLowerCase().startsWith('javascript:')
|
|
110
|
-
) {
|
|
111
|
-
el.removeAttribute(attr.name);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
return doc.body.innerHTML;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export { utils, escapeHtml, sanitizeHtml };
|