@keenthemes/ktui 1.2.0 → 1.2.2
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 +8355 -5213
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +24 -1
- package/lib/cjs/components/carousel/carousel.d.ts +102 -0
- package/lib/cjs/components/carousel/carousel.d.ts.map +1 -0
- package/lib/cjs/components/carousel/carousel.js +769 -0
- package/lib/cjs/components/carousel/carousel.js.map +1 -0
- package/lib/cjs/components/carousel/index.d.ts +7 -0
- package/lib/cjs/components/carousel/index.d.ts.map +1 -0
- package/lib/cjs/components/carousel/index.js +10 -0
- package/lib/cjs/components/carousel/index.js.map +1 -0
- package/lib/cjs/components/carousel/types.d.ts +36 -0
- package/lib/cjs/components/carousel/types.d.ts.map +1 -0
- package/lib/cjs/components/carousel/types.js +7 -0
- package/lib/cjs/components/carousel/types.js.map +1 -0
- package/lib/cjs/components/clipboard/clipboard.d.ts +37 -0
- package/lib/cjs/components/clipboard/clipboard.d.ts.map +1 -0
- package/lib/cjs/components/clipboard/clipboard.js +402 -0
- package/lib/cjs/components/clipboard/clipboard.js.map +1 -0
- package/lib/cjs/components/clipboard/index.d.ts +3 -0
- package/lib/cjs/components/clipboard/index.d.ts.map +1 -0
- package/lib/cjs/components/clipboard/index.js +6 -0
- package/lib/cjs/components/clipboard/index.js.map +1 -0
- package/lib/cjs/components/clipboard/types.d.ts +44 -0
- package/lib/cjs/components/clipboard/types.d.ts.map +1 -0
- package/lib/cjs/components/clipboard/types.js +7 -0
- package/lib/cjs/components/clipboard/types.js.map +1 -0
- package/lib/cjs/components/component.d.ts +3 -3
- package/lib/cjs/components/component.d.ts.map +1 -1
- package/lib/cjs/components/component.js +9 -1
- package/lib/cjs/components/component.js.map +1 -1
- package/lib/cjs/components/datatable/datatable-checkbox.d.ts +1 -1
- package/lib/cjs/components/datatable/datatable-checkbox.d.ts.map +1 -1
- package/lib/cjs/components/datatable/datatable-checkbox.js +1 -1
- package/lib/cjs/components/datatable/datatable-checkbox.js.map +1 -1
- package/lib/cjs/components/datatable/datatable-sort.d.ts +1 -1
- package/lib/cjs/components/datatable/datatable-sort.d.ts.map +1 -1
- package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
- package/lib/cjs/components/datatable/datatable.d.ts +2 -0
- package/lib/cjs/components/datatable/datatable.d.ts.map +1 -1
- package/lib/cjs/components/datatable/datatable.js +29 -16
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/datatable/types.d.ts +2 -1
- package/lib/cjs/components/datatable/types.d.ts.map +1 -1
- package/lib/cjs/components/drawer/drawer.d.ts.map +1 -1
- package/lib/cjs/components/drawer/drawer.js +3 -16
- package/lib/cjs/components/drawer/drawer.js.map +1 -1
- package/lib/cjs/components/dropdown/dropdown.d.ts +1 -1
- package/lib/cjs/components/dropdown/dropdown.d.ts.map +1 -1
- package/lib/cjs/components/dropdown/dropdown.js +2 -3
- package/lib/cjs/components/dropdown/dropdown.js.map +1 -1
- package/lib/cjs/components/pin-input/index.d.ts +3 -0
- package/lib/cjs/components/pin-input/index.d.ts.map +1 -0
- package/lib/cjs/components/pin-input/index.js +6 -0
- package/lib/cjs/components/pin-input/index.js.map +1 -0
- package/lib/cjs/components/pin-input/pin-input.d.ts +56 -0
- package/lib/cjs/components/pin-input/pin-input.d.ts.map +1 -0
- package/lib/cjs/components/pin-input/pin-input.js +455 -0
- package/lib/cjs/components/pin-input/pin-input.js.map +1 -0
- package/lib/cjs/components/pin-input/types.d.ts +41 -0
- package/lib/cjs/components/pin-input/types.d.ts.map +1 -0
- package/lib/cjs/components/pin-input/types.js +6 -0
- package/lib/cjs/components/pin-input/types.js.map +1 -0
- package/lib/cjs/components/range-slider/index.d.ts +7 -0
- package/lib/cjs/components/range-slider/index.d.ts.map +1 -0
- package/lib/cjs/components/range-slider/index.js +10 -0
- package/lib/cjs/components/range-slider/index.js.map +1 -0
- package/lib/cjs/components/range-slider/range-slider.d.ts +42 -0
- package/lib/cjs/components/range-slider/range-slider.d.ts.map +1 -0
- package/lib/cjs/components/range-slider/range-slider.js +254 -0
- package/lib/cjs/components/range-slider/range-slider.js.map +1 -0
- package/lib/cjs/components/range-slider/types.d.ts +33 -0
- package/lib/cjs/components/range-slider/types.d.ts.map +1 -0
- package/lib/cjs/components/range-slider/types.js +7 -0
- package/lib/cjs/components/range-slider/types.js.map +1 -0
- package/lib/cjs/components/rating/rating.d.ts.map +1 -1
- package/lib/cjs/components/rating/rating.js +8 -3
- package/lib/cjs/components/rating/rating.js.map +1 -1
- package/lib/cjs/components/repeater/repeater.d.ts.map +1 -1
- package/lib/cjs/components/repeater/repeater.js +3 -2
- package/lib/cjs/components/repeater/repeater.js.map +1 -1
- package/lib/cjs/components/select/combobox.d.ts.map +1 -1
- package/lib/cjs/components/select/combobox.js +25 -15
- package/lib/cjs/components/select/combobox.js.map +1 -1
- package/lib/cjs/components/select/config.d.ts +2 -2
- package/lib/cjs/components/select/config.d.ts.map +1 -1
- package/lib/cjs/components/select/config.js +10 -9
- package/lib/cjs/components/select/config.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/option.d.ts +2 -1
- package/lib/cjs/components/select/option.d.ts.map +1 -1
- package/lib/cjs/components/select/option.js +9 -3
- package/lib/cjs/components/select/option.js.map +1 -1
- package/lib/cjs/components/select/remote.d.ts +1 -0
- package/lib/cjs/components/select/remote.d.ts.map +1 -1
- package/lib/cjs/components/select/remote.js +21 -14
- package/lib/cjs/components/select/remote.js.map +1 -1
- package/lib/cjs/components/select/search.d.ts +1 -1
- package/lib/cjs/components/select/search.d.ts.map +1 -1
- package/lib/cjs/components/select/search.js +34 -25
- package/lib/cjs/components/select/search.js.map +1 -1
- package/lib/cjs/components/select/select.d.ts +5 -3
- package/lib/cjs/components/select/select.d.ts.map +1 -1
- package/lib/cjs/components/select/select.js +31 -31
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/tags.d.ts.map +1 -1
- package/lib/cjs/components/select/tags.js +22 -13
- package/lib/cjs/components/select/tags.js.map +1 -1
- package/lib/cjs/components/select/templates.d.ts.map +1 -1
- package/lib/cjs/components/select/templates.js +4 -4
- package/lib/cjs/components/select/templates.js.map +1 -1
- package/lib/cjs/components/select/types.d.ts +1 -1
- package/lib/cjs/components/select/types.d.ts.map +1 -1
- package/lib/cjs/components/select/utils.d.ts +4 -4
- package/lib/cjs/components/select/utils.d.ts.map +1 -1
- package/lib/cjs/components/select/utils.js +5 -4
- package/lib/cjs/components/select/utils.js.map +1 -1
- package/lib/cjs/components/sticky/sticky.d.ts +1 -1
- package/lib/cjs/components/sticky/sticky.d.ts.map +1 -1
- package/lib/cjs/components/sticky/sticky.js +16 -14
- package/lib/cjs/components/sticky/sticky.js.map +1 -1
- package/lib/cjs/components/toast/toast.d.ts.map +1 -1
- package/lib/cjs/components/toast/toast.js +17 -9
- package/lib/cjs/components/toast/toast.js.map +1 -1
- package/lib/cjs/components/toast/types.d.ts +3 -0
- package/lib/cjs/components/toast/types.d.ts.map +1 -1
- package/lib/cjs/components/toggle-password/toggle-password.d.ts.map +1 -1
- package/lib/cjs/components/toggle-password/toggle-password.js.map +1 -1
- package/lib/cjs/helpers/dom.d.ts +4 -4
- package/lib/cjs/helpers/dom.d.ts.map +1 -1
- package/lib/cjs/helpers/dom.js +8 -10
- package/lib/cjs/helpers/dom.js.map +1 -1
- package/lib/cjs/helpers/event-handler.d.ts +1 -1
- package/lib/cjs/helpers/event-handler.d.ts.map +1 -1
- package/lib/cjs/helpers/event-handler.js +3 -1
- package/lib/cjs/helpers/event-handler.js.map +1 -1
- package/lib/cjs/helpers/utils.d.ts +1 -1
- package/lib/cjs/helpers/utils.d.ts.map +1 -1
- package/lib/cjs/helpers/utils.js +4 -1
- package/lib/cjs/helpers/utils.js.map +1 -1
- package/lib/cjs/index.d.ts +16 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +17 -1
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/types.d.ts +1 -1
- package/lib/cjs/types.d.ts.map +1 -1
- package/lib/esm/components/carousel/carousel.d.ts +102 -0
- package/lib/esm/components/carousel/carousel.d.ts.map +1 -0
- package/lib/esm/components/carousel/carousel.js +766 -0
- package/lib/esm/components/carousel/carousel.js.map +1 -0
- package/lib/esm/components/carousel/index.d.ts +7 -0
- package/lib/esm/components/carousel/index.d.ts.map +1 -0
- package/lib/esm/components/carousel/index.js +6 -0
- package/lib/esm/components/carousel/index.js.map +1 -0
- package/lib/esm/components/carousel/types.d.ts +36 -0
- package/lib/esm/components/carousel/types.d.ts.map +1 -0
- package/lib/esm/components/carousel/types.js +6 -0
- package/lib/esm/components/carousel/types.js.map +1 -0
- package/lib/esm/components/clipboard/clipboard.d.ts +37 -0
- package/lib/esm/components/clipboard/clipboard.d.ts.map +1 -0
- package/lib/esm/components/clipboard/clipboard.js +399 -0
- package/lib/esm/components/clipboard/clipboard.js.map +1 -0
- package/lib/esm/components/clipboard/index.d.ts +3 -0
- package/lib/esm/components/clipboard/index.d.ts.map +1 -0
- package/lib/esm/components/clipboard/index.js +2 -0
- package/lib/esm/components/clipboard/index.js.map +1 -0
- package/lib/esm/components/clipboard/types.d.ts +44 -0
- package/lib/esm/components/clipboard/types.d.ts.map +1 -0
- package/lib/esm/components/clipboard/types.js +6 -0
- package/lib/esm/components/clipboard/types.js.map +1 -0
- package/lib/esm/components/component.d.ts +3 -3
- package/lib/esm/components/component.d.ts.map +1 -1
- package/lib/esm/components/component.js +9 -1
- package/lib/esm/components/component.js.map +1 -1
- package/lib/esm/components/datatable/datatable-checkbox.d.ts +1 -1
- package/lib/esm/components/datatable/datatable-checkbox.d.ts.map +1 -1
- package/lib/esm/components/datatable/datatable-checkbox.js +1 -1
- package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
- package/lib/esm/components/datatable/datatable-sort.d.ts +1 -1
- package/lib/esm/components/datatable/datatable-sort.d.ts.map +1 -1
- package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
- package/lib/esm/components/datatable/datatable.d.ts +2 -0
- package/lib/esm/components/datatable/datatable.d.ts.map +1 -1
- package/lib/esm/components/datatable/datatable.js +29 -16
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/datatable/types.d.ts +2 -1
- package/lib/esm/components/datatable/types.d.ts.map +1 -1
- package/lib/esm/components/drawer/drawer.d.ts.map +1 -1
- package/lib/esm/components/drawer/drawer.js +3 -16
- package/lib/esm/components/drawer/drawer.js.map +1 -1
- package/lib/esm/components/dropdown/dropdown.d.ts +1 -1
- package/lib/esm/components/dropdown/dropdown.d.ts.map +1 -1
- package/lib/esm/components/dropdown/dropdown.js +2 -3
- package/lib/esm/components/dropdown/dropdown.js.map +1 -1
- package/lib/esm/components/pin-input/index.d.ts +3 -0
- package/lib/esm/components/pin-input/index.d.ts.map +1 -0
- package/lib/esm/components/pin-input/index.js +2 -0
- package/lib/esm/components/pin-input/index.js.map +1 -0
- package/lib/esm/components/pin-input/pin-input.d.ts +56 -0
- package/lib/esm/components/pin-input/pin-input.d.ts.map +1 -0
- package/lib/esm/components/pin-input/pin-input.js +452 -0
- package/lib/esm/components/pin-input/pin-input.js.map +1 -0
- package/lib/esm/components/pin-input/types.d.ts +41 -0
- package/lib/esm/components/pin-input/types.d.ts.map +1 -0
- package/lib/esm/components/pin-input/types.js +5 -0
- package/lib/esm/components/pin-input/types.js.map +1 -0
- package/lib/esm/components/range-slider/index.d.ts +7 -0
- package/lib/esm/components/range-slider/index.d.ts.map +1 -0
- package/lib/esm/components/range-slider/index.js +6 -0
- package/lib/esm/components/range-slider/index.js.map +1 -0
- package/lib/esm/components/range-slider/range-slider.d.ts +42 -0
- package/lib/esm/components/range-slider/range-slider.d.ts.map +1 -0
- package/lib/esm/components/range-slider/range-slider.js +251 -0
- package/lib/esm/components/range-slider/range-slider.js.map +1 -0
- package/lib/esm/components/range-slider/types.d.ts +33 -0
- package/lib/esm/components/range-slider/types.d.ts.map +1 -0
- package/lib/esm/components/range-slider/types.js +6 -0
- package/lib/esm/components/range-slider/types.js.map +1 -0
- package/lib/esm/components/rating/rating.d.ts.map +1 -1
- package/lib/esm/components/rating/rating.js +8 -3
- package/lib/esm/components/rating/rating.js.map +1 -1
- package/lib/esm/components/repeater/repeater.d.ts.map +1 -1
- package/lib/esm/components/repeater/repeater.js +3 -2
- package/lib/esm/components/repeater/repeater.js.map +1 -1
- package/lib/esm/components/select/combobox.d.ts.map +1 -1
- package/lib/esm/components/select/combobox.js +25 -15
- package/lib/esm/components/select/combobox.js.map +1 -1
- package/lib/esm/components/select/config.d.ts +2 -2
- package/lib/esm/components/select/config.d.ts.map +1 -1
- package/lib/esm/components/select/config.js +10 -9
- package/lib/esm/components/select/config.js.map +1 -1
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/option.d.ts +2 -1
- package/lib/esm/components/select/option.d.ts.map +1 -1
- package/lib/esm/components/select/option.js +9 -3
- package/lib/esm/components/select/option.js.map +1 -1
- package/lib/esm/components/select/remote.d.ts +1 -0
- package/lib/esm/components/select/remote.d.ts.map +1 -1
- package/lib/esm/components/select/remote.js +21 -14
- package/lib/esm/components/select/remote.js.map +1 -1
- package/lib/esm/components/select/search.d.ts +1 -1
- package/lib/esm/components/select/search.d.ts.map +1 -1
- package/lib/esm/components/select/search.js +34 -25
- package/lib/esm/components/select/search.js.map +1 -1
- package/lib/esm/components/select/select.d.ts +5 -3
- package/lib/esm/components/select/select.d.ts.map +1 -1
- package/lib/esm/components/select/select.js +31 -31
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/tags.d.ts.map +1 -1
- package/lib/esm/components/select/tags.js +22 -13
- package/lib/esm/components/select/tags.js.map +1 -1
- package/lib/esm/components/select/templates.d.ts.map +1 -1
- package/lib/esm/components/select/templates.js +4 -4
- package/lib/esm/components/select/templates.js.map +1 -1
- package/lib/esm/components/select/types.d.ts +1 -1
- package/lib/esm/components/select/types.d.ts.map +1 -1
- package/lib/esm/components/select/utils.d.ts +4 -4
- package/lib/esm/components/select/utils.d.ts.map +1 -1
- package/lib/esm/components/select/utils.js +5 -4
- package/lib/esm/components/select/utils.js.map +1 -1
- package/lib/esm/components/sticky/sticky.d.ts +1 -1
- package/lib/esm/components/sticky/sticky.d.ts.map +1 -1
- package/lib/esm/components/sticky/sticky.js +16 -14
- package/lib/esm/components/sticky/sticky.js.map +1 -1
- package/lib/esm/components/toast/toast.d.ts.map +1 -1
- package/lib/esm/components/toast/toast.js +17 -9
- package/lib/esm/components/toast/toast.js.map +1 -1
- package/lib/esm/components/toast/types.d.ts +3 -0
- package/lib/esm/components/toast/types.d.ts.map +1 -1
- package/lib/esm/components/toggle-password/toggle-password.d.ts.map +1 -1
- package/lib/esm/components/toggle-password/toggle-password.js.map +1 -1
- package/lib/esm/helpers/dom.d.ts +4 -4
- package/lib/esm/helpers/dom.d.ts.map +1 -1
- package/lib/esm/helpers/dom.js +8 -10
- package/lib/esm/helpers/dom.js.map +1 -1
- package/lib/esm/helpers/event-handler.d.ts +1 -1
- package/lib/esm/helpers/event-handler.d.ts.map +1 -1
- package/lib/esm/helpers/event-handler.js +3 -1
- package/lib/esm/helpers/event-handler.js.map +1 -1
- package/lib/esm/helpers/utils.d.ts +1 -1
- package/lib/esm/helpers/utils.d.ts.map +1 -1
- package/lib/esm/helpers/utils.js +4 -1
- package/lib/esm/helpers/utils.js.map +1 -1
- package/lib/esm/index.d.ts +16 -0
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +12 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/types.d.ts +1 -1
- package/lib/esm/types.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/components/carousel/__tests__/carousel.test.ts +326 -0
- package/src/components/carousel/carousel.css +42 -0
- package/src/components/carousel/carousel.ts +847 -0
- package/src/components/carousel/index.ts +11 -0
- package/src/components/carousel/types.ts +38 -0
- package/src/components/clipboard/__tests__/clipboard.test.ts +438 -0
- package/src/components/clipboard/clipboard.ts +416 -0
- package/src/components/clipboard/index.ts +2 -0
- package/src/components/clipboard/types.ts +51 -0
- package/src/components/component.ts +15 -5
- package/src/components/datatable/__tests__/currency-sort.test.ts +6 -13
- package/src/components/datatable/__tests__/multi-row-headers.test.ts +2 -2
- package/src/components/datatable/__tests__/pagination-reset.test.ts +7 -4
- package/src/components/datatable/__tests__/race-conditions.test.ts +11 -14
- package/src/components/datatable/__tests__/setup.ts +1 -1
- package/src/components/datatable/datatable-checkbox.ts +6 -4
- package/src/components/datatable/datatable-sort.ts +27 -7
- package/src/components/datatable/datatable.ts +67 -42
- package/src/components/datatable/types.ts +3 -1
- package/src/components/drawer/drawer.ts +3 -18
- package/src/components/dropdown/dropdown.ts +2 -3
- package/src/components/pin-input/__tests__/pin-input.test.ts +928 -0
- package/src/components/pin-input/index.ts +6 -0
- package/src/components/pin-input/pin-input.ts +499 -0
- package/src/components/pin-input/types.ts +45 -0
- package/src/components/range-slider/__tests__/range-slider.test.ts +659 -0
- package/src/components/range-slider/index.ts +11 -0
- package/src/components/range-slider/range-slider.ts +276 -0
- package/src/components/range-slider/types.ts +36 -0
- package/src/components/rating/__tests__/rating.test.ts +11 -4
- package/src/components/rating/rating.ts +22 -12
- package/src/components/repeater/__tests__/repeater.test.ts +24 -11
- package/src/components/repeater/repeater.ts +5 -3
- package/src/components/select/__tests__/ux-behaviors.test.ts +25 -6
- package/src/components/select/combobox.ts +23 -16
- package/src/components/select/config.ts +15 -14
- package/src/components/select/dropdown.ts +1 -1
- package/src/components/select/option.ts +14 -4
- package/src/components/select/remote.ts +68 -56
- package/src/components/select/search.ts +30 -27
- package/src/components/select/select.ts +41 -37
- package/src/components/select/tags.ts +14 -8
- package/src/components/select/templates.ts +11 -6
- package/src/components/select/types.ts +1 -1
- package/src/components/select/utils.ts +12 -10
- package/src/components/sticky/__tests__/sticky.test.ts +10 -3
- package/src/components/sticky/sticky.ts +16 -26
- package/src/components/sticky/types.ts +3 -3
- package/src/components/toast/toast.ts +34 -21
- package/src/components/toast/types.ts +5 -1
- package/src/components/toggle-password/toggle-password.ts +0 -1
- package/src/helpers/dom.ts +14 -17
- package/src/helpers/event-handler.ts +5 -6
- package/src/helpers/utils.ts +5 -2
- package/src/index.ts +35 -0
- package/src/types.ts +1 -1
- package/styles.css +1 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
|
|
3
|
+
* Copyright 2025 by Keenthemes Inc
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import KTData from '../../helpers/data';
|
|
7
|
+
import KTComponent from '../component';
|
|
8
|
+
import {
|
|
9
|
+
KTRangeSliderConfigInterface,
|
|
10
|
+
KTRangeSliderEventPayloadInterface,
|
|
11
|
+
KTRangeSliderInterface,
|
|
12
|
+
} from './types';
|
|
13
|
+
|
|
14
|
+
declare global {
|
|
15
|
+
interface Window {
|
|
16
|
+
KTRangeSlider: typeof KTRangeSlider;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const FILL_VAR = '--kt-range-fill';
|
|
21
|
+
|
|
22
|
+
export class KTRangeSlider
|
|
23
|
+
extends KTComponent
|
|
24
|
+
implements KTRangeSliderInterface
|
|
25
|
+
{
|
|
26
|
+
protected override _name: string = 'range-slider';
|
|
27
|
+
protected override _defaultConfig: KTRangeSliderConfigInterface = {
|
|
28
|
+
output: '',
|
|
29
|
+
lazy: false,
|
|
30
|
+
};
|
|
31
|
+
protected override _config: KTRangeSliderConfigInterface =
|
|
32
|
+
this._defaultConfig;
|
|
33
|
+
protected _rangeInput: HTMLInputElement | null = null;
|
|
34
|
+
protected _onNativeInput: ((e: Event) => void) | null = null;
|
|
35
|
+
protected _onNativeChange: ((e: Event) => void) | null = null;
|
|
36
|
+
|
|
37
|
+
constructor(
|
|
38
|
+
element: HTMLElement,
|
|
39
|
+
config: KTRangeSliderConfigInterface | null = null,
|
|
40
|
+
) {
|
|
41
|
+
super();
|
|
42
|
+
|
|
43
|
+
const input = KTRangeSlider.findRangeInput(element);
|
|
44
|
+
if (!input) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (this._shouldSkipInit(element)) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
this._rangeInput = input;
|
|
53
|
+
this._init(element);
|
|
54
|
+
this._buildConfig(config);
|
|
55
|
+
|
|
56
|
+
this._onNativeInput = this._handleNativeInput.bind(this);
|
|
57
|
+
this._onNativeChange = this._handleNativeChange.bind(this);
|
|
58
|
+
// Delegate events to the root so we keep working if the preview
|
|
59
|
+
// re-renders and replaces the native range input element.
|
|
60
|
+
this._element?.addEventListener('input', this._onNativeInput);
|
|
61
|
+
this._element?.addEventListener('change', this._onNativeChange);
|
|
62
|
+
|
|
63
|
+
this._syncFromInput();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private static findRangeInput(root: HTMLElement): HTMLInputElement | null {
|
|
67
|
+
if (root instanceof HTMLInputElement && root.type === 'range') {
|
|
68
|
+
return root;
|
|
69
|
+
}
|
|
70
|
+
return root.querySelector<HTMLInputElement>('input[type="range"]');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected _getOutputSelector(): string {
|
|
74
|
+
const raw = this._getOption('output');
|
|
75
|
+
return typeof raw === 'string' ? raw.trim() : '';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
protected _resolveOutputElement(): HTMLElement | null {
|
|
79
|
+
const selector = this._getOutputSelector();
|
|
80
|
+
if (!selector || !this._element) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const fromRoot = this._element.querySelector<HTMLElement>(selector);
|
|
84
|
+
if (fromRoot) {
|
|
85
|
+
return fromRoot;
|
|
86
|
+
}
|
|
87
|
+
return document.querySelector<HTMLElement>(selector);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
protected _getNumericMin(): number {
|
|
91
|
+
const input = this._rangeInput;
|
|
92
|
+
if (!input) return 0;
|
|
93
|
+
const n =
|
|
94
|
+
typeof input.min === 'string' && input.min !== ''
|
|
95
|
+
? parseFloat(input.min)
|
|
96
|
+
: 0;
|
|
97
|
+
return Number.isFinite(n) ? n : 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
protected _getNumericMax(): number {
|
|
101
|
+
const input = this._rangeInput;
|
|
102
|
+
if (!input) return 100;
|
|
103
|
+
if (typeof input.max === 'string' && input.max !== '') {
|
|
104
|
+
const n = parseFloat(input.max);
|
|
105
|
+
if (Number.isFinite(n)) return n;
|
|
106
|
+
}
|
|
107
|
+
return 100;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Reflects `step` for events; `undefined` when `step="any"`. */
|
|
111
|
+
protected _getStepForPayload(): number | undefined {
|
|
112
|
+
const input = this._rangeInput;
|
|
113
|
+
if (!input) return undefined;
|
|
114
|
+
const raw = input.getAttribute('step');
|
|
115
|
+
if (raw === 'any') return undefined;
|
|
116
|
+
if (raw === null || raw === '') return 1;
|
|
117
|
+
const n = parseFloat(raw);
|
|
118
|
+
return Number.isFinite(n) && n > 0 ? n : 1;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
protected _getCurrentValue(): number {
|
|
122
|
+
const input = this._rangeInput;
|
|
123
|
+
if (!input) return 0;
|
|
124
|
+
const v =
|
|
125
|
+
typeof input.valueAsNumber === 'number' &&
|
|
126
|
+
!Number.isNaN(input.valueAsNumber)
|
|
127
|
+
? input.valueAsNumber
|
|
128
|
+
: parseFloat(input.value);
|
|
129
|
+
return Number.isFinite(v) ? v : 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
protected _clamp(value: number, min: number, max: number): number {
|
|
133
|
+
if (max < min) {
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
return Math.min(max, Math.max(min, value));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
protected _fillRatio(value: number, min: number, max: number): number {
|
|
140
|
+
if (max === min) {
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
143
|
+
return (this._clamp(value, min, max) - min) / (max - min);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
protected _buildEventPayload(): KTRangeSliderEventPayloadInterface {
|
|
147
|
+
const min = this._getNumericMin();
|
|
148
|
+
const max = this._getNumericMax();
|
|
149
|
+
const value = this._getCurrentValue();
|
|
150
|
+
const step = this._getStepForPayload();
|
|
151
|
+
return {
|
|
152
|
+
value,
|
|
153
|
+
min,
|
|
154
|
+
max,
|
|
155
|
+
...(step !== undefined ? { step } : {}),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
protected _syncFromInput(): void {
|
|
160
|
+
if (!this._element || !this._rangeInput) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const min = this._getNumericMin();
|
|
165
|
+
const max = this._getNumericMax();
|
|
166
|
+
const value = this._getCurrentValue();
|
|
167
|
+
const ratio = this._fillRatio(value, min, max);
|
|
168
|
+
|
|
169
|
+
this._element.style.setProperty(FILL_VAR, String(ratio));
|
|
170
|
+
|
|
171
|
+
const out = this._resolveOutputElement();
|
|
172
|
+
if (out) {
|
|
173
|
+
out.textContent = String(this._rangeInput.value);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
protected _handleNativeInput(_event: Event): void {
|
|
178
|
+
const event = _event as Event;
|
|
179
|
+
const target = event.target;
|
|
180
|
+
if (!(target instanceof HTMLInputElement) || target.type !== 'range') {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
this._rangeInput = target;
|
|
185
|
+
this._syncFromInput();
|
|
186
|
+
|
|
187
|
+
const payload = this._buildEventPayload();
|
|
188
|
+
this._fireEvent('input', payload);
|
|
189
|
+
this._dispatchEvent('kt.range-slider.input', payload);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
protected _handleNativeChange(_event: Event): void {
|
|
193
|
+
const event = _event as Event;
|
|
194
|
+
const target = event.target;
|
|
195
|
+
if (!(target instanceof HTMLInputElement) || target.type !== 'range') {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
this._rangeInput = target;
|
|
200
|
+
this._syncFromInput();
|
|
201
|
+
|
|
202
|
+
const payload = this._buildEventPayload();
|
|
203
|
+
this._fireEvent('change', payload);
|
|
204
|
+
this._dispatchEvent('kt.range-slider.change', payload);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
public getRangeInput(): HTMLInputElement | null {
|
|
208
|
+
return this._rangeInput;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
public getValue(): number {
|
|
212
|
+
return this._getCurrentValue();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
public override dispose(): void {
|
|
216
|
+
if (this._element) {
|
|
217
|
+
if (this._onNativeInput) {
|
|
218
|
+
this._element.removeEventListener('input', this._onNativeInput);
|
|
219
|
+
}
|
|
220
|
+
if (this._onNativeChange) {
|
|
221
|
+
this._element.removeEventListener('change', this._onNativeChange);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
this._onNativeInput = null;
|
|
225
|
+
this._onNativeChange = null;
|
|
226
|
+
this._rangeInput = null;
|
|
227
|
+
if (this._element) {
|
|
228
|
+
this._element.style.removeProperty(FILL_VAR);
|
|
229
|
+
}
|
|
230
|
+
super.dispose();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
public static getInstance(element: HTMLElement): KTRangeSlider | null {
|
|
234
|
+
if (!element) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
if (KTData.has(element, 'range-slider')) {
|
|
238
|
+
return KTData.get(element, 'range-slider') as KTRangeSlider;
|
|
239
|
+
}
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
public static getOrCreateInstance(
|
|
244
|
+
element: HTMLElement,
|
|
245
|
+
config?: KTRangeSliderConfigInterface,
|
|
246
|
+
): KTRangeSlider | null {
|
|
247
|
+
const existing = this.getInstance(element);
|
|
248
|
+
if (existing) {
|
|
249
|
+
return existing;
|
|
250
|
+
}
|
|
251
|
+
if (!this.findRangeInput(element)) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
new KTRangeSlider(element, config ?? undefined);
|
|
255
|
+
return this.getInstance(element);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
public static createInstances(): void {
|
|
259
|
+
document
|
|
260
|
+
.querySelectorAll<HTMLElement>('[data-kt-range-slider]')
|
|
261
|
+
.forEach((el) => {
|
|
262
|
+
if (el.getAttribute('data-kt-range-slider-lazy') === 'true') {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
new KTRangeSlider(el);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
public static init(): void {
|
|
270
|
+
KTRangeSlider.createInstances();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (typeof window !== 'undefined') {
|
|
275
|
+
window.KTRangeSlider = KTRangeSlider;
|
|
276
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
|
|
3
|
+
* Copyright 2025 by Keenthemes Inc
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Optional CSS selector (document or root-relative) for an element whose text
|
|
8
|
+
* updates with the current range value. Prefer `data-kt-range-slider-output` on the root.
|
|
9
|
+
*/
|
|
10
|
+
export interface KTRangeSliderConfigInterface {
|
|
11
|
+
/** Selector for the output element; also read from `data-kt-range-slider-output`. */
|
|
12
|
+
output?: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* When true, skip auto-init; use `getInstance` / `new KTRangeSlider(element)` manually.
|
|
16
|
+
*/
|
|
17
|
+
lazy?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface KTRangeSliderEventPayloadInterface {
|
|
21
|
+
value: number;
|
|
22
|
+
min: number;
|
|
23
|
+
max: number;
|
|
24
|
+
/** From the input `step` attribute; omitted when `step="any"`. */
|
|
25
|
+
step?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface KTRangeSliderInterface {
|
|
29
|
+
getOption(name: string): unknown;
|
|
30
|
+
getElement(): HTMLElement;
|
|
31
|
+
getRangeInput(): HTMLInputElement | null;
|
|
32
|
+
getValue(): number;
|
|
33
|
+
on(eventType: string, callback: CallableFunction): string;
|
|
34
|
+
off(eventType: string, eventId: string): void;
|
|
35
|
+
dispose(): void;
|
|
36
|
+
}
|
|
@@ -104,7 +104,9 @@ describe('KTRating', () => {
|
|
|
104
104
|
const instance = new KTRating(ratingEl);
|
|
105
105
|
instance.setValue(3);
|
|
106
106
|
expect(instance.getValue()).toBe(3);
|
|
107
|
-
const checked = ratingEl.querySelector<HTMLInputElement>(
|
|
107
|
+
const checked = ratingEl.querySelector<HTMLInputElement>(
|
|
108
|
+
'input[type="radio"]:checked',
|
|
109
|
+
);
|
|
108
110
|
expect(checked?.value).toBe('3');
|
|
109
111
|
instance.dispose();
|
|
110
112
|
});
|
|
@@ -121,8 +123,11 @@ describe('KTRating', () => {
|
|
|
121
123
|
it('dispatches kt.rating.change when user selects a value', () => {
|
|
122
124
|
const instance = new KTRating(ratingEl);
|
|
123
125
|
const events: CustomEvent[] = [];
|
|
124
|
-
ratingEl.addEventListener('kt.rating.change', ((e: CustomEvent) =>
|
|
125
|
-
|
|
126
|
+
ratingEl.addEventListener('kt.rating.change', ((e: CustomEvent) =>
|
|
127
|
+
events.push(e)) as EventListener);
|
|
128
|
+
const radio3 = ratingEl.querySelector<HTMLInputElement>(
|
|
129
|
+
'input[type="radio"][value="3"]',
|
|
130
|
+
);
|
|
126
131
|
expect(radio3).not.toBeNull();
|
|
127
132
|
radio3!.checked = true;
|
|
128
133
|
radio3!.dispatchEvent(new Event('change', { bubbles: true }));
|
|
@@ -226,7 +231,9 @@ describe('KTRating', () => {
|
|
|
226
231
|
ratingEl.setAttribute('data-kt-rating-value', '2');
|
|
227
232
|
const instance = new KTRating(ratingEl);
|
|
228
233
|
expect(instance.getValue()).toBe(2);
|
|
229
|
-
const checked = ratingEl.querySelector<HTMLInputElement>(
|
|
234
|
+
const checked = ratingEl.querySelector<HTMLInputElement>(
|
|
235
|
+
'input[type="radio"]:checked',
|
|
236
|
+
);
|
|
230
237
|
expect(checked?.value).toBe('2');
|
|
231
238
|
instance.dispose();
|
|
232
239
|
});
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import KTData from '../../helpers/data';
|
|
7
|
-
import KTDom from '../../helpers/dom';
|
|
8
7
|
import KTComponent from '../component';
|
|
9
8
|
import { KTRatingConfigInterface, KTRatingInterface } from './types';
|
|
10
9
|
|
|
@@ -79,7 +78,8 @@ export class KTRating extends KTComponent implements KTRatingInterface {
|
|
|
79
78
|
const svg = `<svg class="shrink-0 size-5" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">${path}</svg>`;
|
|
80
79
|
|
|
81
80
|
const container = document.createElement('div');
|
|
82
|
-
container.className =
|
|
81
|
+
container.className =
|
|
82
|
+
'kt-rating flex flex-row-reverse justify-end items-center gap-0';
|
|
83
83
|
container.setAttribute('role', readonly ? 'img' : 'group');
|
|
84
84
|
container.setAttribute('aria-label', `Rating: ${value} of ${max}`);
|
|
85
85
|
if (readonly) {
|
|
@@ -141,13 +141,21 @@ export class KTRating extends KTComponent implements KTRatingInterface {
|
|
|
141
141
|
'text-muted-foreground/50 dark:text-muted-foreground/50';
|
|
142
142
|
const filledTokens = filledClass.split(' ');
|
|
143
143
|
const unfilledTokens = unfilledClass.split(' ');
|
|
144
|
-
this._container
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
144
|
+
this._container
|
|
145
|
+
.querySelectorAll<HTMLElement>('.kt-rating-label')
|
|
146
|
+
.forEach((label) => {
|
|
147
|
+
const v = parseInt(
|
|
148
|
+
label.getAttribute('data-kt-rating-value') || '0',
|
|
149
|
+
10,
|
|
150
|
+
);
|
|
151
|
+
const filled = v <= (val ?? 0);
|
|
152
|
+
label.classList.remove(...filledTokens, ...unfilledTokens);
|
|
153
|
+
label.classList.add(...(filled ? filledTokens : unfilledTokens));
|
|
154
|
+
});
|
|
155
|
+
this._container.setAttribute(
|
|
156
|
+
'aria-valuenow',
|
|
157
|
+
val != null ? String(val) : '0',
|
|
158
|
+
);
|
|
151
159
|
this._container.setAttribute('aria-label', `Rating: ${val ?? 0} of ${max}`);
|
|
152
160
|
}
|
|
153
161
|
|
|
@@ -189,9 +197,11 @@ export class KTRating extends KTComponent implements KTRatingInterface {
|
|
|
189
197
|
this._updateInteractiveDisplay();
|
|
190
198
|
}
|
|
191
199
|
} else {
|
|
192
|
-
this._container
|
|
193
|
-
|
|
194
|
-
|
|
200
|
+
this._container
|
|
201
|
+
.querySelectorAll<HTMLInputElement>('input[type="radio"]')
|
|
202
|
+
.forEach((r) => {
|
|
203
|
+
r.checked = false;
|
|
204
|
+
});
|
|
195
205
|
this._updateInteractiveDisplay();
|
|
196
206
|
}
|
|
197
207
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Tests for KTRepeater component
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { describe, it, expect,
|
|
5
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
6
6
|
import { KTRepeater } from '../repeater';
|
|
7
7
|
|
|
8
8
|
function createFixture(options?: {
|
|
@@ -150,7 +150,8 @@ describe('KTRepeater', () => {
|
|
|
150
150
|
const { trigger } = createFixture();
|
|
151
151
|
const instance = new KTRepeater(trigger);
|
|
152
152
|
const events: CustomEvent[] = [];
|
|
153
|
-
trigger.addEventListener('add', ((e: Event) =>
|
|
153
|
+
trigger.addEventListener('add', ((e: Event) =>
|
|
154
|
+
events.push(e as CustomEvent)) as EventListener);
|
|
154
155
|
instance.add();
|
|
155
156
|
expect(events.length).toBe(1);
|
|
156
157
|
expect(events[0].detail?.payload?.element).toBeInstanceOf(HTMLElement);
|
|
@@ -160,7 +161,7 @@ describe('KTRepeater', () => {
|
|
|
160
161
|
|
|
161
162
|
describe('limit', () => {
|
|
162
163
|
it('does not add more clones when at limit', () => {
|
|
163
|
-
const {
|
|
164
|
+
const { trigger, wrapper } = createFixture({ limit: 2 });
|
|
164
165
|
const instance = new KTRepeater(trigger);
|
|
165
166
|
expect(wrapper.children.length).toBe(1);
|
|
166
167
|
instance.add();
|
|
@@ -173,7 +174,7 @@ describe('KTRepeater', () => {
|
|
|
173
174
|
});
|
|
174
175
|
|
|
175
176
|
it('disables trigger when at limit', () => {
|
|
176
|
-
const {
|
|
177
|
+
const { trigger } = createFixture({ limit: 2 });
|
|
177
178
|
const instance = new KTRepeater(trigger);
|
|
178
179
|
expect(trigger.hasAttribute('disabled')).toBe(false);
|
|
179
180
|
instance.add();
|
|
@@ -182,7 +183,10 @@ describe('KTRepeater', () => {
|
|
|
182
183
|
});
|
|
183
184
|
|
|
184
185
|
it('re-enables trigger when a clone is removed (delete) and count drops below limit', () => {
|
|
185
|
-
const { wrapper, trigger } = createFixture({
|
|
186
|
+
const { wrapper, trigger } = createFixture({
|
|
187
|
+
limit: 2,
|
|
188
|
+
withDeleteInTarget: true,
|
|
189
|
+
});
|
|
186
190
|
const instance = new KTRepeater(trigger);
|
|
187
191
|
instance.add();
|
|
188
192
|
expect(wrapper.children.length).toBe(2);
|
|
@@ -197,7 +201,7 @@ describe('KTRepeater', () => {
|
|
|
197
201
|
});
|
|
198
202
|
|
|
199
203
|
it('allows unlimited clones when limit is 0 or omitted', () => {
|
|
200
|
-
const {
|
|
204
|
+
const { trigger, wrapper } = createFixture();
|
|
201
205
|
trigger.removeAttribute('data-kt-repeater-limit');
|
|
202
206
|
const instance = new KTRepeater(trigger);
|
|
203
207
|
for (let i = 0; i < 5; i++) instance.add();
|
|
@@ -213,7 +217,9 @@ describe('KTRepeater', () => {
|
|
|
213
217
|
instance.add();
|
|
214
218
|
expect(wrapper.children.length).toBe(2);
|
|
215
219
|
const firstClone = wrapper.children[1];
|
|
216
|
-
const deleteBtn = firstClone.querySelector(
|
|
220
|
+
const deleteBtn = firstClone.querySelector(
|
|
221
|
+
'[data-kt-repeater-delete]',
|
|
222
|
+
) as HTMLElement;
|
|
217
223
|
deleteBtn.click();
|
|
218
224
|
expect(wrapper.children.length).toBe(1);
|
|
219
225
|
instance.dispose();
|
|
@@ -224,7 +230,9 @@ describe('KTRepeater', () => {
|
|
|
224
230
|
const instance = new KTRepeater(trigger);
|
|
225
231
|
expect(wrapper.children.length).toBe(1);
|
|
226
232
|
const onlyRow = wrapper.children[0];
|
|
227
|
-
const deleteBtn = onlyRow.querySelector(
|
|
233
|
+
const deleteBtn = onlyRow.querySelector(
|
|
234
|
+
'[data-kt-repeater-delete]',
|
|
235
|
+
) as HTMLElement;
|
|
228
236
|
deleteBtn.click();
|
|
229
237
|
expect(wrapper.children.length).toBe(1);
|
|
230
238
|
instance.dispose();
|
|
@@ -233,12 +241,17 @@ describe('KTRepeater', () => {
|
|
|
233
241
|
|
|
234
242
|
describe('predefined (hidden) template', () => {
|
|
235
243
|
it('clones from hidden template and appends to wrapper', () => {
|
|
236
|
-
const { wrapper, trigger } = createFixture({
|
|
244
|
+
const { wrapper, trigger } = createFixture({
|
|
245
|
+
hiddenTemplate: true,
|
|
246
|
+
withInitialChild: false,
|
|
247
|
+
});
|
|
237
248
|
expect(wrapper.children.length).toBe(0);
|
|
238
249
|
const instance = new KTRepeater(trigger);
|
|
239
250
|
instance.add();
|
|
240
251
|
expect(wrapper.children.length).toBe(1);
|
|
241
|
-
expect(
|
|
252
|
+
expect(
|
|
253
|
+
wrapper.querySelector('input[placeholder="Enter Name"]'),
|
|
254
|
+
).not.toBeNull();
|
|
242
255
|
instance.dispose();
|
|
243
256
|
});
|
|
244
257
|
});
|
|
@@ -266,7 +279,7 @@ describe('KTRepeater', () => {
|
|
|
266
279
|
});
|
|
267
280
|
|
|
268
281
|
it('createInstances initializes all data-kt-repeater elements', () => {
|
|
269
|
-
const { container,
|
|
282
|
+
const { container, trigger } = createFixture();
|
|
270
283
|
const trigger2 = document.createElement('button');
|
|
271
284
|
trigger2.setAttribute('data-kt-repeater', '');
|
|
272
285
|
trigger2.setAttribute('data-kt-repeater-target', '#repeater-target');
|
|
@@ -23,8 +23,8 @@ export class KTRepeater extends KTComponent implements KTRepeaterInterface {
|
|
|
23
23
|
wrapper: '',
|
|
24
24
|
limit: 0,
|
|
25
25
|
};
|
|
26
|
-
protected override _config: KTRepeaterConfigInterface =
|
|
27
|
-
|
|
26
|
+
protected override _config: KTRepeaterConfigInterface = this
|
|
27
|
+
._defaultConfig as KTRepeaterConfigInterface;
|
|
28
28
|
protected _wrapperElement: HTMLElement | null = null;
|
|
29
29
|
protected _deleteHandler: (e: Event) => void;
|
|
30
30
|
|
|
@@ -155,7 +155,9 @@ export class KTRepeater extends KTComponent implements KTRepeaterInterface {
|
|
|
155
155
|
element: HTMLElement,
|
|
156
156
|
config?: KTRepeaterConfigInterface,
|
|
157
157
|
): KTRepeater {
|
|
158
|
-
return
|
|
158
|
+
return (
|
|
159
|
+
this.getInstance(element) || new KTRepeater(element, config ?? undefined)
|
|
160
|
+
);
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
public static createInstances(): void {
|
|
@@ -34,7 +34,7 @@ describe('KTSelect UX Behaviors', () => {
|
|
|
34
34
|
/**
|
|
35
35
|
* Helper to wait for KTSelect to fully initialize
|
|
36
36
|
*/
|
|
37
|
-
const waitForInit = async (
|
|
37
|
+
const waitForInit = async (_select: KTSelect): Promise<void> => {
|
|
38
38
|
// Wait for async initialization - KTSelect uses promises for setup
|
|
39
39
|
await waitFor(200);
|
|
40
40
|
// Wait for next tick to ensure all modules are initialized
|
|
@@ -52,7 +52,8 @@ describe('KTSelect UX Behaviors', () => {
|
|
|
52
52
|
// Clean up all KTSelect instances
|
|
53
53
|
const selects = document.querySelectorAll('.kt-select');
|
|
54
54
|
selects.forEach((select) => {
|
|
55
|
-
const instance = (select as
|
|
55
|
+
const instance = (select as HTMLElement & { instance?: KTSelect })
|
|
56
|
+
.instance;
|
|
56
57
|
if (instance && typeof instance.destroy === 'function') {
|
|
57
58
|
instance.destroy();
|
|
58
59
|
}
|
|
@@ -60,7 +61,7 @@ describe('KTSelect UX Behaviors', () => {
|
|
|
60
61
|
|
|
61
62
|
// Clear document body
|
|
62
63
|
document.body.innerHTML = '';
|
|
63
|
-
container = null as
|
|
64
|
+
container = null as unknown as HTMLElement;
|
|
64
65
|
|
|
65
66
|
// Clear all event listeners
|
|
66
67
|
vi.clearAllMocks();
|
|
@@ -349,12 +350,30 @@ describe('KTSelect UX Behaviors', () => {
|
|
|
349
350
|
await waitFor(50);
|
|
350
351
|
|
|
351
352
|
// ArrowDown focuses first option; ArrowUp from first wraps to last (3). Enter selects focused.
|
|
352
|
-
searchInput.dispatchEvent(
|
|
353
|
+
searchInput.dispatchEvent(
|
|
354
|
+
new KeyboardEvent('keydown', {
|
|
355
|
+
key: 'ArrowDown',
|
|
356
|
+
bubbles: true,
|
|
357
|
+
cancelable: true,
|
|
358
|
+
}),
|
|
359
|
+
);
|
|
353
360
|
await waitFor(20);
|
|
354
|
-
searchInput.dispatchEvent(
|
|
361
|
+
searchInput.dispatchEvent(
|
|
362
|
+
new KeyboardEvent('keydown', {
|
|
363
|
+
key: 'ArrowUp',
|
|
364
|
+
bubbles: true,
|
|
365
|
+
cancelable: true,
|
|
366
|
+
}),
|
|
367
|
+
);
|
|
355
368
|
await waitFor(20);
|
|
356
369
|
|
|
357
|
-
searchInput.dispatchEvent(
|
|
370
|
+
searchInput.dispatchEvent(
|
|
371
|
+
new KeyboardEvent('keydown', {
|
|
372
|
+
key: 'Enter',
|
|
373
|
+
bubbles: true,
|
|
374
|
+
cancelable: true,
|
|
375
|
+
}),
|
|
376
|
+
);
|
|
358
377
|
await waitFor(150);
|
|
359
378
|
|
|
360
379
|
expect(select.getSelectedOptions()).toContain('3');
|