@keenthemes/ktui 1.1.2 → 1.1.4
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/dist/ktui.js +532 -59
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +51 -0
- package/lib/cjs/components/component.js +22 -0
- package/lib/cjs/components/component.js.map +1 -1
- package/lib/cjs/components/datatable/datatable.js +26 -7
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/drawer/drawer.js +255 -9
- package/lib/cjs/components/drawer/drawer.js.map +1 -1
- package/lib/cjs/components/dropdown/dropdown.js +55 -8
- package/lib/cjs/components/dropdown/dropdown.js.map +1 -1
- package/lib/cjs/components/select/search.js +17 -7
- package/lib/cjs/components/select/search.js.map +1 -1
- package/lib/cjs/components/select/select.js +92 -14
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/sticky/sticky.js +44 -5
- package/lib/cjs/components/sticky/sticky.js.map +1 -1
- package/lib/cjs/helpers/data.js +8 -0
- package/lib/cjs/helpers/data.js.map +1 -1
- package/lib/cjs/helpers/event-handler.js +6 -5
- package/lib/cjs/helpers/event-handler.js.map +1 -1
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/components/component.js +22 -0
- package/lib/esm/components/component.js.map +1 -1
- package/lib/esm/components/datatable/datatable.js +26 -7
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/drawer/drawer.js +255 -9
- package/lib/esm/components/drawer/drawer.js.map +1 -1
- package/lib/esm/components/dropdown/dropdown.js +55 -8
- package/lib/esm/components/dropdown/dropdown.js.map +1 -1
- package/lib/esm/components/select/search.js +17 -7
- package/lib/esm/components/select/search.js.map +1 -1
- package/lib/esm/components/select/select.js +92 -14
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/sticky/sticky.js +44 -5
- package/lib/esm/components/sticky/sticky.js.map +1 -1
- package/lib/esm/helpers/data.js +8 -0
- package/lib/esm/helpers/data.js.map +1 -1
- package/lib/esm/helpers/event-handler.js +6 -5
- package/lib/esm/helpers/event-handler.js.map +1 -1
- package/lib/esm/index.js.map +1 -1
- package/package.json +4 -2
- package/src/components/component.ts +26 -0
- package/src/components/datatable/__tests__/race-conditions.test.ts +2 -2
- package/src/components/datatable/datatable.ts +32 -7
- package/src/components/drawer/drawer.ts +266 -10
- package/src/components/dropdown/dropdown.ts +63 -8
- package/src/components/select/__tests__/ux-behaviors.test.ts +382 -4
- package/src/components/select/search.ts +16 -7
- package/src/components/select/select.css +7 -2
- package/src/components/select/select.ts +112 -20
- package/src/components/sticky/sticky.ts +55 -5
- package/src/helpers/data.ts +10 -0
- package/src/helpers/event-handler.ts +7 -6
- package/src/index.ts +2 -0
package/lib/esm/helpers/data.js
CHANGED
|
@@ -30,6 +30,14 @@ var KTData = {
|
|
|
30
30
|
KTElementMap.delete(element);
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
|
+
// Clear all data for a specific element (useful for reinitialization)
|
|
34
|
+
clear: function (element) {
|
|
35
|
+
KTElementMap.delete(element);
|
|
36
|
+
},
|
|
33
37
|
};
|
|
38
|
+
// Expose KTData on window for external access (useful for Livewire wire:navigate)
|
|
39
|
+
if (typeof window !== 'undefined') {
|
|
40
|
+
window.KTData = KTData;
|
|
41
|
+
}
|
|
34
42
|
export default KTData;
|
|
35
43
|
//# sourceMappingURL=data.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/helpers/data.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,IAAM,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;AAE/B,IAAM,MAAM,GAAG;IACd,GAAG,YAAC,OAAoB,EAAE,GAAW,EAAE,KAAc;QACpD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,IAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE3C,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,GAAG,YAAC,OAAoB,EAAE,GAAW;QACpC,IAAI,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACnD,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED,GAAG,YAAC,OAAoB,EAAE,GAAW;QACpC,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,YAAC,OAAoB,EAAE,GAAW;QACvC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACvE,OAAO;QACR,CAAC;QAED,IAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE3C,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAErB,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACzB,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;IACF,CAAC;CACD,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/helpers/data.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,IAAM,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;AAE/B,IAAM,MAAM,GAAG;IACd,GAAG,YAAC,OAAoB,EAAE,GAAW,EAAE,KAAc;QACpD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,IAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE3C,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,GAAG,YAAC,OAAoB,EAAE,GAAW;QACpC,IAAI,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACnD,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED,GAAG,YAAC,OAAoB,EAAE,GAAW;QACpC,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,YAAC,OAAoB,EAAE,GAAW;QACvC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACvE,OAAO;QACR,CAAC;QAED,IAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE3C,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAErB,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACzB,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;IACF,CAAC;IAED,sEAAsE;IACtE,KAAK,YAAC,OAAoB;QACzB,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;CACD,CAAC;AAEF,kFAAkF;AAClF,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IACnC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;AACxB,CAAC;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -12,13 +12,14 @@ var KTEventHandler = {
|
|
|
12
12
|
}
|
|
13
13
|
var eventId = KTUtils.geUID('event');
|
|
14
14
|
KTDelegatedEventHandlers[eventId] = function (event) {
|
|
15
|
-
|
|
15
|
+
// Fix: Check selector dynamically instead of pre-computing targets
|
|
16
|
+
// This allows event delegation to work with dynamically added elements
|
|
16
17
|
var target = event.target;
|
|
17
18
|
while (target && target !== element) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
// Check if current target matches the selector
|
|
20
|
+
if (target.matches && target.matches(selector)) {
|
|
21
|
+
handler.call(_this, event, target);
|
|
22
|
+
return; // Stop bubbling once we've handled it
|
|
22
23
|
}
|
|
23
24
|
target = target.parentNode;
|
|
24
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-handler.js","sourceRoot":"","sources":["../../../src/helpers/event-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,IAAM,wBAAwB,GAAsC,EAAE,CAAC;AAEvE,IAAM,cAAc,GAAG;IACtB,EAAE,EAAE,UACH,OAAoB,EACpB,QAAgB,EAChB,SAAiB,EACjB,OAAuB;QAJpB,
|
|
1
|
+
{"version":3,"file":"event-handler.js","sourceRoot":"","sources":["../../../src/helpers/event-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,IAAM,wBAAwB,GAAsC,EAAE,CAAC;AAEvE,IAAM,cAAc,GAAG;IACtB,EAAE,EAAE,UACH,OAAoB,EACpB,QAAgB,EAChB,SAAiB,EACjB,OAAuB;QAJpB,iBAiCH;QA3BA,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QACb,CAAC;QAED,IAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEvC,wBAAwB,CAAC,OAAO,CAAC,GAAG,UACnC,KAAsC;YAEtC,mEAAmE;YACnE,uEAAuE;YACvE,IAAI,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAC;YAEzC,OAAO,MAAM,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACrC,+CAA+C;gBAC/C,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChD,OAAO,CAAC,IAAI,CAAC,KAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;oBAClC,OAAO,CAAC,sCAAsC;gBAC/C,CAAC;gBAED,MAAM,GAAG,MAAM,CAAC,UAAyB,CAAC;YAC3C,CAAC;QACF,CAAC,CAAC;QAEF,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;QAEvE,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,GAAG,YAAC,OAAoB,EAAE,SAAiB,EAAE,OAAe;QAC3D,IAAI,CAAC,OAAO,IAAI,wBAAwB,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5D,OAAO;QACR,CAAC;QAED,OAAO,CAAC,mBAAmB,CAAC,SAAS,EAAE,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;QAE1E,OAAO,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;CACD,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
package/lib/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keenthemes/ktui",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Free & Open-Source Tailwind UI Components by Keenthemes",
|
|
5
5
|
"homepage": "https://ktui.io",
|
|
6
6
|
"repository": {
|
|
@@ -85,7 +85,9 @@
|
|
|
85
85
|
"format:check": "npx prettier --check 'src/**/*.ts'",
|
|
86
86
|
"type-check": "npx tsc --noEmit --project tsconfig.lib.json",
|
|
87
87
|
"validate": "npm run lint && npm run format:check && npm run type-check",
|
|
88
|
-
"validate:fix": "npm run lint:fix && npm run format"
|
|
88
|
+
"validate:fix": "npm run lint:fix && npm run format",
|
|
89
|
+
"publish:npm": "node scripts/publish-npm.js",
|
|
90
|
+
"publish:github": "npm publish"
|
|
89
91
|
},
|
|
90
92
|
"devDependencies": {
|
|
91
93
|
"@babel/core": "^7.27.3",
|
|
@@ -27,6 +27,32 @@ export default class KTComponent {
|
|
|
27
27
|
protected _uid: string | null = null;
|
|
28
28
|
protected _element: HTMLElement | null = null;
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Check if component should skip initialization
|
|
32
|
+
* Returns true if element already has an instance and is still connected to DOM
|
|
33
|
+
* Returns false if element should be initialized (no instance or disconnected)
|
|
34
|
+
* @param element The element to check
|
|
35
|
+
* @returns true if initialization should be skipped, false otherwise
|
|
36
|
+
*/
|
|
37
|
+
protected _shouldSkipInit(element: HTMLElement): boolean {
|
|
38
|
+
if (!KTData.has(element, this._name)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const existingInstance = KTData.get(element, this._name) as KTComponent;
|
|
43
|
+
|
|
44
|
+
// If element is not connected to DOM, dispose old instance and allow reinitialization
|
|
45
|
+
if (element.isConnected === false) {
|
|
46
|
+
if (existingInstance && typeof existingInstance.dispose === 'function') {
|
|
47
|
+
existingInstance.dispose();
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Element is connected and has instance, skip initialization
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
30
56
|
protected _init(element: HTMLElement | null) {
|
|
31
57
|
element = KTDom.getElement(element);
|
|
32
58
|
|
|
@@ -42,7 +42,7 @@ describe('KTDataTable Race Condition Fixes', () => {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// Simulate network delay
|
|
45
|
-
return new Promise((resolve, reject) => {
|
|
45
|
+
return new Promise<Response>((resolve, reject) => {
|
|
46
46
|
const timeout = setTimeout(() => {
|
|
47
47
|
if (options?.signal?.aborted) {
|
|
48
48
|
reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
@@ -72,7 +72,7 @@ describe('KTDataTable Race Condition Fixes', () => {
|
|
|
72
72
|
});
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
-
global.fetch = mockFetch;
|
|
75
|
+
global.fetch = mockFetch as typeof fetch;
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
afterEach(() => {
|
|
@@ -668,9 +668,15 @@ export class KTDataTable<T extends KTDataTableDataInterface>
|
|
|
668
668
|
this._storeOriginalClasses();
|
|
669
669
|
|
|
670
670
|
const rows = this._tbodyElement.querySelectorAll<HTMLTableRowElement>('tr');
|
|
671
|
-
|
|
671
|
+
|
|
672
|
+
// Filter th elements to only include those with data-kt-datatable-column attribute
|
|
673
|
+
const allThs: NodeListOf<HTMLTableCellElement> = this._theadElement
|
|
672
674
|
? this._theadElement.querySelectorAll('th')
|
|
673
675
|
: ([] as unknown as NodeListOf<HTMLTableCellElement>);
|
|
676
|
+
|
|
677
|
+
const ths: HTMLTableCellElement[] = Array.from(allThs).filter(th =>
|
|
678
|
+
th.hasAttribute('data-kt-datatable-column')
|
|
679
|
+
);
|
|
674
680
|
|
|
675
681
|
rows.forEach((row: HTMLTableRowElement) => {
|
|
676
682
|
const dataRow: T = {} as T;
|
|
@@ -702,9 +708,15 @@ export class KTDataTable<T extends KTDataTableDataInterface>
|
|
|
702
708
|
*/
|
|
703
709
|
private _localTableHeaderInvalidate(): boolean {
|
|
704
710
|
const { originalData } = this.getState();
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
711
|
+
|
|
712
|
+
// Count only th elements with data-kt-datatable-column attribute
|
|
713
|
+
const allThs: NodeListOf<HTMLTableCellElement> = this._theadElement
|
|
714
|
+
? this._theadElement.querySelectorAll('th')
|
|
715
|
+
: ([] as unknown as NodeListOf<HTMLTableCellElement>);
|
|
716
|
+
const currentTableHeaders = Array.from(allThs).filter(th =>
|
|
717
|
+
th.hasAttribute('data-kt-datatable-column')
|
|
718
|
+
).length;
|
|
719
|
+
|
|
708
720
|
const totalColumns = originalData.length
|
|
709
721
|
? Object.keys(originalData[0]).length
|
|
710
722
|
: 0;
|
|
@@ -998,9 +1010,15 @@ export class KTDataTable<T extends KTDataTableDataInterface>
|
|
|
998
1010
|
return tbodyElement;
|
|
999
1011
|
}
|
|
1000
1012
|
|
|
1001
|
-
|
|
1013
|
+
// Filter th elements to only include those with data-kt-datatable-column attribute
|
|
1014
|
+
// This prevents creating blank td elements for merged header cells (colspan/rowspan)
|
|
1015
|
+
const allThs: NodeListOf<HTMLTableCellElement> = this._theadElement
|
|
1002
1016
|
? this._theadElement.querySelectorAll('th')
|
|
1003
1017
|
: ([] as unknown as NodeListOf<HTMLTableCellElement>);
|
|
1018
|
+
|
|
1019
|
+
const ths: HTMLTableCellElement[] = Array.from(allThs).filter(th =>
|
|
1020
|
+
th.hasAttribute('data-kt-datatable-column')
|
|
1021
|
+
);
|
|
1004
1022
|
|
|
1005
1023
|
this._data.forEach((item: T, rowIndex: number) => {
|
|
1006
1024
|
const row = document.createElement('tr');
|
|
@@ -1015,7 +1033,7 @@ export class KTDataTable<T extends KTDataTableDataInterface>
|
|
|
1015
1033
|
? this.getState().originalDataAttributes[rowIndex]
|
|
1016
1034
|
: null;
|
|
1017
1035
|
|
|
1018
|
-
// Use the order of <th> elements to render <td>s in the correct order
|
|
1036
|
+
// Use the order of <th> elements with data-kt-datatable-column to render <td>s in the correct order
|
|
1019
1037
|
ths.forEach((th, colIndex) => {
|
|
1020
1038
|
const colName = th.getAttribute('data-kt-datatable-column');
|
|
1021
1039
|
const td = document.createElement('td');
|
|
@@ -1777,7 +1795,14 @@ export class KTDataTable<T extends KTDataTableDataInterface>
|
|
|
1777
1795
|
public static getInstance(
|
|
1778
1796
|
element: HTMLElement,
|
|
1779
1797
|
): KTDataTable<KTDataTableDataInterface> | undefined {
|
|
1780
|
-
|
|
1798
|
+
// First check the static Map (for instances created via createInstances)
|
|
1799
|
+
const instanceFromMap = this._instances.get(element);
|
|
1800
|
+
if (instanceFromMap) {
|
|
1801
|
+
return instanceFromMap;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
// Fallback to element's instance property (for manually created instances)
|
|
1805
|
+
return (element as any).instance;
|
|
1781
1806
|
}
|
|
1782
1807
|
|
|
1783
1808
|
/**
|
|
@@ -43,13 +43,16 @@ export class KTDrawer extends KTComponent implements KTDrawerInterface {
|
|
|
43
43
|
constructor(element: HTMLElement, config?: KTDrawerConfigInterface) {
|
|
44
44
|
super();
|
|
45
45
|
|
|
46
|
-
if (KTData.has(element as HTMLElement, this._name))
|
|
46
|
+
if (KTData.has(element as HTMLElement, this._name)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
47
49
|
|
|
48
50
|
this._init(element);
|
|
49
51
|
this._buildConfig(config);
|
|
50
52
|
this._handleClose();
|
|
51
53
|
this._update();
|
|
52
54
|
this._handleContainer();
|
|
55
|
+
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
protected _handleClose(): void {
|
|
@@ -88,6 +91,28 @@ export class KTDrawer extends KTComponent implements KTDrawerInterface {
|
|
|
88
91
|
|
|
89
92
|
KTDrawer.hide();
|
|
90
93
|
|
|
94
|
+
// If drawer needs to be in front of backdrop, ensure it's in body (for proper z-index stacking)
|
|
95
|
+
// This ensures the drawer and backdrop are in the same stacking context
|
|
96
|
+
if (this._getOption('container') === 'body' && this._element.parentElement !== document.body) {
|
|
97
|
+
// Store original parent for restoration when hiding
|
|
98
|
+
if (!this._element.hasAttribute('data-kt-drawer-original-parent-id')) {
|
|
99
|
+
const originalParent = this._element.parentElement;
|
|
100
|
+
if (originalParent && originalParent !== document.body) {
|
|
101
|
+
this._element.setAttribute('data-kt-drawer-original-parent-id', originalParent.id || '');
|
|
102
|
+
// Store a reference to find the parent later (using closest to find Livewire component or header)
|
|
103
|
+
const livewireComponent = originalParent.closest('[wire\\:id]');
|
|
104
|
+
const header = originalParent.closest('header#header');
|
|
105
|
+
if (livewireComponent) {
|
|
106
|
+
this._element.setAttribute('data-kt-drawer-original-wire-id', (livewireComponent as HTMLElement).getAttribute('wire:id') || '');
|
|
107
|
+
}
|
|
108
|
+
if (header) {
|
|
109
|
+
this._element.setAttribute('data-kt-drawer-original-in-header', 'true');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
document.body.appendChild(this._element);
|
|
114
|
+
}
|
|
115
|
+
|
|
91
116
|
if (this._getOption('backdrop') === true) this._createBackdrop();
|
|
92
117
|
|
|
93
118
|
if (relatedTarget) this._relatedTarget = relatedTarget;
|
|
@@ -162,6 +187,10 @@ export class KTDrawer extends KTComponent implements KTDrawerInterface {
|
|
|
162
187
|
this._element.classList.remove(this._getOption('shownClass') as string);
|
|
163
188
|
this._element.style.zIndex = '';
|
|
164
189
|
|
|
190
|
+
// Note: We don't move drawer back to original location here
|
|
191
|
+
// Livewire will handle DOM structure on next navigation, and drawer will be reinitialized
|
|
192
|
+
// in its original location from the persisted component HTML
|
|
193
|
+
|
|
165
194
|
this._fireEvent('hidden');
|
|
166
195
|
this._dispatchEvent('hidden');
|
|
167
196
|
});
|
|
@@ -180,7 +209,25 @@ export class KTDrawer extends KTComponent implements KTDrawerInterface {
|
|
|
180
209
|
protected _handleContainer(): void {
|
|
181
210
|
if (this._getOption('container')) {
|
|
182
211
|
if (this._getOption('container') === 'body') {
|
|
183
|
-
|
|
212
|
+
// Check if drawer is in a persisted Livewire component (like header with @persist)
|
|
213
|
+
// If so, don't move it to body - keep it in place so Livewire can preserve it
|
|
214
|
+
// This follows the same pattern as dropdowns/menus which work with wire:navigate
|
|
215
|
+
const originalParent = this._element.parentNode;
|
|
216
|
+
const isInPersistedComponent = originalParent &&
|
|
217
|
+
((originalParent as HTMLElement).closest('[wire\\:id]') !== null ||
|
|
218
|
+
(originalParent as HTMLElement).closest('header#header') !== null);
|
|
219
|
+
|
|
220
|
+
if (isInPersistedComponent) {
|
|
221
|
+
// Don't move to body - keep in original location for Livewire persistence
|
|
222
|
+
// Use fixed positioning to achieve the same visual effect
|
|
223
|
+
// Ensure drawer has fixed positioning to work from its current location
|
|
224
|
+
if (!this._element.style.position || this._element.style.position === 'static') {
|
|
225
|
+
this._element.style.position = 'fixed';
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
// Not in persisted component - safe to move to body (follows original behavior)
|
|
229
|
+
document.body.appendChild(this._element);
|
|
230
|
+
}
|
|
184
231
|
} else {
|
|
185
232
|
document
|
|
186
233
|
.querySelector(this._getOption('container') as string)
|
|
@@ -265,15 +312,128 @@ export class KTDrawer extends KTComponent implements KTDrawerInterface {
|
|
|
265
312
|
return this._isEnabled();
|
|
266
313
|
}
|
|
267
314
|
|
|
315
|
+
public static getElement(reference: HTMLElement): HTMLElement {
|
|
316
|
+
if (reference && reference.hasAttribute('data-kt-drawer-initialized'))
|
|
317
|
+
return reference;
|
|
318
|
+
|
|
319
|
+
const findElement =
|
|
320
|
+
reference &&
|
|
321
|
+
(reference.closest('[data-kt-drawer-initialized]') as HTMLElement);
|
|
322
|
+
if (findElement) return findElement;
|
|
323
|
+
|
|
324
|
+
// Fallback: look for parent with data-kt-drawer attribute
|
|
325
|
+
if (reference) {
|
|
326
|
+
const drawerContainer = reference.closest('[data-kt-drawer]') as HTMLElement;
|
|
327
|
+
if (drawerContainer) return drawerContainer;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// If reference is a toggle button with a selector, find the drawer by selector
|
|
331
|
+
// This handles cases where the toggle button is not a child of the drawer
|
|
332
|
+
if (reference && reference.hasAttribute('data-kt-drawer-toggle')) {
|
|
333
|
+
const selector = reference.getAttribute('data-kt-drawer-toggle');
|
|
334
|
+
if (selector) {
|
|
335
|
+
// Check both document and body (drawers with container="body" are moved to body)
|
|
336
|
+
const drawerElInDoc = document.querySelector(selector);
|
|
337
|
+
const drawerElInBody = document.body.querySelector(selector);
|
|
338
|
+
const drawerEl = drawerElInDoc || drawerElInBody;
|
|
339
|
+
if (drawerEl) return drawerEl as HTMLElement;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Wait for an element to appear in the DOM using polling with MutationObserver fallback
|
|
348
|
+
* Useful for persisted Livewire components that may not be in DOM immediately
|
|
349
|
+
*/
|
|
350
|
+
public static waitForElement(selector: string, timeout: number = 2000): Promise<HTMLElement | null> {
|
|
351
|
+
return new Promise((resolve) => {
|
|
352
|
+
let resolved = false;
|
|
353
|
+
|
|
354
|
+
const doResolve = (element: HTMLElement | null) => {
|
|
355
|
+
if (!resolved) {
|
|
356
|
+
resolved = true;
|
|
357
|
+
resolve(element);
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// Check if element already exists
|
|
362
|
+
const existing = document.querySelector(selector) || document.body.querySelector(selector);
|
|
363
|
+
if (existing) {
|
|
364
|
+
doResolve(existing as HTMLElement);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Use polling for faster detection (check every 50ms)
|
|
369
|
+
let attempts = 0;
|
|
370
|
+
const maxAttempts = timeout / 50;
|
|
371
|
+
const pollInterval = setInterval(() => {
|
|
372
|
+
if (resolved) {
|
|
373
|
+
clearInterval(pollInterval);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
attempts++;
|
|
377
|
+
const element = document.querySelector(selector) || document.body.querySelector(selector);
|
|
378
|
+
if (element) {
|
|
379
|
+
clearInterval(pollInterval);
|
|
380
|
+
doResolve(element as HTMLElement);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (attempts >= maxAttempts) {
|
|
384
|
+
clearInterval(pollInterval);
|
|
385
|
+
doResolve(null);
|
|
386
|
+
}
|
|
387
|
+
}, 50);
|
|
388
|
+
|
|
389
|
+
// Also use MutationObserver as backup for immediate detection
|
|
390
|
+
const observer = new MutationObserver(() => {
|
|
391
|
+
if (resolved) {
|
|
392
|
+
observer.disconnect();
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
const element = document.querySelector(selector) || document.body.querySelector(selector);
|
|
396
|
+
if (element) {
|
|
397
|
+
clearInterval(pollInterval);
|
|
398
|
+
observer.disconnect();
|
|
399
|
+
doResolve(element as HTMLElement);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
observer.observe(document.body, {
|
|
404
|
+
childList: true,
|
|
405
|
+
subtree: true,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// Cleanup on timeout
|
|
409
|
+
setTimeout(() => {
|
|
410
|
+
if (!resolved) {
|
|
411
|
+
clearInterval(pollInterval);
|
|
412
|
+
observer.disconnect();
|
|
413
|
+
doResolve(null);
|
|
414
|
+
}
|
|
415
|
+
}, timeout);
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
268
419
|
public static getInstance(element: HTMLElement): KTDrawer {
|
|
269
420
|
if (!element) return null;
|
|
270
421
|
|
|
271
|
-
|
|
272
|
-
|
|
422
|
+
const drawerElement = KTDrawer.getElement(element);
|
|
423
|
+
if (!drawerElement) {
|
|
424
|
+
// If element is a toggle button and drawer element wasn't found, return null
|
|
425
|
+
// The handleToggle() will handle waiting for the element to appear
|
|
426
|
+
if (element.hasAttribute('data-kt-drawer-toggle')) {
|
|
427
|
+
}
|
|
428
|
+
return null;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (KTData.has(drawerElement, 'drawer')) {
|
|
432
|
+
return KTData.get(drawerElement, 'drawer') as KTDrawer;
|
|
273
433
|
}
|
|
274
434
|
|
|
275
|
-
if (
|
|
276
|
-
return new KTDrawer(
|
|
435
|
+
if (drawerElement.getAttribute('data-kt-drawer-initialized') === 'true') {
|
|
436
|
+
return new KTDrawer(drawerElement);
|
|
277
437
|
}
|
|
278
438
|
|
|
279
439
|
return null;
|
|
@@ -322,6 +482,14 @@ export class KTDrawer extends KTComponent implements KTDrawerInterface {
|
|
|
322
482
|
}
|
|
323
483
|
|
|
324
484
|
public static handleToggle(): void {
|
|
485
|
+
|
|
486
|
+
// Add raw click listener to document.body to track all clicks
|
|
487
|
+
document.body.addEventListener('click', (rawEvent: MouseEvent) => {
|
|
488
|
+
const target = rawEvent.target as HTMLElement;
|
|
489
|
+
if (target && target.hasAttribute('data-kt-drawer-toggle')) {
|
|
490
|
+
}
|
|
491
|
+
}, true); // Use capture phase to catch before any stopPropagation
|
|
492
|
+
|
|
325
493
|
KTEventHandler.on(
|
|
326
494
|
document.body,
|
|
327
495
|
'[data-kt-drawer-toggle]',
|
|
@@ -332,10 +500,49 @@ export class KTDrawer extends KTComponent implements KTDrawerInterface {
|
|
|
332
500
|
const selector = target.getAttribute('data-kt-drawer-toggle');
|
|
333
501
|
if (!selector) return;
|
|
334
502
|
|
|
335
|
-
|
|
336
|
-
const drawer = KTDrawer.getInstance(
|
|
503
|
+
// Try to get instance immediately
|
|
504
|
+
const drawer = KTDrawer.getInstance(target);
|
|
505
|
+
|
|
337
506
|
if (drawer) {
|
|
338
507
|
drawer.toggle();
|
|
508
|
+
} else {
|
|
509
|
+
// Drawer element not found - wait for it to appear (handles persisted Livewire components)
|
|
510
|
+
// Check if drawer exists in persisted components (might be in header that's persisted)
|
|
511
|
+
const persistedHeader = document.querySelector('[wire\\:id]')?.closest('[wire\\:id]') || document.querySelector('header#header');
|
|
512
|
+
const drawerInPersisted = persistedHeader ? persistedHeader.querySelector(selector) : null;
|
|
513
|
+
|
|
514
|
+
// Wait longer for persisted components that may take time to render
|
|
515
|
+
// Also check if drawer exists in persisted header component
|
|
516
|
+
KTDrawer.waitForElement(selector, 5000).then((drawerElement) => {
|
|
517
|
+
if (drawerElement) {
|
|
518
|
+
// Initialize the drawer if not already initialized
|
|
519
|
+
if (!KTData.has(drawerElement, 'drawer')) {
|
|
520
|
+
new KTDrawer(drawerElement);
|
|
521
|
+
}
|
|
522
|
+
// Get instance and toggle
|
|
523
|
+
const drawerInstance = KTDrawer.getInstance(drawerElement);
|
|
524
|
+
if (drawerInstance) {
|
|
525
|
+
drawerInstance.toggle();
|
|
526
|
+
}
|
|
527
|
+
} else {
|
|
528
|
+
// Drawer never appeared - trigger a reinit to see if it helps
|
|
529
|
+
// This handles cases where drawers are in persisted components that haven't rendered yet
|
|
530
|
+
setTimeout(() => {
|
|
531
|
+
KTDrawer.reinit();
|
|
532
|
+
// Try one more time after reinit
|
|
533
|
+
const drawerAfterReinit = document.querySelector(selector) || document.body.querySelector(selector);
|
|
534
|
+
if (drawerAfterReinit) {
|
|
535
|
+
if (!KTData.has(drawerAfterReinit as HTMLElement, 'drawer')) {
|
|
536
|
+
new KTDrawer(drawerAfterReinit as HTMLElement);
|
|
537
|
+
}
|
|
538
|
+
const drawerInstance = KTDrawer.getInstance(drawerAfterReinit as HTMLElement);
|
|
539
|
+
if (drawerInstance) {
|
|
540
|
+
drawerInstance.toggle();
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}, 500);
|
|
544
|
+
}
|
|
545
|
+
});
|
|
339
546
|
}
|
|
340
547
|
},
|
|
341
548
|
);
|
|
@@ -411,8 +618,12 @@ export class KTDrawer extends KTComponent implements KTDrawerInterface {
|
|
|
411
618
|
}
|
|
412
619
|
|
|
413
620
|
public static createInstances(): void {
|
|
414
|
-
|
|
415
|
-
|
|
621
|
+
// Find all drawer elements - check both document and body (drawers with container="body" are moved there)
|
|
622
|
+
const elementsInDoc = document.querySelectorAll('[data-kt-drawer]');
|
|
623
|
+
const elementsInBody = document.body.querySelectorAll('[data-kt-drawer]');
|
|
624
|
+
// Combine and deduplicate
|
|
625
|
+
const allElements = new Set([...Array.from(elementsInDoc), ...Array.from(elementsInBody)]);
|
|
626
|
+
const elements = Array.from(allElements);
|
|
416
627
|
elements.forEach((element) => {
|
|
417
628
|
new KTDrawer(element as HTMLElement);
|
|
418
629
|
});
|
|
@@ -430,6 +641,51 @@ export class KTDrawer extends KTComponent implements KTDrawerInterface {
|
|
|
430
641
|
window.KT_DRAWER_INITIALIZED = true;
|
|
431
642
|
}
|
|
432
643
|
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Force reinitialization of drawers by clearing KTData entries.
|
|
647
|
+
* Useful for Livewire wire:navigate where persisted elements need reinitialization.
|
|
648
|
+
*/
|
|
649
|
+
public static reinit(): void {
|
|
650
|
+
// Follow the same simple pattern as KTDropdown.reinit()
|
|
651
|
+
// Find all drawer elements - check both document and body (some may be moved to body)
|
|
652
|
+
const elementsInDoc = document.querySelectorAll('[data-kt-drawer]');
|
|
653
|
+
const elementsInBody = document.body.querySelectorAll('[data-kt-drawer]');
|
|
654
|
+
// Combine and deduplicate
|
|
655
|
+
const allElements = new Set([...Array.from(elementsInDoc), ...Array.from(elementsInBody)]);
|
|
656
|
+
const elements = Array.from(allElements);
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
// Clean up existing instances
|
|
660
|
+
elements.forEach((element) => {
|
|
661
|
+
try {
|
|
662
|
+
// Get existing instance to clean up
|
|
663
|
+
const instance = KTDrawer.getInstance(element as HTMLElement);
|
|
664
|
+
if (instance && typeof instance.hide === 'function') {
|
|
665
|
+
instance.hide(); // This will clean up backdrop and state
|
|
666
|
+
}
|
|
667
|
+
// Clear KTData entries
|
|
668
|
+
const hadDrawer = KTData.has(element as HTMLElement, 'drawer');
|
|
669
|
+
KTData.remove(element as HTMLElement, 'drawer');
|
|
670
|
+
// Remove initialization attribute to allow fresh initialization
|
|
671
|
+
element.removeAttribute('data-kt-drawer-initialized');
|
|
672
|
+
} catch (e) {
|
|
673
|
+
// Ignore errors for individual elements
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
// Now create fresh instances
|
|
678
|
+
KTDrawer.createInstances();
|
|
679
|
+
|
|
680
|
+
// Always ensure handlers are set up (similar to KTMenu.init() behavior)
|
|
681
|
+
// Event handlers use delegation so they persist, but we ensure they're attached
|
|
682
|
+
KTDrawer.handleToggle();
|
|
683
|
+
KTDrawer.handleDismiss();
|
|
684
|
+
KTDrawer.handleResize();
|
|
685
|
+
KTDrawer.handleClickAway();
|
|
686
|
+
KTDrawer.handleKeyword();
|
|
687
|
+
|
|
688
|
+
}
|
|
433
689
|
}
|
|
434
690
|
|
|
435
691
|
if (typeof window !== 'undefined') {
|