@dodlhuat/basix 1.3.4 → 1.4.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 +160 -18
- package/css/checkbox.scss +15 -2
- package/css/color-picker.scss +278 -0
- package/css/datepicker.scss +5 -3
- package/css/push-menu.scss +7 -0
- package/css/stepper.scss +1 -1
- package/css/style.css +291 -6
- package/css/style.css.map +1 -1
- package/css/style.min.css +1 -1
- package/css/style.min.css.map +1 -1
- package/css/style.scss +1 -0
- package/css/table.scss +33 -0
- package/js/bottom-sheet.d.ts +0 -2
- package/js/bottom-sheet.js +0 -2
- package/js/calendar.d.ts +9 -17
- package/js/calendar.js +4 -7
- package/js/carousel.d.ts +0 -2
- package/js/carousel.js +1 -3
- package/js/chart.d.ts +6 -14
- package/js/chart.js +3 -5
- package/js/code-viewer.d.ts +2 -1
- package/js/code-viewer.js +8 -2
- package/js/color-picker.d.ts +50 -0
- package/js/color-picker.js +291 -0
- package/js/context-menu.d.ts +0 -3
- package/js/context-menu.js +0 -3
- package/js/datepicker.d.ts +0 -4
- package/js/datepicker.js +0 -1
- package/js/docs-nav.js +1 -0
- package/js/dropdown.d.ts +1 -4
- package/js/dropdown.js +0 -1
- package/js/editor.d.ts +4 -3
- package/js/editor.js +50 -35
- package/js/file-uploader.d.ts +0 -4
- package/js/file-uploader.js +0 -1
- package/js/flyout-menu.d.ts +0 -2
- package/js/flyout-menu.js +0 -1
- package/js/gallery.d.ts +1 -4
- package/js/gallery.js +18 -23
- package/js/group-picker.d.ts +0 -5
- package/js/group-picker.js +6 -8
- package/js/lightbox.d.ts +1 -4
- package/js/lightbox.js +6 -10
- package/js/modal.d.ts +0 -2
- package/js/modal.js +0 -1
- package/js/popover.d.ts +0 -3
- package/js/popover.js +0 -2
- package/js/position.d.ts +0 -13
- package/js/position.js +0 -12
- package/js/push-menu.d.ts +0 -3
- package/js/push-menu.js +6 -11
- package/js/range-slider.d.ts +0 -1
- package/js/range-slider.js +2 -3
- package/js/scroll.d.ts +0 -2
- package/js/scroll.js +5 -6
- package/js/scrollbar.d.ts +2 -10
- package/js/scrollbar.js +25 -42
- package/js/select.d.ts +2 -3
- package/js/select.js +6 -9
- package/js/sidebar-nav.d.ts +4 -15
- package/js/sidebar-nav.js +21 -35
- package/js/stepper.d.ts +5 -2
- package/js/stepper.js +42 -6
- package/js/table.d.ts +1 -56
- package/js/table.js +4 -56
- package/js/tabs.d.ts +1 -32
- package/js/tabs.js +7 -39
- package/js/theme.d.ts +0 -44
- package/js/theme.js +0 -44
- package/js/timepicker.d.ts +1 -4
- package/js/timepicker.js +1 -2
- package/js/toast.d.ts +0 -2
- package/js/toast.js +0 -1
- package/js/tooltip.d.ts +0 -4
- package/js/tooltip.js +0 -1
- package/js/tree.d.ts +0 -3
- package/js/tree.js +9 -11
- package/js/utils.d.ts +0 -10
- package/js/utils.js +2 -42
- package/js/virtual-dropdown.d.ts +3 -5
- package/js/virtual-dropdown.js +17 -66
- package/package.json +1 -1
package/js/utils.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** Shape of the `utils` helper object. */
|
|
2
1
|
interface Utils {
|
|
3
2
|
ready(fn: () => void): void;
|
|
4
3
|
value(element: HTMLElement): string;
|
|
@@ -8,15 +7,6 @@ interface Utils {
|
|
|
8
7
|
isHidden(element: HTMLElement): boolean;
|
|
9
8
|
}
|
|
10
9
|
declare const utils: Utils;
|
|
11
|
-
/**
|
|
12
|
-
* Escape a plain-text string so it is safe to inject into innerHTML.
|
|
13
|
-
* Use this whenever inserting user-controlled strings into HTML templates.
|
|
14
|
-
*/
|
|
15
10
|
declare function escapeHtml(text: string): string;
|
|
16
|
-
/**
|
|
17
|
-
* Sanitize an HTML string by removing dangerous elements and attributes
|
|
18
|
-
* (script, iframe, on* handlers, javascript: hrefs) while preserving safe markup.
|
|
19
|
-
* Use this when a component intentionally accepts rich HTML from callers.
|
|
20
|
-
*/
|
|
21
11
|
declare function sanitizeHtml(html: string): string;
|
|
22
12
|
export { utils, escapeHtml, sanitizeHtml };
|
package/js/utils.js
CHANGED
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
const utils = {
|
|
2
|
-
/**
|
|
3
|
-
* Execute a function when the DOM is ready
|
|
4
|
-
* @param fn - Callback function to execute
|
|
5
|
-
*/
|
|
6
2
|
ready(fn) {
|
|
7
|
-
if (document.readyState ===
|
|
3
|
+
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
|
8
4
|
setTimeout(fn, 1);
|
|
9
5
|
}
|
|
10
6
|
else {
|
|
11
|
-
document.addEventListener(
|
|
7
|
+
document.addEventListener('DOMContentLoaded', fn);
|
|
12
8
|
}
|
|
13
9
|
},
|
|
14
|
-
/**
|
|
15
|
-
* Get the value of an element from various sources
|
|
16
|
-
* Priority: value attribute > data-value attribute > innerText
|
|
17
|
-
* @param element - HTML element to get value from
|
|
18
|
-
* @returns The element's value as a string
|
|
19
|
-
*/
|
|
20
10
|
value(element) {
|
|
21
11
|
if (element.hasAttribute('value')) {
|
|
22
12
|
return element.getAttribute('value') || '';
|
|
@@ -26,57 +16,27 @@ const utils = {
|
|
|
26
16
|
}
|
|
27
17
|
return element.innerText;
|
|
28
18
|
},
|
|
29
|
-
/**
|
|
30
|
-
* Get the text content of an element
|
|
31
|
-
* @param element - HTML element to get text from
|
|
32
|
-
* @returns The element's inner text
|
|
33
|
-
*/
|
|
34
19
|
text(element) {
|
|
35
20
|
return element.innerText;
|
|
36
21
|
},
|
|
37
|
-
/**
|
|
38
|
-
* Get an attribute value from an element
|
|
39
|
-
* @param element - HTML element to get attribute from
|
|
40
|
-
* @param attribute - Name of the attribute to retrieve
|
|
41
|
-
* @returns The attribute value or undefined if not present
|
|
42
|
-
*/
|
|
43
22
|
attribute(element, attribute) {
|
|
44
23
|
if (element.hasAttribute(attribute)) {
|
|
45
24
|
return element.getAttribute(attribute) || undefined;
|
|
46
25
|
}
|
|
47
26
|
return undefined;
|
|
48
27
|
},
|
|
49
|
-
/**
|
|
50
|
-
* Check if an element is a NodeList
|
|
51
|
-
* @param element - Element or NodeList to check
|
|
52
|
-
* @returns True if the element is a NodeList
|
|
53
|
-
*/
|
|
54
28
|
isList(element) {
|
|
55
29
|
return NodeList.prototype.isPrototypeOf(element);
|
|
56
30
|
},
|
|
57
|
-
/**
|
|
58
|
-
* Check if an element is hidden
|
|
59
|
-
* @param element - HTML element to check
|
|
60
|
-
* @returns True if the element is hidden
|
|
61
|
-
*/
|
|
62
31
|
isHidden(element) {
|
|
63
32
|
return element.offsetParent === null;
|
|
64
33
|
}
|
|
65
34
|
};
|
|
66
|
-
/**
|
|
67
|
-
* Escape a plain-text string so it is safe to inject into innerHTML.
|
|
68
|
-
* Use this whenever inserting user-controlled strings into HTML templates.
|
|
69
|
-
*/
|
|
70
35
|
function escapeHtml(text) {
|
|
71
36
|
const div = document.createElement('div');
|
|
72
37
|
div.textContent = text;
|
|
73
38
|
return div.innerHTML;
|
|
74
39
|
}
|
|
75
|
-
/**
|
|
76
|
-
* Sanitize an HTML string by removing dangerous elements and attributes
|
|
77
|
-
* (script, iframe, on* handlers, javascript: hrefs) while preserving safe markup.
|
|
78
|
-
* Use this when a component intentionally accepts rich HTML from callers.
|
|
79
|
-
*/
|
|
80
40
|
function sanitizeHtml(html) {
|
|
81
41
|
const parser = new DOMParser();
|
|
82
42
|
const doc = parser.parseFromString(html, 'text/html');
|
package/js/virtual-dropdown.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
/** A single selectable option for a VirtualDropdown. */
|
|
2
1
|
interface DropdownOption {
|
|
3
2
|
label: string;
|
|
4
3
|
value: string | number;
|
|
5
4
|
}
|
|
6
|
-
/** Configuration for a VirtualDropdown instance. */
|
|
7
5
|
interface VirtualDropdownConfig {
|
|
8
6
|
container: string | HTMLElement;
|
|
9
7
|
options: DropdownOption[];
|
|
@@ -14,7 +12,6 @@ interface VirtualDropdownConfig {
|
|
|
14
12
|
itemHeight?: number;
|
|
15
13
|
onSelect?: (selectedValues: Array<string | number>) => void;
|
|
16
14
|
}
|
|
17
|
-
/** Virtualised dropdown that renders only visible items for performance with large option lists. */
|
|
18
15
|
declare class VirtualDropdown {
|
|
19
16
|
private readonly container;
|
|
20
17
|
private readonly options;
|
|
@@ -37,7 +34,7 @@ declare class VirtualDropdown {
|
|
|
37
34
|
private filteredOptions;
|
|
38
35
|
private isOpen;
|
|
39
36
|
private scrollTop;
|
|
40
|
-
private
|
|
37
|
+
private abortController;
|
|
41
38
|
constructor(config: VirtualDropdownConfig);
|
|
42
39
|
private init;
|
|
43
40
|
private renderBase;
|
|
@@ -55,4 +52,5 @@ declare class VirtualDropdown {
|
|
|
55
52
|
clearSelection(): void;
|
|
56
53
|
destroy(): void;
|
|
57
54
|
}
|
|
58
|
-
export { VirtualDropdown
|
|
55
|
+
export { VirtualDropdown };
|
|
56
|
+
export type { DropdownOption, VirtualDropdownConfig };
|
package/js/virtual-dropdown.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { escapeHtml } from './utils.js';
|
|
2
|
-
/** Virtualised dropdown that renders only visible items for performance with large option lists. */
|
|
3
2
|
class VirtualDropdown {
|
|
4
3
|
container;
|
|
5
4
|
options;
|
|
@@ -9,8 +8,6 @@ class VirtualDropdown {
|
|
|
9
8
|
renderLimit;
|
|
10
9
|
itemHeight;
|
|
11
10
|
onSelect;
|
|
12
|
-
// Unique CSS anchor name for this instance — prevents conflicts when
|
|
13
|
-
// multiple dropdowns exist on the same page.
|
|
14
11
|
anchorName;
|
|
15
12
|
trigger;
|
|
16
13
|
triggerText;
|
|
@@ -24,7 +21,7 @@ class VirtualDropdown {
|
|
|
24
21
|
filteredOptions;
|
|
25
22
|
isOpen;
|
|
26
23
|
scrollTop;
|
|
27
|
-
|
|
24
|
+
abortController = new AbortController();
|
|
28
25
|
constructor(config) {
|
|
29
26
|
const containerElement = typeof config.container === 'string'
|
|
30
27
|
? document.querySelector(config.container)
|
|
@@ -45,7 +42,6 @@ class VirtualDropdown {
|
|
|
45
42
|
this.filteredOptions = [...this.options];
|
|
46
43
|
this.isOpen = false;
|
|
47
44
|
this.scrollTop = 0;
|
|
48
|
-
this.boundHandlers = new Map();
|
|
49
45
|
this.init();
|
|
50
46
|
}
|
|
51
47
|
init() {
|
|
@@ -77,8 +73,6 @@ class VirtualDropdown {
|
|
|
77
73
|
this.scroller = this.querySelector('.dropdown-list-scroller');
|
|
78
74
|
this.spacer = this.querySelector('.virtual-spacer');
|
|
79
75
|
this.content = this.querySelector('.virtual-content');
|
|
80
|
-
// Wire up anchor positioning: each instance gets a unique anchor name
|
|
81
|
-
// so multiple dropdowns on the same page don't interfere.
|
|
82
76
|
this.trigger.style.setProperty('anchor-name', this.anchorName);
|
|
83
77
|
this.menu.style.setProperty('position-anchor', this.anchorName);
|
|
84
78
|
if (this.searchable) {
|
|
@@ -93,10 +87,9 @@ class VirtualDropdown {
|
|
|
93
87
|
return element;
|
|
94
88
|
}
|
|
95
89
|
bindEvents() {
|
|
96
|
-
const
|
|
97
|
-
this.trigger.addEventListener('click',
|
|
98
|
-
this.
|
|
99
|
-
const handleTriggerKeydown = (e) => {
|
|
90
|
+
const sig = { signal: this.abortController.signal };
|
|
91
|
+
this.trigger.addEventListener('click', () => this.toggle(), sig);
|
|
92
|
+
this.trigger.addEventListener('keydown', (e) => {
|
|
100
93
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
101
94
|
e.preventDefault();
|
|
102
95
|
this.toggle();
|
|
@@ -104,46 +97,29 @@ class VirtualDropdown {
|
|
|
104
97
|
else if (e.key === 'Escape' && this.isOpen) {
|
|
105
98
|
this.close();
|
|
106
99
|
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
this.boundHandlers.set('triggerKeydown', handleTriggerKeydown);
|
|
110
|
-
// Close when clicking outside. Still needed because popover="manual"
|
|
111
|
-
// does not auto-dismiss on outside clicks.
|
|
112
|
-
const handleDocumentClick = (e) => {
|
|
100
|
+
}, sig);
|
|
101
|
+
document.addEventListener('click', (e) => {
|
|
113
102
|
if (!this.container.contains(e.target) && !this.menu.contains(e.target)) {
|
|
114
103
|
this.close();
|
|
115
104
|
}
|
|
116
|
-
};
|
|
117
|
-
document.addEventListener('click', handleDocumentClick);
|
|
118
|
-
this.boundHandlers.set('documentClick', handleDocumentClick);
|
|
105
|
+
}, sig);
|
|
119
106
|
if (this.searchable && this.searchInput) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
};
|
|
124
|
-
this.searchInput.addEventListener('input', handleSearchInput);
|
|
125
|
-
this.boundHandlers.set('searchInput', handleSearchInput);
|
|
107
|
+
this.searchInput.addEventListener('input', (e) => {
|
|
108
|
+
this.handleSearch(e.target.value);
|
|
109
|
+
}, sig);
|
|
126
110
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
this.scrollTop = target.scrollTop;
|
|
111
|
+
this.listWrapper.addEventListener('scroll', (e) => {
|
|
112
|
+
this.scrollTop = e.target.scrollTop;
|
|
130
113
|
this.renderList();
|
|
131
|
-
};
|
|
132
|
-
this.
|
|
133
|
-
this.boundHandlers.set('scroll', handleScroll);
|
|
134
|
-
// Sync isOpen if the browser closes the popover externally (e.g. another
|
|
135
|
-
// popover="auto" element stealing focus — not typical for "manual" but
|
|
136
|
-
// good defensive practice).
|
|
137
|
-
const handlePopoverToggle = (e) => {
|
|
114
|
+
}, sig);
|
|
115
|
+
this.menu.addEventListener('toggle', (e) => {
|
|
138
116
|
const te = e;
|
|
139
117
|
if (te.newState === 'closed' && this.isOpen) {
|
|
140
118
|
this.isOpen = false;
|
|
141
119
|
this.container.classList.remove('open');
|
|
142
120
|
this.trigger.setAttribute('aria-expanded', 'false');
|
|
143
121
|
}
|
|
144
|
-
};
|
|
145
|
-
this.menu.addEventListener('toggle', handlePopoverToggle);
|
|
146
|
-
this.boundHandlers.set('popoverToggle', handlePopoverToggle);
|
|
122
|
+
}, sig);
|
|
147
123
|
}
|
|
148
124
|
toggle() {
|
|
149
125
|
this.isOpen ? this.close() : this.open();
|
|
@@ -290,34 +266,9 @@ class VirtualDropdown {
|
|
|
290
266
|
}
|
|
291
267
|
}
|
|
292
268
|
destroy() {
|
|
293
|
-
if (this.isOpen)
|
|
269
|
+
if (this.isOpen)
|
|
294
270
|
this.menu.hidePopover();
|
|
295
|
-
|
|
296
|
-
const triggerClick = this.boundHandlers.get('triggerClick');
|
|
297
|
-
if (triggerClick) {
|
|
298
|
-
this.trigger.removeEventListener('click', triggerClick);
|
|
299
|
-
}
|
|
300
|
-
const triggerKeydown = this.boundHandlers.get('triggerKeydown');
|
|
301
|
-
if (triggerKeydown) {
|
|
302
|
-
this.trigger.removeEventListener('keydown', triggerKeydown);
|
|
303
|
-
}
|
|
304
|
-
const documentClick = this.boundHandlers.get('documentClick');
|
|
305
|
-
if (documentClick) {
|
|
306
|
-
document.removeEventListener('click', documentClick);
|
|
307
|
-
}
|
|
308
|
-
const searchInput = this.boundHandlers.get('searchInput');
|
|
309
|
-
if (searchInput && this.searchInput) {
|
|
310
|
-
this.searchInput.removeEventListener('input', searchInput);
|
|
311
|
-
}
|
|
312
|
-
const scroll = this.boundHandlers.get('scroll');
|
|
313
|
-
if (scroll) {
|
|
314
|
-
this.listWrapper.removeEventListener('scroll', scroll);
|
|
315
|
-
}
|
|
316
|
-
const popoverToggle = this.boundHandlers.get('popoverToggle');
|
|
317
|
-
if (popoverToggle) {
|
|
318
|
-
this.menu.removeEventListener('toggle', popoverToggle);
|
|
319
|
-
}
|
|
320
|
-
this.boundHandlers.clear();
|
|
271
|
+
this.abortController.abort();
|
|
321
272
|
this.container.innerHTML = '';
|
|
322
273
|
this.container.classList.remove('custom-dropdown', 'open');
|
|
323
274
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dodlhuat/basix",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Basix is intended as a starter for the rapid development of a design. Each design element can be added individually to include only the data required. It is using plain javascript / typescript and therefore is not dependent on any plugin.",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./css/*": "./css/*",
|