From dd447bb1c16fe0d97603a28453cef8e83b0471b7 Mon Sep 17 00:00:00 2001 From: Andreas Olsson Date: Wed, 4 Sep 2024 18:00:25 +0200 Subject: [PATCH] Update of choices select box plugin --- .../assets/images/android-chrome-192x192.png | Bin 0 -> 6751 bytes .../public/assets/images/apple-touch-icon.png | Bin 0 -> 1739 bytes .../public/assets/images/browserconfig.xml | 9 + .../public/assets/images/favicon-16x16.png | Bin 0 -> 574 bytes .../public/assets/images/favicon-32x32.png | Bin 0 -> 887 bytes .../public/assets/images/favicon.ico | Bin 0 -> 15086 bytes .../public/assets/images/favicon.png | Bin 0 -> 6153 bytes .../choices.js/public/assets/images/logo.svg | 10 + .../public/assets/images/manifest.json | 12 + .../public/assets/images/mstile-150x150.png | Bin 0 -> 3067 bytes .../assets/images/safari-pinned-tab.svg | 28 + .../public/assets/scripts/.eslintrc.js | 27 - .../public/assets/scripts/choices.js | 11798 +++++++--------- .../public/assets/scripts/choices.min.js | 4 +- .../assets/scripts/choices.min.js.LICENSE.txt | 1 - .../public/assets/scripts/choices.mjs | 5159 +++++++ .../assets/scripts/choices.search-basic.js | 4685 ++++++ .../scripts/choices.search-basic.min.js | 2 + .../assets/scripts/choices.search-basic.mjs | 4677 ++++++ .../assets/scripts/choices.search-prefix.js | 3527 +++++ .../scripts/choices.search-prefix.min.js | 2 + .../assets/scripts/choices.search-prefix.mjs | 3519 +++++ .../choices.js/public/assets/styles/base.css | 5 +- .../public/assets/styles/base.min.css | 2 +- .../public/assets/styles/choices.css | 32 +- .../public/assets/styles/choices.css.map | 2 +- .../public/assets/styles/choices.min.css | 2 +- .../extensions/choices.js/public/index.html | 968 ++ .../extensions/choices.js/public/robots.txt | 1 + .../choices.js/public/test/data.json | 42 + .../select-multiple/index-performance.html | 101 + .../public/test/select-multiple/index.html | 951 ++ .../public/test/select-one/index.html | 903 ++ .../choices.js/public/test/text/index.html | 375 + .../cypress/e2e/select-multiple.spec.d.ts | 1 - .../cypress/e2e/select-multiple.spec.d.ts.map | 1 - .../types/cypress/e2e/select-one.spec.d.ts | 1 - .../cypress/e2e/select-one.spec.d.ts.map | 1 - .../public/types/cypress/e2e/text.spec.d.ts | 1 - .../types/cypress/e2e/text.spec.d.ts.map | 1 - .../integration/select-multiple.spec.d.ts | 1 - .../integration/select-multiple.spec.d.ts.map | 1 - .../cypress/integration/select-one.spec.d.ts | 1 - .../integration/select-one.spec.d.ts.map | 1 - .../types/cypress/integration/text.spec.d.ts | 1 - .../cypress/integration/text.spec.d.ts.map | 1 - .../public/types/cypress/plugins/index.d.ts | 3 - .../types/cypress/plugins/index.d.ts.map | 1 - .../types/cypress/support/commands.d.ts | 1 - .../types/cypress/support/commands.d.ts.map | 1 - .../public/types/cypress/support/e2e.d.ts | 2 - .../public/types/cypress/support/e2e.d.ts.map | 1 - .../public/types/cypress/support/index.d.ts | 2 - .../types/cypress/support/index.d.ts.map | 1 - .../choices.js/public/types/src/index.d.ts | 1 - .../public/types/src/index.d.ts.map | 1 - .../types/src/scripts/actions/choices.d.ts | 58 +- .../src/scripts/actions/choices.d.ts.map | 1 - .../src/scripts/actions/choices.test.d.ts | 2 - .../src/scripts/actions/choices.test.d.ts.map | 1 - .../types/src/scripts/actions/groups.d.ts | 21 +- .../types/src/scripts/actions/groups.d.ts.map | 1 - .../src/scripts/actions/groups.test.d.ts | 2 - .../src/scripts/actions/groups.test.d.ts.map | 1 - .../types/src/scripts/actions/items.d.ts | 44 +- .../types/src/scripts/actions/items.d.ts.map | 1 - .../types/src/scripts/actions/items.test.d.ts | 2 - .../src/scripts/actions/items.test.d.ts.map | 1 - .../types/src/scripts/actions/misc.d.ts | 17 - .../types/src/scripts/actions/misc.d.ts.map | 1 - .../types/src/scripts/actions/misc.test.d.ts | 2 - .../src/scripts/actions/misc.test.d.ts.map | 1 - .../public/types/src/scripts/choices.d.ts | 140 +- .../public/types/src/scripts/choices.d.ts.map | 1 - .../types/src/scripts/choices.test.d.ts | 2 - .../types/src/scripts/choices.test.d.ts.map | 1 - .../src/scripts/components/container.d.ts | 13 +- .../src/scripts/components/container.d.ts.map | 1 - .../scripts/components/container.test.d.ts | 2 - .../components/container.test.d.ts.map | 1 - .../src/scripts/components/dropdown.d.ts | 6 - .../src/scripts/components/dropdown.d.ts.map | 1 - .../src/scripts/components/dropdown.test.d.ts | 2 - .../scripts/components/dropdown.test.d.ts.map | 1 - .../types/src/scripts/components/index.d.ts | 1 - .../src/scripts/components/index.d.ts.map | 1 - .../types/src/scripts/components/input.d.ts | 2 - .../src/scripts/components/input.d.ts.map | 1 - .../src/scripts/components/input.test.d.ts | 2 - .../scripts/components/input.test.d.ts.map | 1 - .../types/src/scripts/components/list.d.ts | 6 +- .../src/scripts/components/list.d.ts.map | 1 - .../src/scripts/components/list.test.d.ts | 2 - .../src/scripts/components/list.test.d.ts.map | 1 - .../scripts/components/wrapped-element.d.ts | 10 +- .../components/wrapped-element.d.ts.map | 1 - .../components/wrapped-element.test.d.ts | 2 - .../components/wrapped-element.test.d.ts.map | 1 - .../src/scripts/components/wrapped-input.d.ts | 13 +- .../scripts/components/wrapped-input.d.ts.map | 1 - .../components/wrapped-input.test.d.ts | 2 - .../components/wrapped-input.test.d.ts.map | 1 - .../scripts/components/wrapped-select.d.ts | 19 +- .../components/wrapped-select.d.ts.map | 1 - .../components/wrapped-select.test.d.ts | 2 - .../components/wrapped-select.test.d.ts.map | 1 - .../public/types/src/scripts/constants.d.ts | 12 +- .../types/src/scripts/constants.d.ts.map | 1 - .../types/src/scripts/constants.test.d.ts | 2 - .../types/src/scripts/constants.test.d.ts.map | 1 - .../public/types/src/scripts/defaults.d.ts | 1 - .../types/src/scripts/defaults.d.ts.map | 1 - .../src/scripts/interfaces/action-type.d.ts | 15 +- .../scripts/interfaces/action-type.d.ts.map | 1 - .../src/scripts/interfaces/build-flags.d.ts | 9 + .../src/scripts/interfaces/choice-full.d.ts | 22 + .../types/src/scripts/interfaces/choice.d.ts | 16 - .../src/scripts/interfaces/choice.d.ts.map | 1 - .../types/src/scripts/interfaces/choices.d.ts | 46 - .../src/scripts/interfaces/choices.d.ts.map | 1 - .../src/scripts/interfaces/class-names.d.ts | 111 +- .../scripts/interfaces/class-names.d.ts.map | 1 - .../src/scripts/interfaces/event-choice.d.ts | 6 + .../src/scripts/interfaces/event-type.d.ts | 16 +- .../scripts/interfaces/event-type.d.ts.map | 1 - .../src/scripts/interfaces/group-full.d.ts | 10 + .../types/src/scripts/interfaces/group.d.ts | 7 - .../src/scripts/interfaces/group.d.ts.map | 1 - .../types/src/scripts/interfaces/index.d.ts | 8 +- .../src/scripts/interfaces/index.d.ts.map | 1 - .../src/scripts/interfaces/input-choice.d.ts | 14 + .../src/scripts/interfaces/input-group.d.ts | 10 + .../types/src/scripts/interfaces/item.d.ts | 21 +- .../src/scripts/interfaces/item.d.ts.map | 1 - .../src/scripts/interfaces/keycode-map.d.ts | 21 +- .../scripts/interfaces/keycode-map.d.ts.map | 1 - .../types/src/scripts/interfaces/notice.d.ts | 5 - .../src/scripts/interfaces/notice.d.ts.map | 1 - .../types/src/scripts/interfaces/options.d.ts | 161 +- .../src/scripts/interfaces/options.d.ts.map | 1 - .../interfaces/passed-element-type.d.ts | 9 +- .../interfaces/passed-element-type.d.ts.map | 1 - .../scripts/interfaces/passed-element.d.ts | 54 +- .../interfaces/passed-element.d.ts.map | 1 - .../interfaces/position-options-type.d.ts | 1 - .../interfaces/position-options-type.d.ts.map | 1 - .../types/src/scripts/interfaces/search.d.ts | 11 + .../types/src/scripts/interfaces/state.d.ts | 16 +- .../src/scripts/interfaces/state.d.ts.map | 1 - .../types/src/scripts/interfaces/store.d.ts | 64 + .../interfaces/string-pre-escaped.d.ts | 3 + .../scripts/interfaces/string-untrusted.d.ts | 4 + .../src/scripts/interfaces/templates.d.ts | 28 + .../types/src/scripts/interfaces/types.d.ts | 11 +- .../src/scripts/interfaces/types.d.ts.map | 1 - .../types/src/scripts/lib/choice-input.d.ts | 9 + .../scripts/lib/html-guard-statements.d.ts | 4 + .../public/types/src/scripts/lib/utils.d.ts | 45 +- .../types/src/scripts/lib/utils.d.ts.map | 1 - .../types/src/scripts/lib/utils.test.d.ts | 2 - .../types/src/scripts/lib/utils.test.d.ts.map | 1 - .../types/src/scripts/reducers/choices.d.ts | 14 +- .../src/scripts/reducers/choices.d.ts.map | 1 - .../src/scripts/reducers/choices.test.d.ts | 2 - .../scripts/reducers/choices.test.d.ts.map | 1 - .../types/src/scripts/reducers/groups.d.ts | 13 +- .../src/scripts/reducers/groups.d.ts.map | 1 - .../src/scripts/reducers/groups.test.d.ts | 2 - .../src/scripts/reducers/groups.test.d.ts.map | 1 - .../types/src/scripts/reducers/index.d.ts | 9 - .../types/src/scripts/reducers/index.d.ts.map | 1 - .../src/scripts/reducers/index.test.d.ts | 2 - .../src/scripts/reducers/index.test.d.ts.map | 1 - .../types/src/scripts/reducers/items.d.ts | 13 +- .../types/src/scripts/reducers/items.d.ts.map | 1 - .../src/scripts/reducers/items.test.d.ts | 2 - .../src/scripts/reducers/items.test.d.ts.map | 1 - .../types/src/scripts/reducers/loading.d.ts | 7 - .../src/scripts/reducers/loading.d.ts.map | 1 - .../src/scripts/reducers/loading.test.d.ts | 2 - .../scripts/reducers/loading.test.d.ts.map | 1 - .../public/types/src/scripts/search/fuse.d.ts | 14 + .../types/src/scripts/search/index.d.ts | 3 + .../src/scripts/search/prefix-filter.d.ts | 11 + .../public/types/src/scripts/store/store.d.ts | 69 +- .../types/src/scripts/store/store.d.ts.map | 1 - .../types/src/scripts/store/store.test.d.ts | 2 - .../src/scripts/store/store.test.d.ts.map | 1 - .../public/types/src/scripts/templates.d.ts | 25 +- .../types/src/scripts/templates.d.ts.map | 1 - .../types/src/scripts/templates.test.d.ts | 2 - .../types/src/scripts/templates.test.d.ts.map | 1 - assets/extensions/choices.js/src/entry.js | 3 + .../src/scripts/actions/choices.test.ts | 92 - .../choices.js/src/scripts/actions/choices.ts | 90 +- .../src/scripts/actions/groups.test.ts | 25 - .../choices.js/src/scripts/actions/groups.ts | 33 +- .../src/scripts/actions/items.test.ts | 72 - .../choices.js/src/scripts/actions/items.ts | 76 +- .../src/scripts/actions/misc.test.ts | 56 - .../choices.js/src/scripts/actions/misc.ts | 30 - .../choices.js/src/scripts/choices.test.ts | 2361 ---- .../choices.js/src/scripts/choices.ts | 2626 ++-- .../src/scripts/components/container.test.ts | 485 - .../src/scripts/components/container.ts | 95 +- .../src/scripts/components/dropdown.test.ts | 143 - .../src/scripts/components/dropdown.ts | 16 +- .../src/scripts/components/input.test.ts | 352 - .../src/scripts/components/input.ts | 47 +- .../src/scripts/components/list.test.ts | 96 - .../choices.js/src/scripts/components/list.ts | 26 +- .../components/wrapped-element.test.ts | 179 - .../src/scripts/components/wrapped-element.ts | 57 +- .../scripts/components/wrapped-input.test.ts | 66 - .../src/scripts/components/wrapped-input.ts | 29 +- .../scripts/components/wrapped-select.test.ts | 183 - .../src/scripts/components/wrapped-select.ts | 99 +- .../choices.js/src/scripts/constants.test.ts | 155 - .../choices.js/src/scripts/constants.ts | 50 +- .../choices.js/src/scripts/defaults.ts | 76 +- .../src/scripts/interfaces/action-type.ts | 27 +- .../src/scripts/interfaces/build-flags.ts | 15 + .../src/scripts/interfaces/choice-full.ts | 25 + .../src/scripts/interfaces/choice.ts | 17 - .../src/scripts/interfaces/choices.ts | 87 - .../src/scripts/interfaces/class-names.ts | 110 +- .../src/scripts/interfaces/event-choice.ts | 7 + .../src/scripts/interfaces/event-type.ts | 27 +- .../src/scripts/interfaces/group-full.ts | 13 + .../src/scripts/interfaces/group.ts | 8 - .../src/scripts/interfaces/index.ts | 7 +- .../src/scripts/interfaces/input-choice.ts | 17 + .../src/scripts/interfaces/input-group.ts | 13 + .../choices.js/src/scripts/interfaces/item.ts | 21 +- .../src/scripts/interfaces/keycode-map.ts | 20 +- .../src/scripts/interfaces/notice.ts | 5 - .../src/scripts/interfaces/options.ts | 170 +- .../scripts/interfaces/passed-element-type.ts | 10 +- .../src/scripts/interfaces/passed-element.ts | 62 +- .../src/scripts/interfaces/search.ts | 12 + .../src/scripts/interfaces/state.ts | 16 +- .../src/scripts/interfaces/store.ts | 84 + .../scripts/interfaces/string-pre-escaped.ts | 3 + .../scripts/interfaces/string-untrusted.ts | 5 + .../src/scripts/interfaces/templates.ts | 60 + .../src/scripts/interfaces/types.ts | 21 +- .../src/scripts/lib/choice-input.ts | 83 + .../src/scripts/lib/html-guard-statements.ts | 7 + .../choices.js/src/scripts/lib/utils.test.ts | 281 - .../choices.js/src/scripts/lib/utils.ts | 231 +- .../src/scripts/reducers/choices.test.ts | 295 - .../src/scripts/reducers/choices.ts | 158 +- .../src/scripts/reducers/groups.test.ts | 71 - .../choices.js/src/scripts/reducers/groups.ts | 43 +- .../src/scripts/reducers/index.test.ts | 60 - .../choices.js/src/scripts/reducers/index.ts | 37 - .../src/scripts/reducers/items.test.ts | 182 - .../choices.js/src/scripts/reducers/items.ts | 124 +- .../src/scripts/reducers/loading.test.ts | 21 - .../src/scripts/reducers/loading.ts | 23 - .../choices.js/src/scripts/search/fuse.ts | 59 + .../choices.js/src/scripts/search/index.ts | 13 + .../src/scripts/search/prefix-filter.ts | 42 + .../src/scripts/store/store.test.ts | 257 - .../choices.js/src/scripts/store/store.ts | 194 +- .../choices.js/src/scripts/templates.test.ts | 716 - .../choices.js/src/scripts/templates.ts | 441 +- .../choices.js/src/styles/base.scss | 2 +- .../choices.js/src/styles/choices.scss | 49 +- .../extensions/choices.js/src/tsconfig.json | 22 + 270 files changed, 33718 insertions(+), 16443 deletions(-) create mode 100644 assets/extensions/choices.js/public/assets/images/android-chrome-192x192.png create mode 100644 assets/extensions/choices.js/public/assets/images/apple-touch-icon.png create mode 100644 assets/extensions/choices.js/public/assets/images/browserconfig.xml create mode 100644 assets/extensions/choices.js/public/assets/images/favicon-16x16.png create mode 100644 assets/extensions/choices.js/public/assets/images/favicon-32x32.png create mode 100644 assets/extensions/choices.js/public/assets/images/favicon.ico create mode 100644 assets/extensions/choices.js/public/assets/images/favicon.png create mode 100644 assets/extensions/choices.js/public/assets/images/logo.svg create mode 100644 assets/extensions/choices.js/public/assets/images/manifest.json create mode 100644 assets/extensions/choices.js/public/assets/images/mstile-150x150.png create mode 100644 assets/extensions/choices.js/public/assets/images/safari-pinned-tab.svg delete mode 100644 assets/extensions/choices.js/public/assets/scripts/.eslintrc.js delete mode 100644 assets/extensions/choices.js/public/assets/scripts/choices.min.js.LICENSE.txt create mode 100644 assets/extensions/choices.js/public/assets/scripts/choices.mjs create mode 100644 assets/extensions/choices.js/public/assets/scripts/choices.search-basic.js create mode 100644 assets/extensions/choices.js/public/assets/scripts/choices.search-basic.min.js create mode 100644 assets/extensions/choices.js/public/assets/scripts/choices.search-basic.mjs create mode 100644 assets/extensions/choices.js/public/assets/scripts/choices.search-prefix.js create mode 100644 assets/extensions/choices.js/public/assets/scripts/choices.search-prefix.min.js create mode 100644 assets/extensions/choices.js/public/assets/scripts/choices.search-prefix.mjs create mode 100644 assets/extensions/choices.js/public/index.html create mode 100644 assets/extensions/choices.js/public/robots.txt create mode 100644 assets/extensions/choices.js/public/test/data.json create mode 100644 assets/extensions/choices.js/public/test/select-multiple/index-performance.html create mode 100644 assets/extensions/choices.js/public/test/select-multiple/index.html create mode 100644 assets/extensions/choices.js/public/test/select-one/index.html create mode 100644 assets/extensions/choices.js/public/test/text/index.html delete mode 100644 assets/extensions/choices.js/public/types/cypress/e2e/select-multiple.spec.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/e2e/select-multiple.spec.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/cypress/e2e/select-one.spec.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/e2e/select-one.spec.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/cypress/e2e/text.spec.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/e2e/text.spec.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/cypress/integration/select-multiple.spec.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/integration/select-multiple.spec.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/cypress/integration/select-one.spec.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/integration/select-one.spec.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/cypress/integration/text.spec.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/integration/text.spec.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/cypress/plugins/index.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/plugins/index.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/cypress/support/commands.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/support/commands.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/cypress/support/e2e.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/support/e2e.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/cypress/support/index.d.ts delete mode 100644 assets/extensions/choices.js/public/types/cypress/support/index.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/index.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/choices.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/choices.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/choices.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/groups.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/groups.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/groups.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/items.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/items.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/items.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/misc.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/misc.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/misc.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/actions/misc.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/choices.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/choices.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/choices.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/container.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/container.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/container.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/dropdown.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/dropdown.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/dropdown.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/index.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/input.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/input.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/input.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/list.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/list.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/list.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/constants.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/constants.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/constants.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/defaults.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/action-type.d.ts.map create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/build-flags.d.ts create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/choice-full.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/choice.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/choice.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/choices.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/choices.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/class-names.d.ts.map create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/event-choice.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/event-type.d.ts.map create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/group-full.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/group.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/group.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/index.d.ts.map create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/input-choice.d.ts create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/input-group.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/item.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/notice.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/notice.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/options.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts.map create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/search.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/state.d.ts.map create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/store.d.ts create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/string-pre-escaped.d.ts create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/string-untrusted.d.ts create mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/templates.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/interfaces/types.d.ts.map create mode 100644 assets/extensions/choices.js/public/types/src/scripts/lib/choice-input.d.ts create mode 100644 assets/extensions/choices.js/public/types/src/scripts/lib/html-guard-statements.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/lib/utils.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/lib/utils.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/lib/utils.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/choices.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/choices.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/choices.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/groups.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/groups.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/groups.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/index.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/index.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/index.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/index.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/items.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/items.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/items.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/loading.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/loading.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/loading.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/reducers/loading.test.d.ts.map create mode 100644 assets/extensions/choices.js/public/types/src/scripts/search/fuse.d.ts create mode 100644 assets/extensions/choices.js/public/types/src/scripts/search/index.d.ts create mode 100644 assets/extensions/choices.js/public/types/src/scripts/search/prefix-filter.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/store/store.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/store/store.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/store/store.test.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/templates.d.ts.map delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/templates.test.d.ts delete mode 100644 assets/extensions/choices.js/public/types/src/scripts/templates.test.d.ts.map create mode 100644 assets/extensions/choices.js/src/entry.js delete mode 100644 assets/extensions/choices.js/src/scripts/actions/choices.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/actions/groups.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/actions/items.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/actions/misc.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/actions/misc.ts delete mode 100644 assets/extensions/choices.js/src/scripts/choices.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/components/container.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/components/dropdown.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/components/input.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/components/list.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/components/wrapped-element.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/components/wrapped-input.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/components/wrapped-select.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/constants.test.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/build-flags.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/choice-full.ts delete mode 100644 assets/extensions/choices.js/src/scripts/interfaces/choice.ts delete mode 100644 assets/extensions/choices.js/src/scripts/interfaces/choices.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/event-choice.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/group-full.ts delete mode 100644 assets/extensions/choices.js/src/scripts/interfaces/group.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/input-choice.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/input-group.ts delete mode 100644 assets/extensions/choices.js/src/scripts/interfaces/notice.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/search.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/store.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/string-pre-escaped.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/string-untrusted.ts create mode 100644 assets/extensions/choices.js/src/scripts/interfaces/templates.ts create mode 100644 assets/extensions/choices.js/src/scripts/lib/choice-input.ts create mode 100644 assets/extensions/choices.js/src/scripts/lib/html-guard-statements.ts delete mode 100644 assets/extensions/choices.js/src/scripts/lib/utils.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/reducers/choices.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/reducers/groups.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/reducers/index.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/reducers/index.ts delete mode 100644 assets/extensions/choices.js/src/scripts/reducers/items.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/reducers/loading.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/reducers/loading.ts create mode 100644 assets/extensions/choices.js/src/scripts/search/fuse.ts create mode 100644 assets/extensions/choices.js/src/scripts/search/index.ts create mode 100644 assets/extensions/choices.js/src/scripts/search/prefix-filter.ts delete mode 100644 assets/extensions/choices.js/src/scripts/store/store.test.ts delete mode 100644 assets/extensions/choices.js/src/scripts/templates.test.ts create mode 100644 assets/extensions/choices.js/src/tsconfig.json diff --git a/assets/extensions/choices.js/public/assets/images/android-chrome-192x192.png b/assets/extensions/choices.js/public/assets/images/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..5ee80a7ac9547f63cc5ec5fb5cef08ddc8db2b1b GIT binary patch literal 6751 zcmZ{Ic|4R|*zg%MnX!*0`!XcSV;Qmxk7W#ntWiCP5RD{^B}5pEQAo%5DmbREdVM>0B{k~ zK3`L%{-C|1ucHl4|9vPmZ)2%Fa4$W>%kU`#GaDbzP+f8y06aiXTl2c_$m*+a(X-~> zY7?FQf3QEcjNxvj+8WC_-@n7Q3?tG-`1N?VQY!8W3;%hR1q8Yd5H~M z2&3$;rQP!k1#4eVqE3%?m-oFZ({*lR+TSoLBxd4O(Q!W+?1M8O;4h}~wf%|?aiiN2 z5Kf2ADB~XMJoO?S?5pdx+GI^3pfr6D6BH>JNdMg6&gJTB141wq98aNMeey zX~I*Im_#->4WbdGm5aKwIvSCCa_ww+ zy-mimUV^K!J6rY=rA>8_CQBhaBB*=ALLb&f1f|H=XmYuOGB!TC*fCj>@=uKTBV5 z@z1?3G2xbVm(J{R%_}wT8@hnsVK4P=jG7=6WRR{In`Rparl^juDzW_5I6W%EJTS|Q zvm4;XZ*P=N$z?Kbh&zh#o(rkJVsh!^UCBq6*mTcma+2P2s-;thy=&8TG|}y!xbW!} zx(@4#@e}_I-b!}f z(Yv?vt-beoAZJj5)8|-~XAKzju~nr*mW&|PR!OPGBE`(Ir%k&LSUBrZ5RMibYwo$0 zTQ>i2(E#~fN7WbUx@tB}feQhaLB6G_G84_W*QMDf{%&rj+K5kUcm)0NBdJg_+b6mw z>>Q~v?}BDdSm;>ny_uEhk+D>?y<$fSQ|T|wdpmmXw#{N%GB^*%-}-Ho81;xM{fX=m=>I~?&l7Yh50P4jK4 zCHF1fIn2KOW`@)mJsh9?;TE``QIIIc0~YRFi(#OoWNb%J%s_eZTlvS#U~}^HMCf!a zQOV{sR(OT4eF(1KI?}7U<{dX-fzwL5J@aHtEJ20uMMJ2Gb4IQw-~Ep6j%1-pjic?N z({-WKT^nFR|C$5mhLN9Jy7g>O8R&v_joST#j0{JgQyT8qsGvu==e?Mtx|r(RB))DT z|El>Yf7A#Uh2-Nvo=9 z1P!3@oQlNVsZ&)o&?U|q3Y=}UQBSJ60uiljKMONk1HB_eZG*821^z|wdI z4Vd$;J@_cjf{n?aMZ6f@U%J&AJN+5Hz@eE1?#uqLI1S?H2wX;-9dyNn0D!?=rh*JI zEkT?#d{y(yJf%DU>`A{o66pzw^)1 z2-B4qiIk20z>lB8w}OjhIBBi{+kF&wqqNCf4mz$gvc8zg>zo0QQp0}bpF(y`a>ZUn z&fy899xb##%Uflvo3Tl%u+k2YZ4Qg7S#K=oi$obVoveh;;2QQZSZ8i|2|A-}8TQ35 zU%a(g-#pbm_-(eBxK;7Rob54Va9m6}+eDSK5{G7rNrV4e(zdO(aZj%4lg`b+Y#wW? zs!T*L3GY>6F;O&Co{j85o1k!6mn8Gm503sWFtchV`s!ad)i+M0jjvpMpyFH)OKC9+UQ^jG4v242)$%QdU_O6`ZrjQp&EDX<^o50wA0dS5t> zg)QRTOGY{qJTcu6>2#KuL9jnPh7R;ur4`ZTB5za;vE&QdZey_aT=!3(`f`tatrV%Dfzt+RV1}^|mkEUMJ+R1u#z^3ET`8sfa#D5^UK2 zn;XMvqO_2+*6kq(27quZrMO=VlJ+Q6Q#i&h>Mh$>5Tl1RUHqaD#q?Rj#70T{48V)e zC$CT3uDXkmBN_O*G5!46*J{MdxOnFE;jmnvl`WUJ9GyIu&*AWgYPHkLHP{O@zUDQR z75knak#oOFNPk%JmG;n-3%OEsw@R%Bu|~(tvhSMN{gu zh*>?Wgxs`LW+m5xHp03FtFt36T>?iWbA)w%^dr8UaP1LKI!wkwP(MW2H>K%+sYk8Q z7HBY~i>3dzJ1Z`yu=&npGIUE%wuZ{PAnHYM(Z6G3ahFOA9MB_B(C0xk&^5la4O+{3 zqGU>s#4JKRi3cd|U@K6IXLKWn8PInQiLifIg7Cr{{nW5C;hy24wyjMBQk!T7ukt&t zg$L@`xo~|QS~VS@=}N2PF&f733!3H!7AGOdG&s?K5$7=~@C&jeQ!85EdkawDSTUV` z@8vyOl@Wh8M4Wr27fcPvN%0Gd&Th^ib4_W5IeVs5kaI1JdJ4;{T|iLWbbk|6ZBX!Xn%~{=`gM4;gmC!%s%lhN!N_rfNpz* zuHoBxx?oy45$CV}+l*SERjUzrE!4#?EDjuAVsH*C;n{%KGq_6>!`}Nf*|zoiH%GFb zkhB0@7l~2wzd`0WZ7~OME?@I`B)-9iwC=0~)0D1fZBSr06r@z}#?gR&gFn%C5F`V3 zojh?EVHlf)=cmeK;lWY|{|R=uwyxQ>1Vrkg<*rF)zD8mLj0ny$J>Te3WQBOgXhRH0 z@0gxvAhRlytgFr-HhJm!YTt9}dJ0-qLH>gTZ!maS6*D7}RT4gYhuQ%h2thIwEA}kg zpn*6Kl{e%%$4TJePF4(KQnEfi{LO5g3)d9W4~28fvoQj!Wb;)MhY=3NF$@=={7pwI z8FnQn+Q0INO$=<-f!kq*Ls9iWHV=R%IV#eeXPuGC@Gz|7(-7#tE^+aJ?{zk-bQtr6 zMil$oJB_niC>^>9Hr8bMFs41~dcozvGPRygX)VheB4jTF`;jGWrPVE zGiWlj{?t07dcv!C?7{$*oSs?9^cB9}{BX)tUpXHURg_sg{e2cxsz{Qt|Eb4~&8jm_ zU``qM0f$}=#mD&3uY-IOTc-5E)cD7QG1+j?D3hr!@~_0I%v0|!*fUdEwPYrUkqRwQ zI^Urv_Hf=<+}AfrIhK?x(@z5%|B(sii>=%5Kb53YzZ3`vW4R0epS$8vPF63mdMly+ zP?TAddqKY7R8*npkb4&Uk|bx7a4bnBzw-MIGFO4FFkCZ%FP<&(C$d#uc;KSzb$Y^0 zws94t_b&*7%Ij;SV|kARIarVq0R|nY088MGT#^d(2-g2NwMHm&N67z=6-3gj7EAxojKyB!XdHxK^{&&*;@c=dFwGYz+s+he zWil%t_fuMU@$ryGpoVC&$o!i%!hmTeja_0~Q-=qJHI_mGbD2{l2ar=p+Y=$S-wy_L z2TmUv=V2(bP-1CdN}pQYr(iTFw)60%4X4_To7pOfKRr{KPQ6!wImVwTs*bGI5toyF zQktC61Ygi4LQ*29+X5KC%_Yg{EB610%U%5R-GAQ{G1zxzWwy ztZ<3Z&NCU_D(54i?2!`w%rA3Y)Cq11_sW-Bb*ZAr(x)n{kGPt&ZV?5HqIGg;+;6u3 zx;9ncjre-&L}3EAowzP@V#> z%4ZFIzj-Ji+6~;(cqUXhj)w7sWVEnIa$(KbRR2s+E`-`?vZ-OiUn1wO5W)&}nL{9q z{0Jzx^n5SF-4*SzjGP}+od_cT`V%x}ZyKq@N447HAyemAXC-DB}8?6Ppr z{=PuQLlGJoL*_B@_w<)td0qRu^kbon=s=>K9zm9uUjSwlrRmC_xg)Kc^$w8F*Gt($ zbXd^Ocl`@XBseNvK6Rzfe-C64xQo1TOGus>0Po64!8fMHgRZC$FX4DU%e9K14u7bN z0gw_#y5Bss*hCDSjTn>e>VEn4wb$v58Z2NELBt+kxW5t1)9QjNxMBC<6ee&U>G<18 zIWU2$0}Fod4DpF`h{|iZrNcADf1T;MMbCs*g`wrwEG>Z8=swiwOE|FQcpErl?o69Y2v*u z)CX+Qkgnxrh-Lgw(r6rO+>mPuUTuM^WD-_K26a6l?A!EgIbQ_Iko0Xj%fx~f+D6g8 z*X@{2!U9|T_Y-z?8BnQ!!2BJ#+b>ATK`une&Vsv!J?xjnK6{6pSkHaJgf`~flQAqYwcvK?iNiT0CKbE1Ev!2u0Qx+M?KlcKopK-XCPaS3-(r&*uF)s}ZYLb^zxgic z0g)$T4b`w<7TzEaa?$E5A)@=!BTPC-Kt$;UB4)J~At@~o%W0_k7hal+Ko^4A9~C-1 zf_Dzdv7fkc%sY2BTgeLYwgl)PDtCp>?4QEjyJWN2?Yx@GM;Ho}OwVf^tv(MrfdbK( zQ9KXr4zETX8UoV%h#cVcEBq6R3Ze3FyM4CK6(9! zdSSD2X8PCK$;qSI&y(Si4>?Hr*Z*u8w3@i{NC@M!l0WSV3GVOM4Txu67xm)Qi@%(H zb=Qtxtut#JUm4_QLT5;0E zhoG9d;xt-9aiGs~?XB$Ik0hBr3a7;9>m{vLmr-*hAn< z>BE)IHB(_OvaHj^y9sF5i$9}dgzY(7pJCHV`z#G#eebhujQXY;zZx=E%oN**clVv> zm^t>0X*#rcJk*^vAHXft7H%2${Yqt_bT%+;U6m#uE!ij>$?($LV7FtEx!u^HZ-mrz zJ$n78M&dEyfoddV4t38V4mWS)W0ax6q5c1 zI+K>&#e2V?iz_QxA%ZXVYWzx#K*jz*cRE{;_A?Ig$mgGAph*aN&1DvnoBl zw27hNI`zuWA%?E|9~^Cjz6QHUkAYvr7S?l(r!CvgKn0f@+K`VVdiYDwJ>KAl>(o`w z@Gc-QI%%aHNl_NB+zZSyA9fffT+P0dS*o2Y*)_W=xqCh3j}w2`#&q!$??cp6wmSux zUH50K9+s6``d?~V2$wX>aE3qb{)QlAY(S$BeD_6iBZCKamx~mn7`vMLL{n-5MoJ3Z z5^1^t`s^uZhNv^At^2_d}Gt$wqFE;G2Nn5%k%VRlNPD0F}4Q&%sy6J zWV-YcvBwn6jQEzVUH9{~-*DHddEuXVqlzu~OXNI1#PO+T0>*K(yu43Y>sfzCN?W|; zTio5e9*KAfeTGn@8c97;n;iZbzJ=R0Zsy8gnel9v7x86cT{j#}Z!lHYj^kq<&OR6| z`ttTf%_Y)#SUvw(=+03V%!E~QzjmqD>ph3&j}w#3;`G(p!CRNn*y^20<69#LvTRP} zR0Km|@>B|44$o|Y=@LRX+QjrpCDJw6TIFSwdouj9>bGmYHa-N1;Bt$kc)V;;Uf261Hq;N-k zR%lDe$nI131e{rhHuQ6m~#g6VK-PKK! z?Th)!>tn{ZJZgBTBdzd9C1~UJGeNtuV{(bz%}PO$lpK5eF1LfDLi@y{no-6~8A)zl z2?YT@zraDNWT_+l-Ycz%a@&f9BLzxWe#0*tY;JPiYTIMA_F92KuL|>RZG6#9++TUu zoQpF)a+W1p2pGVd$r@dTkK1}*lH!-QImE*_Oqj zv_@10%w_i9*KUz{pHxki>qq&-)la+&-rES`{OT#Ey-vCa066b;+1$&)&g-sN z1ImulCdxNDK+lz4N3{?2wKjD$@i)QSiMo`l(qM^;)oT-{5Kkom^e!7|7vgL~{vSfo BDO~^n literal 0 HcmV?d00001 diff --git a/assets/extensions/choices.js/public/assets/images/apple-touch-icon.png b/assets/extensions/choices.js/public/assets/images/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a6c4f84a342c74c584ce8aea80826600bf36438a GIT binary patch literal 1739 zcmZ{jX;2e(8pi*UatKtE!%(gUSrKq{0=q(DFn3TBIopin{xf`S+jtSExJQwjmA z)gp%?@u+JHRdKE16oMdU0tpETA%r9(0!bhVZhxd8rd1sz^KfLp+JRT4K z)ZD=w0PtySOk|?L+y5Lhh(XP5HVg_r$vTWU48V(83vIfwA;U6a5)lAg{wn}wHvmu@ zR%Jo}3Vi@rN&_IM4ghF=BOxIKfGs1(k0PTsH#fEVO{GpRQfucG>PeaMon*ajN!rL4 zSI)0s8A8-FA33=YH9j9O%-T1^-2I;6Oq|)-N4M&wnfFYac2kYJs776sEu9pdese>o zpW9H6NfiW<3@?yWb5;tO!qZeiY_sQXQ;gB@p+#QvoPX}^*fqbHx<%Feg1LHsefi$@AM~K)B=X!IGMAe*7|;! zrOA~J{q#VYIg2V|Mo!c|WbRA$=_Dq{}Q$t7R zj*>X1DBK+S;;jYIBf;vM71{9G#>~1(pwdK)v6H5_c{74;v3ydd;43xm@0lqS-nX+K z8~9?XTxs7&-#;{~(&-)hXJ$84y^{3@i;|#`xgEWX^|6tMk;M!VQx))Ig45s{ znQrqkM0R}7sL#fb2P(FH$meBV|Il4~&$ueDJ>M2BP2d{Gvx7ZL57F*T33SlTtHtPU z#al&~2_&Q1_r3jpiH0rxGE2TLvof7pC$ZkA3X&3zkC@Ukr{6aDDv<0n5KW?OdLIg@X`JYmOUn|C}jN%b(& zCqJ~lID9Taes1>!JmG~0;rAG0!Xu<@YI2KF>C>aOsYOY~gcNAhGT)P=h#dQRIn;Qu zt~edrSx(0E?62<58^rG&?ZaF&c1cx*+v}RGYg@m!j)wn@L#~XH_7jb{z1^P@hChCv^(PNviw3@EpcL#<_@ zmk7M5e?ge8EQLLVJBhA;E_940lHKxOxyCp--+)_vcgD1QVrNA<^0LjtT-(}>s_oJ6 zkOBOIP-yg_YyX5ZA0M+$HE%tquHK3tL|#$(c~`q6r5!vfY(bYs7!#s4zUVdSvBXk% z776mISUVx*rxxK)&pb(OsJ1KE&cy3GPYd>(P0y#K9TV<72-+>Lrq)aUu*fqNup6oH=6DT> zr>P!z9CoZ|K{|Z)7W0WtDXjBv2+l6d{L+^>^`^aU?P|eL&9xpie!6k_y_I8w{#1>q ziPiN>y{@A6L72-54J8tZbA$h_4G0Lcr#0ndjiLSrI5Kq@#Oh{YnPlEpVgPqHHtHl6 zm5$8}$|%S*81VD)J?P~V=;iB=^bHL13kdS_-|OQSp0Bwa?H#3rU+g5?+Fp|f){Vc3%VOjve4HUog-My}M-?84U`9>d2*Mq~Mj0ODrh zonc|)W)pYY7GeX7Ec5S2LEK&;VIy?P5OI{~L^K^Ki)lXM4VIugu+oSx?ifyh*r@o( J)`+z7KLEQNkWc^s literal 0 HcmV?d00001 diff --git a/assets/extensions/choices.js/public/assets/images/browserconfig.xml b/assets/extensions/choices.js/public/assets/images/browserconfig.xml new file mode 100644 index 00000000..daccb526 --- /dev/null +++ b/assets/extensions/choices.js/public/assets/images/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #ffffff + + + diff --git a/assets/extensions/choices.js/public/assets/images/favicon-16x16.png b/assets/extensions/choices.js/public/assets/images/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..8a14f87d78b6847b282a969ebac14f78ae5d2874 GIT binary patch literal 574 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>$qswaksN_uEeD?k;&(C>oKxK?c-tI0k zb66bNfgJV{PhVH|2ONAt(vmk0%$x!git==E43W5;dcsqvK|z4!VB5sd7zf9L|NmcJ zEqiUPP(YMg^4!g7LTefR2go%lI!LfgR7^^nF;PNDrulbsYQzSkH8&*8-tbr(IlEcz zs~4HGHMU&-SWjL2+IjkCHN~T{E~%sgZBZ?8jVMV;EJ?LWE=mPb3`PcqX1WFzx`rkp zh89*v=2k|g+6G2e1_o2b-v2?-kei>9nO2Eg!xQgt2cU-Vs*s41pu}>8f};Gi%$!t( zlFEWqh0KDIWCn(cIgdZ_a1@4VXq@stea7=?5CgL^w_Y;0u(GiCWD#az1(ybs!zs+l tn?n>%-?(z($eANDN7zp{cr5VJV|XPlSn|oqbSlsa22WQ%mvv4FO#l+d&PV_N literal 0 HcmV?d00001 diff --git a/assets/extensions/choices.js/public/assets/images/favicon-32x32.png b/assets/extensions/choices.js/public/assets/images/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..7c4a93a67ad495eef1876f6a70a6f3833f089981 GIT binary patch literal 887 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10;&y;fh%3Y1t3W2h-YX1y zh(GyKmVATZ#?_-i~k6}@?G0^Q9q|`Jbv@zkKbP(T|Tg)C+}~7@k_2A!*4Q2WCzI3O)98 zaSX9I-FnGgsL6rB<)T~2g}}6sGfC$pH#bE-_-Fo!A#7{??fjb#KK<&G+Gcun`&^sk z<*7Ye@a2?D72!f#wkMxhcSi(W^j{USh5M(>si_?yD;I^OFNkwKoOmE}!Of%vS6dcJ z1hCx_T-(dXE?Z*xV$pF&elvEnUou||A0#lGY;1Yt@R!}0uT7%Rpy_a9vmtx3kHw6H zQwK$i`O;<-8yrtM`Ryr_b~j^o>(mc$R0`{(ule*3C=y73nMNxe)AlS+~VfZkOtag8WRNi0dVN-jzT zQVd20hGx137P^KeA%+%KM&?#VrrHKZRt5%B#oqrx(U6;;l9^VCTf-CYa0j4<@T!oA zlAy$Lg@U5|w9K4Tg_6pGRE5lfl4J&kiaC!z@o*G|X=t4CKYhmYX%GXmGPhnbx3IFX z_hb=fVFi~4lfx;@%9}$JPT#n4;>ejJGDp}?H+U@Y(qnifE?Dx($#g2v3I~swaaYVNRF^5&2LC z&4XZM7<8egm&_TCG+n3+qM4%==@d~JWmnBh&h+~^XAOsg#@X%@>#PmGS^M&R-~Yew zXRo~{gq|=z^z{YWO4zj`gn-_;ZouPj{>-~ugy~lfi-nVD$U++0y`{VZ4`}-Mhf4xs; z?0*99J}<=mkz1?xpECBZ_un)2uXmrzayxFKU%lt_+!cMtR_{6fc8LD<-c9`s(O0{z z-v5Disx^26*>qqZ7K6}OW)B6t@Z-2dim9c-lf10s>y^m$=U+=z4 zi04CYt=^x_*uUN%g&coF=vnV~Lyq@gJ?s4@_!DwF_VujyKFIMNrsqETaF@~UhupUR ze!cS!;1ay=&Cvf|z4MNEKHhg`=znK@lo$I9c;B3%|IK=Lz`O6ab36Xm&$>V3e>MJ( zWwZ`@UESn=1=IG$<+2a-%2zA11LyGqrU$|AK!#u#-UPoJ`4WDFKfrt5|M^?P+G?n! zrrLVY%P{CokAr%S{#)AvW1+|8yj#7L*j~5>*1#R`5IhYp!rSl>9DwiOXYjsw0_+>m zk2vl;mlm{&9ZEZgz8^LyFmjP$bY{Z6X_gE04<7T z;WZco-;Ym%&!`6*IPN@`8Dp$D=32vA)?B8BTG2}t3X?gWob--Eph??N5ypYeZ8e0K5PWnFRHc`h@? zSaZy^hPA9|Z8esvskYrTHF^}PbQ83~;*Jc}v($DTeM3X`Q`jw0fw_JP{@1K^!1Hpr zAD)2`*awHeZ|z)faol+>GsakR%-slXr=rKNIp)4}9=TD=-1kc4n_K1_HMh()#@sU3 zNPp*eoW|`@w2jAk(YzRMzUN<@F4~&=TZw#g?VB#D8{^HjPc}{$ZOwh9M83IOO5~e6 p09)a8(9aZj&U#$M{p+~%TxN{1TVbF^pJ#Qh*Rb{K@ZZzs{R_iA#isxO literal 0 HcmV?d00001 diff --git a/assets/extensions/choices.js/public/assets/images/favicon.png b/assets/extensions/choices.js/public/assets/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..bfc463c14c6a219129bf172f0712d45001162d0d GIT binary patch literal 6153 zcmZ8lc{r5s*B_4uqp?gBMwXE=lBEen*~U^#V~G}tn6j6Bi3*t^OIb%4WQkJRl;vwL z6Up9`6lJN%E@UV9-Q)Xv-}k!SKjxb2e(rP5bJou}=ZQUTZp^<;d>aCR;3t_FSs@S{ zV(cH18$5|l7>@&gu&chAJ_7L~5%uRh7Xl$#PcqU!8O$-AJ?YO3QD<_0jH`Ks$F$@xlUfy=1>(R;g^w_r>pjzQytLj4EMrPEFc>Gsa~%LC-ynHpWS z+1)(fMolghKi3*iN$(0eEWf2mS!YwMnvuh56LuAY=30onRL>1@zPzfE@jiejW|ULNX?8u!wcYz%+4OM!-;3wkhxaQ8q!`^P z5op}sPY(VZM@++zj6{aj6n68r^m*EvcxTyGdwM$vV3NH>7J@%#3Nj=0S(~e4wK^F4 zkBq3{WNxY*%RwR)pKO93QE}^y9SW`1TwBF{%XzqOAlb?5u?{`Kdi)nduA+l%AkSSf zEnPg&z2>MF6RHjS4;84T2{?4O1e@7JAKQHN*Pu3k6)QxNvukn+G8!q^e7_B;*`G0A z(EgTWFz_-dQrFsH)6Pe?)M>Wr+^e+?OP;_LnvJb(Ne!8P16J(`JB6K3ulfw{GdVKT z;CUL4BvNh?E3>^bd~lMRHuzj@-glZ2jw5?;?e(*BUo*dqgbyz4W9Wsw@UYOZ_FNx- z#8CYbI53}PYQemf5tL{a)Wo(pG6vz``>~lS+^W`VkK*QWqvBu8$yTfV9 zq@$yvx}}QN>h@*JMRk;cjrmuTMEiF?Wnz=4Q`x$<2H*Aw_q2o`{k?y)sBV7p`X&G7 zX?T86!{Nn)#0IReFpNdZQs1N$f6+VlDcrwQ!Tq%7$xAB>Pfsrv@o^yAMX6~5Zt`N} z;to;evz#2rGFet9hccI=6JffOyIh9g4WB)fmrb#P)x7I&ED`f|{!1VFuCAMT90Q>l z8qiY-mL1{x%B*vLrobzU*Dwdth)fh{wqx-T{h8Wc8kJoh%O7b7I6;ysqT;3^rjnR& zPVZZ|3`>~WlulBHhj#Hy7gR zHo)c34x|Jx6t9wkZco;vPF=4UF(do5v>9;7C(TTSdtL3IC7bPkJ&X-T>Nj=QHNOMQu^OAoO zjetjzh!MjD_5}C3`y*&cGhp`wQr*X}j?(TQdy*$}5gkJ(*6o_$8fu~BPid)(LxHe( zKK>KVn(NPk}7GTyv!Z`SP~j6F^wdNoT}+7}&;xMI3wm5^`%9Uk7T znSYj$<4PGbK!+2#sF_-%12mb4B4XQKB(eTcO43DUW!Ysk&ueho2w#-2RAz{49f?aV zG(V^}cFTYS2Sk?{iE%s|wW6Wk{4d^*YW|af_k1$PkZ&+@H9U-FQnA#Ek)F!~> z2@m!vQ=WNxY%h$~B}zQ~2I;0Td7I-?K;HZnzX3j(~6So~+EbBaB$z zDtNI2LWkGmsD9Qbkx}~@q{wz4&>3z$XQ?DM!?Px`_@=~13AheRz+q)~IcTlK zSpJ*O@A2J6?iiAYfbPRIMVi{S!V65?PX!BoJ`te%3*kM!M_*7r1RS_*UnUKq-SqPs zF>h%5y(}w;ZTOKH7!*N+JHj_Ydypg=%oyv>*lt-{H7+gv8c zCjxd3u#?1%m{%`ZN+Z>(ifs`o^X{m0JWVisyFw;EI|=MF+Pe2Wy^;+f3;@GJ{5My6 ziVf3;rzlhA5>Vj+)Y*ZPM;40hB!klu+)VkR=7<88$WX&^>w_RXG2fHY$wVri#=h z={rbZ#R7cPyoF2c+clH-K}ZA4C!j#2wAgO=l{I)Z6W;={L=S`^5zG^lq~#YS^xu4y!aRNsxmR*VU?6dUyfWP&!c zV1^A89}e`Yn%O|J6DNuI!&-=}LyMj5>vBRam=nEtF?{JJbtx`9;4-|=fLr+cl?N?o zO*B-%7e&6udAGwHi^g!o&-jTdl=z$b%lJ^>fatT11is%=Vm_B)Dg)W9+)5D}jvv3% zbs8xlMx7FB!8j6lj^2^f$L@v(0%Dzz`1}**CuDq*U~p*iC-B7H3Dw6+K{65NlQeSX z&B*Ml-}?4V6ao67bsA9#4q0+GR%M*&)R>N}rwTQDoyfA)WM!AAA&FQa$V(=U$+z2G zxdZeYf!pEIkv!ArcB+A^D>^1}%Yv4w!VI)#Fp%%-MBow3(J{b6kRJ+T3Xf*s4Zisx zBl)6gOrjfd>I^8qc%6chj+@)cG z*l>6V-7dp)tw1xp+2Yzmaxa|ap*G;^#oEt*a2-T5Ex5CY5M zyb75|CO#32vt;MvWdo(PD4Y5aw=E=6NvBh``k(7vU4#1tlP}PZ} zG~c*}04Nm;aLK&hnS{ddZLmW_4Sz=$QDsQ6goL2?!agaOIJG89{>*knIPn3DR~2)O zV+OPWU;xNIj4hUrh^^CNg&_mT*jK){6PcAE#KNzVXwZIQ((8xC;@%B5q9W2jFYgy( z)ZQ8n7AUl>G>QONRj9_8x$qXW1Oxyo({1><nz4XbBl;zKGg&VrwD5d^PAsM6Jqsz7Y%-3?P&lHh(82q*bhaAh|>i#?HoV zy}@R9-Q?ZManKysu>`RxJN|gC(v1Mu@45!13Lt`7)PPF=1L`8}i6TpYJt(;|Nf;vFY|mKR3o9PESB}pyO)<6n?M{R zK{uvRc27a-7-(br!yOmQe@C7VkI%%A*NiL4r$l`I6h1YgJZk0!?%{n6 zrd9-W1U`6EL$XtMF9zoak=F_!Yh#9EmbiA=e$K5g21CVX2>>HVi11R+_5Sjd5trOt#ZHRBk(rg&dbRM|K*S*q?_ALq zIgjH?jOR_5Ap(^XtYyc|>Z{^Qw*92dg~%82iMN4b;r(~WZt;8&`{)SIzGF zfk}vrJ1huzEb?CO{7EBmBMYUJ4*(Bsv%ZbOpR49Q#I~gz-fL&6!nl6r+@>CV{pCT; zoq!^Sw|RSp;?3=V?qkqD_O%!?J6j#5n4Ew&V>JK>>7oWHcSk;~4lv=ui# ziNgOBQds(HxGr;?l-IPqo926z`vfUH6&-VDi@9_`!jX`?ES)JxJq8^B{Ow?Q?cylRl;R-*xGL;D@Qjo*n@R ztvT}Vlh4H)4{f_0B>i_t=z`=@;5a1XZy3nB%8Z=8l=JEF0M{kp;Z@mhdKW(wy3ppr zo{|U?z-jN%D|sYx7H`uN%jbBldjen!5rxGM-Mvc@5$DQ6d8k8MlYNG;_%;__raIAl zC$iBnFGDz!7rz-g@T!S3F%3lOC*0@oI4nBIuf~PeQh~jdfqSbBUy%FuWX>#ightBb ziBHu62)+Zho6pki;A+Uew`WZtK9a}@#TUC|qME9j^mj>MPk~qr9m~6c%0#*B*C)I! zH}vU4kI{)JQFYOF@4-J-4wzupPhTMvu-XNtanexY<{exqJh)r#$h3=S#tE>Chf_w% zL|ID61*1G;W?7|9_lY4SiUTQuXD{vzrA5W(+*!H$k&*r zM_+-tarNnAm#?33Sruh_uV1NAn&ZPiRt3#i;yl#(&tg|$Nru zwBjxsjr0%?_qDs(VVC;DhHx1X83LyXr##oX)=*1s>o@Py?tq&2O2 zFQ)EHxxysYre65N2UF|Qr^wOi0YcXD!v$A@^dnfV69&(vplkSVeHs(~LAd02$=Ki) zSxjGvsK~)7jaOGIM|<8<8dgP3`$=aU^v(xua9#VoV1SqCs!a(t$f%=5PC0k%>%MUz z)D-SZi=1=D3;G9r48m=X#bsGvxiFWI{kcTZI;YXdImmW~RZSkAG(lF?%H+K2v@ zGM-Quy1J`-&bW>g9U2mXuGZzW7ZiJWZ8DBuD!2T+-zV_p) zzPMpepfQ3O@YZi8*=vQ%c6Ii)C;!41-KX9TcU04lY5%>gi!M-&X&w(f=%&2C_ogmR zaqYR1;w3BhyLO+h>YNKTRePu{8~o%Sk4MT`d!>uw_hujK7|l;2)JAS^{C;w+cAxyry@}Gr-C&%i;`Jp~xn<~v+4}me#Hy*Wf)i+A_9p@fp_S`_2h7T< T7W-lFZ6858Vs7-zfI|BZkHLv@ literal 0 HcmV?d00001 diff --git a/assets/extensions/choices.js/public/assets/images/logo.svg b/assets/extensions/choices.js/public/assets/images/logo.svg new file mode 100644 index 00000000..271609ca --- /dev/null +++ b/assets/extensions/choices.js/public/assets/images/logo.svg @@ -0,0 +1,10 @@ + + + + Slice 1 + Created with Sketch. + + + + + \ No newline at end of file diff --git a/assets/extensions/choices.js/public/assets/images/manifest.json b/assets/extensions/choices.js/public/assets/images/manifest.json new file mode 100644 index 00000000..572d844f --- /dev/null +++ b/assets/extensions/choices.js/public/assets/images/manifest.json @@ -0,0 +1,12 @@ +{ + "name": "Choices.js", + "icons": [ + { + "src": "\/assets\/images\/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image\/png" + } + ], + "theme_color": "#ffffff", + "display": "standalone" +} diff --git a/assets/extensions/choices.js/public/assets/images/mstile-150x150.png b/assets/extensions/choices.js/public/assets/images/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..9e7cf45cca13cdf0a2f76490f1484b42887061cb GIT binary patch literal 3067 zcmb_ec{r478-E#DvTuWo$y%8thL{w|(pbXbn1(bm*3yV!XpCr-gwaTd$&!*KRF=Xa zne5?EMrA!TB)cpJq2qgpuIu~0^IhM6=X&4wdY@T)x;oW<70{|dw zX<_C709+!RkDnK$kW0Vkf&-7wNt=@ZP?{jPiQfgT6+J8*Yyg0=4*;l90I&{{s1pDX ztOWp5ZUA7A1^_Yv8P)d3K?bk8HQEf=;yl^4`AHy!k7Q|M&Nsp@A|Wr=%VZ=2!0rr7 zvy+bG{@Ed%ztks%mWBDgKOy7z+uB_5OYiQyP_oiIh$(!esunI;J8eCUJ8y2$O|!yK z7|{L#RV7p!)n=2rmsyi9;{#(M7LQ625)7AqSmfXYRR8LjU;EnE$H3iDwY>Y!y$hE(E!j4V#Z9xgv zQQxSot30pwmzlW<*YAnMQ1F?pIuWZOg!L02f}t(=jTxFzgVw1rsYJOE?nXf#Z>4jQ zD72?Yl~6|smLIZ0=cQWBp4IrryMo!t4vt-1n!0x&(3(!R4EPp*5lKd8%_2uubThBq!@f(XHMIQ61$yX!GoJ$RW-|?ai0nam{xXyO0&8K zU5`@RcIKuAoze-x-Ul_$A=O=^%TQB{{X>p{@|9$T!F*FBy*bHT-&N|Hb>srMsPAUtH@iq55ZF>Ks;F z(@|!U&+HM`ZIt?n@`pbF{jxLkCVTf6 zI#lw*No`Uu`)2aXKn=P?BG(@wL%Ue;vT+xTn6AOHpn_DbRXG%fMvKhz8sl zT8e5r$K4G2;nwB&Uz0neh?Q4cLII+Uw6g)ARs2zOES*8RP zXjEeuyT7A)>}twyD|q6V5c=0OTqzD&fc#{nLC=u2^B|JmX1AT&07aGIL{j_DIrqQk zi+OK`jTMkLD`h;LVWH*Z4;ND76Sv{TWcY->;Z6GKx@`rEyiPD&cT3P&XDHfMh{ahv z-;ujOBw7EIIZl{`>vWZ%7B?mG=CqfDXewRiJ%-*{;NC)|@vG!F=cAhvzaIKH6jV6L zML+hR?B0GuD4N4np4w4y&TMGZ-kU>t`~Igcm#LbT4jm2p@m2fPw9x2d2fE}3t9K|e z+Z0gPhyxGc`|^DtKdj?;1G{ypJ#Po~%AN(8Xk~r*Ni#uq{35(9hgh#aRK$9SuFS#fSvUxkCyP6! z7PHm9a$Yk`R79(aTMbwM6BR|AY?X>FTI;luNecqY)olH=$aA<~ zoiqiC7NF%=`0rYKIH^vWh)`VF+{LL5@%3pjxSnCOhzmJwr<@+?M^(LBmNg&{mAsz9 zXgQ5x{-?NyIU>#@E`NlvMDsM=h{@%s{;qgIXIQQ~8HlhorTIzJ4!%lmvPXR5AHM5X zE^YFS{oDjB{cmEloZrt}{aTy>@}gVFVd3eAFmgrICi_DDe%{v?DMAYO{R`tU;8uc1 zGkut!zz%4-6r93o4lj8UP-oi-(_k-jX4)|?=LkDga5|E>6Yvr2Kzx^x0RT@ z!Z+-KOILkwiy7@#2qui`zsfXIaR>qbYDY(Zb?w3adVxZfoE$%)DaPP)<&Cf$6OO3^ zTz8FA%bDug!^;H<`aBgDpN0qd<|Nkk)L)|>jtt|0RxNY}vTkJQLR(I*wa+pGNOATs zpxn&$<{ILOMMz~4Q}>BuUcm6)WQ%o+mf&to?J(Ds)rx>rCeAI^)hTy)fc;}SLUBPb zZ~y6$nA$4S7F1wnz*CP zxdnNkEa~i88zahq%a~|l)BDHil^czpQA(%98EVb6D3svm+`@Aql{99kn=#^^4pVh9 z_m_mER1eimAKAN|M~*8=Hy|eEm*9zWf@f8u%wt4j@v&lXaVOYt?8Jj0%X9eXzB}`VbPm+%4XLu6c z>ms^Ur^yaVsOdt_NHh7#rwow2`)WyKlj>9MIh4Pm#6HFlwF(A<2`y#rFb!bnn + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + diff --git a/assets/extensions/choices.js/public/assets/scripts/.eslintrc.js b/assets/extensions/choices.js/public/assets/scripts/.eslintrc.js deleted file mode 100644 index d761728a..00000000 --- a/assets/extensions/choices.js/public/assets/scripts/.eslintrc.js +++ /dev/null @@ -1,27 +0,0 @@ -// get polyfill settings from top level config -// @ts-ignore -const { settings } = require('../../../.eslintrc.json'); - -// Adding non-polyfilable Symbol-related functions as they are most probably -// behind the flag - -settings.polyfills.push( - 'Symbol.toStringTag', - 'Symbol.for', - 'Object.getOwnPropertySymbols', - 'Object.getOwnPropertyDescriptors', - 'Promise', // Promise is gate checked -); - -module.exports = /** @type {import('eslint').Linter.Config} */ ({ - root: true, - extends: ['plugin:compat/recommended'], - parserOptions: { - // ensure that it's compatible with ES5 browsers, so, no `const`, etc - ecmaVersion: 5, - }, - env: { - browser: true, - }, - settings, -}); diff --git a/assets/extensions/choices.js/public/assets/scripts/choices.js b/assets/extensions/choices.js/public/assets/scripts/choices.js index 8cadac64..0ff95bf3 100644 --- a/assets/extensions/choices.js/public/assets/scripts/choices.js +++ b/assets/extensions/choices.js/public/assets/scripts/choices.js @@ -1,6925 +1,5167 @@ -/*! choices.js v10.2.0 | © 2022 Josh Johnson | https://github.com/jshjohnson/Choices#readme */ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["Choices"] = factory(); - else - root["Choices"] = factory(); -})(window, function() { -return /******/ (function() { // webpackBootstrap -/******/ "use strict"; -/******/ var __webpack_modules__ = ({ - -/***/ 282: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.clearChoices = exports.activateChoices = exports.filterChoices = exports.addChoice = void 0; -var constants_1 = __webpack_require__(883); -var addChoice = function (_a) { - var value = _a.value, - label = _a.label, - id = _a.id, - groupId = _a.groupId, - disabled = _a.disabled, - elementId = _a.elementId, - customProperties = _a.customProperties, - placeholder = _a.placeholder, - keyCode = _a.keyCode; - return { - type: constants_1.ACTION_TYPES.ADD_CHOICE, - value: value, - label: label, - id: id, - groupId: groupId, - disabled: disabled, - elementId: elementId, - customProperties: customProperties, - placeholder: placeholder, - keyCode: keyCode - }; -}; -exports.addChoice = addChoice; -var filterChoices = function (results) { - return { - type: constants_1.ACTION_TYPES.FILTER_CHOICES, - results: results - }; -}; -exports.filterChoices = filterChoices; -var activateChoices = function (active) { - if (active === void 0) { - active = true; - } - return { - type: constants_1.ACTION_TYPES.ACTIVATE_CHOICES, - active: active - }; -}; -exports.activateChoices = activateChoices; -var clearChoices = function () { - return { - type: constants_1.ACTION_TYPES.CLEAR_CHOICES - }; -}; -exports.clearChoices = clearChoices; - -/***/ }), - -/***/ 783: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { +/*! choices.js v11.0.1 | © 2024 Josh Johnson | https://github.com/jshjohnson/Choices#readme */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Choices = factory()); +})(this, (function () { 'use strict'; + + /****************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise, SuppressedError, Symbol */ + + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + }; + return extendStatics(d, b); + }; + function __extends(d, b) { + if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); + } + typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + var ActionType = { + ADD_CHOICE: 'ADD_CHOICE', + REMOVE_CHOICE: 'REMOVE_CHOICE', + FILTER_CHOICES: 'FILTER_CHOICES', + ACTIVATE_CHOICES: 'ACTIVATE_CHOICES', + CLEAR_CHOICES: 'CLEAR_CHOICES', + ADD_GROUP: 'ADD_GROUP', + ADD_ITEM: 'ADD_ITEM', + REMOVE_ITEM: 'REMOVE_ITEM', + HIGHLIGHT_ITEM: 'HIGHLIGHT_ITEM', + }; + var EventType = { + showDropdown: 'showDropdown', + hideDropdown: 'hideDropdown', + change: 'change', + choice: 'choice', + search: 'search', + addItem: 'addItem', + removeItem: 'removeItem', + highlightItem: 'highlightItem', + highlightChoice: 'highlightChoice', + unhighlightItem: 'unhighlightItem', + }; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.addGroup = void 0; -var constants_1 = __webpack_require__(883); -var addGroup = function (_a) { - var value = _a.value, - id = _a.id, - active = _a.active, - disabled = _a.disabled; - return { - type: constants_1.ACTION_TYPES.ADD_GROUP, - value: value, - id: id, - active: active, - disabled: disabled - }; -}; -exports.addGroup = addGroup; + var ObjectsInConfig = ['fuseOptions', 'classNames']; -/***/ }), + var PassedElementTypes = { + Text: 'text', + SelectOne: 'select-one', + SelectMultiple: 'select-multiple', + }; -/***/ 464: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + var addChoice = function (choice) { return ({ + type: ActionType.ADD_CHOICE, + choice: choice, + }); }; + var removeChoice = function (choice) { return ({ + type: ActionType.REMOVE_CHOICE, + choice: choice, + }); }; + var filterChoices = function (results) { return ({ + type: ActionType.FILTER_CHOICES, + results: results, + }); }; + var activateChoices = function (active) { + return ({ + type: ActionType.ACTIVATE_CHOICES, + active: active, + }); + }; + var addGroup = function (group) { return ({ + type: ActionType.ADD_GROUP, + group: group, + }); }; + + var addItem = function (item) { return ({ + type: ActionType.ADD_ITEM, + item: item, + }); }; + var removeItem$1 = function (item) { return ({ + type: ActionType.REMOVE_ITEM, + item: item, + }); }; + var highlightItem = function (item, highlighted) { return ({ + type: ActionType.HIGHLIGHT_ITEM, + item: item, + highlighted: highlighted, + }); }; + + /* eslint-disable @typescript-eslint/no-explicit-any */ + var getRandomNumber = function (min, max) { return Math.floor(Math.random() * (max - min) + min); }; + var generateChars = function (length) { + return Array.from({ length: length }, function () { return getRandomNumber(0, 36).toString(36); }).join(''); + }; + var generateId = function (element, prefix) { + var id = element.id || (element.name && "".concat(element.name, "-").concat(generateChars(2))) || generateChars(4); + id = id.replace(/(:|\.|\[|\]|,)/g, ''); + id = "".concat(prefix, "-").concat(id); + return id; + }; + var getAdjacentEl = function (startEl, selector, direction) { + if (direction === void 0) { direction = 1; } + var prop = "".concat(direction > 0 ? 'next' : 'previous', "ElementSibling"); + var sibling = startEl[prop]; + while (sibling) { + if (sibling.matches(selector)) { + return sibling; + } + sibling = sibling[prop]; + } + return null; + }; + var isScrolledIntoView = function (element, parent, direction) { + if (direction === void 0) { direction = 1; } + var isVisible; + if (direction > 0) { + // In view from bottom + isVisible = parent.scrollTop + parent.offsetHeight >= element.offsetTop + element.offsetHeight; + } + else { + // In view from top + isVisible = element.offsetTop >= parent.scrollTop; + } + return isVisible; + }; + var sanitise = function (value) { + if (typeof value !== 'string') { + if (value === null || value === undefined) { + return ''; + } + if (typeof value === 'object') { + if ('raw' in value) { + return sanitise(value.raw); + } + if ('trusted' in value) { + return value.trusted; + } + } + return value; + } + return value + .replace(/&/g, '&') + .replace(/>/g, '>') + .replace(/= 0 && + !window.matchMedia("(min-height: ".concat(dropdownPos + 1, "px)")).matches; + } + else if (this.position === 'top') { + shouldFlip = true; + } + return shouldFlip; + }; + Container.prototype.setActiveDescendant = function (activeDescendantID) { + this.element.setAttribute('aria-activedescendant', activeDescendantID); + }; + Container.prototype.removeActiveDescendant = function () { + this.element.removeAttribute('aria-activedescendant'); + }; + Container.prototype.open = function (dropdownPos, dropdownHeight) { + addClassesToElement(this.element, this.classNames.openState); + this.element.setAttribute('aria-expanded', 'true'); + this.isOpen = true; + if (this.shouldFlip(dropdownPos, dropdownHeight)) { + addClassesToElement(this.element, this.classNames.flippedState); + this.isFlipped = true; + } + }; + Container.prototype.close = function () { + removeClassesFromElement(this.element, this.classNames.openState); + this.element.setAttribute('aria-expanded', 'false'); + this.removeActiveDescendant(); + this.isOpen = false; + // A dropdown flips if it does not have space within the page + if (this.isFlipped) { + removeClassesFromElement(this.element, this.classNames.flippedState); + this.isFlipped = false; + } + }; + Container.prototype.addFocusState = function () { + addClassesToElement(this.element, this.classNames.focusState); + }; + Container.prototype.removeFocusState = function () { + removeClassesFromElement(this.element, this.classNames.focusState); + }; + Container.prototype.enable = function () { + removeClassesFromElement(this.element, this.classNames.disabledState); + this.element.removeAttribute('aria-disabled'); + if (this.type === PassedElementTypes.SelectOne) { + this.element.setAttribute('tabindex', '0'); + } + this.isDisabled = false; + }; + Container.prototype.disable = function () { + addClassesToElement(this.element, this.classNames.disabledState); + this.element.setAttribute('aria-disabled', 'true'); + if (this.type === PassedElementTypes.SelectOne) { + this.element.setAttribute('tabindex', '-1'); + } + this.isDisabled = true; + }; + Container.prototype.wrap = function (element) { + var el = this.element; + var parentNode = element.parentNode; + if (parentNode) { + if (element.nextSibling) { + parentNode.insertBefore(el, element.nextSibling); + } + else { + parentNode.appendChild(el); + } + } + el.appendChild(element); + }; + Container.prototype.unwrap = function (element) { + var el = this.element; + var parentNode = el.parentNode; + if (parentNode) { + // Move passed element outside this element + parentNode.insertBefore(element, el); + // Remove this element + parentNode.removeChild(el); + } + }; + Container.prototype.addLoadingState = function () { + addClassesToElement(this.element, this.classNames.loadingState); + this.element.setAttribute('aria-busy', 'true'); + this.isLoading = true; + }; + Container.prototype.removeLoadingState = function () { + removeClassesFromElement(this.element, this.classNames.loadingState); + this.element.removeAttribute('aria-busy'); + this.isLoading = false; + }; + return Container; + }()); + + var Input = /** @class */ (function () { + function Input(_a) { + var element = _a.element, type = _a.type, classNames = _a.classNames, preventPaste = _a.preventPaste; + this.element = element; + this.type = type; + this.classNames = classNames; + this.preventPaste = preventPaste; + this.isFocussed = this.element.isEqualNode(document.activeElement); + this.isDisabled = element.disabled; + this._onPaste = this._onPaste.bind(this); + this._onInput = this._onInput.bind(this); + this._onFocus = this._onFocus.bind(this); + this._onBlur = this._onBlur.bind(this); + } + Object.defineProperty(Input.prototype, "placeholder", { + set: function (placeholder) { + this.element.placeholder = placeholder; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Input.prototype, "value", { + get: function () { + return this.element.value; + }, + set: function (value) { + this.element.value = value; + }, + enumerable: false, + configurable: true + }); + Input.prototype.addEventListeners = function () { + var el = this.element; + el.addEventListener('paste', this._onPaste); + el.addEventListener('input', this._onInput, { + passive: true, + }); + el.addEventListener('focus', this._onFocus, { + passive: true, + }); + el.addEventListener('blur', this._onBlur, { + passive: true, + }); + }; + Input.prototype.removeEventListeners = function () { + var el = this.element; + el.removeEventListener('input', this._onInput); + el.removeEventListener('paste', this._onPaste); + el.removeEventListener('focus', this._onFocus); + el.removeEventListener('blur', this._onBlur); + }; + Input.prototype.enable = function () { + var el = this.element; + el.removeAttribute('disabled'); + this.isDisabled = false; + }; + Input.prototype.disable = function () { + var el = this.element; + el.setAttribute('disabled', ''); + this.isDisabled = true; + }; + Input.prototype.focus = function () { + if (!this.isFocussed) { + this.element.focus(); + } + }; + Input.prototype.blur = function () { + if (this.isFocussed) { + this.element.blur(); + } + }; + Input.prototype.clear = function (setWidth) { + if (setWidth === void 0) { setWidth = true; } + this.element.value = ''; + if (setWidth) { + this.setWidth(); + } + return this; + }; + /** + * Set the correct input width based on placeholder + * value or input value + */ + Input.prototype.setWidth = function () { + // Resize input to contents or placeholder + var element = this.element; + element.style.minWidth = "".concat(element.placeholder.length + 1, "ch"); + element.style.width = "".concat(element.value.length + 1, "ch"); + }; + Input.prototype.setActiveDescendant = function (activeDescendantID) { + this.element.setAttribute('aria-activedescendant', activeDescendantID); + }; + Input.prototype.removeActiveDescendant = function () { + this.element.removeAttribute('aria-activedescendant'); + }; + Input.prototype._onInput = function () { + if (this.type !== PassedElementTypes.SelectOne) { + this.setWidth(); + } + }; + Input.prototype._onPaste = function (event) { + if (this.preventPaste) { + event.preventDefault(); + } + }; + Input.prototype._onFocus = function () { + this.isFocussed = true; + }; + Input.prototype._onBlur = function () { + this.isFocussed = false; + }; + return Input; + }()); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.highlightItem = exports.removeItem = exports.addItem = void 0; -var constants_1 = __webpack_require__(883); -var addItem = function (_a) { - var value = _a.value, - label = _a.label, - id = _a.id, - choiceId = _a.choiceId, - groupId = _a.groupId, - customProperties = _a.customProperties, - placeholder = _a.placeholder, - keyCode = _a.keyCode; - return { - type: constants_1.ACTION_TYPES.ADD_ITEM, - value: value, - label: label, - id: id, - choiceId: choiceId, - groupId: groupId, - customProperties: customProperties, - placeholder: placeholder, - keyCode: keyCode - }; -}; -exports.addItem = addItem; -var removeItem = function (id, choiceId) { - return { - type: constants_1.ACTION_TYPES.REMOVE_ITEM, - id: id, - choiceId: choiceId - }; -}; -exports.removeItem = removeItem; -var highlightItem = function (id, highlighted) { - return { - type: constants_1.ACTION_TYPES.HIGHLIGHT_ITEM, - id: id, - highlighted: highlighted - }; -}; -exports.highlightItem = highlightItem; + var SCROLLING_SPEED = 4; -/***/ }), + var List = /** @class */ (function () { + function List(_a) { + var element = _a.element; + this.element = element; + this.scrollPos = this.element.scrollTop; + this.height = this.element.offsetHeight; + } + List.prototype.prepend = function (node) { + var child = this.element.firstElementChild; + if (child) { + this.element.insertBefore(node, child); + } + else { + this.element.append(node); + } + }; + List.prototype.scrollToTop = function () { + this.element.scrollTop = 0; + }; + List.prototype.scrollToChildElement = function (element, direction) { + var _this = this; + if (!element) { + return; + } + var listHeight = this.element.offsetHeight; + // Scroll position of dropdown + var listScrollPosition = this.element.scrollTop + listHeight; + var elementHeight = element.offsetHeight; + // Distance from bottom of element to top of parent + var elementPos = element.offsetTop + elementHeight; + // Difference between the element and scroll position + var destination = direction > 0 ? this.element.scrollTop + elementPos - listScrollPosition : element.offsetTop; + requestAnimationFrame(function () { + _this._animateScroll(destination, direction); + }); + }; + List.prototype._scrollDown = function (scrollPos, strength, destination) { + var easing = (destination - scrollPos) / strength; + var distance = easing > 1 ? easing : 1; + this.element.scrollTop = scrollPos + distance; + }; + List.prototype._scrollUp = function (scrollPos, strength, destination) { + var easing = (scrollPos - destination) / strength; + var distance = easing > 1 ? easing : 1; + this.element.scrollTop = scrollPos - distance; + }; + List.prototype._animateScroll = function (destination, direction) { + var _this = this; + var strength = SCROLLING_SPEED; + var choiceListScrollTop = this.element.scrollTop; + var continueAnimation = false; + if (direction > 0) { + this._scrollDown(choiceListScrollTop, strength, destination); + if (choiceListScrollTop < destination) { + continueAnimation = true; + } + } + else { + this._scrollUp(choiceListScrollTop, strength, destination); + if (choiceListScrollTop > destination) { + continueAnimation = true; + } + } + if (continueAnimation) { + requestAnimationFrame(function () { + _this._animateScroll(destination, direction); + }); + } + }; + return List; + }()); + + var WrappedElement = /** @class */ (function () { + function WrappedElement(_a) { + var element = _a.element, classNames = _a.classNames; + this.element = element; + this.classNames = classNames; + this.isDisabled = false; + } + Object.defineProperty(WrappedElement.prototype, "isActive", { + get: function () { + return this.element.dataset.choice === 'active'; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(WrappedElement.prototype, "dir", { + get: function () { + return this.element.dir; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(WrappedElement.prototype, "value", { + get: function () { + return this.element.value; + }, + set: function (value) { + this.element.setAttribute('value', value); + this.element.value = value; + }, + enumerable: false, + configurable: true + }); + WrappedElement.prototype.conceal = function () { + var el = this.element; + // Hide passed input + addClassesToElement(el, this.classNames.input); + el.hidden = true; + // Remove element from tab index + el.tabIndex = -1; + // Backup original styles if any + var origStyle = el.getAttribute('style'); + if (origStyle) { + el.setAttribute('data-choice-orig-style', origStyle); + } + el.setAttribute('data-choice', 'active'); + }; + WrappedElement.prototype.reveal = function () { + var el = this.element; + // Reinstate passed element + removeClassesFromElement(el, this.classNames.input); + el.hidden = false; + el.removeAttribute('tabindex'); + // Recover original styles if any + var origStyle = el.getAttribute('data-choice-orig-style'); + if (origStyle) { + el.removeAttribute('data-choice-orig-style'); + el.setAttribute('style', origStyle); + } + else { + el.removeAttribute('style'); + } + el.removeAttribute('data-choice'); + }; + WrappedElement.prototype.enable = function () { + this.element.removeAttribute('disabled'); + this.element.disabled = false; + this.isDisabled = false; + }; + WrappedElement.prototype.disable = function () { + this.element.setAttribute('disabled', ''); + this.element.disabled = true; + this.isDisabled = true; + }; + WrappedElement.prototype.triggerEvent = function (eventType, data) { + dispatchEvent(this.element, eventType, data || {}); + }; + return WrappedElement; + }()); -/***/ 137: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + var WrappedInput = /** @class */ (function (_super) { + __extends(WrappedInput, _super); + function WrappedInput() { + return _super !== null && _super.apply(this, arguments) || this; + } + return WrappedInput; + }(WrappedElement)); + var coerceBool = function (arg, defaultValue) { + if (defaultValue === void 0) { defaultValue = true; } + return typeof arg === 'undefined' ? defaultValue : !!arg; + }; + var stringToHtmlClass = function (input) { + if (typeof input === 'string') { + // eslint-disable-next-line no-param-reassign + input = input.split(' ').filter(function (s) { return s.length; }); + } + if (Array.isArray(input) && input.length) { + return input; + } + return undefined; + }; + var mapInputToChoice = function (value, allowGroup) { + if (typeof value === 'string') { + var result_1 = mapInputToChoice({ + value: value, + label: value, + }, false); + return result_1; + } + var groupOrChoice = value; + if ('choices' in groupOrChoice) { + if (!allowGroup) { + // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup + throw new TypeError("optGroup is not allowed"); + } + var group = groupOrChoice; + var choices = group.choices.map(function (e) { return mapInputToChoice(e, false); }); + var result_2 = { + id: 0, // actual ID will be assigned during _addGroup + label: unwrapStringForRaw(group.label) || group.value, + active: !!choices.length, + disabled: !!group.disabled, + choices: choices, + }; + return result_2; + } + var choice = groupOrChoice; + var result = { + id: 0, // actual ID will be assigned during _addChoice + groupId: 0, // actual ID will be assigned during _addGroup but before _addChoice + score: 0, // used in search + rank: 0, // used in search, stable sort order + value: choice.value, + label: choice.label || choice.value, + active: coerceBool(choice.active), + selected: coerceBool(choice.selected, false), + disabled: coerceBool(choice.disabled, false), + placeholder: coerceBool(choice.placeholder, false), + highlighted: false, + labelClass: stringToHtmlClass(choice.labelClass), + labelDescription: choice.labelDescription, + customProperties: choice.customProperties, + }; + return result; + }; + var isHtmlInputElement = function (e) { return e.tagName === 'INPUT'; }; + var isHtmlSelectElement = function (e) { return e.tagName === 'SELECT'; }; + var isHtmlOption = function (e) { return e.tagName === 'OPTION'; }; + var isHtmlOptgroup = function (e) { return e.tagName === 'OPTGROUP'; }; + + var WrappedSelect = /** @class */ (function (_super) { + __extends(WrappedSelect, _super); + function WrappedSelect(_a) { + var element = _a.element, classNames = _a.classNames, template = _a.template, extractPlaceholder = _a.extractPlaceholder; + var _this = _super.call(this, { element: element, classNames: classNames }) || this; + _this.template = template; + _this.extractPlaceholder = extractPlaceholder; + return _this; + } + Object.defineProperty(WrappedSelect.prototype, "placeholderOption", { + get: function () { + return (this.element.querySelector('option[value=""]') || + // Backward compatibility layer for the non-standard placeholder attribute supported in older versions. + this.element.querySelector('option[placeholder]')); + }, + enumerable: false, + configurable: true + }); + WrappedSelect.prototype.addOptions = function (choices) { + var _this = this; + var fragment = document.createDocumentFragment(); + choices.forEach(function (obj) { + var choice = obj; + if (choice.element) { + return; + } + var option = _this.template(choice); + fragment.appendChild(option); + choice.element = option; + }); + this.element.appendChild(fragment); + }; + WrappedSelect.prototype.optionsAsChoices = function () { + var _this = this; + var choices = []; + this.element.querySelectorAll(':scope > option, :scope > optgroup').forEach(function (e) { + if (isHtmlOption(e)) { + choices.push(_this._optionToChoice(e)); + } + else if (isHtmlOptgroup(e)) { + choices.push(_this._optgroupToChoice(e)); + } + // todo: hr as empty optgroup, requires displaying empty opt-groups to be useful + }); + return choices; + }; + // eslint-disable-next-line class-methods-use-this + WrappedSelect.prototype._optionToChoice = function (option) { + // option.value returns the label if there is no value attribute, which can break legacy placeholder attribute support + if (!option.hasAttribute('value') && option.hasAttribute('placeholder')) { + option.setAttribute('value', ''); + option.value = ''; + } + return { + id: 0, + groupId: 0, + score: 0, + rank: 0, + value: option.value, + label: option.innerHTML, + element: option, + active: true, + // this returns true if nothing is selected on initial load, which will break placeholder support + selected: this.extractPlaceholder ? option.selected : option.hasAttribute('selected'), + disabled: option.disabled, + highlighted: false, + placeholder: this.extractPlaceholder && (!option.value || option.hasAttribute('placeholder')), + labelClass: typeof option.dataset.labelClass !== 'undefined' ? stringToHtmlClass(option.dataset.labelClass) : undefined, + labelDescription: typeof option.dataset.labelDescription !== 'undefined' ? option.dataset.labelDescription : undefined, + customProperties: parseCustomProperties(option.dataset.customProperties), + }; + }; + WrappedSelect.prototype._optgroupToChoice = function (optgroup) { + var _this = this; + var options = optgroup.querySelectorAll('option'); + var choices = Array.from(options).map(function (option) { return _this._optionToChoice(option); }); + return { + id: 0, + label: optgroup.label || '', + element: optgroup, + active: !!choices.length, + disabled: optgroup.disabled, + choices: choices, + }; + }; + return WrappedSelect; + }(WrappedElement)); + + var DEFAULT_CLASSNAMES = { + containerOuter: ['choices'], + containerInner: ['choices__inner'], + input: ['choices__input'], + inputCloned: ['choices__input--cloned'], + list: ['choices__list'], + listItems: ['choices__list--multiple'], + listSingle: ['choices__list--single'], + listDropdown: ['choices__list--dropdown'], + item: ['choices__item'], + itemSelectable: ['choices__item--selectable'], + itemDisabled: ['choices__item--disabled'], + itemChoice: ['choices__item--choice'], + description: ['choices__description'], + placeholder: ['choices__placeholder'], + group: ['choices__group'], + groupHeading: ['choices__heading'], + button: ['choices__button'], + activeState: ['is-active'], + focusState: ['is-focused'], + openState: ['is-open'], + disabledState: ['is-disabled'], + highlightedState: ['is-highlighted'], + selectedState: ['is-selected'], + flippedState: ['is-flipped'], + loadingState: ['is-loading'], + notice: ['choices__notice'], + addChoice: ['choices__item--selectable', 'add-choice'], + noResults: ['has-no-results'], + noChoices: ['has-no-choices'], + }; + var DEFAULT_CONFIG = { + items: [], + choices: [], + silent: false, + renderChoiceLimit: -1, + maxItemCount: -1, + closeDropdownOnSelect: 'auto', + singleModeForMultiSelect: false, + addChoices: false, + addItems: true, + addItemFilter: function (value) { return !!value && value !== ''; }, + removeItems: true, + removeItemButton: false, + removeItemButtonAlignLeft: false, + editItems: false, + allowHTML: false, + allowHtmlUserInput: false, + duplicateItemsAllowed: true, + delimiter: ',', + paste: true, + searchEnabled: true, + searchChoices: true, + searchFloor: 1, + searchResultLimit: 4, + searchFields: ['label', 'value'], + position: 'auto', + resetScrollPosition: true, + shouldSort: true, + shouldSortItems: false, + sorter: sortByAlpha, + shadowRoot: null, + placeholder: true, + placeholderValue: null, + searchPlaceholderValue: null, + prependValue: null, + appendValue: null, + renderSelectedChoices: 'auto', + loadingText: 'Loading...', + noResultsText: 'No results found', + noChoicesText: 'No choices to choose from', + itemSelectText: 'Press to select', + uniqueItemText: 'Only unique values can be added', + customAddItemText: 'Only values matching specific conditions can be added', + addItemText: function (value) { return "Press Enter to add \"".concat(value, "\""); }, + removeItemIconText: function () { return "Remove item"; }, + removeItemLabelText: function (value) { return "Remove item: ".concat(value); }, + maxItemText: function (maxItemCount) { return "Only ".concat(maxItemCount, " values can be added"); }, + valueComparer: function (value1, value2) { return value1 === value2; }, + fuseOptions: { + includeScore: true, + }, + labelId: '', + callbackOnInit: null, + callbackOnCreateTemplates: null, + classNames: DEFAULT_CLASSNAMES, + appendGroupInSearch: false, + }; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.setIsLoading = exports.resetTo = exports.clearAll = void 0; -var constants_1 = __webpack_require__(883); -var clearAll = function () { - return { - type: constants_1.ACTION_TYPES.CLEAR_ALL - }; -}; -exports.clearAll = clearAll; -var resetTo = function (state) { - return { - type: constants_1.ACTION_TYPES.RESET_TO, - state: state - }; -}; -exports.resetTo = resetTo; -var setIsLoading = function (isLoading) { - return { - type: constants_1.ACTION_TYPES.SET_IS_LOADING, - isLoading: isLoading - }; -}; -exports.setIsLoading = setIsLoading; + var removeItem = function (item) { + var itemEl = item.itemEl; + if (itemEl) { + itemEl.remove(); + item.itemEl = undefined; + } + }; + function items(s, action, context) { + var state = s; + var update = true; + switch (action.type) { + case ActionType.ADD_ITEM: { + action.item.selected = true; + var el = action.item.element; + if (el) { + el.selected = true; + el.setAttribute('selected', ''); + } + state.push(action.item); + break; + } + case ActionType.REMOVE_ITEM: { + action.item.selected = false; + var el = action.item.element; + if (el) { + el.selected = false; + el.removeAttribute('selected'); + // For a select-one, if all options are deselected, the first item is selected. To set a black value, select.value needs to be set + var select = el.parentElement; + if (select && isHtmlSelectElement(select) && select.type === PassedElementTypes.SelectOne) { + select.value = ''; + } + } + // this is mixing concerns, but this is *so much faster* + removeItem(action.item); + state = state.filter(function (choice) { return choice.id !== action.item.id; }); + break; + } + case ActionType.REMOVE_CHOICE: { + state = state.filter(function (item) { return item.id !== action.choice.id; }); + removeItem(action.choice); + break; + } + case ActionType.HIGHLIGHT_ITEM: { + var highlighted = action.highlighted; + var item = state.find(function (obj) { return obj.id === action.item.id; }); + if (item && item.highlighted !== highlighted) { + item.highlighted = highlighted; + if (context) { + updateClassList(item, highlighted ? context.classNames.highlightedState : context.classNames.selectedState, highlighted ? context.classNames.selectedState : context.classNames.highlightedState); + } + } + break; + } + default: { + update = false; + break; + } + } + return { state: state, update: update }; + } -/***/ }), + function groups(s, action) { + var state = s; + var update = true; + switch (action.type) { + case ActionType.ADD_GROUP: { + state.push(action.group); + break; + } + case ActionType.CLEAR_CHOICES: { + state = []; + break; + } + default: { + update = false; + break; + } + } + return { state: state, update: update }; + } + + /* eslint-disable */ + function choices(s, action, context) { + var state = s; + var update = true; + switch (action.type) { + case ActionType.ADD_CHOICE: { + /* + A disabled choice appears in the choice dropdown but cannot be selected + A selected choice has been added to the passed input's value (added as an item) + An active choice appears within the choice dropdown + */ + state.push(action.choice); + break; + } + case ActionType.REMOVE_CHOICE: { + action.choice.choiceEl = undefined; + state = state.filter(function (obj) { return obj.id !== action.choice.id; }); + break; + } + case ActionType.ADD_ITEM: + case ActionType.REMOVE_ITEM: { + action.item.choiceEl = undefined; + break; + } + case ActionType.FILTER_CHOICES: { + // avoid O(n^2) algorithm complexity when searching/filtering choices + var scoreLookup_1 = []; + action.results.forEach(function (result) { + scoreLookup_1[result.item.id] = result; + }); + state.forEach(function (choice) { + var result = scoreLookup_1[choice.id]; + if (result !== undefined) { + choice.score = result.score; + choice.rank = result.rank; + choice.active = true; + } + else { + choice.score = 0; + choice.rank = 0; + choice.active = false; + } + if (context && context.appendGroupInSearch) { + choice.choiceEl = undefined; + } + }); + break; + } + case ActionType.ACTIVATE_CHOICES: { + state.forEach(function (choice) { + choice.active = action.active; + if (context && context.appendGroupInSearch) { + choice.choiceEl = undefined; + } + }); + break; + } + case ActionType.CLEAR_CHOICES: { + state = []; + break; + } + default: { + update = false; + break; + } + } + return { state: state, update: update }; + } -/***/ 373: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + var reducers = { + groups: groups, + items: items, + choices: choices, + }; + var Store = /** @class */ (function () { + function Store(context) { + this._state = this.defaultState; + this._listeners = []; + this._txn = 0; + this._context = context; + } + Object.defineProperty(Store.prototype, "defaultState", { + // eslint-disable-next-line class-methods-use-this + get: function () { + return { + groups: [], + items: [], + choices: [], + }; + }, + enumerable: false, + configurable: true + }); + // eslint-disable-next-line class-methods-use-this + Store.prototype.changeSet = function (init) { + return { + groups: init, + items: init, + choices: init, + }; + }; + Store.prototype.reset = function () { + this._state = this.defaultState; + var changes = this.changeSet(true); + if (this._txn) { + this._changeSet = changes; + } + else { + this._listeners.forEach(function (l) { return l(changes); }); + } + }; + Store.prototype.subscribe = function (onChange) { + this._listeners.push(onChange); + }; + Store.prototype.dispatch = function (action) { + var _this = this; + var state = this._state; + var hasChanges = false; + var changes = this._changeSet || this.changeSet(false); + Object.keys(reducers).forEach(function (key) { + var stateUpdate = reducers[key](state[key], action, _this._context); + if (stateUpdate.update) { + hasChanges = true; + changes[key] = true; + state[key] = stateUpdate.state; + } + }); + if (hasChanges) { + if (this._txn) { + this._changeSet = changes; + } + else { + this._listeners.forEach(function (l) { return l(changes); }); + } + } + }; + Store.prototype.withTxn = function (func) { + this._txn++; + try { + func(); + } + finally { + this._txn = Math.max(0, this._txn - 1); + if (!this._txn) { + var changeSet_1 = this._changeSet; + if (changeSet_1) { + this._changeSet = undefined; + this._listeners.forEach(function (l) { return l(changeSet_1); }); + } + } + } + }; + Object.defineProperty(Store.prototype, "state", { + /** + * Get store object + */ + get: function () { + return this._state; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "items", { + /** + * Get items from store + */ + get: function () { + return this.state.items; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "highlightedActiveItems", { + /** + * Get highlighted items from store + */ + get: function () { + return this.items.filter(function (item) { return !item.disabled && item.active && item.highlighted; }); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "choices", { + /** + * Get choices from store + */ + get: function () { + return this.state.choices; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "activeChoices", { + /** + * Get active choices from store + */ + get: function () { + return this.choices.filter(function (choice) { return choice.active; }); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "searchableChoices", { + /** + * Get choices that can be searched (excluding placeholders) + */ + get: function () { + return this.choices.filter(function (choice) { return !choice.disabled && !choice.placeholder; }); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "groups", { + /** + * Get groups from store + */ + get: function () { + return this.state.groups; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "activeGroups", { + /** + * Get active groups from store + */ + get: function () { + var _this = this; + return this.state.groups.filter(function (group) { + var isActive = group.active && !group.disabled; + var hasActiveOptions = _this.state.choices.some(function (choice) { return choice.active && !choice.disabled; }); + return isActive && hasActiveOptions; + }, []); + }, + enumerable: false, + configurable: true + }); + Store.prototype.inTxn = function () { + return this._txn > 0; + }; + /** + * Get single choice by it's ID + */ + Store.prototype.getChoiceById = function (id) { + return this.activeChoices.find(function (choice) { return choice.id === id; }); + }; + /** + * Get group by group id + */ + Store.prototype.getGroupById = function (id) { + return this.groups.find(function (group) { return group.id === id; }); + }; + return Store; + }()); + + var NoticeTypes = { + noChoices: 'no-choices', + noResults: 'no-results', + addChoice: 'add-choice', + generic: '', + }; + function _defineProperty(e, r, t) { + return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { + value: t, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[r] = t, e; + } + function ownKeys(e, r) { + var t = Object.keys(e); + if (Object.getOwnPropertySymbols) { + var o = Object.getOwnPropertySymbols(e); + r && (o = o.filter(function (r) { + return Object.getOwnPropertyDescriptor(e, r).enumerable; + })), t.push.apply(t, o); + } + return t; + } + function _objectSpread2(e) { + for (var r = 1; r < arguments.length; r++) { + var t = null != arguments[r] ? arguments[r] : {}; + r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { + _defineProperty(e, r, t[r]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { + Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); + }); + } + return e; + } + function _toPrimitive(t, r) { + if ("object" != typeof t || !t) return t; + var e = t[Symbol.toPrimitive]; + if (void 0 !== e) { + var i = e.call(t, r || "default"); + if ("object" != typeof i) return i; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return ("string" === r ? String : Number)(t); + } + function _toPropertyKey(t) { + var i = _toPrimitive(t, "string"); + return "symbol" == typeof i ? i : i + ""; + } + /** + * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2023 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ -var __spreadArray = this && this.__spreadArray || function (to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -}; -var __importDefault = this && this.__importDefault || function (mod) { - return mod && mod.__esModule ? mod : { - "default": mod - }; -}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var deepmerge_1 = __importDefault(__webpack_require__(996)); -/* eslint-disable @typescript-eslint/no-explicit-any */ -var fuse_js_1 = __importDefault(__webpack_require__(221)); -var choices_1 = __webpack_require__(282); -var groups_1 = __webpack_require__(783); -var items_1 = __webpack_require__(464); -var misc_1 = __webpack_require__(137); -var components_1 = __webpack_require__(520); -var constants_1 = __webpack_require__(883); -var defaults_1 = __webpack_require__(789); -var utils_1 = __webpack_require__(799); -var reducers_1 = __webpack_require__(655); -var store_1 = __importDefault(__webpack_require__(744)); -var templates_1 = __importDefault(__webpack_require__(686)); -/** @see {@link http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c} */ -var IS_IE11 = '-ms-scroll-limit' in document.documentElement.style && '-ms-ime-align' in document.documentElement.style; -var USER_DEFAULTS = {}; -/** - * Choices - * @author Josh Johnson - */ -var Choices = /** @class */function () { - function Choices(element, userConfig) { - if (element === void 0) { - element = '[data-choice]'; + function isArray(value) { + return !Array.isArray ? getTag(value) === '[object Array]' : Array.isArray(value); } - if (userConfig === void 0) { - userConfig = {}; + + // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js + const INFINITY = 1 / 0; + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + let result = value + ''; + return result == '0' && 1 / value == -INFINITY ? '-0' : result; } - var _this = this; - if (userConfig.allowHTML === undefined) { - console.warn('Deprecation warning: allowHTML will default to false in a future release. To render HTML in Choices, you will need to set it to true. Setting allowHTML will suppress this message.'); + function toString(value) { + return value == null ? '' : baseToString(value); } - this.config = deepmerge_1.default.all([defaults_1.DEFAULT_CONFIG, Choices.defaults.options, userConfig], - // When merging array configs, replace with a copy of the userConfig array, - // instead of concatenating with the default array - { - arrayMerge: function (_, sourceArray) { - return __spreadArray([], sourceArray, true); - } - }); - var invalidConfigOptions = (0, utils_1.diff)(this.config, defaults_1.DEFAULT_CONFIG); - if (invalidConfigOptions.length) { - console.warn('Unknown config option(s) passed', invalidConfigOptions.join(', ')); + function isString(value) { + return typeof value === 'string'; } - var passedElement = typeof element === 'string' ? document.querySelector(element) : element; - if (!(passedElement instanceof HTMLInputElement || passedElement instanceof HTMLSelectElement)) { - throw TypeError('Expected one of the following types text|select-one|select-multiple'); + function isNumber(value) { + return typeof value === 'number'; } - this._isTextElement = passedElement.type === constants_1.TEXT_TYPE; - this._isSelectOneElement = passedElement.type === constants_1.SELECT_ONE_TYPE; - this._isSelectMultipleElement = passedElement.type === constants_1.SELECT_MULTIPLE_TYPE; - this._isSelectElement = this._isSelectOneElement || this._isSelectMultipleElement; - this.config.searchEnabled = this._isSelectMultipleElement || this.config.searchEnabled; - if (!['auto', 'always'].includes("".concat(this.config.renderSelectedChoices))) { - this.config.renderSelectedChoices = 'auto'; + + // Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js + function isBoolean(value) { + return value === true || value === false || isObjectLike(value) && getTag(value) == '[object Boolean]'; } - if (userConfig.addItemFilter && typeof userConfig.addItemFilter !== 'function') { - var re = userConfig.addItemFilter instanceof RegExp ? userConfig.addItemFilter : new RegExp(userConfig.addItemFilter); - this.config.addItemFilter = re.test.bind(re); + function isObject(value) { + return typeof value === 'object'; } - if (this._isTextElement) { - this.passedElement = new components_1.WrappedInput({ - element: passedElement, - classNames: this.config.classNames, - delimiter: this.config.delimiter - }); - } else { - this.passedElement = new components_1.WrappedSelect({ - element: passedElement, - classNames: this.config.classNames, - template: function (data) { - return _this._templates.option(data); - } - }); + + // Checks if `value` is object-like. + function isObjectLike(value) { + return isObject(value) && value !== null; } - this.initialised = false; - this._store = new store_1.default(); - this._initialState = reducers_1.defaultState; - this._currentState = reducers_1.defaultState; - this._prevState = reducers_1.defaultState; - this._currentValue = ''; - this._canSearch = !!this.config.searchEnabled; - this._isScrollingOnIe = false; - this._highlightPosition = 0; - this._wasTap = true; - this._placeholderValue = this._generatePlaceholderValue(); - this._baseId = (0, utils_1.generateId)(this.passedElement.element, 'choices-'); - /** - * setting direction in cases where it's explicitly set on passedElement - * or when calculated direction is different from the document - */ - this._direction = this.passedElement.dir; - if (!this._direction) { - var elementDirection = window.getComputedStyle(this.passedElement.element).direction; - var documentDirection = window.getComputedStyle(document.documentElement).direction; - if (elementDirection !== documentDirection) { - this._direction = elementDirection; - } + function isDefined(value) { + return value !== undefined && value !== null; } - this._idNames = { - itemChoice: 'item-choice' - }; - if (this._isSelectElement) { - // Assign preset groups from passed element - this._presetGroups = this.passedElement.optionGroups; - // Assign preset options from passed element - this._presetOptions = this.passedElement.options; + function isBlank(value) { + return !value.trim().length; } - // Assign preset choices from passed object - this._presetChoices = this.config.choices; - // Assign preset items from passed object first - this._presetItems = this.config.items; - // Add any values passed from attribute - if (this.passedElement.value && this._isTextElement) { - var splitValues = this.passedElement.value.split(this.config.delimiter); - this._presetItems = this._presetItems.concat(splitValues); + + // Gets the `toStringTag` of `value`. + // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js + function getTag(value) { + return value == null ? value === undefined ? '[object Undefined]' : '[object Null]' : Object.prototype.toString.call(value); } - // Create array of choices from option elements - if (this.passedElement.options) { - this.passedElement.options.forEach(function (option) { - _this._presetChoices.push({ - value: option.value, - label: option.innerHTML, - selected: !!option.selected, - disabled: option.disabled || option.parentNode.disabled, - placeholder: option.value === '' || option.hasAttribute('placeholder'), - customProperties: (0, utils_1.parseCustomProperties)(option.dataset.customProperties) + const EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available'; + const INCORRECT_INDEX_TYPE = "Incorrect 'index' type"; + const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = key => `Invalid value for key ${key}`; + const PATTERN_LENGTH_TOO_LARGE = max => `Pattern length exceeds max of ${max}.`; + const MISSING_KEY_PROPERTY = name => `Missing ${name} property in key`; + const INVALID_KEY_WEIGHT_VALUE = key => `Property 'weight' in key '${key}' must be a positive integer`; + const hasOwn = Object.prototype.hasOwnProperty; + class KeyStore { + constructor(keys) { + this._keys = []; + this._keyMap = {}; + let totalWeight = 0; + keys.forEach(key => { + let obj = createKey(key); + this._keys.push(obj); + this._keyMap[obj.id] = obj; + totalWeight += obj.weight; }); - }); - } - this._render = this._render.bind(this); - this._onFocus = this._onFocus.bind(this); - this._onBlur = this._onBlur.bind(this); - this._onKeyUp = this._onKeyUp.bind(this); - this._onKeyDown = this._onKeyDown.bind(this); - this._onClick = this._onClick.bind(this); - this._onTouchMove = this._onTouchMove.bind(this); - this._onTouchEnd = this._onTouchEnd.bind(this); - this._onMouseDown = this._onMouseDown.bind(this); - this._onMouseOver = this._onMouseOver.bind(this); - this._onFormReset = this._onFormReset.bind(this); - this._onSelectKey = this._onSelectKey.bind(this); - this._onEnterKey = this._onEnterKey.bind(this); - this._onEscapeKey = this._onEscapeKey.bind(this); - this._onDirectionKey = this._onDirectionKey.bind(this); - this._onDeleteKey = this._onDeleteKey.bind(this); - // If element has already been initialised with Choices, fail silently - if (this.passedElement.isActive) { - if (!this.config.silent) { - console.warn('Trying to initialise Choices on element already initialised', { - element: element + + // Normalize weights so that their sum is equal to 1 + this._keys.forEach(key => { + key.weight /= totalWeight; }); } - this.initialised = true; - return; - } - // Let's go - this.init(); - } - Object.defineProperty(Choices, "defaults", { - get: function () { - return Object.preventExtensions({ - get options() { - return USER_DEFAULTS; - }, - get templates() { - return templates_1.default; - } - }); - }, - enumerable: false, - configurable: true - }); - Choices.prototype.init = function () { - if (this.initialised) { - return; - } - this._createTemplates(); - this._createElements(); - this._createStructure(); - this._store.subscribe(this._render); - this._render(); - this._addEventListeners(); - var shouldDisable = !this.config.addItems || this.passedElement.element.hasAttribute('disabled'); - if (shouldDisable) { - this.disable(); - } - this.initialised = true; - var callbackOnInit = this.config.callbackOnInit; - // Run callback if it is a function - if (callbackOnInit && typeof callbackOnInit === 'function') { - callbackOnInit.call(this); - } - }; - Choices.prototype.destroy = function () { - if (!this.initialised) { - return; - } - this._removeEventListeners(); - this.passedElement.reveal(); - this.containerOuter.unwrap(this.passedElement.element); - this.clearStore(); - if (this._isSelectElement) { - this.passedElement.options = this._presetOptions; - } - this._templates = templates_1.default; - this.initialised = false; - }; - Choices.prototype.enable = function () { - if (this.passedElement.isDisabled) { - this.passedElement.enable(); - } - if (this.containerOuter.isDisabled) { - this._addEventListeners(); - this.input.enable(); - this.containerOuter.enable(); - } - return this; - }; - Choices.prototype.disable = function () { - if (!this.passedElement.isDisabled) { - this.passedElement.disable(); - } - if (!this.containerOuter.isDisabled) { - this._removeEventListeners(); - this.input.disable(); - this.containerOuter.disable(); - } - return this; - }; - Choices.prototype.highlightItem = function (item, runEvent) { - if (runEvent === void 0) { - runEvent = true; - } - if (!item || !item.id) { - return this; - } - var id = item.id, - _a = item.groupId, - groupId = _a === void 0 ? -1 : _a, - _b = item.value, - value = _b === void 0 ? '' : _b, - _c = item.label, - label = _c === void 0 ? '' : _c; - var group = groupId >= 0 ? this._store.getGroupById(groupId) : null; - this._store.dispatch((0, items_1.highlightItem)(id, true)); - if (runEvent) { - this.passedElement.triggerEvent(constants_1.EVENTS.highlightItem, { - id: id, - value: value, - label: label, - groupValue: group && group.value ? group.value : null - }); - } - return this; - }; - Choices.prototype.unhighlightItem = function (item) { - if (!item || !item.id) { - return this; - } - var id = item.id, - _a = item.groupId, - groupId = _a === void 0 ? -1 : _a, - _b = item.value, - value = _b === void 0 ? '' : _b, - _c = item.label, - label = _c === void 0 ? '' : _c; - var group = groupId >= 0 ? this._store.getGroupById(groupId) : null; - this._store.dispatch((0, items_1.highlightItem)(id, false)); - this.passedElement.triggerEvent(constants_1.EVENTS.highlightItem, { - id: id, - value: value, - label: label, - groupValue: group && group.value ? group.value : null - }); - return this; - }; - Choices.prototype.highlightAll = function () { - var _this = this; - this._store.items.forEach(function (item) { - return _this.highlightItem(item); - }); - return this; - }; - Choices.prototype.unhighlightAll = function () { - var _this = this; - this._store.items.forEach(function (item) { - return _this.unhighlightItem(item); - }); - return this; - }; - Choices.prototype.removeActiveItemsByValue = function (value) { - var _this = this; - this._store.activeItems.filter(function (item) { - return item.value === value; - }).forEach(function (item) { - return _this._removeItem(item); - }); - return this; - }; - Choices.prototype.removeActiveItems = function (excludedId) { - var _this = this; - this._store.activeItems.filter(function (_a) { - var id = _a.id; - return id !== excludedId; - }).forEach(function (item) { - return _this._removeItem(item); - }); - return this; - }; - Choices.prototype.removeHighlightedItems = function (runEvent) { - var _this = this; - if (runEvent === void 0) { - runEvent = false; - } - this._store.highlightedActiveItems.forEach(function (item) { - _this._removeItem(item); - // If this action was performed by the user - // trigger the event - if (runEvent) { - _this._triggerChange(item.value); - } - }); - return this; - }; - Choices.prototype.showDropdown = function (preventInputFocus) { - var _this = this; - if (this.dropdown.isActive) { - return this; - } - requestAnimationFrame(function () { - _this.dropdown.show(); - _this.containerOuter.open(_this.dropdown.distanceFromTopWindow); - if (!preventInputFocus && _this._canSearch) { - _this.input.focus(); - } - _this.passedElement.triggerEvent(constants_1.EVENTS.showDropdown, {}); - }); - return this; - }; - Choices.prototype.hideDropdown = function (preventInputBlur) { - var _this = this; - if (!this.dropdown.isActive) { - return this; - } - requestAnimationFrame(function () { - _this.dropdown.hide(); - _this.containerOuter.close(); - if (!preventInputBlur && _this._canSearch) { - _this.input.removeActiveDescendant(); - _this.input.blur(); - } - _this.passedElement.triggerEvent(constants_1.EVENTS.hideDropdown, {}); - }); - return this; - }; - Choices.prototype.getValue = function (valueOnly) { - if (valueOnly === void 0) { - valueOnly = false; - } - var values = this._store.activeItems.reduce(function (selectedItems, item) { - var itemValue = valueOnly ? item.value : item; - selectedItems.push(itemValue); - return selectedItems; - }, []); - return this._isSelectOneElement ? values[0] : values; - }; - Choices.prototype.setValue = function (items) { - var _this = this; - if (!this.initialised) { - return this; - } - items.forEach(function (value) { - return _this._setChoiceOrItem(value); - }); - return this; - }; - Choices.prototype.setChoiceByValue = function (value) { - var _this = this; - if (!this.initialised || this._isTextElement) { - return this; - } - // If only one value has been passed, convert to array - var choiceValue = Array.isArray(value) ? value : [value]; - // Loop through each value and - choiceValue.forEach(function (val) { - return _this._findAndSelectChoiceByValue(val); - }); - return this; - }; - /** - * Set choices of select input via an array of objects (or function that returns array of object or promise of it), - * a value field name and a label field name. - * This behaves the same as passing items via the choices option but can be called after initialising Choices. - * This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices. - * Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc). - * - * **Input types affected:** select-one, select-multiple - * - * @example - * ```js - * const example = new Choices(element); - * - * example.setChoices([ - * {value: 'One', label: 'Label One', disabled: true}, - * {value: 'Two', label: 'Label Two', selected: true}, - * {value: 'Three', label: 'Label Three'}, - * ], 'value', 'label', false); - * ``` - * - * @example - * ```js - * const example = new Choices(element); - * - * example.setChoices(async () => { - * try { - * const items = await fetch('/items'); - * return items.json() - * } catch(err) { - * console.error(err) - * } - * }); - * ``` - * - * @example - * ```js - * const example = new Choices(element); - * - * example.setChoices([{ - * label: 'Group one', - * id: 1, - * disabled: false, - * choices: [ - * {value: 'Child One', label: 'Child One', selected: true}, - * {value: 'Child Two', label: 'Child Two', disabled: true}, - * {value: 'Child Three', label: 'Child Three'}, - * ] - * }, - * { - * label: 'Group two', - * id: 2, - * disabled: false, - * choices: [ - * {value: 'Child Four', label: 'Child Four', disabled: true}, - * {value: 'Child Five', label: 'Child Five'}, - * {value: 'Child Six', label: 'Child Six', customProperties: { - * description: 'Custom description about child six', - * random: 'Another random custom property' - * }}, - * ] - * }], 'value', 'label', false); - * ``` - */ - Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices) { - var _this = this; - if (choicesArrayOrFetcher === void 0) { - choicesArrayOrFetcher = []; - } - if (value === void 0) { - value = 'value'; - } - if (label === void 0) { - label = 'label'; - } - if (replaceChoices === void 0) { - replaceChoices = false; - } - if (!this.initialised) { - throw new ReferenceError("setChoices was called on a non-initialized instance of Choices"); - } - if (!this._isSelectElement) { - throw new TypeError("setChoices can't be used with INPUT based Choices"); - } - if (typeof value !== 'string' || !value) { - throw new TypeError("value parameter must be a name of 'value' field in passed objects"); - } - // Clear choices if needed - if (replaceChoices) { - this.clearChoices(); - } - if (typeof choicesArrayOrFetcher === 'function') { - // it's a choices fetcher function - var fetcher_1 = choicesArrayOrFetcher(this); - if (typeof Promise === 'function' && fetcher_1 instanceof Promise) { - // that's a promise - // eslint-disable-next-line no-promise-executor-return - return new Promise(function (resolve) { - return requestAnimationFrame(resolve); - }).then(function () { - return _this._handleLoadingState(true); - }).then(function () { - return fetcher_1; - }).then(function (data) { - return _this.setChoices(data, value, label, replaceChoices); - }).catch(function (err) { - if (!_this.config.silent) { - console.error(err); - } - }).then(function () { - return _this._handleLoadingState(false); - }).then(function () { - return _this; - }); - } - // function returned something else than promise, let's check if it's an array of choices - if (!Array.isArray(fetcher_1)) { - throw new TypeError(".setChoices first argument function must return either array of choices or Promise, got: ".concat(typeof fetcher_1)); + get(keyId) { + return this._keyMap[keyId]; } - // recursion with results, it's sync and choices were cleared already - return this.setChoices(fetcher_1, value, label, false); - } - if (!Array.isArray(choicesArrayOrFetcher)) { - throw new TypeError(".setChoices must be called either with array of choices with a function resulting into Promise of array of choices"); - } - this.containerOuter.removeLoadingState(); - this._startLoading(); - choicesArrayOrFetcher.forEach(function (groupOrChoice) { - if (groupOrChoice.choices) { - _this._addGroup({ - id: groupOrChoice.id ? parseInt("".concat(groupOrChoice.id), 10) : null, - group: groupOrChoice, - valueKey: value, - labelKey: label - }); - } else { - var choice = groupOrChoice; - _this._addChoice({ - value: choice[value], - label: choice[label], - isSelected: !!choice.selected, - isDisabled: !!choice.disabled, - placeholder: !!choice.placeholder, - customProperties: choice.customProperties - }); + keys() { + return this._keys; } - }); - this._stopLoading(); - return this; - }; - Choices.prototype.clearChoices = function () { - this._store.dispatch((0, choices_1.clearChoices)()); - return this; - }; - Choices.prototype.clearStore = function () { - this._store.dispatch((0, misc_1.clearAll)()); - return this; - }; - Choices.prototype.clearInput = function () { - var shouldSetInputWidth = !this._isSelectOneElement; - this.input.clear(shouldSetInputWidth); - if (!this._isTextElement && this._canSearch) { - this._isSearching = false; - this._store.dispatch((0, choices_1.activateChoices)(true)); - } - return this; - }; - Choices.prototype._render = function () { - if (this._store.isLoading()) { - return; - } - this._currentState = this._store.state; - var stateChanged = this._currentState.choices !== this._prevState.choices || this._currentState.groups !== this._prevState.groups || this._currentState.items !== this._prevState.items; - var shouldRenderChoices = this._isSelectElement; - var shouldRenderItems = this._currentState.items !== this._prevState.items; - if (!stateChanged) { - return; - } - if (shouldRenderChoices) { - this._renderChoices(); - } - if (shouldRenderItems) { - this._renderItems(); - } - this._prevState = this._currentState; - }; - Choices.prototype._renderChoices = function () { - var _this = this; - var _a = this._store, - activeGroups = _a.activeGroups, - activeChoices = _a.activeChoices; - var choiceListFragment = document.createDocumentFragment(); - this.choiceList.clear(); - if (this.config.resetScrollPosition) { - requestAnimationFrame(function () { - return _this.choiceList.scrollToTop(); - }); - } - // If we have grouped options - if (activeGroups.length >= 1 && !this._isSearching) { - // If we have a placeholder choice along with groups - var activePlaceholders = activeChoices.filter(function (activeChoice) { - return activeChoice.placeholder === true && activeChoice.groupId === -1; - }); - if (activePlaceholders.length >= 1) { - choiceListFragment = this._createChoicesFragment(activePlaceholders, choiceListFragment); + toJSON() { + return JSON.stringify(this._keys); } - choiceListFragment = this._createGroupsFragment(activeGroups, activeChoices, choiceListFragment); - } else if (activeChoices.length >= 1) { - choiceListFragment = this._createChoicesFragment(activeChoices, choiceListFragment); } - // If we have choices to show - if (choiceListFragment.childNodes && choiceListFragment.childNodes.length > 0) { - var activeItems = this._store.activeItems; - var canAddItem = this._canAddItem(activeItems, this.input.value); - // ...and we can select them - if (canAddItem.response) { - // ...append them and highlight the first choice - this.choiceList.append(choiceListFragment); - this._highlightChoice(); - } else { - var notice = this._getTemplate('notice', canAddItem.notice); - this.choiceList.append(notice); - } - } else { - // Otherwise show a notice - var dropdownItem = void 0; - var notice = void 0; - if (this._isSearching) { - notice = typeof this.config.noResultsText === 'function' ? this.config.noResultsText() : this.config.noResultsText; - dropdownItem = this._getTemplate('notice', notice, 'no-results'); + function createKey(key) { + let path = null; + let id = null; + let src = null; + let weight = 1; + let getFn = null; + if (isString(key) || isArray(key)) { + src = key; + path = createKeyPath(key); + id = createKeyId(key); } else { - notice = typeof this.config.noChoicesText === 'function' ? this.config.noChoicesText() : this.config.noChoicesText; - dropdownItem = this._getTemplate('notice', notice, 'no-choices'); + if (!hasOwn.call(key, 'name')) { + throw new Error(MISSING_KEY_PROPERTY('name')); + } + const name = key.name; + src = name; + if (hasOwn.call(key, 'weight')) { + weight = key.weight; + if (weight <= 0) { + throw new Error(INVALID_KEY_WEIGHT_VALUE(name)); + } + } + path = createKeyPath(name); + id = createKeyId(name); + getFn = key.getFn; } - this.choiceList.append(dropdownItem); + return { + path, + id, + weight, + src, + getFn + }; } - }; - Choices.prototype._renderItems = function () { - var activeItems = this._store.activeItems || []; - this.itemList.clear(); - // Create a fragment to store our list items - // (so we don't have to update the DOM for each item) - var itemListFragment = this._createItemsFragment(activeItems); - // If we have items to add, append them - if (itemListFragment.childNodes) { - this.itemList.append(itemListFragment); + function createKeyPath(key) { + return isArray(key) ? key : key.split('.'); } - }; - Choices.prototype._createGroupsFragment = function (groups, choices, fragment) { - var _this = this; - if (fragment === void 0) { - fragment = document.createDocumentFragment(); + function createKeyId(key) { + return isArray(key) ? key.join('.') : key; } - var getGroupChoices = function (group) { - return choices.filter(function (choice) { - if (_this._isSelectOneElement) { - return choice.groupId === group.id; + function get(obj, path) { + let list = []; + let arr = false; + const deepGet = (obj, path, index) => { + if (!isDefined(obj)) { + return; } - return choice.groupId === group.id && (_this.config.renderSelectedChoices === 'always' || !choice.selected); - }); + if (!path[index]) { + // If there's no path left, we've arrived at the object we care about. + list.push(obj); + } else { + let key = path[index]; + const value = obj[key]; + if (!isDefined(value)) { + return; + } + + // If we're at the last value in the path, and if it's a string/number/bool, + // add it to the list + if (index === path.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) { + list.push(toString(value)); + } else if (isArray(value)) { + arr = true; + // Search each item in the array. + for (let i = 0, len = value.length; i < len; i += 1) { + deepGet(value[i], path, index + 1); + } + } else if (path.length) { + // An object. Recurse further. + deepGet(value, path, index + 1); + } + } + }; + + // Backwards compatibility (since path used to be a string) + deepGet(obj, isString(path) ? path.split('.') : path, 0); + return arr ? list : list[0]; + } + const MatchOptions = { + // Whether the matches should be included in the result set. When `true`, each record in the result + // set will include the indices of the matched characters. + // These can consequently be used for highlighting purposes. + includeMatches: false, + // When `true`, the matching function will continue to the end of a search pattern even if + // a perfect match has already been located in the string. + findAllMatches: false, + // Minimum number of characters that must be matched before a result is considered a match + minMatchCharLength: 1 }; - // If sorting is enabled, filter groups - if (this.config.shouldSort) { - groups.sort(this.config.sorter); - } - groups.forEach(function (group) { - var groupChoices = getGroupChoices(group); - if (groupChoices.length >= 1) { - var dropdownGroup = _this._getTemplate('choiceGroup', group); - fragment.appendChild(dropdownGroup); - _this._createChoicesFragment(groupChoices, fragment, true); - } - }); - return fragment; - }; - Choices.prototype._createChoicesFragment = function (choices, fragment, withinGroup) { - var _this = this; - if (fragment === void 0) { - fragment = document.createDocumentFragment(); - } - if (withinGroup === void 0) { - withinGroup = false; - } - // Create a fragment to store our list items (so we don't have to update the DOM for each item) - var _a = this.config, - renderSelectedChoices = _a.renderSelectedChoices, - searchResultLimit = _a.searchResultLimit, - renderChoiceLimit = _a.renderChoiceLimit; - var filter = this._isSearching ? utils_1.sortByScore : this.config.sorter; - var appendChoice = function (choice) { - var shouldRender = renderSelectedChoices === 'auto' ? _this._isSelectOneElement || !choice.selected : true; - if (shouldRender) { - var dropdownItem = _this._getTemplate('choice', choice, _this.config.itemSelectText); - fragment.appendChild(dropdownItem); - } + const BasicOptions = { + // When `true`, the algorithm continues searching to the end of the input even if a perfect + // match is found before the end of the same input. + isCaseSensitive: false, + // When true, the matching function will continue to the end of a search pattern even if + includeScore: false, + // List of properties that will be searched. This also supports nested properties. + keys: [], + // Whether to sort the result list, by score + shouldSort: true, + // Default sort function: sort by ascending score, ascending index + sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1 }; - var rendererableChoices = choices; - if (renderSelectedChoices === 'auto' && !this._isSelectOneElement) { - rendererableChoices = choices.filter(function (choice) { - return !choice.selected; - }); - } - // Split array into placeholders and "normal" choices - var _b = rendererableChoices.reduce(function (acc, choice) { - if (choice.placeholder) { - acc.placeholderChoices.push(choice); - } else { - acc.normalChoices.push(choice); + const FuzzyOptions = { + // Approximately where in the text is the pattern expected to be found? + location: 0, + // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match + // (of both letters and location), a threshold of '1.0' would match anything. + threshold: 0.6, + // Determines how close the match must be to the fuzzy location (specified above). + // An exact letter match which is 'distance' characters away from the fuzzy location + // would score as a complete mismatch. A distance of '0' requires the match be at + // the exact location specified, a threshold of '1000' would require a perfect match + // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold. + distance: 100 + }; + const AdvancedOptions = { + // When `true`, it enables the use of unix-like search commands + useExtendedSearch: false, + // The get function to use when fetching an object's properties. + // The default will search nested paths *ie foo.bar.baz* + getFn: get, + // When `true`, search will ignore `location` and `distance`, so it won't matter + // where in the string the pattern appears. + // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score + ignoreLocation: false, + // When `true`, the calculation for the relevance score (used for sorting) will + // ignore the field-length norm. + // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm + ignoreFieldNorm: false, + // The weight to determine how much field length norm effects scoring. + fieldNormWeight: 1 + }; + var Config = _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, BasicOptions), MatchOptions), FuzzyOptions), AdvancedOptions); + const SPACE = /[^ ]+/g; + + // Field-length norm: the shorter the field, the higher the weight. + // Set to 3 decimals to reduce index size. + function norm(weight = 1, mantissa = 3) { + const cache = new Map(); + const m = Math.pow(10, mantissa); + return { + get(value) { + const numTokens = value.match(SPACE).length; + if (cache.has(numTokens)) { + return cache.get(numTokens); + } + + // Default function is 1/sqrt(x), weight makes that variable + const norm = 1 / Math.pow(numTokens, 0.5 * weight); + + // In place of `toFixed(mantissa)`, for faster computation + const n = parseFloat(Math.round(norm * m) / m); + cache.set(numTokens, n); + return n; + }, + clear() { + cache.clear(); } - return acc; - }, { - placeholderChoices: [], - normalChoices: [] - }), - placeholderChoices = _b.placeholderChoices, - normalChoices = _b.normalChoices; - // If sorting is enabled or the user is searching, filter choices - if (this.config.shouldSort || this._isSearching) { - normalChoices.sort(filter); - } - var choiceLimit = rendererableChoices.length; - // Prepend placeholeder - var sortedChoices = this._isSelectOneElement ? __spreadArray(__spreadArray([], placeholderChoices, true), normalChoices, true) : normalChoices; - if (this._isSearching) { - choiceLimit = searchResultLimit; - } else if (renderChoiceLimit && renderChoiceLimit > 0 && !withinGroup) { - choiceLimit = renderChoiceLimit; + }; } - // Add each choice to dropdown within range - for (var i = 0; i < choiceLimit; i += 1) { - if (sortedChoices[i]) { - appendChoice(sortedChoices[i]); + class FuseIndex { + constructor({ + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight + } = {}) { + this.norm = norm(fieldNormWeight, 3); + this.getFn = getFn; + this.isCreated = false; + this.setIndexRecords(); } - } - return fragment; - }; - Choices.prototype._createItemsFragment = function (items, fragment) { - var _this = this; - if (fragment === void 0) { - fragment = document.createDocumentFragment(); - } - // Create fragment to add elements to - var _a = this.config, - shouldSortItems = _a.shouldSortItems, - sorter = _a.sorter, - removeItemButton = _a.removeItemButton; - // If sorting is enabled, filter items - if (shouldSortItems && !this._isSelectOneElement) { - items.sort(sorter); - } - if (this._isTextElement) { - // Update the value of the hidden input - this.passedElement.value = items.map(function (_a) { - var value = _a.value; - return value; - }).join(this.config.delimiter); - } else { - // Update the options of the hidden input - this.passedElement.options = items; - } - var addItemToFragment = function (item) { - // Create new list element - var listItem = _this._getTemplate('item', item, removeItemButton); - // Append it to list - fragment.appendChild(listItem); - }; - // Add each list item to list - items.forEach(addItemToFragment); - return fragment; - }; - Choices.prototype._triggerChange = function (value) { - if (value === undefined || value === null) { - return; - } - this.passedElement.triggerEvent(constants_1.EVENTS.change, { - value: value - }); - }; - Choices.prototype._selectPlaceholderChoice = function (placeholderChoice) { - this._addItem({ - value: placeholderChoice.value, - label: placeholderChoice.label, - choiceId: placeholderChoice.id, - groupId: placeholderChoice.groupId, - placeholder: placeholderChoice.placeholder - }); - this._triggerChange(placeholderChoice.value); - }; - Choices.prototype._handleButtonAction = function (activeItems, element) { - if (!activeItems || !element || !this.config.removeItems || !this.config.removeItemButton) { - return; - } - var itemId = element.parentNode && element.parentNode.dataset.id; - var itemToRemove = itemId && activeItems.find(function (item) { - return item.id === parseInt(itemId, 10); - }); - if (!itemToRemove) { - return; - } - // Remove item associated with button - this._removeItem(itemToRemove); - this._triggerChange(itemToRemove.value); - if (this._isSelectOneElement && this._store.placeholderChoice) { - this._selectPlaceholderChoice(this._store.placeholderChoice); - } - }; - Choices.prototype._handleItemAction = function (activeItems, element, hasShiftKey) { - var _this = this; - if (hasShiftKey === void 0) { - hasShiftKey = false; - } - if (!activeItems || !element || !this.config.removeItems || this._isSelectOneElement) { - return; - } - var passedId = element.dataset.id; - // We only want to select one item with a click - // so we deselect any items that aren't the target - // unless shift is being pressed - activeItems.forEach(function (item) { - if (item.id === parseInt("".concat(passedId), 10) && !item.highlighted) { - _this.highlightItem(item); - } else if (!hasShiftKey && item.highlighted) { - _this.unhighlightItem(item); + setSources(docs = []) { + this.docs = docs; } - }); - // Focus input as without focus, a user cannot do anything with a - // highlighted item - this.input.focus(); - }; - Choices.prototype._handleChoiceAction = function (activeItems, element) { - if (!activeItems || !element) { - return; - } - // If we are clicking on an option - var id = element.dataset.id; - var choice = id && this._store.getChoiceById(id); - if (!choice) { - return; - } - var passedKeyCode = activeItems[0] && activeItems[0].keyCode ? activeItems[0].keyCode : undefined; - var hasActiveDropdown = this.dropdown.isActive; - // Update choice keyCode - choice.keyCode = passedKeyCode; - this.passedElement.triggerEvent(constants_1.EVENTS.choice, { - choice: choice - }); - if (!choice.selected && !choice.disabled) { - var canAddItem = this._canAddItem(activeItems, choice.value); - if (canAddItem.response) { - this._addItem({ - value: choice.value, - label: choice.label, - choiceId: choice.id, - groupId: choice.groupId, - customProperties: choice.customProperties, - placeholder: choice.placeholder, - keyCode: choice.keyCode + setIndexRecords(records = []) { + this.records = records; + } + setKeys(keys = []) { + this.keys = keys; + this._keysMap = {}; + keys.forEach((key, idx) => { + this._keysMap[key.id] = idx; }); - this._triggerChange(choice.value); } - } - this.clearInput(); - // We want to close the dropdown if we are dealing with a single select box - if (hasActiveDropdown && this._isSelectOneElement) { - this.hideDropdown(true); - this.containerOuter.focus(); - } - }; - Choices.prototype._handleBackspace = function (activeItems) { - if (!this.config.removeItems || !activeItems) { - return; - } - var lastItem = activeItems[activeItems.length - 1]; - var hasHighlightedItems = activeItems.some(function (item) { - return item.highlighted; - }); - // If editing the last item is allowed and there are not other selected items, - // we can edit the item value. Otherwise if we can remove items, remove all selected items - if (this.config.editItems && !hasHighlightedItems && lastItem) { - this.input.value = lastItem.value; - this.input.setWidth(); - this._removeItem(lastItem); - this._triggerChange(lastItem.value); - } else { - if (!hasHighlightedItems) { - // Highlight last item if none already highlighted - this.highlightItem(lastItem, false); + create() { + if (this.isCreated || !this.docs.length) { + return; + } + this.isCreated = true; + + // List is Array + if (isString(this.docs[0])) { + this.docs.forEach((doc, docIndex) => { + this._addString(doc, docIndex); + }); + } else { + // List is Array + this.docs.forEach((doc, docIndex) => { + this._addObject(doc, docIndex); + }); + } + this.norm.clear(); } - this.removeHighlightedItems(true); - } - }; - Choices.prototype._startLoading = function () { - this._store.dispatch((0, misc_1.setIsLoading)(true)); - }; - Choices.prototype._stopLoading = function () { - this._store.dispatch((0, misc_1.setIsLoading)(false)); - }; - Choices.prototype._handleLoadingState = function (setLoading) { - if (setLoading === void 0) { - setLoading = true; - } - var placeholderItem = this.itemList.getChild(".".concat(this.config.classNames.placeholder)); - if (setLoading) { - this.disable(); - this.containerOuter.addLoadingState(); - if (this._isSelectOneElement) { - if (!placeholderItem) { - placeholderItem = this._getTemplate('placeholder', this.config.loadingText); - if (placeholderItem) { - this.itemList.append(placeholderItem); - } + // Adds a doc to the end of the index + add(doc) { + const idx = this.size(); + if (isString(doc)) { + this._addString(doc, idx); } else { - placeholderItem.innerHTML = this.config.loadingText; + this._addObject(doc, idx); } - } else { - this.input.placeholder = this.config.loadingText; } - } else { - this.enable(); - this.containerOuter.removeLoadingState(); - if (this._isSelectOneElement) { - if (placeholderItem) { - placeholderItem.innerHTML = this._placeholderValue || ''; + // Removes the doc at the specified index of the index + removeAt(idx) { + this.records.splice(idx, 1); + + // Change ref index of every subsquent doc + for (let i = idx, len = this.size(); i < len; i += 1) { + this.records[i].i -= 1; } - } else { - this.input.placeholder = this._placeholderValue || ''; } - } - }; - Choices.prototype._handleSearch = function (value) { - if (!this.input.isFocussed) { - return; - } - var choices = this._store.choices; - var _a = this.config, - searchFloor = _a.searchFloor, - searchChoices = _a.searchChoices; - var hasUnactiveChoices = choices.some(function (option) { - return !option.active; - }); - // Check that we have a value to search and the input was an alphanumeric character - if (value !== null && typeof value !== 'undefined' && value.length >= searchFloor) { - var resultCount = searchChoices ? this._searchChoices(value) : 0; - // Trigger search event - this.passedElement.triggerEvent(constants_1.EVENTS.search, { - value: value, - resultCount: resultCount - }); - } else if (hasUnactiveChoices) { - // Otherwise reset choices to active - this._isSearching = false; - this._store.dispatch((0, choices_1.activateChoices)(true)); - } - }; - Choices.prototype._canAddItem = function (activeItems, value) { - var canAddItem = true; - var notice = typeof this.config.addItemText === 'function' ? this.config.addItemText(value) : this.config.addItemText; - if (!this._isSelectOneElement) { - var isDuplicateValue = (0, utils_1.existsInArray)(activeItems, value); - if (this.config.maxItemCount > 0 && this.config.maxItemCount <= activeItems.length) { - // If there is a max entry limit and we have reached that limit - // don't update - canAddItem = false; - notice = typeof this.config.maxItemText === 'function' ? this.config.maxItemText(this.config.maxItemCount) : this.config.maxItemText; + getValueForItemAtKeyId(item, keyId) { + return item[this._keysMap[keyId]]; } - if (!this.config.duplicateItemsAllowed && isDuplicateValue && canAddItem) { - canAddItem = false; - notice = typeof this.config.uniqueItemText === 'function' ? this.config.uniqueItemText(value) : this.config.uniqueItemText; + size() { + return this.records.length; } - if (this._isTextElement && this.config.addItems && canAddItem && typeof this.config.addItemFilter === 'function' && !this.config.addItemFilter(value)) { - canAddItem = false; - notice = typeof this.config.customAddItemText === 'function' ? this.config.customAddItemText(value) : this.config.customAddItemText; + _addString(doc, docIndex) { + if (!isDefined(doc) || isBlank(doc)) { + return; + } + let record = { + v: doc, + i: docIndex, + n: this.norm.get(doc) + }; + this.records.push(record); + } + _addObject(doc, docIndex) { + let record = { + i: docIndex, + $: {} + }; + + // Iterate over every key (i.e, path), and fetch the value at that key + this.keys.forEach((key, keyIndex) => { + let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path); + if (!isDefined(value)) { + return; + } + if (isArray(value)) { + let subRecords = []; + const stack = [{ + nestedArrIndex: -1, + value + }]; + while (stack.length) { + const { + nestedArrIndex, + value + } = stack.pop(); + if (!isDefined(value)) { + continue; + } + if (isString(value) && !isBlank(value)) { + let subRecord = { + v: value, + i: nestedArrIndex, + n: this.norm.get(value) + }; + subRecords.push(subRecord); + } else if (isArray(value)) { + value.forEach((item, k) => { + stack.push({ + nestedArrIndex: k, + value: item + }); + }); + } else ; + } + record.$[keyIndex] = subRecords; + } else if (isString(value) && !isBlank(value)) { + let subRecord = { + v: value, + n: this.norm.get(value) + }; + record.$[keyIndex] = subRecord; + } + }); + this.records.push(record); + } + toJSON() { + return { + keys: this.keys, + records: this.records + }; } } - return { - response: canAddItem, - notice: notice - }; - }; - Choices.prototype._searchChoices = function (value) { - var newValue = typeof value === 'string' ? value.trim() : value; - var currentValue = typeof this._currentValue === 'string' ? this._currentValue.trim() : this._currentValue; - if (newValue.length < 1 && newValue === "".concat(currentValue, " ")) { - return 0; - } - // If new value matches the desired length and is not the same as the current value with a space - var haystack = this._store.searchableChoices; - var needle = newValue; - var options = Object.assign(this.config.fuseOptions, { - keys: __spreadArray([], this.config.searchFields, true), - includeMatches: true - }); - var fuse = new fuse_js_1.default(haystack, options); - var results = fuse.search(needle); // see https://github.com/krisk/Fuse/issues/303 - this._currentValue = newValue; - this._highlightPosition = 0; - this._isSearching = true; - this._store.dispatch((0, choices_1.filterChoices)(results)); - return results.length; - }; - Choices.prototype._addEventListeners = function () { - var documentElement = document.documentElement; - // capture events - can cancel event processing or propagation - documentElement.addEventListener('touchend', this._onTouchEnd, true); - this.containerOuter.element.addEventListener('keydown', this._onKeyDown, true); - this.containerOuter.element.addEventListener('mousedown', this._onMouseDown, true); - // passive events - doesn't call `preventDefault` or `stopPropagation` - documentElement.addEventListener('click', this._onClick, { - passive: true - }); - documentElement.addEventListener('touchmove', this._onTouchMove, { - passive: true - }); - this.dropdown.element.addEventListener('mouseover', this._onMouseOver, { - passive: true - }); - if (this._isSelectOneElement) { - this.containerOuter.element.addEventListener('focus', this._onFocus, { - passive: true + function createIndex(keys, docs, { + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight + } = {}) { + const myIndex = new FuseIndex({ + getFn, + fieldNormWeight }); - this.containerOuter.element.addEventListener('blur', this._onBlur, { - passive: true - }); - } - this.input.element.addEventListener('keyup', this._onKeyUp, { - passive: true - }); - this.input.element.addEventListener('focus', this._onFocus, { - passive: true - }); - this.input.element.addEventListener('blur', this._onBlur, { - passive: true - }); - if (this.input.element.form) { - this.input.element.form.addEventListener('reset', this._onFormReset, { - passive: true + myIndex.setKeys(keys.map(createKey)); + myIndex.setSources(docs); + myIndex.create(); + return myIndex; + } + function parseIndex(data, { + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight + } = {}) { + const { + keys, + records + } = data; + const myIndex = new FuseIndex({ + getFn, + fieldNormWeight }); - } - this.input.addEventListeners(); - }; - Choices.prototype._removeEventListeners = function () { - var documentElement = document.documentElement; - documentElement.removeEventListener('touchend', this._onTouchEnd, true); - this.containerOuter.element.removeEventListener('keydown', this._onKeyDown, true); - this.containerOuter.element.removeEventListener('mousedown', this._onMouseDown, true); - documentElement.removeEventListener('click', this._onClick); - documentElement.removeEventListener('touchmove', this._onTouchMove); - this.dropdown.element.removeEventListener('mouseover', this._onMouseOver); - if (this._isSelectOneElement) { - this.containerOuter.element.removeEventListener('focus', this._onFocus); - this.containerOuter.element.removeEventListener('blur', this._onBlur); - } - this.input.element.removeEventListener('keyup', this._onKeyUp); - this.input.element.removeEventListener('focus', this._onFocus); - this.input.element.removeEventListener('blur', this._onBlur); - if (this.input.element.form) { - this.input.element.form.removeEventListener('reset', this._onFormReset); - } - this.input.removeEventListeners(); - }; - Choices.prototype._onKeyDown = function (event) { - var keyCode = event.keyCode; - var activeItems = this._store.activeItems; - var hasFocusedInput = this.input.isFocussed; - var hasActiveDropdown = this.dropdown.isActive; - var hasItems = this.itemList.hasChildren(); - var keyString = String.fromCharCode(keyCode); - // eslint-disable-next-line no-control-regex - var wasPrintableChar = /[^\x00-\x1F]/.test(keyString); - var BACK_KEY = constants_1.KEY_CODES.BACK_KEY, - DELETE_KEY = constants_1.KEY_CODES.DELETE_KEY, - ENTER_KEY = constants_1.KEY_CODES.ENTER_KEY, - A_KEY = constants_1.KEY_CODES.A_KEY, - ESC_KEY = constants_1.KEY_CODES.ESC_KEY, - UP_KEY = constants_1.KEY_CODES.UP_KEY, - DOWN_KEY = constants_1.KEY_CODES.DOWN_KEY, - PAGE_UP_KEY = constants_1.KEY_CODES.PAGE_UP_KEY, - PAGE_DOWN_KEY = constants_1.KEY_CODES.PAGE_DOWN_KEY; - if (!this._isTextElement && !hasActiveDropdown && wasPrintableChar) { - this.showDropdown(); - if (!this.input.isFocussed) { - /* - We update the input value with the pressed key as - the input was not focussed at the time of key press - therefore does not have the value of the key. - */ - this.input.value += event.key.toLowerCase(); + myIndex.setKeys(keys); + myIndex.setIndexRecords(records); + return myIndex; + } + function computeScore$1(pattern, { + errors = 0, + currentLocation = 0, + expectedLocation = 0, + distance = Config.distance, + ignoreLocation = Config.ignoreLocation + } = {}) { + const accuracy = errors / pattern.length; + if (ignoreLocation) { + return accuracy; } + const proximity = Math.abs(expectedLocation - currentLocation); + if (!distance) { + // Dodge divide by zero error. + return proximity ? 1.0 : accuracy; + } + return accuracy + proximity / distance; } - switch (keyCode) { - case A_KEY: - return this._onSelectKey(event, hasItems); - case ENTER_KEY: - return this._onEnterKey(event, activeItems, hasActiveDropdown); - case ESC_KEY: - return this._onEscapeKey(hasActiveDropdown); - case UP_KEY: - case PAGE_UP_KEY: - case DOWN_KEY: - case PAGE_DOWN_KEY: - return this._onDirectionKey(event, hasActiveDropdown); - case DELETE_KEY: - case BACK_KEY: - return this._onDeleteKey(event, activeItems, hasFocusedInput); - default: - } - }; - Choices.prototype._onKeyUp = function (_a) { - var target = _a.target, - keyCode = _a.keyCode; - var value = this.input.value; - var activeItems = this._store.activeItems; - var canAddItem = this._canAddItem(activeItems, value); - var backKey = constants_1.KEY_CODES.BACK_KEY, - deleteKey = constants_1.KEY_CODES.DELETE_KEY; - // We are typing into a text input and have a value, we want to show a dropdown - // notice. Otherwise hide the dropdown - if (this._isTextElement) { - var canShowDropdownNotice = canAddItem.notice && value; - if (canShowDropdownNotice) { - var dropdownItem = this._getTemplate('notice', canAddItem.notice); - this.dropdown.element.innerHTML = dropdownItem.outerHTML; - this.showDropdown(true); - } else { - this.hideDropdown(true); + function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) { + let indices = []; + let start = -1; + let end = -1; + let i = 0; + for (let len = matchmask.length; i < len; i += 1) { + let match = matchmask[i]; + if (match && start === -1) { + start = i; + } else if (!match && start !== -1) { + end = i - 1; + if (end - start + 1 >= minMatchCharLength) { + indices.push([start, end]); + } + start = -1; + } } - } else { - var wasRemovalKeyCode = keyCode === backKey || keyCode === deleteKey; - var userHasRemovedValue = wasRemovalKeyCode && target && !target.value; - var canReactivateChoices = !this._isTextElement && this._isSearching; - var canSearch = this._canSearch && canAddItem.response; - if (userHasRemovedValue && canReactivateChoices) { - this._isSearching = false; - this._store.dispatch((0, choices_1.activateChoices)(true)); - } else if (canSearch) { - this._handleSearch(this.input.rawValue); + + // (i-1 - start) + 1 => i - start + if (matchmask[i - 1] && i - start >= minMatchCharLength) { + indices.push([start, i - 1]); } + return indices; } - this._canSearch = this.config.searchEnabled; - }; - Choices.prototype._onSelectKey = function (event, hasItems) { - var ctrlKey = event.ctrlKey, - metaKey = event.metaKey; - var hasCtrlDownKeyPressed = ctrlKey || metaKey; - // If CTRL + A or CMD + A have been pressed and there are items to select - if (hasCtrlDownKeyPressed && hasItems) { - this._canSearch = false; - var shouldHightlightAll = this.config.removeItems && !this.input.value && this.input.element === document.activeElement; - if (shouldHightlightAll) { - this.highlightAll(); + + // Machine word size + const MAX_BITS = 32; + function search(text, pattern, patternAlphabet, { + location = Config.location, + distance = Config.distance, + threshold = Config.threshold, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + includeMatches = Config.includeMatches, + ignoreLocation = Config.ignoreLocation + } = {}) { + if (pattern.length > MAX_BITS) { + throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS)); } - } - }; - Choices.prototype._onEnterKey = function (event, activeItems, hasActiveDropdown) { - var target = event.target; - var enterKey = constants_1.KEY_CODES.ENTER_KEY; - var targetWasButton = target && target.hasAttribute('data-button'); - if (this._isTextElement && target && target.value) { - var value = this.input.value; - var canAddItem = this._canAddItem(activeItems, value); - if (canAddItem.response) { - this.hideDropdown(true); - this._addItem({ - value: value + const patternLen = pattern.length; + // Set starting location at beginning text and initialize the alphabet. + const textLen = text.length; + // Handle the case when location > text.length + const expectedLocation = Math.max(0, Math.min(location, textLen)); + // Highest score beyond which we give up. + let currentThreshold = threshold; + // Is there a nearby exact match? (speedup) + let bestLocation = expectedLocation; + + // Performance: only computer matches when the minMatchCharLength > 1 + // OR if `includeMatches` is true. + const computeMatches = minMatchCharLength > 1 || includeMatches; + // A mask of the matches, used for building the indices + const matchMask = computeMatches ? Array(textLen) : []; + let index; + + // Get all exact matches, here for speed up + while ((index = text.indexOf(pattern, bestLocation)) > -1) { + let score = computeScore$1(pattern, { + currentLocation: index, + expectedLocation, + distance, + ignoreLocation }); - this._triggerChange(value); - this.clearInput(); - } - } - if (targetWasButton) { - this._handleButtonAction(activeItems, target); - event.preventDefault(); - } - if (hasActiveDropdown) { - var highlightedChoice = this.dropdown.getChild(".".concat(this.config.classNames.highlightedState)); - if (highlightedChoice) { - // add enter keyCode value - if (activeItems[0]) { - activeItems[0].keyCode = enterKey; // eslint-disable-line no-param-reassign + currentThreshold = Math.min(score, currentThreshold); + bestLocation = index + patternLen; + if (computeMatches) { + let i = 0; + while (i < patternLen) { + matchMask[index + i] = 1; + i += 1; + } } - - this._handleChoiceAction(activeItems, highlightedChoice); } - event.preventDefault(); - } else if (this._isSelectOneElement) { - this.showDropdown(); - event.preventDefault(); - } - }; - Choices.prototype._onEscapeKey = function (hasActiveDropdown) { - if (hasActiveDropdown) { - this.hideDropdown(true); - this.containerOuter.focus(); - } - }; - Choices.prototype._onDirectionKey = function (event, hasActiveDropdown) { - var keyCode = event.keyCode, - metaKey = event.metaKey; - var downKey = constants_1.KEY_CODES.DOWN_KEY, - pageUpKey = constants_1.KEY_CODES.PAGE_UP_KEY, - pageDownKey = constants_1.KEY_CODES.PAGE_DOWN_KEY; - // If up or down key is pressed, traverse through options - if (hasActiveDropdown || this._isSelectOneElement) { - this.showDropdown(); - this._canSearch = false; - var directionInt = keyCode === downKey || keyCode === pageDownKey ? 1 : -1; - var skipKey = metaKey || keyCode === pageDownKey || keyCode === pageUpKey; - var selectableChoiceIdentifier = '[data-choice-selectable]'; - var nextEl = void 0; - if (skipKey) { - if (directionInt > 0) { - nextEl = this.dropdown.element.querySelector("".concat(selectableChoiceIdentifier, ":last-of-type")); - } else { - nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); + + // Reset the best location + bestLocation = -1; + let lastBitArr = []; + let finalScore = 1; + let binMax = patternLen + textLen; + const mask = 1 << patternLen - 1; + for (let i = 0; i < patternLen; i += 1) { + // Scan for the best match; each iteration allows for one more error. + // Run a binary search to determine how far from the match location we can stray + // at this error level. + let binMin = 0; + let binMid = binMax; + while (binMin < binMid) { + const score = computeScore$1(pattern, { + errors: i, + currentLocation: expectedLocation + binMid, + expectedLocation, + distance, + ignoreLocation + }); + if (score <= currentThreshold) { + binMin = binMid; + } else { + binMax = binMid; + } + binMid = Math.floor((binMax - binMin) / 2 + binMin); } - } else { - var currentEl = this.dropdown.element.querySelector(".".concat(this.config.classNames.highlightedState)); - if (currentEl) { - nextEl = (0, utils_1.getAdjacentEl)(currentEl, selectableChoiceIdentifier, directionInt); - } else { - nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); + + // Use the result from this iteration as the maximum for the next. + binMax = binMid; + let start = Math.max(1, expectedLocation - binMid + 1); + let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen; + + // Initialize the bit array + let bitArr = Array(finish + 2); + bitArr[finish + 1] = (1 << i) - 1; + for (let j = finish; j >= start; j -= 1) { + let currentLocation = j - 1; + let charMatch = patternAlphabet[text.charAt(currentLocation)]; + if (computeMatches) { + // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`) + matchMask[currentLocation] = +!!charMatch; + } + + // First pass: exact match + bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch; + + // Subsequent passes: fuzzy match + if (i) { + bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1]; + } + if (bitArr[j] & mask) { + finalScore = computeScore$1(pattern, { + errors: i, + currentLocation, + expectedLocation, + distance, + ignoreLocation + }); + + // This match will almost certainly be better than any existing match. + // But check anyway. + if (finalScore <= currentThreshold) { + // Indeed it is + currentThreshold = finalScore; + bestLocation = currentLocation; + + // Already passed `loc`, downhill from here on in. + if (bestLocation <= expectedLocation) { + break; + } + + // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`. + start = Math.max(1, 2 * expectedLocation - bestLocation); + } + } } - } - if (nextEl) { - // We prevent default to stop the cursor moving - // when pressing the arrow - if (!(0, utils_1.isScrolledIntoView)(nextEl, this.choiceList.element, directionInt)) { - this.choiceList.scrollToChildElement(nextEl, directionInt); + + // No hope for a (better) match at greater error levels. + const score = computeScore$1(pattern, { + errors: i + 1, + currentLocation: expectedLocation, + expectedLocation, + distance, + ignoreLocation + }); + if (score > currentThreshold) { + break; } - this._highlightChoice(nextEl); + lastBitArr = bitArr; } - // Prevent default to maintain cursor position whilst - // traversing dropdown options - event.preventDefault(); - } - }; - Choices.prototype._onDeleteKey = function (event, activeItems, hasFocusedInput) { - var target = event.target; - // If backspace or delete key is pressed and the input has no value - if (!this._isSelectOneElement && !target.value && hasFocusedInput) { - this._handleBackspace(activeItems); - event.preventDefault(); - } - }; - Choices.prototype._onTouchMove = function () { - if (this._wasTap) { - this._wasTap = false; - } - }; - Choices.prototype._onTouchEnd = function (event) { - var target = (event || event.touches[0]).target; - var touchWasWithinContainer = this._wasTap && this.containerOuter.element.contains(target); - if (touchWasWithinContainer) { - var containerWasExactTarget = target === this.containerOuter.element || target === this.containerInner.element; - if (containerWasExactTarget) { - if (this._isTextElement) { - this.input.focus(); - } else if (this._isSelectMultipleElement) { - this.showDropdown(); + const result = { + isMatch: bestLocation >= 0, + // Count exact matches (those with a score of 0) to be "almost" exact + score: Math.max(0.001, finalScore) + }; + if (computeMatches) { + const indices = convertMaskToIndices(matchMask, minMatchCharLength); + if (!indices.length) { + result.isMatch = false; + } else if (includeMatches) { + result.indices = indices; } } - // Prevents focus event firing - event.stopPropagation(); - } - this._wasTap = true; - }; - /** - * Handles mousedown event in capture mode for containetOuter.element - */ - Choices.prototype._onMouseDown = function (event) { - var target = event.target; - if (!(target instanceof HTMLElement)) { - return; - } - // If we have our mouse down on the scrollbar and are on IE11... - if (IS_IE11 && this.choiceList.element.contains(target)) { - // check if click was on a scrollbar area - var firstChoice = this.choiceList.element.firstElementChild; - var isOnScrollbar = this._direction === 'ltr' ? event.offsetX >= firstChoice.offsetWidth : event.offsetX < firstChoice.offsetLeft; - this._isScrollingOnIe = isOnScrollbar; - } - if (target === this.input.element) { - return; + return result; } - var item = target.closest('[data-button],[data-item],[data-choice]'); - if (item instanceof HTMLElement) { - var hasShiftKey = event.shiftKey; - var activeItems = this._store.activeItems; - var dataset = item.dataset; - if ('button' in dataset) { - this._handleButtonAction(activeItems, item); - } else if ('item' in dataset) { - this._handleItemAction(activeItems, item, hasShiftKey); - } else if ('choice' in dataset) { - this._handleChoiceAction(activeItems, item); + function createPatternAlphabet(pattern) { + let mask = {}; + for (let i = 0, len = pattern.length; i < len; i += 1) { + const char = pattern.charAt(i); + mask[char] = (mask[char] || 0) | 1 << len - i - 1; } - } - event.preventDefault(); - }; - /** - * Handles mouseover event over this.dropdown - * @param {MouseEvent} event - */ - Choices.prototype._onMouseOver = function (_a) { - var target = _a.target; - if (target instanceof HTMLElement && 'choice' in target.dataset) { - this._highlightChoice(target); - } - }; - Choices.prototype._onClick = function (_a) { - var target = _a.target; - var clickWasWithinContainer = this.containerOuter.element.contains(target); - if (clickWasWithinContainer) { - if (!this.dropdown.isActive && !this.containerOuter.isDisabled) { - if (this._isTextElement) { - if (document.activeElement !== this.input.element) { - this.input.focus(); + return mask; + } + class BitapSearch { + constructor(pattern, { + location = Config.location, + threshold = Config.threshold, + distance = Config.distance, + includeMatches = Config.includeMatches, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + isCaseSensitive = Config.isCaseSensitive, + ignoreLocation = Config.ignoreLocation + } = {}) { + this.options = { + location, + threshold, + distance, + includeMatches, + findAllMatches, + minMatchCharLength, + isCaseSensitive, + ignoreLocation + }; + this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); + this.chunks = []; + if (!this.pattern.length) { + return; + } + const addChunk = (pattern, startIndex) => { + this.chunks.push({ + pattern, + alphabet: createPatternAlphabet(pattern), + startIndex + }); + }; + const len = this.pattern.length; + if (len > MAX_BITS) { + let i = 0; + const remainder = len % MAX_BITS; + const end = len - remainder; + while (i < end) { + addChunk(this.pattern.substr(i, MAX_BITS), i); + i += MAX_BITS; + } + if (remainder) { + const startIndex = len - MAX_BITS; + addChunk(this.pattern.substr(startIndex), startIndex); } } else { - this.showDropdown(); - this.containerOuter.focus(); + addChunk(this.pattern, 0); } - } else if (this._isSelectOneElement && target !== this.input.element && !this.dropdown.element.contains(target)) { - this.hideDropdown(); - } - } else { - var hasHighlightedItems = this._store.highlightedActiveItems.length > 0; - if (hasHighlightedItems) { - this.unhighlightAll(); - } - this.containerOuter.removeFocusState(); - this.hideDropdown(true); - } - }; - Choices.prototype._onFocus = function (_a) { - var _b; - var _this = this; - var target = _a.target; - var focusWasWithinContainer = target && this.containerOuter.element.contains(target); - if (!focusWasWithinContainer) { - return; - } - var focusActions = (_b = {}, _b[constants_1.TEXT_TYPE] = function () { - if (target === _this.input.element) { - _this.containerOuter.addFocusState(); - } - }, _b[constants_1.SELECT_ONE_TYPE] = function () { - _this.containerOuter.addFocusState(); - if (target === _this.input.element) { - _this.showDropdown(true); } - }, _b[constants_1.SELECT_MULTIPLE_TYPE] = function () { - if (target === _this.input.element) { - _this.showDropdown(true); - // If element is a select box, the focused element is the container and the dropdown - // isn't already open, focus and show dropdown - _this.containerOuter.addFocusState(); - } - }, _b); - focusActions[this.passedElement.element.type](); - }; - Choices.prototype._onBlur = function (_a) { - var _b; - var _this = this; - var target = _a.target; - var blurWasWithinContainer = target && this.containerOuter.element.contains(target); - if (blurWasWithinContainer && !this._isScrollingOnIe) { - var activeItems = this._store.activeItems; - var hasHighlightedItems_1 = activeItems.some(function (item) { - return item.highlighted; - }); - var blurActions = (_b = {}, _b[constants_1.TEXT_TYPE] = function () { - if (target === _this.input.element) { - _this.containerOuter.removeFocusState(); - if (hasHighlightedItems_1) { - _this.unhighlightAll(); - } - _this.hideDropdown(true); - } - }, _b[constants_1.SELECT_ONE_TYPE] = function () { - _this.containerOuter.removeFocusState(); - if (target === _this.input.element || target === _this.containerOuter.element && !_this._canSearch) { - _this.hideDropdown(true); + searchIn(text) { + const { + isCaseSensitive, + includeMatches + } = this.options; + if (!isCaseSensitive) { + text = text.toLowerCase(); } - }, _b[constants_1.SELECT_MULTIPLE_TYPE] = function () { - if (target === _this.input.element) { - _this.containerOuter.removeFocusState(); - _this.hideDropdown(true); - if (hasHighlightedItems_1) { - _this.unhighlightAll(); + + // Exact match + if (this.pattern === text) { + let result = { + isMatch: true, + score: 0 + }; + if (includeMatches) { + result.indices = [[0, text.length - 1]]; } + return result; } - }, _b); - blurActions[this.passedElement.element.type](); - } else { - // On IE11, clicking the scollbar blurs our input and thus - // closes the dropdown. To stop this, we refocus our input - // if we know we are on IE *and* are scrolling. - this._isScrollingOnIe = false; - this.input.element.focus(); - } - }; - Choices.prototype._onFormReset = function () { - this._store.dispatch((0, misc_1.resetTo)(this._initialState)); - }; - Choices.prototype._highlightChoice = function (el) { - var _this = this; - if (el === void 0) { - el = null; - } - var choices = Array.from(this.dropdown.element.querySelectorAll('[data-choice-selectable]')); - if (!choices.length) { - return; + + // Otherwise, use Bitap algorithm + const { + location, + distance, + threshold, + findAllMatches, + minMatchCharLength, + ignoreLocation + } = this.options; + let allIndices = []; + let totalScore = 0; + let hasMatches = false; + this.chunks.forEach(({ + pattern, + alphabet, + startIndex + }) => { + const { + isMatch, + score, + indices + } = search(text, pattern, alphabet, { + location: location + startIndex, + distance, + threshold, + findAllMatches, + minMatchCharLength, + includeMatches, + ignoreLocation + }); + if (isMatch) { + hasMatches = true; + } + totalScore += score; + if (isMatch && indices) { + allIndices = [...allIndices, ...indices]; + } + }); + let result = { + isMatch: hasMatches, + score: hasMatches ? totalScore / this.chunks.length : 1 + }; + if (hasMatches && includeMatches) { + result.indices = allIndices; + } + return result; + } } - var passedEl = el; - var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(".".concat(this.config.classNames.highlightedState))); - // Remove any highlighted choices - highlightedChoices.forEach(function (choice) { - choice.classList.remove(_this.config.classNames.highlightedState); - choice.setAttribute('aria-selected', 'false'); - }); - if (passedEl) { - this._highlightPosition = choices.indexOf(passedEl); - } else { - // Highlight choice based on last known highlight location - if (choices.length > this._highlightPosition) { - // If we have an option to highlight - passedEl = choices[this._highlightPosition]; - } else { - // Otherwise highlight the option before - passedEl = choices[choices.length - 1]; + class BaseMatch { + constructor(pattern) { + this.pattern = pattern; + } + static isMultiMatch(pattern) { + return getMatch(pattern, this.multiRegex); } - if (!passedEl) { - passedEl = choices[0]; + static isSingleMatch(pattern) { + return getMatch(pattern, this.singleRegex); } + search( /*text*/) {} } - passedEl.classList.add(this.config.classNames.highlightedState); - passedEl.setAttribute('aria-selected', 'true'); - this.passedElement.triggerEvent(constants_1.EVENTS.highlightChoice, { - el: passedEl - }); - if (this.dropdown.isActive) { - // IE11 ignores aria-label and blocks virtual keyboard - // if aria-activedescendant is set without a dropdown - this.input.setActiveDescendant(passedEl.id); - this.containerOuter.setActiveDescendant(passedEl.id); + function getMatch(pattern, exp) { + const matches = pattern.match(exp); + return matches ? matches[1] : null; } - }; - Choices.prototype._addItem = function (_a) { - var value = _a.value, - _b = _a.label, - label = _b === void 0 ? null : _b, - _c = _a.choiceId, - choiceId = _c === void 0 ? -1 : _c, - _d = _a.groupId, - groupId = _d === void 0 ? -1 : _d, - _e = _a.customProperties, - customProperties = _e === void 0 ? {} : _e, - _f = _a.placeholder, - placeholder = _f === void 0 ? false : _f, - _g = _a.keyCode, - keyCode = _g === void 0 ? -1 : _g; - var passedValue = typeof value === 'string' ? value.trim() : value; - var items = this._store.items; - var passedLabel = label || passedValue; - var passedOptionId = choiceId || -1; - var group = groupId >= 0 ? this._store.getGroupById(groupId) : null; - var id = items ? items.length + 1 : 1; - // If a prepended value has been passed, prepend it - if (this.config.prependValue) { - passedValue = this.config.prependValue + passedValue.toString(); + + // Token: 'file + + class ExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'exact'; + } + static get multiRegex() { + return /^="(.*)"$/; + } + static get singleRegex() { + return /^=(.*)$/; + } + search(text) { + const isMatch = text === this.pattern; + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, this.pattern.length - 1] + }; + } } - // If an appended value has been passed, append it - if (this.config.appendValue) { - passedValue += this.config.appendValue.toString(); + + // Token: !fire + + class InverseExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'inverse-exact'; + } + static get multiRegex() { + return /^!"(.*)"$/; + } + static get singleRegex() { + return /^!(.*)$/; + } + search(text) { + const index = text.indexOf(this.pattern); + const isMatch = index === -1; + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, text.length - 1] + }; + } } - this._store.dispatch((0, items_1.addItem)({ - value: passedValue, - label: passedLabel, - id: id, - choiceId: passedOptionId, - groupId: groupId, - customProperties: customProperties, - placeholder: placeholder, - keyCode: keyCode - })); - if (this._isSelectOneElement) { - this.removeActiveItems(id); + + // Token: ^file + + class PrefixExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'prefix-exact'; + } + static get multiRegex() { + return /^\^"(.*)"$/; + } + static get singleRegex() { + return /^\^(.*)$/; + } + search(text) { + const isMatch = text.startsWith(this.pattern); + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, this.pattern.length - 1] + }; + } } - // Trigger change event - this.passedElement.triggerEvent(constants_1.EVENTS.addItem, { - id: id, - value: passedValue, - label: passedLabel, - customProperties: customProperties, - groupValue: group && group.value ? group.value : null, - keyCode: keyCode - }); - }; - Choices.prototype._removeItem = function (item) { - var id = item.id, - value = item.value, - label = item.label, - customProperties = item.customProperties, - choiceId = item.choiceId, - groupId = item.groupId; - var group = groupId && groupId >= 0 ? this._store.getGroupById(groupId) : null; - if (!id || !choiceId) { - return; + + // Token: !^fire + + class InversePrefixExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'inverse-prefix-exact'; + } + static get multiRegex() { + return /^!\^"(.*)"$/; + } + static get singleRegex() { + return /^!\^(.*)$/; + } + search(text) { + const isMatch = !text.startsWith(this.pattern); + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, text.length - 1] + }; + } } - this._store.dispatch((0, items_1.removeItem)(id, choiceId)); - this.passedElement.triggerEvent(constants_1.EVENTS.removeItem, { - id: id, - value: value, - label: label, - customProperties: customProperties, - groupValue: group && group.value ? group.value : null - }); - }; - Choices.prototype._addChoice = function (_a) { - var value = _a.value, - _b = _a.label, - label = _b === void 0 ? null : _b, - _c = _a.isSelected, - isSelected = _c === void 0 ? false : _c, - _d = _a.isDisabled, - isDisabled = _d === void 0 ? false : _d, - _e = _a.groupId, - groupId = _e === void 0 ? -1 : _e, - _f = _a.customProperties, - customProperties = _f === void 0 ? {} : _f, - _g = _a.placeholder, - placeholder = _g === void 0 ? false : _g, - _h = _a.keyCode, - keyCode = _h === void 0 ? -1 : _h; - if (typeof value === 'undefined' || value === null) { - return; + + // Token: .file$ + + class SuffixExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'suffix-exact'; + } + static get multiRegex() { + return /^"(.*)"\$$/; + } + static get singleRegex() { + return /^(.*)\$$/; + } + search(text) { + const isMatch = text.endsWith(this.pattern); + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [text.length - this.pattern.length, text.length - 1] + }; + } } - // Generate unique id - var choices = this._store.choices; - var choiceLabel = label || value; - var choiceId = choices ? choices.length + 1 : 1; - var choiceElementId = "".concat(this._baseId, "-").concat(this._idNames.itemChoice, "-").concat(choiceId); - this._store.dispatch((0, choices_1.addChoice)({ - id: choiceId, - groupId: groupId, - elementId: choiceElementId, - value: value, - label: choiceLabel, - disabled: isDisabled, - customProperties: customProperties, - placeholder: placeholder, - keyCode: keyCode - })); - if (isSelected) { - this._addItem({ - value: value, - label: choiceLabel, - choiceId: choiceId, - customProperties: customProperties, - placeholder: placeholder, - keyCode: keyCode - }); + + // Token: !.file$ + + class InverseSuffixExactMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'inverse-suffix-exact'; + } + static get multiRegex() { + return /^!"(.*)"\$$/; + } + static get singleRegex() { + return /^!(.*)\$$/; + } + search(text) { + const isMatch = !text.endsWith(this.pattern); + return { + isMatch, + score: isMatch ? 0 : 1, + indices: [0, text.length - 1] + }; + } } - }; - Choices.prototype._addGroup = function (_a) { - var _this = this; - var group = _a.group, - id = _a.id, - _b = _a.valueKey, - valueKey = _b === void 0 ? 'value' : _b, - _c = _a.labelKey, - labelKey = _c === void 0 ? 'label' : _c; - var groupChoices = (0, utils_1.isType)('Object', group) ? group.choices : Array.from(group.getElementsByTagName('OPTION')); - var groupId = id || Math.floor(new Date().valueOf() * Math.random()); - var isDisabled = group.disabled ? group.disabled : false; - if (groupChoices) { - this._store.dispatch((0, groups_1.addGroup)({ - value: group.label, - id: groupId, - active: true, - disabled: isDisabled - })); - var addGroupChoices = function (choice) { - var isOptDisabled = choice.disabled || choice.parentNode && choice.parentNode.disabled; - _this._addChoice({ - value: choice[valueKey], - label: (0, utils_1.isType)('Object', choice) ? choice[labelKey] : choice.innerHTML, - isSelected: choice.selected, - isDisabled: isOptDisabled, - groupId: groupId, - customProperties: choice.customProperties, - placeholder: choice.placeholder + class FuzzyMatch extends BaseMatch { + constructor(pattern, { + location = Config.location, + threshold = Config.threshold, + distance = Config.distance, + includeMatches = Config.includeMatches, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + isCaseSensitive = Config.isCaseSensitive, + ignoreLocation = Config.ignoreLocation + } = {}) { + super(pattern); + this._bitapSearch = new BitapSearch(pattern, { + location, + threshold, + distance, + includeMatches, + findAllMatches, + minMatchCharLength, + isCaseSensitive, + ignoreLocation }); - }; - groupChoices.forEach(addGroupChoices); - } else { - this._store.dispatch((0, groups_1.addGroup)({ - value: group.label, - id: group.id, - active: false, - disabled: group.disabled - })); - } - }; - Choices.prototype._getTemplate = function (template) { - var _a; - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; + } + static get type() { + return 'fuzzy'; + } + static get multiRegex() { + return /^"(.*)"$/; + } + static get singleRegex() { + return /^(.*)$/; + } + search(text) { + return this._bitapSearch.searchIn(text); + } } - return (_a = this._templates[template]).call.apply(_a, __spreadArray([this, this.config], args, false)); - }; - Choices.prototype._createTemplates = function () { - var callbackOnCreateTemplates = this.config.callbackOnCreateTemplates; - var userTemplates = {}; - if (callbackOnCreateTemplates && typeof callbackOnCreateTemplates === 'function') { - userTemplates = callbackOnCreateTemplates.call(this, utils_1.strToEl); + + // Token: 'file + + class IncludeMatch extends BaseMatch { + constructor(pattern) { + super(pattern); + } + static get type() { + return 'include'; + } + static get multiRegex() { + return /^'"(.*)"$/; + } + static get singleRegex() { + return /^'(.*)$/; + } + search(text) { + let location = 0; + let index; + const indices = []; + const patternLen = this.pattern.length; + + // Get all exact matches + while ((index = text.indexOf(this.pattern, location)) > -1) { + location = index + patternLen; + indices.push([index, location - 1]); + } + const isMatch = !!indices.length; + return { + isMatch, + score: isMatch ? 0 : 1, + indices + }; + } } - this._templates = (0, deepmerge_1.default)(templates_1.default, userTemplates); - }; - Choices.prototype._createElements = function () { - this.containerOuter = new components_1.Container({ - element: this._getTemplate('containerOuter', this._direction, this._isSelectElement, this._isSelectOneElement, this.config.searchEnabled, this.passedElement.element.type, this.config.labelId), - classNames: this.config.classNames, - type: this.passedElement.element.type, - position: this.config.position - }); - this.containerInner = new components_1.Container({ - element: this._getTemplate('containerInner'), - classNames: this.config.classNames, - type: this.passedElement.element.type, - position: this.config.position - }); - this.input = new components_1.Input({ - element: this._getTemplate('input', this._placeholderValue), - classNames: this.config.classNames, - type: this.passedElement.element.type, - preventPaste: !this.config.paste - }); - this.choiceList = new components_1.List({ - element: this._getTemplate('choiceList', this._isSelectOneElement) - }); - this.itemList = new components_1.List({ - element: this._getTemplate('itemList', this._isSelectOneElement) - }); - this.dropdown = new components_1.Dropdown({ - element: this._getTemplate('dropdown'), - classNames: this.config.classNames, - type: this.passedElement.element.type - }); - }; - Choices.prototype._createStructure = function () { - // Hide original element - this.passedElement.conceal(); - // Wrap input in container preserving DOM ordering - this.containerInner.wrap(this.passedElement.element); - // Wrapper inner container with outer container - this.containerOuter.wrap(this.containerInner.element); - if (this._isSelectOneElement) { - this.input.placeholder = this.config.searchPlaceholderValue || ''; - } else if (this._placeholderValue) { - this.input.placeholder = this._placeholderValue; - this.input.setWidth(); + + // ❗Order is important. DO NOT CHANGE. + const searchers = [ExactMatch, IncludeMatch, PrefixExactMatch, InversePrefixExactMatch, InverseSuffixExactMatch, SuffixExactMatch, InverseExactMatch, FuzzyMatch]; + const searchersLen = searchers.length; + + // Regex to split by spaces, but keep anything in quotes together + const SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/; + const OR_TOKEN = '|'; + + // Return a 2D array representation of the query, for simpler parsing. + // Example: + // "^core go$ | rb$ | py$ xy$" => [["^core", "go$"], ["rb$"], ["py$", "xy$"]] + function parseQuery(pattern, options = {}) { + return pattern.split(OR_TOKEN).map(item => { + let query = item.trim().split(SPACE_RE).filter(item => item && !!item.trim()); + let results = []; + for (let i = 0, len = query.length; i < len; i += 1) { + const queryItem = query[i]; + + // 1. Handle multiple query match (i.e, once that are quoted, like `"hello world"`) + let found = false; + let idx = -1; + while (!found && ++idx < searchersLen) { + const searcher = searchers[idx]; + let token = searcher.isMultiMatch(queryItem); + if (token) { + results.push(new searcher(token, options)); + found = true; + } + } + if (found) { + continue; + } + + // 2. Handle single query matches (i.e, once that are *not* quoted) + idx = -1; + while (++idx < searchersLen) { + const searcher = searchers[idx]; + let token = searcher.isSingleMatch(queryItem); + if (token) { + results.push(new searcher(token, options)); + break; + } + } + } + return results; + }); } - this.containerOuter.element.appendChild(this.containerInner.element); - this.containerOuter.element.appendChild(this.dropdown.element); - this.containerInner.element.appendChild(this.itemList.element); - if (!this._isTextElement) { - this.dropdown.element.appendChild(this.choiceList.element); + + // These extended matchers can return an array of matches, as opposed + // to a singl match + const MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]); + + /** + * Command-like searching + * ====================== + * + * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`, + * search in a given text. + * + * Search syntax: + * + * | Token | Match type | Description | + * | ----------- | -------------------------- | -------------------------------------- | + * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` | + * | `=scheme` | exact-match | Items that are `scheme` | + * | `'python` | include-match | Items that include `python` | + * | `!ruby` | inverse-exact-match | Items that do not include `ruby` | + * | `^java` | prefix-exact-match | Items that start with `java` | + * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` | + * | `.js$` | suffix-exact-match | Items that end with `.js` | + * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` | + * + * A single pipe character acts as an OR operator. For example, the following + * query matches entries that start with `core` and end with either`go`, `rb`, + * or`py`. + * + * ``` + * ^core go$ | rb$ | py$ + * ``` + */ + class ExtendedSearch { + constructor(pattern, { + isCaseSensitive = Config.isCaseSensitive, + includeMatches = Config.includeMatches, + minMatchCharLength = Config.minMatchCharLength, + ignoreLocation = Config.ignoreLocation, + findAllMatches = Config.findAllMatches, + location = Config.location, + threshold = Config.threshold, + distance = Config.distance + } = {}) { + this.query = null; + this.options = { + isCaseSensitive, + includeMatches, + minMatchCharLength, + findAllMatches, + ignoreLocation, + location, + threshold, + distance + }; + this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); + this.query = parseQuery(this.pattern, this.options); + } + static condition(_, options) { + return options.useExtendedSearch; + } + searchIn(text) { + const query = this.query; + if (!query) { + return { + isMatch: false, + score: 1 + }; + } + const { + includeMatches, + isCaseSensitive + } = this.options; + text = isCaseSensitive ? text : text.toLowerCase(); + let numMatches = 0; + let allIndices = []; + let totalScore = 0; + + // ORs + for (let i = 0, qLen = query.length; i < qLen; i += 1) { + const searchers = query[i]; + + // Reset indices + allIndices.length = 0; + numMatches = 0; + + // ANDs + for (let j = 0, pLen = searchers.length; j < pLen; j += 1) { + const searcher = searchers[j]; + const { + isMatch, + indices, + score + } = searcher.search(text); + if (isMatch) { + numMatches += 1; + totalScore += score; + if (includeMatches) { + const type = searcher.constructor.type; + if (MultiMatchSet.has(type)) { + allIndices = [...allIndices, ...indices]; + } else { + allIndices.push(indices); + } + } + } else { + totalScore = 0; + numMatches = 0; + allIndices.length = 0; + break; + } + } + + // OR condition, so if TRUE, return + if (numMatches) { + let result = { + isMatch: true, + score: totalScore / numMatches + }; + if (includeMatches) { + result.indices = allIndices; + } + return result; + } + } + + // Nothing was matched + return { + isMatch: false, + score: 1 + }; + } } - if (!this._isSelectOneElement) { - this.containerInner.element.appendChild(this.input.element); - } else if (this.config.searchEnabled) { - this.dropdown.element.insertBefore(this.input.element, this.dropdown.element.firstChild); + const registeredSearchers = []; + function register(...args) { + registeredSearchers.push(...args); } - if (this._isSelectElement) { - this._highlightPosition = 0; - this._isSearching = false; - this._startLoading(); - if (this._presetGroups.length) { - this._addPredefinedGroups(this._presetGroups); - } else { - this._addPredefinedChoices(this._presetChoices); + function createSearcher(pattern, options) { + for (let i = 0, len = registeredSearchers.length; i < len; i += 1) { + let searcherClass = registeredSearchers[i]; + if (searcherClass.condition(pattern, options)) { + return new searcherClass(pattern, options); + } } - this._stopLoading(); - } - if (this._isTextElement) { - this._addPredefinedItems(this._presetItems); + return new BitapSearch(pattern, options); } - }; - Choices.prototype._addPredefinedGroups = function (groups) { - var _this = this; - // If we have a placeholder option - var placeholderChoice = this.passedElement.placeholderOption; - if (placeholderChoice && placeholderChoice.parentNode && placeholderChoice.parentNode.tagName === 'SELECT') { - this._addChoice({ - value: placeholderChoice.value, - label: placeholderChoice.innerHTML, - isSelected: placeholderChoice.selected, - isDisabled: placeholderChoice.disabled, - placeholder: true + const LogicalOperator = { + AND: '$and', + OR: '$or' + }; + const KeyType = { + PATH: '$path', + PATTERN: '$val' + }; + const isExpression = query => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]); + const isPath = query => !!query[KeyType.PATH]; + const isLeaf = query => !isArray(query) && isObject(query) && !isExpression(query); + const convertToExplicit = query => ({ + [LogicalOperator.AND]: Object.keys(query).map(key => ({ + [key]: query[key] + })) + }); + + // When `auto` is `true`, the parse function will infer and initialize and add + // the appropriate `Searcher` instance + function parse(query, options, { + auto = true + } = {}) { + const next = query => { + let keys = Object.keys(query); + const isQueryPath = isPath(query); + if (!isQueryPath && keys.length > 1 && !isExpression(query)) { + return next(convertToExplicit(query)); + } + if (isLeaf(query)) { + const key = isQueryPath ? query[KeyType.PATH] : keys[0]; + const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key]; + if (!isString(pattern)) { + throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key)); + } + const obj = { + keyId: createKeyId(key), + pattern + }; + if (auto) { + obj.searcher = createSearcher(pattern, options); + } + return obj; + } + let node = { + children: [], + operator: keys[0] + }; + keys.forEach(key => { + const value = query[key]; + if (isArray(value)) { + value.forEach(item => { + node.children.push(next(item)); + }); + } + }); + return node; + }; + if (!isExpression(query)) { + query = convertToExplicit(query); + } + return next(query); + } + + // Practical scoring function + function computeScore(results, { + ignoreFieldNorm = Config.ignoreFieldNorm + }) { + results.forEach(result => { + let totalScore = 1; + result.matches.forEach(({ + key, + norm, + score + }) => { + const weight = key ? key.weight : null; + totalScore *= Math.pow(score === 0 && weight ? Number.EPSILON : score, (weight || 1) * (ignoreFieldNorm ? 1 : norm)); + }); + result.score = totalScore; }); } - groups.forEach(function (group) { - return _this._addGroup({ - group: group, - id: group.id || null + function transformMatches(result, data) { + const matches = result.matches; + data.matches = []; + if (!isDefined(matches)) { + return; + } + matches.forEach(match => { + if (!isDefined(match.indices) || !match.indices.length) { + return; + } + const { + indices, + value + } = match; + let obj = { + indices, + value + }; + if (match.key) { + obj.key = match.key.src; + } + if (match.idx > -1) { + obj.refIndex = match.idx; + } + data.matches.push(obj); }); - }); - }; - Choices.prototype._addPredefinedChoices = function (choices) { - var _this = this; - // If sorting is enabled or the user is searching, filter choices - if (this.config.shouldSort) { - choices.sort(this.config.sorter); } - var hasSelectedChoice = choices.some(function (choice) { - return choice.selected; - }); - var firstEnabledChoiceIndex = choices.findIndex(function (choice) { - return choice.disabled === undefined || !choice.disabled; - }); - choices.forEach(function (choice, index) { - var _a = choice.value, - value = _a === void 0 ? '' : _a, - label = choice.label, - customProperties = choice.customProperties, - placeholder = choice.placeholder; - if (_this._isSelectElement) { - // If the choice is actually a group - if (choice.choices) { - _this._addGroup({ - group: choice, - id: choice.id || null - }); - } else { - /** - * If there is a selected choice already or the choice is not the first in - * the array, add each choice normally. - * - * Otherwise we pre-select the first enabled choice in the array ("select-one" only) - */ - var shouldPreselect = _this._isSelectOneElement && !hasSelectedChoice && index === firstEnabledChoiceIndex; - var isSelected = shouldPreselect ? true : choice.selected; - var isDisabled = choice.disabled; - _this._addChoice({ - value: value, - label: label, - isSelected: !!isSelected, - isDisabled: !!isDisabled, - placeholder: !!placeholder, - customProperties: customProperties + function transformScore(result, data) { + data.score = result.score; + } + function format(results, docs, { + includeMatches = Config.includeMatches, + includeScore = Config.includeScore + } = {}) { + const transformers = []; + if (includeMatches) transformers.push(transformMatches); + if (includeScore) transformers.push(transformScore); + return results.map(result => { + const { + idx + } = result; + const data = { + item: docs[idx], + refIndex: idx + }; + if (transformers.length) { + transformers.forEach(transformer => { + transformer(result, data); }); } - } else { - _this._addChoice({ - value: value, - label: label, - isSelected: !!choice.selected, - isDisabled: !!choice.disabled, - placeholder: !!choice.placeholder, - customProperties: customProperties + return data; + }); + } + class Fuse { + constructor(docs, options = {}, index) { + this.options = _objectSpread2(_objectSpread2({}, Config), options); + if (this.options.useExtendedSearch && !true) { + throw new Error(EXTENDED_SEARCH_UNAVAILABLE); + } + this._keyStore = new KeyStore(this.options.keys); + this.setCollection(docs, index); + } + setCollection(docs, index) { + this._docs = docs; + if (index && !(index instanceof FuseIndex)) { + throw new Error(INCORRECT_INDEX_TYPE); + } + this._myIndex = index || createIndex(this.options.keys, this._docs, { + getFn: this.options.getFn, + fieldNormWeight: this.options.fieldNormWeight }); } - }); - }; - Choices.prototype._addPredefinedItems = function (items) { - var _this = this; - items.forEach(function (item) { - if (typeof item === 'object' && item.value) { - _this._addItem({ - value: item.value, - label: item.label, - choiceId: item.id, - customProperties: item.customProperties, - placeholder: item.placeholder + add(doc) { + if (!isDefined(doc)) { + return; + } + this._docs.push(doc); + this._myIndex.add(doc); + } + remove(predicate = ( /* doc, idx */) => false) { + const results = []; + for (let i = 0, len = this._docs.length; i < len; i += 1) { + const doc = this._docs[i]; + if (predicate(doc, i)) { + this.removeAt(i); + i -= 1; + len -= 1; + results.push(doc); + } + } + return results; + } + removeAt(idx) { + this._docs.splice(idx, 1); + this._myIndex.removeAt(idx); + } + getIndex() { + return this._myIndex; + } + search(query, { + limit = -1 + } = {}) { + const { + includeMatches, + includeScore, + shouldSort, + sortFn, + ignoreFieldNorm + } = this.options; + let results = isString(query) ? isString(this._docs[0]) ? this._searchStringList(query) : this._searchObjectList(query) : this._searchLogical(query); + computeScore(results, { + ignoreFieldNorm + }); + if (shouldSort) { + results.sort(sortFn); + } + if (isNumber(limit) && limit > -1) { + results = results.slice(0, limit); + } + return format(results, this._docs, { + includeMatches, + includeScore }); } - if (typeof item === 'string') { - _this._addItem({ - value: item + _searchStringList(query) { + const searcher = createSearcher(query, this.options); + const { + records + } = this._myIndex; + const results = []; + + // Iterate over every string in the index + records.forEach(({ + v: text, + i: idx, + n: norm + }) => { + if (!isDefined(text)) { + return; + } + const { + isMatch, + score, + indices + } = searcher.searchIn(text); + if (isMatch) { + results.push({ + item: text, + idx, + matches: [{ + score, + value: text, + norm, + indices + }] + }); + } }); + return results; } - }); - }; - Choices.prototype._setChoiceOrItem = function (item) { - var _this = this; - var itemType = (0, utils_1.getType)(item).toLowerCase(); - var handleType = { - object: function () { - if (!item.value) { - return; - } - // If we are dealing with a select input, we need to create an option first - // that is then selected. For text inputs we can just add items normally. - if (!_this._isTextElement) { - _this._addChoice({ - value: item.value, - label: item.label, - isSelected: true, - isDisabled: false, - customProperties: item.customProperties, - placeholder: item.placeholder - }); - } else { - _this._addItem({ - value: item.value, - label: item.label, - choiceId: item.id, - customProperties: item.customProperties, - placeholder: item.placeholder + _searchLogical(query) { + const expression = parse(query, this.options); + const evaluate = (node, item, idx) => { + if (!node.children) { + const { + keyId, + searcher + } = node; + const matches = this._findMatches({ + key: this._keyStore.get(keyId), + value: this._myIndex.getValueForItemAtKeyId(item, keyId), + searcher + }); + if (matches && matches.length) { + return [{ + idx, + item, + matches + }]; + } + return []; + } + const res = []; + for (let i = 0, len = node.children.length; i < len; i += 1) { + const child = node.children[i]; + const result = evaluate(child, item, idx); + if (result.length) { + res.push(...result); + } else if (node.operator === LogicalOperator.AND) { + return []; + } + } + return res; + }; + const records = this._myIndex.records; + const resultMap = {}; + const results = []; + records.forEach(({ + $: item, + i: idx + }) => { + if (isDefined(item)) { + let expResults = evaluate(expression, item, idx); + if (expResults.length) { + // Dedupe when adding + if (!resultMap[idx]) { + resultMap[idx] = { + idx, + item, + matches: [] + }; + results.push(resultMap[idx]); + } + expResults.forEach(({ + matches + }) => { + resultMap[idx].matches.push(...matches); + }); + } + } + }); + return results; + } + _searchObjectList(query) { + const searcher = createSearcher(query, this.options); + const { + keys, + records + } = this._myIndex; + const results = []; + + // List is Array + records.forEach(({ + $: item, + i: idx + }) => { + if (!isDefined(item)) { + return; + } + let matches = []; + + // Iterate over every key (i.e, path), and fetch the value at that key + keys.forEach((key, keyIndex) => { + matches.push(...this._findMatches({ + key, + value: item[keyIndex], + searcher + })); }); + if (matches.length) { + results.push({ + idx, + item, + matches + }); + } + }); + return results; + } + _findMatches({ + key, + value, + searcher + }) { + if (!isDefined(value)) { + return []; } - }, - string: function () { - if (!_this._isTextElement) { - _this._addChoice({ - value: item, - label: item, - isSelected: true, - isDisabled: false + let matches = []; + if (isArray(value)) { + value.forEach(({ + v: text, + i: idx, + n: norm + }) => { + if (!isDefined(text)) { + return; + } + const { + isMatch, + score, + indices + } = searcher.searchIn(text); + if (isMatch) { + matches.push({ + score, + key, + value: text, + idx, + norm, + indices + }); + } }); } else { - _this._addItem({ - value: item - }); + const { + v: text, + n: norm + } = value; + const { + isMatch, + score, + indices + } = searcher.searchIn(text); + if (isMatch) { + matches.push({ + score, + key, + value: text, + norm, + indices + }); + } } + return matches; } - }; - handleType[itemType](); - }; - Choices.prototype._findAndSelectChoiceByValue = function (value) { - var _this = this; - var choices = this._store.choices; - // Check 'value' property exists and the choice isn't already selected - var foundChoice = choices.find(function (choice) { - return _this.config.valueComparer(choice.value, value); - }); - if (foundChoice && !foundChoice.selected) { - this._addItem({ - value: foundChoice.value, - label: foundChoice.label, - choiceId: foundChoice.id, - groupId: foundChoice.groupId, - customProperties: foundChoice.customProperties, - placeholder: foundChoice.placeholder, - keyCode: foundChoice.keyCode - }); } - }; - Choices.prototype._generatePlaceholderValue = function () { - if (this._isSelectElement && this.passedElement.placeholderOption) { - var placeholderOption = this.passedElement.placeholderOption; - return placeholderOption ? placeholderOption.text : null; + Fuse.version = '7.0.0'; + Fuse.createIndex = createIndex; + Fuse.parseIndex = parseIndex; + Fuse.config = Config; + { + Fuse.parseQuery = parse; } - var _a = this.config, - placeholder = _a.placeholder, - placeholderValue = _a.placeholderValue; - var dataset = this.passedElement.element.dataset; - if (placeholder) { - if (placeholderValue) { - return placeholderValue; - } - if (dataset.placeholder) { - return dataset.placeholder; - } + { + register(ExtendedSearch); } - return null; - }; - return Choices; -}(); -exports["default"] = Choices; - -/***/ }), - -/***/ 613: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - + var SearchByFuse = /** @class */ (function () { + function SearchByFuse(config) { + this._haystack = []; + this._fuseOptions = __assign(__assign({}, config.fuseOptions), { keys: __spreadArray([], config.searchFields, true), includeMatches: true }); + } + SearchByFuse.prototype.index = function (data) { + this._haystack = data; + if (this._fuse) { + this._fuse.setCollection(data); + } + }; + SearchByFuse.prototype.reset = function () { + this._haystack = []; + this._fuse = undefined; + }; + SearchByFuse.prototype.isEmptyIndex = function () { + return !this._haystack.length; + }; + SearchByFuse.prototype.search = function (needle) { + if (!this._fuse) { + { + this._fuse = new Fuse(this._haystack, this._fuseOptions); + } + } + var results = this._fuse.search(needle); + return results.map(function (value, i) { + return { + item: value.item, + score: value.score || 0, + rank: i + 1, // If value.score is used for sorting, this can create non-stable sorts! + }; + }); + }; + return SearchByFuse; + }()); -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var utils_1 = __webpack_require__(799); -var constants_1 = __webpack_require__(883); -var Container = /** @class */function () { - function Container(_a) { - var element = _a.element, - type = _a.type, - classNames = _a.classNames, - position = _a.position; - this.element = element; - this.classNames = classNames; - this.type = type; - this.position = position; - this.isOpen = false; - this.isFlipped = false; - this.isFocussed = false; - this.isDisabled = false; - this.isLoading = false; - this._onFocus = this._onFocus.bind(this); - this._onBlur = this._onBlur.bind(this); - } - Container.prototype.addEventListeners = function () { - this.element.addEventListener('focus', this._onFocus); - this.element.addEventListener('blur', this._onBlur); - }; - Container.prototype.removeEventListeners = function () { - this.element.removeEventListener('focus', this._onFocus); - this.element.removeEventListener('blur', this._onBlur); - }; - /** - * Determine whether container should be flipped based on passed - * dropdown position - */ - Container.prototype.shouldFlip = function (dropdownPos) { - if (typeof dropdownPos !== 'number') { - return false; - } - // If flip is enabled and the dropdown bottom position is - // greater than the window height flip the dropdown. - var shouldFlip = false; - if (this.position === 'auto') { - shouldFlip = !window.matchMedia("(min-height: ".concat(dropdownPos + 1, "px)")).matches; - } else if (this.position === 'top') { - shouldFlip = true; - } - return shouldFlip; - }; - Container.prototype.setActiveDescendant = function (activeDescendantID) { - this.element.setAttribute('aria-activedescendant', activeDescendantID); - }; - Container.prototype.removeActiveDescendant = function () { - this.element.removeAttribute('aria-activedescendant'); - }; - Container.prototype.open = function (dropdownPos) { - this.element.classList.add(this.classNames.openState); - this.element.setAttribute('aria-expanded', 'true'); - this.isOpen = true; - if (this.shouldFlip(dropdownPos)) { - this.element.classList.add(this.classNames.flippedState); - this.isFlipped = true; - } - }; - Container.prototype.close = function () { - this.element.classList.remove(this.classNames.openState); - this.element.setAttribute('aria-expanded', 'false'); - this.removeActiveDescendant(); - this.isOpen = false; - // A dropdown flips if it does not have space within the page - if (this.isFlipped) { - this.element.classList.remove(this.classNames.flippedState); - this.isFlipped = false; - } - }; - Container.prototype.focus = function () { - if (!this.isFocussed) { - this.element.focus(); - } - }; - Container.prototype.addFocusState = function () { - this.element.classList.add(this.classNames.focusState); - }; - Container.prototype.removeFocusState = function () { - this.element.classList.remove(this.classNames.focusState); - }; - Container.prototype.enable = function () { - this.element.classList.remove(this.classNames.disabledState); - this.element.removeAttribute('aria-disabled'); - if (this.type === constants_1.SELECT_ONE_TYPE) { - this.element.setAttribute('tabindex', '0'); - } - this.isDisabled = false; - }; - Container.prototype.disable = function () { - this.element.classList.add(this.classNames.disabledState); - this.element.setAttribute('aria-disabled', 'true'); - if (this.type === constants_1.SELECT_ONE_TYPE) { - this.element.setAttribute('tabindex', '-1'); - } - this.isDisabled = true; - }; - Container.prototype.wrap = function (element) { - (0, utils_1.wrap)(element, this.element); - }; - Container.prototype.unwrap = function (element) { - if (this.element.parentNode) { - // Move passed element outside this element - this.element.parentNode.insertBefore(element, this.element); - // Remove this element - this.element.parentNode.removeChild(this.element); + function getSearcher(config) { + { + return new SearchByFuse(config); + } } - }; - Container.prototype.addLoadingState = function () { - this.element.classList.add(this.classNames.loadingState); - this.element.setAttribute('aria-busy', 'true'); - this.isLoading = true; - }; - Container.prototype.removeLoadingState = function () { - this.element.classList.remove(this.classNames.loadingState); - this.element.removeAttribute('aria-busy'); - this.isLoading = false; - }; - Container.prototype._onFocus = function () { - this.isFocussed = true; - }; - Container.prototype._onBlur = function () { - this.isFocussed = false; - }; - return Container; -}(); -exports["default"] = Container; - -/***/ }), - -/***/ 217: -/***/ (function(__unused_webpack_module, exports) { - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var Dropdown = /** @class */function () { - function Dropdown(_a) { - var element = _a.element, - type = _a.type, - classNames = _a.classNames; - this.element = element; - this.classNames = classNames; - this.type = type; - this.isActive = false; - } - Object.defineProperty(Dropdown.prototype, "distanceFromTopWindow", { /** - * Bottom position of dropdown in viewport coordinates + * Helpers to create HTML elements used by Choices + * Can be overridden by providing `callbackOnCreateTemplates` option. + * `Choices.defaults.templates` allows access to the default template methods from `callbackOnCreateTemplates` */ - get: function () { - return this.element.getBoundingClientRect().bottom; - }, - enumerable: false, - configurable: true - }); - Dropdown.prototype.getChild = function (selector) { - return this.element.querySelector(selector); - }; - /** - * Show dropdown to user by adding active state class - */ - Dropdown.prototype.show = function () { - this.element.classList.add(this.classNames.activeState); - this.element.setAttribute('aria-expanded', 'true'); - this.isActive = true; - return this; - }; - /** - * Hide dropdown from user - */ - Dropdown.prototype.hide = function () { - this.element.classList.remove(this.classNames.activeState); - this.element.setAttribute('aria-expanded', 'false'); - this.isActive = false; - return this; - }; - return Dropdown; -}(); -exports["default"] = Dropdown; - -/***/ }), - -/***/ 520: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -var __importDefault = this && this.__importDefault || function (mod) { - return mod && mod.__esModule ? mod : { - "default": mod - }; -}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.WrappedSelect = exports.WrappedInput = exports.List = exports.Input = exports.Container = exports.Dropdown = void 0; -var dropdown_1 = __importDefault(__webpack_require__(217)); -exports.Dropdown = dropdown_1.default; -var container_1 = __importDefault(__webpack_require__(613)); -exports.Container = container_1.default; -var input_1 = __importDefault(__webpack_require__(11)); -exports.Input = input_1.default; -var list_1 = __importDefault(__webpack_require__(624)); -exports.List = list_1.default; -var wrapped_input_1 = __importDefault(__webpack_require__(541)); -exports.WrappedInput = wrapped_input_1.default; -var wrapped_select_1 = __importDefault(__webpack_require__(982)); -exports.WrappedSelect = wrapped_select_1.default; - -/***/ }), - -/***/ 11: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var utils_1 = __webpack_require__(799); -var constants_1 = __webpack_require__(883); -var Input = /** @class */function () { - function Input(_a) { - var element = _a.element, - type = _a.type, - classNames = _a.classNames, - preventPaste = _a.preventPaste; - this.element = element; - this.type = type; - this.classNames = classNames; - this.preventPaste = preventPaste; - this.isFocussed = this.element.isEqualNode(document.activeElement); - this.isDisabled = element.disabled; - this._onPaste = this._onPaste.bind(this); - this._onInput = this._onInput.bind(this); - this._onFocus = this._onFocus.bind(this); - this._onBlur = this._onBlur.bind(this); - } - Object.defineProperty(Input.prototype, "placeholder", { - set: function (placeholder) { - this.element.placeholder = placeholder; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Input.prototype, "value", { - get: function () { - return (0, utils_1.sanitise)(this.element.value); - }, - set: function (value) { - this.element.value = value; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Input.prototype, "rawValue", { - get: function () { - return this.element.value; - }, - enumerable: false, - configurable: true - }); - Input.prototype.addEventListeners = function () { - this.element.addEventListener('paste', this._onPaste); - this.element.addEventListener('input', this._onInput, { - passive: true - }); - this.element.addEventListener('focus', this._onFocus, { - passive: true - }); - this.element.addEventListener('blur', this._onBlur, { - passive: true - }); - }; - Input.prototype.removeEventListeners = function () { - this.element.removeEventListener('input', this._onInput); - this.element.removeEventListener('paste', this._onPaste); - this.element.removeEventListener('focus', this._onFocus); - this.element.removeEventListener('blur', this._onBlur); - }; - Input.prototype.enable = function () { - this.element.removeAttribute('disabled'); - this.isDisabled = false; - }; - Input.prototype.disable = function () { - this.element.setAttribute('disabled', ''); - this.isDisabled = true; - }; - Input.prototype.focus = function () { - if (!this.isFocussed) { - this.element.focus(); - } - }; - Input.prototype.blur = function () { - if (this.isFocussed) { - this.element.blur(); - } - }; - Input.prototype.clear = function (setWidth) { - if (setWidth === void 0) { - setWidth = true; - } - if (this.element.value) { - this.element.value = ''; - } - if (setWidth) { - this.setWidth(); - } - return this; - }; - /** - * Set the correct input width based on placeholder - * value or input value - */ - Input.prototype.setWidth = function () { - // Resize input to contents or placeholder - var _a = this.element, - style = _a.style, - value = _a.value, - placeholder = _a.placeholder; - style.minWidth = "".concat(placeholder.length + 1, "ch"); - style.width = "".concat(value.length + 1, "ch"); - }; - Input.prototype.setActiveDescendant = function (activeDescendantID) { - this.element.setAttribute('aria-activedescendant', activeDescendantID); - }; - Input.prototype.removeActiveDescendant = function () { - this.element.removeAttribute('aria-activedescendant'); - }; - Input.prototype._onInput = function () { - if (this.type !== constants_1.SELECT_ONE_TYPE) { - this.setWidth(); - } - }; - Input.prototype._onPaste = function (event) { - if (this.preventPaste) { - event.preventDefault(); - } - }; - Input.prototype._onFocus = function () { - this.isFocussed = true; - }; - Input.prototype._onBlur = function () { - this.isFocussed = false; - }; - return Input; -}(); -exports["default"] = Input; - -/***/ }), - -/***/ 624: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var constants_1 = __webpack_require__(883); -var List = /** @class */function () { - function List(_a) { - var element = _a.element; - this.element = element; - this.scrollPos = this.element.scrollTop; - this.height = this.element.offsetHeight; - } - List.prototype.clear = function () { - this.element.innerHTML = ''; - }; - List.prototype.append = function (node) { - this.element.appendChild(node); - }; - List.prototype.getChild = function (selector) { - return this.element.querySelector(selector); - }; - List.prototype.hasChildren = function () { - return this.element.hasChildNodes(); - }; - List.prototype.scrollToTop = function () { - this.element.scrollTop = 0; - }; - List.prototype.scrollToChildElement = function (element, direction) { - var _this = this; - if (!element) { - return; - } - var listHeight = this.element.offsetHeight; - // Scroll position of dropdown - var listScrollPosition = this.element.scrollTop + listHeight; - var elementHeight = element.offsetHeight; - // Distance from bottom of element to top of parent - var elementPos = element.offsetTop + elementHeight; - // Difference between the element and scroll position - var destination = direction > 0 ? this.element.scrollTop + elementPos - listScrollPosition : element.offsetTop; - requestAnimationFrame(function () { - _this._animateScroll(destination, direction); - }); - }; - List.prototype._scrollDown = function (scrollPos, strength, destination) { - var easing = (destination - scrollPos) / strength; - var distance = easing > 1 ? easing : 1; - this.element.scrollTop = scrollPos + distance; - }; - List.prototype._scrollUp = function (scrollPos, strength, destination) { - var easing = (scrollPos - destination) / strength; - var distance = easing > 1 ? easing : 1; - this.element.scrollTop = scrollPos - distance; - }; - List.prototype._animateScroll = function (destination, direction) { - var _this = this; - var strength = constants_1.SCROLLING_SPEED; - var choiceListScrollTop = this.element.scrollTop; - var continueAnimation = false; - if (direction > 0) { - this._scrollDown(choiceListScrollTop, strength, destination); - if (choiceListScrollTop < destination) { - continueAnimation = true; - } - } else { - this._scrollUp(choiceListScrollTop, strength, destination); - if (choiceListScrollTop > destination) { - continueAnimation = true; - } - } - if (continueAnimation) { - requestAnimationFrame(function () { - _this._animateScroll(destination, direction); - }); - } - }; - return List; -}(); -exports["default"] = List; - -/***/ }), - -/***/ 730: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var utils_1 = __webpack_require__(799); -var WrappedElement = /** @class */function () { - function WrappedElement(_a) { - var element = _a.element, - classNames = _a.classNames; - this.element = element; - this.classNames = classNames; - if (!(element instanceof HTMLInputElement) && !(element instanceof HTMLSelectElement)) { - throw new TypeError('Invalid element passed'); - } - this.isDisabled = false; - } - Object.defineProperty(WrappedElement.prototype, "isActive", { - get: function () { - return this.element.dataset.choice === 'active'; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(WrappedElement.prototype, "dir", { - get: function () { - return this.element.dir; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(WrappedElement.prototype, "value", { - get: function () { - return this.element.value; - }, - set: function (value) { - // you must define setter here otherwise it will be readonly property - this.element.value = value; - }, - enumerable: false, - configurable: true - }); - WrappedElement.prototype.conceal = function () { - // Hide passed input - this.element.classList.add(this.classNames.input); - this.element.hidden = true; - // Remove element from tab index - this.element.tabIndex = -1; - // Backup original styles if any - var origStyle = this.element.getAttribute('style'); - if (origStyle) { - this.element.setAttribute('data-choice-orig-style', origStyle); - } - this.element.setAttribute('data-choice', 'active'); - }; - WrappedElement.prototype.reveal = function () { - // Reinstate passed element - this.element.classList.remove(this.classNames.input); - this.element.hidden = false; - this.element.removeAttribute('tabindex'); - // Recover original styles if any - var origStyle = this.element.getAttribute('data-choice-orig-style'); - if (origStyle) { - this.element.removeAttribute('data-choice-orig-style'); - this.element.setAttribute('style', origStyle); - } else { - this.element.removeAttribute('style'); - } - this.element.removeAttribute('data-choice'); - // Re-assign values - this is weird, I know - // @todo Figure out why we need to do this - this.element.value = this.element.value; // eslint-disable-line no-self-assign - }; - - WrappedElement.prototype.enable = function () { - this.element.removeAttribute('disabled'); - this.element.disabled = false; - this.isDisabled = false; - }; - WrappedElement.prototype.disable = function () { - this.element.setAttribute('disabled', ''); - this.element.disabled = true; - this.isDisabled = true; - }; - WrappedElement.prototype.triggerEvent = function (eventType, data) { - (0, utils_1.dispatchEvent)(this.element, eventType, data); - }; - return WrappedElement; -}(); -exports["default"] = WrappedElement; - -/***/ }), - -/***/ 541: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -var __extends = this && this.__extends || function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || { - __proto__: [] - } instanceof Array && function (d, b) { - d.__proto__ = b; - } || function (d, b) { - for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + var isEmptyObject = function (obj) { + // eslint-disable-next-line no-restricted-syntax + for (var prop in obj) { + if (Object.prototype.hasOwnProperty.call(obj, prop)) { + return false; + } + } + return true; }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { - this.constructor = d; - } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -}(); -var __importDefault = this && this.__importDefault || function (mod) { - return mod && mod.__esModule ? mod : { - "default": mod - }; -}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var wrapped_element_1 = __importDefault(__webpack_require__(730)); -var WrappedInput = /** @class */function (_super) { - __extends(WrappedInput, _super); - function WrappedInput(_a) { - var element = _a.element, - classNames = _a.classNames, - delimiter = _a.delimiter; - var _this = _super.call(this, { - element: element, - classNames: classNames - }) || this; - _this.delimiter = delimiter; - return _this; - } - Object.defineProperty(WrappedInput.prototype, "value", { - get: function () { - return this.element.value; - }, - set: function (value) { - this.element.setAttribute('value', value); - this.element.value = value; - }, - enumerable: false, - configurable: true - }); - return WrappedInput; -}(wrapped_element_1.default); -exports["default"] = WrappedInput; - -/***/ }), - -/***/ 982: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -var __extends = this && this.__extends || function () { - var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || { - __proto__: [] - } instanceof Array && function (d, b) { - d.__proto__ = b; - } || function (d, b) { - for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + var assignCustomProperties = function (el, choice, withCustomProperties) { + var dataset = el.dataset; + var customProperties = choice.customProperties, labelClass = choice.labelClass, labelDescription = choice.labelDescription; + if (labelClass) { + dataset.labelClass = getClassNames(labelClass).join(' '); + } + if (labelDescription) { + dataset.labelDescription = labelDescription; + } + if (withCustomProperties && customProperties) { + if (typeof customProperties === 'string') { + dataset.customProperties = customProperties; + } + else if (typeof customProperties === 'object' && !isEmptyObject(customProperties)) { + dataset.customProperties = JSON.stringify(customProperties); + } + } }; - return extendStatics(d, b); - }; - return function (d, b) { - if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { - this.constructor = d; - } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -}(); -var __importDefault = this && this.__importDefault || function (mod) { - return mod && mod.__esModule ? mod : { - "default": mod - }; -}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var wrapped_element_1 = __importDefault(__webpack_require__(730)); -var WrappedSelect = /** @class */function (_super) { - __extends(WrappedSelect, _super); - function WrappedSelect(_a) { - var element = _a.element, - classNames = _a.classNames, - template = _a.template; - var _this = _super.call(this, { - element: element, - classNames: classNames - }) || this; - _this.template = template; - return _this; - } - Object.defineProperty(WrappedSelect.prototype, "placeholderOption", { - get: function () { - return this.element.querySelector('option[value=""]') || - // Backward compatibility layer for the non-standard placeholder attribute supported in older versions. - this.element.querySelector('option[placeholder]'); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(WrappedSelect.prototype, "optionGroups", { - get: function () { - return Array.from(this.element.getElementsByTagName('OPTGROUP')); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(WrappedSelect.prototype, "options", { - get: function () { - return Array.from(this.element.options); - }, - set: function (options) { - var _this = this; - var fragment = document.createDocumentFragment(); - var addOptionToFragment = function (data) { - // Create a standard select option - var option = _this.template(data); - // Append it to fragment - fragment.appendChild(option); - }; - // Add each list item to list - options.forEach(function (optionData) { - return addOptionToFragment(optionData); - }); - this.appendDocFragment(fragment); - }, - enumerable: false, - configurable: true - }); - WrappedSelect.prototype.appendDocFragment = function (fragment) { - this.element.innerHTML = ''; - this.element.appendChild(fragment); - }; - return WrappedSelect; -}(wrapped_element_1.default); -exports["default"] = WrappedSelect; - -/***/ }), - -/***/ 883: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.SCROLLING_SPEED = exports.SELECT_MULTIPLE_TYPE = exports.SELECT_ONE_TYPE = exports.TEXT_TYPE = exports.KEY_CODES = exports.ACTION_TYPES = exports.EVENTS = void 0; -exports.EVENTS = { - showDropdown: 'showDropdown', - hideDropdown: 'hideDropdown', - change: 'change', - choice: 'choice', - search: 'search', - addItem: 'addItem', - removeItem: 'removeItem', - highlightItem: 'highlightItem', - highlightChoice: 'highlightChoice', - unhighlightItem: 'unhighlightItem' -}; -exports.ACTION_TYPES = { - ADD_CHOICE: 'ADD_CHOICE', - FILTER_CHOICES: 'FILTER_CHOICES', - ACTIVATE_CHOICES: 'ACTIVATE_CHOICES', - CLEAR_CHOICES: 'CLEAR_CHOICES', - ADD_GROUP: 'ADD_GROUP', - ADD_ITEM: 'ADD_ITEM', - REMOVE_ITEM: 'REMOVE_ITEM', - HIGHLIGHT_ITEM: 'HIGHLIGHT_ITEM', - CLEAR_ALL: 'CLEAR_ALL', - RESET_TO: 'RESET_TO', - SET_IS_LOADING: 'SET_IS_LOADING' -}; -exports.KEY_CODES = { - BACK_KEY: 46, - DELETE_KEY: 8, - ENTER_KEY: 13, - A_KEY: 65, - ESC_KEY: 27, - UP_KEY: 38, - DOWN_KEY: 40, - PAGE_UP_KEY: 33, - PAGE_DOWN_KEY: 34 -}; -exports.TEXT_TYPE = 'text'; -exports.SELECT_ONE_TYPE = 'select-one'; -exports.SELECT_MULTIPLE_TYPE = 'select-multiple'; -exports.SCROLLING_SPEED = 4; - -/***/ }), - -/***/ 789: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.DEFAULT_CONFIG = exports.DEFAULT_CLASSNAMES = void 0; -var utils_1 = __webpack_require__(799); -exports.DEFAULT_CLASSNAMES = { - containerOuter: 'choices', - containerInner: 'choices__inner', - input: 'choices__input', - inputCloned: 'choices__input--cloned', - list: 'choices__list', - listItems: 'choices__list--multiple', - listSingle: 'choices__list--single', - listDropdown: 'choices__list--dropdown', - item: 'choices__item', - itemSelectable: 'choices__item--selectable', - itemDisabled: 'choices__item--disabled', - itemChoice: 'choices__item--choice', - placeholder: 'choices__placeholder', - group: 'choices__group', - groupHeading: 'choices__heading', - button: 'choices__button', - activeState: 'is-active', - focusState: 'is-focused', - openState: 'is-open', - disabledState: 'is-disabled', - highlightedState: 'is-highlighted', - selectedState: 'is-selected', - flippedState: 'is-flipped', - loadingState: 'is-loading', - noResults: 'has-no-results', - noChoices: 'has-no-choices' -}; -exports.DEFAULT_CONFIG = { - items: [], - choices: [], - silent: false, - renderChoiceLimit: -1, - maxItemCount: -1, - addItems: true, - addItemFilter: null, - removeItems: true, - removeItemButton: false, - editItems: false, - allowHTML: true, - duplicateItemsAllowed: true, - delimiter: ',', - paste: true, - searchEnabled: true, - searchChoices: true, - searchFloor: 1, - searchResultLimit: 4, - searchFields: ['label', 'value'], - position: 'auto', - resetScrollPosition: true, - shouldSort: true, - shouldSortItems: false, - sorter: utils_1.sortByAlpha, - placeholder: true, - placeholderValue: null, - searchPlaceholderValue: null, - prependValue: null, - appendValue: null, - renderSelectedChoices: 'auto', - loadingText: 'Loading...', - noResultsText: 'No results found', - noChoicesText: 'No choices to choose from', - itemSelectText: 'Press to select', - uniqueItemText: 'Only unique values can be added', - customAddItemText: 'Only values matching specific conditions can be added', - addItemText: function (value) { - return "Press Enter to add \"".concat((0, utils_1.sanitise)(value), "\""); - }, - maxItemText: function (maxItemCount) { - return "Only ".concat(maxItemCount, " values can be added"); - }, - valueComparer: function (value1, value2) { - return value1 === value2; - }, - fuseOptions: { - includeScore: true - }, - labelId: '', - callbackOnInit: null, - callbackOnCreateTemplates: null, - classNames: exports.DEFAULT_CLASSNAMES -}; - -/***/ }), - -/***/ 18: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 978: -/***/ (function(__unused_webpack_module, exports) { - - - -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 948: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 359: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 285: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 533: -/***/ (function(__unused_webpack_module, exports) { - - - -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 187: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -var __createBinding = this && this.__createBinding || (Object.create ? function (o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { - enumerable: true, - get: function () { - return m[k]; - } + var addAriaLabel = function (docRoot, id, element) { + var label = id && docRoot.querySelector("label[for='".concat(id, "']")); + var text = label && label.innerText; + if (text) { + element.setAttribute('aria-label', text); + } + }; + var templates = { + containerOuter: function (_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType, labelId) { + var containerOuter = _a.classNames.containerOuter; + var div = document.createElement('div'); + addClassesToElement(div, containerOuter); + div.dataset.type = passedElementType; + if (dir) { + div.dir = dir; + } + if (isSelectOneElement) { + div.tabIndex = 0; + } + if (isSelectElement) { + div.setAttribute('role', searchEnabled ? 'combobox' : 'listbox'); + if (searchEnabled) { + div.setAttribute('aria-autocomplete', 'list'); + } + else if (!labelId) { + addAriaLabel(this._docRoot, this.passedElement.element.id, div); + } + div.setAttribute('aria-haspopup', 'true'); + div.setAttribute('aria-expanded', 'false'); + } + if (labelId) { + div.setAttribute('aria-labelledby', labelId); + } + return div; + }, + containerInner: function (_a) { + var containerInner = _a.classNames.containerInner; + var div = document.createElement('div'); + addClassesToElement(div, containerInner); + return div; + }, + itemList: function (_a, isSelectOneElement) { + var searchEnabled = _a.searchEnabled, _b = _a.classNames, list = _b.list, listSingle = _b.listSingle, listItems = _b.listItems; + var div = document.createElement('div'); + addClassesToElement(div, list); + addClassesToElement(div, isSelectOneElement ? listSingle : listItems); + if (this._isSelectElement && searchEnabled) { + div.setAttribute('role', 'listbox'); + } + return div; + }, + placeholder: function (_a, value) { + var allowHTML = _a.allowHTML, placeholder = _a.classNames.placeholder; + var div = document.createElement('div'); + addClassesToElement(div, placeholder); + setElementHtml(div, allowHTML, value); + return div; + }, + item: function (_a, choice, removeItemButton) { + var allowHTML = _a.allowHTML, removeItemButtonAlignLeft = _a.removeItemButtonAlignLeft, removeItemIconText = _a.removeItemIconText, removeItemLabelText = _a.removeItemLabelText, _b = _a.classNames, item = _b.item, button = _b.button, highlightedState = _b.highlightedState, itemSelectable = _b.itemSelectable, placeholder = _b.placeholder; + var rawValue = unwrapStringForRaw(choice.value); + var div = document.createElement('div'); + addClassesToElement(div, item); + if (choice.labelClass) { + var spanLabel = document.createElement('span'); + setElementHtml(spanLabel, allowHTML, choice.label); + addClassesToElement(spanLabel, choice.labelClass); + div.appendChild(spanLabel); + } + else { + setElementHtml(div, allowHTML, choice.label); + } + div.dataset.item = ''; + div.dataset.id = choice.id; + div.dataset.value = rawValue; + assignCustomProperties(div, choice, true); + if (choice.disabled || this.containerOuter.isDisabled) { + div.setAttribute('aria-disabled', 'true'); + } + if (this._isSelectElement) { + div.setAttribute('aria-selected', 'true'); + div.setAttribute('role', 'option'); + } + if (choice.placeholder) { + addClassesToElement(div, placeholder); + div.dataset.placeholder = ''; + } + addClassesToElement(div, choice.highlighted ? highlightedState : itemSelectable); + if (removeItemButton) { + if (choice.disabled) { + removeClassesFromElement(div, itemSelectable); + } + div.dataset.deletable = ''; + var removeButton = document.createElement('button'); + removeButton.type = 'button'; + addClassesToElement(removeButton, button); + setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value)); + var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value); + if (REMOVE_ITEM_LABEL) { + removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL); + } + removeButton.dataset.button = ''; + if (removeItemButtonAlignLeft) { + div.insertAdjacentElement('afterbegin', removeButton); + } + else { + div.appendChild(removeButton); + } + } + return div; + }, + choiceList: function (_a, isSelectOneElement) { + var list = _a.classNames.list; + var div = document.createElement('div'); + addClassesToElement(div, list); + if (!isSelectOneElement) { + div.setAttribute('aria-multiselectable', 'true'); + } + div.setAttribute('role', 'listbox'); + return div; + }, + choiceGroup: function (_a, _b) { + var allowHTML = _a.allowHTML, _c = _a.classNames, group = _c.group, groupHeading = _c.groupHeading, itemDisabled = _c.itemDisabled; + var id = _b.id, label = _b.label, disabled = _b.disabled; + var rawLabel = unwrapStringForRaw(label); + var div = document.createElement('div'); + addClassesToElement(div, group); + if (disabled) { + addClassesToElement(div, itemDisabled); + } + div.setAttribute('role', 'group'); + div.dataset.group = ''; + div.dataset.id = id; + div.dataset.value = rawLabel; + if (disabled) { + div.setAttribute('aria-disabled', 'true'); + } + var heading = document.createElement('div'); + addClassesToElement(heading, groupHeading); + setElementHtml(heading, allowHTML, label || ''); + div.appendChild(heading); + return div; + }, + choice: function (_a, choice, selectText, groupName) { + var allowHTML = _a.allowHTML, _b = _a.classNames, item = _b.item, itemChoice = _b.itemChoice, itemSelectable = _b.itemSelectable, selectedState = _b.selectedState, itemDisabled = _b.itemDisabled, description = _b.description, placeholder = _b.placeholder; + // eslint-disable-next-line prefer-destructuring + var label = choice.label; + var rawValue = unwrapStringForRaw(choice.value); + var div = document.createElement('div'); + div.id = choice.elementId; + addClassesToElement(div, item); + addClassesToElement(div, itemChoice); + if (groupName && typeof label === 'string') { + label = escapeForTemplate(allowHTML, label); + label += " (".concat(groupName, ")"); + label = { trusted: label }; + div.dataset.groupId = "".concat(choice.groupId); + } + var describedBy = div; + if (choice.labelClass) { + var spanLabel = document.createElement('span'); + setElementHtml(spanLabel, allowHTML, label); + addClassesToElement(spanLabel, choice.labelClass); + describedBy = spanLabel; + div.appendChild(spanLabel); + } + else { + setElementHtml(div, allowHTML, label); + } + if (choice.labelDescription) { + var descId = "".concat(choice.elementId, "-description"); + describedBy.setAttribute('aria-describedby', descId); + var spanDesc = document.createElement('span'); + setElementHtml(spanDesc, allowHTML, choice.labelDescription); + spanDesc.id = descId; + addClassesToElement(spanDesc, description); + div.appendChild(spanDesc); + } + if (choice.selected) { + addClassesToElement(div, selectedState); + } + if (choice.placeholder) { + addClassesToElement(div, placeholder); + } + div.setAttribute('role', choice.groupId ? 'treeitem' : 'option'); + div.dataset.choice = ''; + div.dataset.id = choice.id; + div.dataset.value = rawValue; + if (selectText) { + div.dataset.selectText = selectText; + } + assignCustomProperties(div, choice, false); + if (choice.disabled) { + addClassesToElement(div, itemDisabled); + div.dataset.choiceDisabled = ''; + div.setAttribute('aria-disabled', 'true'); + } + else { + addClassesToElement(div, itemSelectable); + div.dataset.choiceSelectable = ''; + } + return div; + }, + input: function (_a, placeholderValue) { + var _b = _a.classNames, input = _b.input, inputCloned = _b.inputCloned, labelId = _a.labelId; + var inp = document.createElement('input'); + inp.type = 'search'; + addClassesToElement(inp, input); + addClassesToElement(inp, inputCloned); + inp.autocomplete = 'off'; + inp.autocapitalize = 'off'; + inp.spellcheck = false; + inp.setAttribute('role', 'textbox'); + inp.setAttribute('aria-autocomplete', 'list'); + if (placeholderValue) { + inp.setAttribute('aria-label', placeholderValue); + } + else if (!labelId) { + addAriaLabel(this._docRoot, this.passedElement.element.id, inp); + } + return inp; + }, + dropdown: function (_a) { + var _b = _a.classNames, list = _b.list, listDropdown = _b.listDropdown; + var div = document.createElement('div'); + addClassesToElement(div, list); + addClassesToElement(div, listDropdown); + div.setAttribute('aria-expanded', 'false'); + return div; + }, + notice: function (_a, innerHTML, type) { + var _b = _a.classNames, item = _b.item, itemChoice = _b.itemChoice, addChoice = _b.addChoice, noResults = _b.noResults, noChoices = _b.noChoices, noticeItem = _b.notice; + if (type === void 0) { type = NoticeTypes.generic; } + var notice = document.createElement('div'); + setElementHtml(notice, true, innerHTML); + addClassesToElement(notice, item); + addClassesToElement(notice, itemChoice); + addClassesToElement(notice, noticeItem); + // eslint-disable-next-line default-case + switch (type) { + case NoticeTypes.addChoice: + addClassesToElement(notice, addChoice); + break; + case NoticeTypes.noResults: + addClassesToElement(notice, noResults); + break; + case NoticeTypes.noChoices: + addClassesToElement(notice, noChoices); + break; + } + if (type === NoticeTypes.addChoice) { + notice.dataset.choiceSelectable = ''; + notice.dataset.choice = ''; + } + return notice; + }, + option: function (choice) { + // HtmlOptionElement's label value does not support HTML, so the avoid double escaping unwrap the untrusted string. + var labelValue = unwrapStringForRaw(choice.label); + var opt = new Option(labelValue, choice.value, false, choice.selected); + assignCustomProperties(opt, choice, true); + opt.disabled = choice.disabled; + if (choice.selected) { + opt.setAttribute('selected', ''); + } + return opt; + }, }; - } - Object.defineProperty(o, k2, desc); -} : function (o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -}); -var __exportStar = this && this.__exportStar || function (m, exports) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); -}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -__exportStar(__webpack_require__(18), exports); -__exportStar(__webpack_require__(978), exports); -__exportStar(__webpack_require__(948), exports); -__exportStar(__webpack_require__(359), exports); -__exportStar(__webpack_require__(285), exports); -__exportStar(__webpack_require__(533), exports); -__exportStar(__webpack_require__(287), exports); -__exportStar(__webpack_require__(132), exports); -__exportStar(__webpack_require__(837), exports); -__exportStar(__webpack_require__(598), exports); -__exportStar(__webpack_require__(369), exports); -__exportStar(__webpack_require__(37), exports); -__exportStar(__webpack_require__(47), exports); -__exportStar(__webpack_require__(923), exports); -__exportStar(__webpack_require__(876), exports); - -/***/ }), - -/***/ 287: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 132: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 837: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 598: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 37: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 369: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 47: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 923: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 876: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); - -/***/ }), - -/***/ 799: -/***/ (function(__unused_webpack_module, exports) { - - - -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.parseCustomProperties = exports.diff = exports.cloneObject = exports.existsInArray = exports.dispatchEvent = exports.sortByScore = exports.sortByAlpha = exports.strToEl = exports.sanitise = exports.isScrolledIntoView = exports.getAdjacentEl = exports.wrap = exports.isType = exports.getType = exports.generateId = exports.generateChars = exports.getRandomNumber = void 0; -var getRandomNumber = function (min, max) { - return Math.floor(Math.random() * (max - min) + min); -}; -exports.getRandomNumber = getRandomNumber; -var generateChars = function (length) { - return Array.from({ - length: length - }, function () { - return (0, exports.getRandomNumber)(0, 36).toString(36); - }).join(''); -}; -exports.generateChars = generateChars; -var generateId = function (element, prefix) { - var id = element.id || element.name && "".concat(element.name, "-").concat((0, exports.generateChars)(2)) || (0, exports.generateChars)(4); - id = id.replace(/(:|\.|\[|\]|,)/g, ''); - id = "".concat(prefix, "-").concat(id); - return id; -}; -exports.generateId = generateId; -var getType = function (obj) { - return Object.prototype.toString.call(obj).slice(8, -1); -}; -exports.getType = getType; -var isType = function (type, obj) { - return obj !== undefined && obj !== null && (0, exports.getType)(obj) === type; -}; -exports.isType = isType; -var wrap = function (element, wrapper) { - if (wrapper === void 0) { - wrapper = document.createElement('div'); - } - if (element.parentNode) { - if (element.nextSibling) { - element.parentNode.insertBefore(wrapper, element.nextSibling); - } else { - element.parentNode.appendChild(wrapper); - } - } - return wrapper.appendChild(element); -}; -exports.wrap = wrap; -var getAdjacentEl = function (startEl, selector, direction) { - if (direction === void 0) { - direction = 1; - } - var prop = "".concat(direction > 0 ? 'next' : 'previous', "ElementSibling"); - var sibling = startEl[prop]; - while (sibling) { - if (sibling.matches(selector)) { - return sibling; - } - sibling = sibling[prop]; - } - return sibling; -}; -exports.getAdjacentEl = getAdjacentEl; -var isScrolledIntoView = function (element, parent, direction) { - if (direction === void 0) { - direction = 1; - } - if (!element) { - return false; - } - var isVisible; - if (direction > 0) { - // In view from bottom - isVisible = parent.scrollTop + parent.offsetHeight >= element.offsetTop + element.offsetHeight; - } else { - // In view from top - isVisible = element.offsetTop >= parent.scrollTop; - } - return isVisible; -}; -exports.isScrolledIntoView = isScrolledIntoView; -var sanitise = function (value) { - if (typeof value !== 'string') { - return value; - } - return value.replace(/&/g, '&').replace(/>/g, '>').replace(/ -1) { - return state.map(function (obj) { - var choice = obj; - if (choice.id === parseInt("".concat(addItemAction_1.choiceId), 10)) { - choice.selected = true; - } - return choice; - }); - } - return state; - } - case 'REMOVE_ITEM': - { - var removeItemAction_1 = action; - // When an item is removed and it has an associated choice, - // we want to re-enable it so it can be chosen again - if (removeItemAction_1.choiceId && removeItemAction_1.choiceId > -1) { - return state.map(function (obj) { - var choice = obj; - if (choice.id === parseInt("".concat(removeItemAction_1.choiceId), 10)) { - choice.selected = false; - } - return choice; - }); + /** @see {@link http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c} */ + var IS_IE11 = '-ms-scroll-limit' in document.documentElement.style && + '-ms-ime-align' in document.documentElement.style; + var USER_DEFAULTS = {}; + var parseDataSetId = function (element) { + if (!element) { + return undefined; } - return state; - } - case 'FILTER_CHOICES': - { - var filterChoicesAction_1 = action; - return state.map(function (obj) { - var choice = obj; - // Set active state based on whether choice is - // within filtered results - choice.active = filterChoicesAction_1.results.some(function (_a) { - var item = _a.item, - score = _a.score; - if (item.id === choice.id) { - choice.score = score; - return true; + return element.dataset.id ? parseInt(element.dataset.id, 10) : undefined; + }; + var selectableChoiceIdentifier = '[data-choice-selectable]'; + /** + * Choices + * @author Josh Johnson + */ + var Choices = /** @class */ (function () { + function Choices(element, userConfig) { + if (element === void 0) { element = '[data-choice]'; } + if (userConfig === void 0) { userConfig = {}; } + var _this = this; + this.initialisedOK = undefined; + this._hasNonChoicePlaceholder = false; + this._lastAddedChoiceId = 0; + this._lastAddedGroupId = 0; + var defaults = Choices.defaults; + this.config = __assign(__assign(__assign({}, defaults.allOptions), defaults.options), userConfig); + ObjectsInConfig.forEach(function (key) { + _this.config[key] = __assign(__assign(__assign({}, defaults.allOptions[key]), defaults.options[key]), userConfig[key]); + }); + var config = this.config; + if (!config.silent) { + this._validateConfig(); } - return false; - }); - return choice; - }); - } - case 'ACTIVATE_CHOICES': - { - var activateChoicesAction_1 = action; - return state.map(function (obj) { - var choice = obj; - choice.active = activateChoicesAction_1.active; - return choice; - }); - } - case 'CLEAR_CHOICES': - { - return exports.defaultState; - } - default: - { - return state; - } - } -} -exports["default"] = choices; - -/***/ }), - -/***/ 871: -/***/ (function(__unused_webpack_module, exports) { - - - -var __spreadArray = this && this.__spreadArray || function (to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.defaultState = void 0; -exports.defaultState = []; -function groups(state, action) { - if (state === void 0) { - state = exports.defaultState; - } - if (action === void 0) { - action = {}; - } - switch (action.type) { - case 'ADD_GROUP': - { - var addGroupAction = action; - return __spreadArray(__spreadArray([], state, true), [{ - id: addGroupAction.id, - value: addGroupAction.value, - active: addGroupAction.active, - disabled: addGroupAction.disabled - }], false); - } - case 'CLEAR_CHOICES': - { - return []; - } - default: - { - return state; - } - } -} -exports["default"] = groups; - -/***/ }), - -/***/ 655: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -var __importDefault = this && this.__importDefault || function (mod) { - return mod && mod.__esModule ? mod : { - "default": mod - }; -}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.defaultState = void 0; -var redux_1 = __webpack_require__(791); -var items_1 = __importDefault(__webpack_require__(52)); -var groups_1 = __importDefault(__webpack_require__(871)); -var choices_1 = __importDefault(__webpack_require__(273)); -var loading_1 = __importDefault(__webpack_require__(502)); -var utils_1 = __webpack_require__(799); -exports.defaultState = { - groups: [], - items: [], - choices: [], - loading: false -}; -var appReducer = (0, redux_1.combineReducers)({ - items: items_1.default, - groups: groups_1.default, - choices: choices_1.default, - loading: loading_1.default -}); -var rootReducer = function (passedState, action) { - var state = passedState; - // If we are clearing all items, groups and options we reassign - // state and then pass that state to our proper reducer. This isn't - // mutating our actual state - // See: http://stackoverflow.com/a/35641992 - if (action.type === 'CLEAR_ALL') { - state = exports.defaultState; - } else if (action.type === 'RESET_TO') { - return (0, utils_1.cloneObject)(action.state); - } - return appReducer(state, action); -}; -exports["default"] = rootReducer; - -/***/ }), - -/***/ 52: -/***/ (function(__unused_webpack_module, exports) { - - - -var __spreadArray = this && this.__spreadArray || function (to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.defaultState = void 0; -exports.defaultState = []; -function items(state, action) { - if (state === void 0) { - state = exports.defaultState; - } - if (action === void 0) { - action = {}; - } - switch (action.type) { - case 'ADD_ITEM': - { - var addItemAction = action; - // Add object to items array - var newState = __spreadArray(__spreadArray([], state, true), [{ - id: addItemAction.id, - choiceId: addItemAction.choiceId, - groupId: addItemAction.groupId, - value: addItemAction.value, - label: addItemAction.label, - active: true, - highlighted: false, - customProperties: addItemAction.customProperties, - placeholder: addItemAction.placeholder || false, - keyCode: null - }], false); - return newState.map(function (obj) { - var item = obj; - item.highlighted = false; - return item; - }); - } - case 'REMOVE_ITEM': - { - // Set item to inactive - return state.map(function (obj) { - var item = obj; - if (item.id === action.id) { - item.active = false; - } - return item; - }); - } - case 'HIGHLIGHT_ITEM': - { - var highlightItemAction_1 = action; - return state.map(function (obj) { - var item = obj; - if (item.id === highlightItemAction_1.id) { - item.highlighted = highlightItemAction_1.highlighted; - } - return item; - }); - } - default: - { - return state; - } - } -} -exports["default"] = items; - -/***/ }), - -/***/ 502: -/***/ (function(__unused_webpack_module, exports) { - - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports.defaultState = void 0; -exports.defaultState = false; -var general = function (state, action) { - if (state === void 0) { - state = exports.defaultState; - } - if (action === void 0) { - action = {}; - } - switch (action.type) { - case 'SET_IS_LOADING': - { - return action.isLoading; - } - default: - { - return state; - } - } -}; -exports["default"] = general; - -/***/ }), - -/***/ 744: -/***/ (function(__unused_webpack_module, exports, __webpack_require__) { - - - -var __spreadArray = this && this.__spreadArray || function (to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -}; -var __importDefault = this && this.__importDefault || function (mod) { - return mod && mod.__esModule ? mod : { - "default": mod - }; -}; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -/* eslint-disable @typescript-eslint/no-explicit-any */ -var redux_1 = __webpack_require__(791); -var index_1 = __importDefault(__webpack_require__(655)); -var Store = /** @class */function () { - function Store() { - this._store = (0, redux_1.createStore)(index_1.default, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()); - } - /** - * Subscribe store to function call (wrapped Redux method) - */ - Store.prototype.subscribe = function (onChange) { - this._store.subscribe(onChange); - }; - /** - * Dispatch event to store (wrapped Redux method) - */ - Store.prototype.dispatch = function (action) { - this._store.dispatch(action); - }; - Object.defineProperty(Store.prototype, "state", { - /** - * Get store object (wrapping Redux method) - */ - get: function () { - return this._store.getState(); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "items", { - /** - * Get items from store - */ - get: function () { - return this.state.items; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "activeItems", { - /** - * Get active items from store - */ - get: function () { - return this.items.filter(function (item) { - return item.active === true; - }); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "highlightedActiveItems", { - /** - * Get highlighted items from store - */ - get: function () { - return this.items.filter(function (item) { - return item.active && item.highlighted; - }); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "choices", { - /** - * Get choices from store - */ - get: function () { - return this.state.choices; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "activeChoices", { - /** - * Get active choices from store - */ - get: function () { - return this.choices.filter(function (choice) { - return choice.active === true; - }); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "selectableChoices", { - /** - * Get selectable choices from store - */ - get: function () { - return this.choices.filter(function (choice) { - return choice.disabled !== true; - }); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "searchableChoices", { - /** - * Get choices that can be searched (excluding placeholders) - */ - get: function () { - return this.selectableChoices.filter(function (choice) { - return choice.placeholder !== true; - }); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "placeholderChoice", { - /** - * Get placeholder choice from store - */ - get: function () { - return __spreadArray([], this.choices, true).reverse().find(function (choice) { - return choice.placeholder === true; - }); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "groups", { - /** - * Get groups from store - */ - get: function () { - return this.state.groups; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Store.prototype, "activeGroups", { - /** - * Get active groups from store - */ - get: function () { - var _a = this, - groups = _a.groups, - choices = _a.choices; - return groups.filter(function (group) { - var isActive = group.active === true && group.disabled === false; - var hasActiveOptions = choices.some(function (choice) { - return choice.active === true && choice.disabled === false; - }); - return isActive && hasActiveOptions; - }, []); - }, - enumerable: false, - configurable: true - }); - /** - * Get loading state from store - */ - Store.prototype.isLoading = function () { - return this.state.loading; - }; - /** - * Get single choice by it's ID - */ - Store.prototype.getChoiceById = function (id) { - return this.activeChoices.find(function (choice) { - return choice.id === parseInt(id, 10); - }); - }; - /** - * Get group by group id - */ - Store.prototype.getGroupById = function (id) { - return this.groups.find(function (group) { - return group.id === id; - }); - }; - return Store; -}(); -exports["default"] = Store; - -/***/ }), - -/***/ 686: -/***/ (function(__unused_webpack_module, exports) { - - - -/** - * Helpers to create HTML elements used by Choices - * Can be overridden by providing `callbackOnCreateTemplates` option - */ -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -var templates = { - containerOuter: function (_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType, labelId) { - var containerOuter = _a.classNames.containerOuter; - var div = Object.assign(document.createElement('div'), { - className: containerOuter - }); - div.dataset.type = passedElementType; - if (dir) { - div.dir = dir; - } - if (isSelectOneElement) { - div.tabIndex = 0; - } - if (isSelectElement) { - div.setAttribute('role', searchEnabled ? 'combobox' : 'listbox'); - if (searchEnabled) { - div.setAttribute('aria-autocomplete', 'list'); - } - } - div.setAttribute('aria-haspopup', 'true'); - div.setAttribute('aria-expanded', 'false'); - if (labelId) { - div.setAttribute('aria-labelledby', labelId); - } - return div; - }, - containerInner: function (_a) { - var containerInner = _a.classNames.containerInner; - return Object.assign(document.createElement('div'), { - className: containerInner - }); - }, - itemList: function (_a, isSelectOneElement) { - var _b = _a.classNames, - list = _b.list, - listSingle = _b.listSingle, - listItems = _b.listItems; - return Object.assign(document.createElement('div'), { - className: "".concat(list, " ").concat(isSelectOneElement ? listSingle : listItems) - }); - }, - placeholder: function (_a, value) { - var _b; - var allowHTML = _a.allowHTML, - placeholder = _a.classNames.placeholder; - return Object.assign(document.createElement('div'), (_b = { - className: placeholder - }, _b[allowHTML ? 'innerHTML' : 'innerText'] = value, _b)); - }, - item: function (_a, _b, removeItemButton) { - var _c, _d; - var allowHTML = _a.allowHTML, - _e = _a.classNames, - item = _e.item, - button = _e.button, - highlightedState = _e.highlightedState, - itemSelectable = _e.itemSelectable, - placeholder = _e.placeholder; - var id = _b.id, - value = _b.value, - label = _b.label, - customProperties = _b.customProperties, - active = _b.active, - disabled = _b.disabled, - highlighted = _b.highlighted, - isPlaceholder = _b.placeholder; - var div = Object.assign(document.createElement('div'), (_c = { - className: item - }, _c[allowHTML ? 'innerHTML' : 'innerText'] = label, _c)); - Object.assign(div.dataset, { - item: '', - id: id, - value: value, - customProperties: customProperties - }); - if (active) { - div.setAttribute('aria-selected', 'true'); - } - if (disabled) { - div.setAttribute('aria-disabled', 'true'); - } - if (isPlaceholder) { - div.classList.add(placeholder); - } - div.classList.add(highlighted ? highlightedState : itemSelectable); - if (removeItemButton) { - if (disabled) { - div.classList.remove(itemSelectable); - } - div.dataset.deletable = ''; - /** @todo This MUST be localizable, not hardcoded! */ - var REMOVE_ITEM_TEXT = 'Remove item'; - var removeButton = Object.assign(document.createElement('button'), (_d = { - type: 'button', - className: button - }, _d[allowHTML ? 'innerHTML' : 'innerText'] = REMOVE_ITEM_TEXT, _d)); - removeButton.setAttribute('aria-label', "".concat(REMOVE_ITEM_TEXT, ": '").concat(value, "'")); - removeButton.dataset.button = ''; - div.appendChild(removeButton); - } - return div; - }, - choiceList: function (_a, isSelectOneElement) { - var list = _a.classNames.list; - var div = Object.assign(document.createElement('div'), { - className: list - }); - if (!isSelectOneElement) { - div.setAttribute('aria-multiselectable', 'true'); - } - div.setAttribute('role', 'listbox'); - return div; - }, - choiceGroup: function (_a, _b) { - var _c; - var allowHTML = _a.allowHTML, - _d = _a.classNames, - group = _d.group, - groupHeading = _d.groupHeading, - itemDisabled = _d.itemDisabled; - var id = _b.id, - value = _b.value, - disabled = _b.disabled; - var div = Object.assign(document.createElement('div'), { - className: "".concat(group, " ").concat(disabled ? itemDisabled : '') - }); - div.setAttribute('role', 'group'); - Object.assign(div.dataset, { - group: '', - id: id, - value: value - }); - if (disabled) { - div.setAttribute('aria-disabled', 'true'); - } - div.appendChild(Object.assign(document.createElement('div'), (_c = { - className: groupHeading - }, _c[allowHTML ? 'innerHTML' : 'innerText'] = value, _c))); - return div; - }, - choice: function (_a, _b, selectText) { - var _c; - var allowHTML = _a.allowHTML, - _d = _a.classNames, - item = _d.item, - itemChoice = _d.itemChoice, - itemSelectable = _d.itemSelectable, - selectedState = _d.selectedState, - itemDisabled = _d.itemDisabled, - placeholder = _d.placeholder; - var id = _b.id, - value = _b.value, - label = _b.label, - groupId = _b.groupId, - elementId = _b.elementId, - isDisabled = _b.disabled, - isSelected = _b.selected, - isPlaceholder = _b.placeholder; - var div = Object.assign(document.createElement('div'), (_c = { - id: elementId - }, _c[allowHTML ? 'innerHTML' : 'innerText'] = label, _c.className = "".concat(item, " ").concat(itemChoice), _c)); - if (isSelected) { - div.classList.add(selectedState); - } - if (isPlaceholder) { - div.classList.add(placeholder); - } - div.setAttribute('role', groupId && groupId > 0 ? 'treeitem' : 'option'); - Object.assign(div.dataset, { - choice: '', - id: id, - value: value, - selectText: selectText - }); - if (isDisabled) { - div.classList.add(itemDisabled); - div.dataset.choiceDisabled = ''; - div.setAttribute('aria-disabled', 'true'); - } else { - div.classList.add(itemSelectable); - div.dataset.choiceSelectable = ''; - } - return div; - }, - input: function (_a, placeholderValue) { - var _b = _a.classNames, - input = _b.input, - inputCloned = _b.inputCloned; - var inp = Object.assign(document.createElement('input'), { - type: 'search', - name: 'search_terms', - className: "".concat(input, " ").concat(inputCloned), - autocomplete: 'off', - autocapitalize: 'off', - spellcheck: false - }); - inp.setAttribute('role', 'textbox'); - inp.setAttribute('aria-autocomplete', 'list'); - inp.setAttribute('aria-label', placeholderValue); - return inp; - }, - dropdown: function (_a) { - var _b = _a.classNames, - list = _b.list, - listDropdown = _b.listDropdown; - var div = document.createElement('div'); - div.classList.add(list, listDropdown); - div.setAttribute('aria-expanded', 'false'); - return div; - }, - notice: function (_a, innerText, type) { - var _b; - var allowHTML = _a.allowHTML, - _c = _a.classNames, - item = _c.item, - itemChoice = _c.itemChoice, - noResults = _c.noResults, - noChoices = _c.noChoices; - if (type === void 0) { - type = ''; - } - var classes = [item, itemChoice]; - if (type === 'no-choices') { - classes.push(noChoices); - } else if (type === 'no-results') { - classes.push(noResults); - } - return Object.assign(document.createElement('div'), (_b = {}, _b[allowHTML ? 'innerHTML' : 'innerText'] = innerText, _b.className = classes.join(' '), _b)); - }, - option: function (_a) { - var label = _a.label, - value = _a.value, - customProperties = _a.customProperties, - active = _a.active, - disabled = _a.disabled; - var opt = new Option(label, value, false, active); - if (customProperties) { - opt.dataset.customProperties = "".concat(customProperties); - } - opt.disabled = !!disabled; - return opt; - } -}; -exports["default"] = templates; - -/***/ }), - -/***/ 996: -/***/ (function(module) { - - - -var isMergeableObject = function isMergeableObject(value) { - return isNonNullObject(value) - && !isSpecial(value) -}; - -function isNonNullObject(value) { - return !!value && typeof value === 'object' -} - -function isSpecial(value) { - var stringValue = Object.prototype.toString.call(value); - - return stringValue === '[object RegExp]' - || stringValue === '[object Date]' - || isReactElement(value) -} - -// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25 -var canUseSymbol = typeof Symbol === 'function' && Symbol.for; -var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7; - -function isReactElement(value) { - return value.$$typeof === REACT_ELEMENT_TYPE -} - -function emptyTarget(val) { - return Array.isArray(val) ? [] : {} -} - -function cloneUnlessOtherwiseSpecified(value, options) { - return (options.clone !== false && options.isMergeableObject(value)) - ? deepmerge(emptyTarget(value), value, options) - : value -} - -function defaultArrayMerge(target, source, options) { - return target.concat(source).map(function(element) { - return cloneUnlessOtherwiseSpecified(element, options) - }) -} - -function getMergeFunction(key, options) { - if (!options.customMerge) { - return deepmerge - } - var customMerge = options.customMerge(key); - return typeof customMerge === 'function' ? customMerge : deepmerge -} - -function getEnumerableOwnPropertySymbols(target) { - return Object.getOwnPropertySymbols - ? Object.getOwnPropertySymbols(target).filter(function(symbol) { - return target.propertyIsEnumerable(symbol) - }) - : [] -} - -function getKeys(target) { - return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)) -} - -function propertyIsOnObject(object, property) { - try { - return property in object - } catch(_) { - return false - } -} - -// Protects from prototype poisoning and unexpected merging up the prototype chain. -function propertyIsUnsafe(target, key) { - return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet, - && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain, - && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable. -} - -function mergeObject(target, source, options) { - var destination = {}; - if (options.isMergeableObject(target)) { - getKeys(target).forEach(function(key) { - destination[key] = cloneUnlessOtherwiseSpecified(target[key], options); - }); - } - getKeys(source).forEach(function(key) { - if (propertyIsUnsafe(target, key)) { - return - } - - if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) { - destination[key] = getMergeFunction(key, options)(target[key], source[key], options); - } else { - destination[key] = cloneUnlessOtherwiseSpecified(source[key], options); - } - }); - return destination -} - -function deepmerge(target, source, options) { - options = options || {}; - options.arrayMerge = options.arrayMerge || defaultArrayMerge; - options.isMergeableObject = options.isMergeableObject || isMergeableObject; - // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge() - // implementations can use it. The caller may not replace it. - options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified; - - var sourceIsArray = Array.isArray(source); - var targetIsArray = Array.isArray(target); - var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray; - - if (!sourceAndTargetTypesMatch) { - return cloneUnlessOtherwiseSpecified(source, options) - } else if (sourceIsArray) { - return options.arrayMerge(target, source, options) - } else { - return mergeObject(target, source, options) - } -} - -deepmerge.all = function deepmergeAll(array, options) { - if (!Array.isArray(array)) { - throw new Error('first argument should be an array') - } - - return array.reduce(function(prev, next) { - return deepmerge(prev, next, options) - }, {}) -}; - -var deepmerge_1 = deepmerge; - -module.exports = deepmerge_1; - - -/***/ }), - -/***/ 221: -/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { - -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": function() { return /* binding */ Fuse; } -/* harmony export */ }); -/** - * Fuse.js v6.6.2 - Lightweight fuzzy-search (http://fusejs.io) - * - * Copyright (c) 2022 Kiro Risk (http://kiro.me) - * All Rights Reserved. Apache Software License 2.0 - * - * http://www.apache.org/licenses/LICENSE-2.0 - */ - -function isArray(value) { - return !Array.isArray - ? getTag(value) === '[object Array]' - : Array.isArray(value) -} - -// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js -const INFINITY = 1 / 0; -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value - } - let result = value + ''; - return result == '0' && 1 / value == -INFINITY ? '-0' : result -} - -function toString(value) { - return value == null ? '' : baseToString(value) -} - -function isString(value) { - return typeof value === 'string' -} - -function isNumber(value) { - return typeof value === 'number' -} - -// Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js -function isBoolean(value) { - return ( - value === true || - value === false || - (isObjectLike(value) && getTag(value) == '[object Boolean]') - ) -} - -function isObject(value) { - return typeof value === 'object' -} - -// Checks if `value` is object-like. -function isObjectLike(value) { - return isObject(value) && value !== null -} - -function isDefined(value) { - return value !== undefined && value !== null -} - -function isBlank(value) { - return !value.trim().length -} - -// Gets the `toStringTag` of `value`. -// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js -function getTag(value) { - return value == null - ? value === undefined - ? '[object Undefined]' - : '[object Null]' - : Object.prototype.toString.call(value) -} - -const EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available'; - -const INCORRECT_INDEX_TYPE = "Incorrect 'index' type"; - -const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) => - `Invalid value for key ${key}`; - -const PATTERN_LENGTH_TOO_LARGE = (max) => - `Pattern length exceeds max of ${max}.`; - -const MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`; - -const INVALID_KEY_WEIGHT_VALUE = (key) => - `Property 'weight' in key '${key}' must be a positive integer`; - -const hasOwn = Object.prototype.hasOwnProperty; - -class KeyStore { - constructor(keys) { - this._keys = []; - this._keyMap = {}; - - let totalWeight = 0; - - keys.forEach((key) => { - let obj = createKey(key); - - totalWeight += obj.weight; - - this._keys.push(obj); - this._keyMap[obj.id] = obj; - - totalWeight += obj.weight; - }); - - // Normalize weights so that their sum is equal to 1 - this._keys.forEach((key) => { - key.weight /= totalWeight; - }); - } - get(keyId) { - return this._keyMap[keyId] - } - keys() { - return this._keys - } - toJSON() { - return JSON.stringify(this._keys) - } -} - -function createKey(key) { - let path = null; - let id = null; - let src = null; - let weight = 1; - let getFn = null; - - if (isString(key) || isArray(key)) { - src = key; - path = createKeyPath(key); - id = createKeyId(key); - } else { - if (!hasOwn.call(key, 'name')) { - throw new Error(MISSING_KEY_PROPERTY('name')) - } - - const name = key.name; - src = name; - - if (hasOwn.call(key, 'weight')) { - weight = key.weight; - - if (weight <= 0) { - throw new Error(INVALID_KEY_WEIGHT_VALUE(name)) - } - } - - path = createKeyPath(name); - id = createKeyId(name); - getFn = key.getFn; - } - - return { path, id, weight, src, getFn } -} - -function createKeyPath(key) { - return isArray(key) ? key : key.split('.') -} - -function createKeyId(key) { - return isArray(key) ? key.join('.') : key -} - -function get(obj, path) { - let list = []; - let arr = false; - - const deepGet = (obj, path, index) => { - if (!isDefined(obj)) { - return - } - if (!path[index]) { - // If there's no path left, we've arrived at the object we care about. - list.push(obj); - } else { - let key = path[index]; - - const value = obj[key]; - - if (!isDefined(value)) { - return - } - - // If we're at the last value in the path, and if it's a string/number/bool, - // add it to the list - if ( - index === path.length - 1 && - (isString(value) || isNumber(value) || isBoolean(value)) - ) { - list.push(toString(value)); - } else if (isArray(value)) { - arr = true; - // Search each item in the array. - for (let i = 0, len = value.length; i < len; i += 1) { - deepGet(value[i], path, index + 1); - } - } else if (path.length) { - // An object. Recurse further. - deepGet(value, path, index + 1); - } - } - }; - - // Backwards compatibility (since path used to be a string) - deepGet(obj, isString(path) ? path.split('.') : path, 0); - - return arr ? list : list[0] -} - -const MatchOptions = { - // Whether the matches should be included in the result set. When `true`, each record in the result - // set will include the indices of the matched characters. - // These can consequently be used for highlighting purposes. - includeMatches: false, - // When `true`, the matching function will continue to the end of a search pattern even if - // a perfect match has already been located in the string. - findAllMatches: false, - // Minimum number of characters that must be matched before a result is considered a match - minMatchCharLength: 1 -}; - -const BasicOptions = { - // When `true`, the algorithm continues searching to the end of the input even if a perfect - // match is found before the end of the same input. - isCaseSensitive: false, - // When true, the matching function will continue to the end of a search pattern even if - includeScore: false, - // List of properties that will be searched. This also supports nested properties. - keys: [], - // Whether to sort the result list, by score - shouldSort: true, - // Default sort function: sort by ascending score, ascending index - sortFn: (a, b) => - a.score === b.score ? (a.idx < b.idx ? -1 : 1) : a.score < b.score ? -1 : 1 -}; - -const FuzzyOptions = { - // Approximately where in the text is the pattern expected to be found? - location: 0, - // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match - // (of both letters and location), a threshold of '1.0' would match anything. - threshold: 0.6, - // Determines how close the match must be to the fuzzy location (specified above). - // An exact letter match which is 'distance' characters away from the fuzzy location - // would score as a complete mismatch. A distance of '0' requires the match be at - // the exact location specified, a threshold of '1000' would require a perfect match - // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold. - distance: 100 -}; - -const AdvancedOptions = { - // When `true`, it enables the use of unix-like search commands - useExtendedSearch: false, - // The get function to use when fetching an object's properties. - // The default will search nested paths *ie foo.bar.baz* - getFn: get, - // When `true`, search will ignore `location` and `distance`, so it won't matter - // where in the string the pattern appears. - // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score - ignoreLocation: false, - // When `true`, the calculation for the relevance score (used for sorting) will - // ignore the field-length norm. - // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm - ignoreFieldNorm: false, - // The weight to determine how much field length norm effects scoring. - fieldNormWeight: 1 -}; - -var Config = { - ...BasicOptions, - ...MatchOptions, - ...FuzzyOptions, - ...AdvancedOptions -}; - -const SPACE = /[^ ]+/g; - -// Field-length norm: the shorter the field, the higher the weight. -// Set to 3 decimals to reduce index size. -function norm(weight = 1, mantissa = 3) { - const cache = new Map(); - const m = Math.pow(10, mantissa); - - return { - get(value) { - const numTokens = value.match(SPACE).length; - - if (cache.has(numTokens)) { - return cache.get(numTokens) - } - - // Default function is 1/sqrt(x), weight makes that variable - const norm = 1 / Math.pow(numTokens, 0.5 * weight); - - // In place of `toFixed(mantissa)`, for faster computation - const n = parseFloat(Math.round(norm * m) / m); - - cache.set(numTokens, n); - - return n - }, - clear() { - cache.clear(); - } - } -} - -class FuseIndex { - constructor({ - getFn = Config.getFn, - fieldNormWeight = Config.fieldNormWeight - } = {}) { - this.norm = norm(fieldNormWeight, 3); - this.getFn = getFn; - this.isCreated = false; - - this.setIndexRecords(); - } - setSources(docs = []) { - this.docs = docs; - } - setIndexRecords(records = []) { - this.records = records; - } - setKeys(keys = []) { - this.keys = keys; - this._keysMap = {}; - keys.forEach((key, idx) => { - this._keysMap[key.id] = idx; - }); - } - create() { - if (this.isCreated || !this.docs.length) { - return - } - - this.isCreated = true; - - // List is Array - if (isString(this.docs[0])) { - this.docs.forEach((doc, docIndex) => { - this._addString(doc, docIndex); - }); - } else { - // List is Array - this.docs.forEach((doc, docIndex) => { - this._addObject(doc, docIndex); - }); - } - - this.norm.clear(); - } - // Adds a doc to the end of the index - add(doc) { - const idx = this.size(); - - if (isString(doc)) { - this._addString(doc, idx); - } else { - this._addObject(doc, idx); - } - } - // Removes the doc at the specified index of the index - removeAt(idx) { - this.records.splice(idx, 1); - - // Change ref index of every subsquent doc - for (let i = idx, len = this.size(); i < len; i += 1) { - this.records[i].i -= 1; - } - } - getValueForItemAtKeyId(item, keyId) { - return item[this._keysMap[keyId]] - } - size() { - return this.records.length - } - _addString(doc, docIndex) { - if (!isDefined(doc) || isBlank(doc)) { - return - } - - let record = { - v: doc, - i: docIndex, - n: this.norm.get(doc) - }; - - this.records.push(record); - } - _addObject(doc, docIndex) { - let record = { i: docIndex, $: {} }; - - // Iterate over every key (i.e, path), and fetch the value at that key - this.keys.forEach((key, keyIndex) => { - let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path); - - if (!isDefined(value)) { - return - } - - if (isArray(value)) { - let subRecords = []; - const stack = [{ nestedArrIndex: -1, value }]; - - while (stack.length) { - const { nestedArrIndex, value } = stack.pop(); - - if (!isDefined(value)) { - continue - } - - if (isString(value) && !isBlank(value)) { - let subRecord = { - v: value, - i: nestedArrIndex, - n: this.norm.get(value) + var docRoot = config.shadowRoot || document.documentElement; + this._docRoot = docRoot; + var passedElement = typeof element === 'string' ? docRoot.querySelector(element) : element; + if (!passedElement || + typeof passedElement !== 'object' || + !(isHtmlInputElement(passedElement) || isHtmlSelectElement(passedElement))) { + if (!passedElement && typeof element === 'string') { + throw TypeError("Selector ".concat(element, " failed to find an element")); + } + throw TypeError("Expected one of the following types text|select-one|select-multiple"); + } + var elementType = passedElement.type; + var isText = elementType === PassedElementTypes.Text; + if (isText || config.maxItemCount !== 1) { + config.singleModeForMultiSelect = false; + } + if (config.singleModeForMultiSelect) { + elementType = PassedElementTypes.SelectMultiple; + } + var isSelectOne = elementType === PassedElementTypes.SelectOne; + var isSelectMultiple = elementType === PassedElementTypes.SelectMultiple; + var isSelect = isSelectOne || isSelectMultiple; + this._elementType = elementType; + this._isTextElement = isText; + this._isSelectOneElement = isSelectOne; + this._isSelectMultipleElement = isSelectMultiple; + this._isSelectElement = isSelectOne || isSelectMultiple; + this._canAddUserChoices = (isText && config.addItems) || (isSelect && config.addChoices); + if (typeof config.renderSelectedChoices !== 'boolean') { + config.renderSelectedChoices = config.renderSelectedChoices === 'always' || isSelectOne; + } + if (config.closeDropdownOnSelect === 'auto') { + config.closeDropdownOnSelect = isText || isSelectOne || config.singleModeForMultiSelect; + } + else { + config.closeDropdownOnSelect = coerceBool(config.closeDropdownOnSelect); + } + if (config.placeholder) { + if (config.placeholderValue) { + this._hasNonChoicePlaceholder = true; + } + else if (passedElement.dataset.placeholder) { + this._hasNonChoicePlaceholder = true; + config.placeholderValue = passedElement.dataset.placeholder; + } + } + if (userConfig.addItemFilter && typeof userConfig.addItemFilter !== 'function') { + var re = userConfig.addItemFilter instanceof RegExp ? userConfig.addItemFilter : new RegExp(userConfig.addItemFilter); + config.addItemFilter = re.test.bind(re); + } + if (this._isTextElement) { + this.passedElement = new WrappedInput({ + element: passedElement, + classNames: config.classNames, + }); + } + else { + var selectEl = passedElement; + this.passedElement = new WrappedSelect({ + element: selectEl, + classNames: config.classNames, + template: function (data) { return _this._templates.option(data); }, + extractPlaceholder: config.placeholder && !this._hasNonChoicePlaceholder, + }); + } + this.initialised = false; + this._store = new Store(config); + this._currentValue = ''; + config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple; + this._canSearch = config.searchEnabled; + this._isScrollingOnIe = false; + this._highlightPosition = 0; + this._wasTap = true; + this._placeholderValue = this._generatePlaceholderValue(); + this._baseId = generateId(passedElement, 'choices-'); + /** + * setting direction in cases where it's explicitly set on passedElement + * or when calculated direction is different from the document + */ + this._direction = passedElement.dir; + if (!this._direction) { + var elementDirection = window.getComputedStyle(passedElement).direction; + var documentDirection = window.getComputedStyle(document.documentElement).direction; + if (elementDirection !== documentDirection) { + this._direction = elementDirection; + } + } + this._idNames = { + itemChoice: 'item-choice', }; - - subRecords.push(subRecord); - } else if (isArray(value)) { - value.forEach((item, k) => { - stack.push({ - nestedArrIndex: k, - value: item - }); - }); - } else ; + this._templates = defaults.templates; + this._render = this._render.bind(this); + this._onFocus = this._onFocus.bind(this); + this._onBlur = this._onBlur.bind(this); + this._onKeyUp = this._onKeyUp.bind(this); + this._onKeyDown = this._onKeyDown.bind(this); + this._onInput = this._onInput.bind(this); + this._onClick = this._onClick.bind(this); + this._onTouchMove = this._onTouchMove.bind(this); + this._onTouchEnd = this._onTouchEnd.bind(this); + this._onMouseDown = this._onMouseDown.bind(this); + this._onMouseOver = this._onMouseOver.bind(this); + this._onFormReset = this._onFormReset.bind(this); + this._onSelectKey = this._onSelectKey.bind(this); + this._onEnterKey = this._onEnterKey.bind(this); + this._onEscapeKey = this._onEscapeKey.bind(this); + this._onDirectionKey = this._onDirectionKey.bind(this); + this._onDeleteKey = this._onDeleteKey.bind(this); + // If element has already been initialised with Choices, fail silently + if (this.passedElement.isActive) { + if (!config.silent) { + console.warn('Trying to initialise Choices on element already initialised', { element: element }); + } + this.initialised = true; + this.initialisedOK = false; + return; + } + // Let's go + this.init(); + // preserve the selected item list after setup for form reset + this._initialItems = this._store.items.map(function (choice) { return choice.value; }); } - record.$[keyIndex] = subRecords; - } else if (isString(value) && !isBlank(value)) { - let subRecord = { - v: value, - n: this.norm.get(value) + Object.defineProperty(Choices, "defaults", { + get: function () { + return Object.preventExtensions({ + get options() { + return USER_DEFAULTS; + }, + get allOptions() { + return DEFAULT_CONFIG; + }, + get templates() { + return templates; + }, + }); + }, + enumerable: false, + configurable: true + }); + Choices.prototype.init = function () { + if (this.initialised || this.initialisedOK !== undefined) { + return; + } + this._searcher = getSearcher(this.config); + this._loadChoices(); + this._createTemplates(); + this._createElements(); + this._createStructure(); + if ((this._isTextElement && !this.config.addItems) || + this.passedElement.element.hasAttribute('disabled') || + !!this.passedElement.element.closest('fieldset:disabled')) { + this.disable(); + } + else { + this.enable(); + this._addEventListeners(); + } + // should be triggered **after** disabled state to avoid additional re-draws + this._initStore(); + this.initialised = true; + this.initialisedOK = true; + var callbackOnInit = this.config.callbackOnInit; + // Run callback if it is a function + if (typeof callbackOnInit === 'function') { + callbackOnInit.call(this); + } }; - - record.$[keyIndex] = subRecord; - } - }); - - this.records.push(record); - } - toJSON() { - return { - keys: this.keys, - records: this.records - } - } -} - -function createIndex( - keys, - docs, - { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {} -) { - const myIndex = new FuseIndex({ getFn, fieldNormWeight }); - myIndex.setKeys(keys.map(createKey)); - myIndex.setSources(docs); - myIndex.create(); - return myIndex -} - -function parseIndex( - data, - { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {} -) { - const { keys, records } = data; - const myIndex = new FuseIndex({ getFn, fieldNormWeight }); - myIndex.setKeys(keys); - myIndex.setIndexRecords(records); - return myIndex -} - -function computeScore$1( - pattern, - { - errors = 0, - currentLocation = 0, - expectedLocation = 0, - distance = Config.distance, - ignoreLocation = Config.ignoreLocation - } = {} -) { - const accuracy = errors / pattern.length; - - if (ignoreLocation) { - return accuracy - } - - const proximity = Math.abs(expectedLocation - currentLocation); - - if (!distance) { - // Dodge divide by zero error. - return proximity ? 1.0 : accuracy - } - - return accuracy + proximity / distance -} - -function convertMaskToIndices( - matchmask = [], - minMatchCharLength = Config.minMatchCharLength -) { - let indices = []; - let start = -1; - let end = -1; - let i = 0; - - for (let len = matchmask.length; i < len; i += 1) { - let match = matchmask[i]; - if (match && start === -1) { - start = i; - } else if (!match && start !== -1) { - end = i - 1; - if (end - start + 1 >= minMatchCharLength) { - indices.push([start, end]); - } - start = -1; - } - } - - // (i-1 - start) + 1 => i - start - if (matchmask[i - 1] && i - start >= minMatchCharLength) { - indices.push([start, i - 1]); - } - - return indices -} - -// Machine word size -const MAX_BITS = 32; - -function search( - text, - pattern, - patternAlphabet, - { - location = Config.location, - distance = Config.distance, - threshold = Config.threshold, - findAllMatches = Config.findAllMatches, - minMatchCharLength = Config.minMatchCharLength, - includeMatches = Config.includeMatches, - ignoreLocation = Config.ignoreLocation - } = {} -) { - if (pattern.length > MAX_BITS) { - throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS)) - } - - const patternLen = pattern.length; - // Set starting location at beginning text and initialize the alphabet. - const textLen = text.length; - // Handle the case when location > text.length - const expectedLocation = Math.max(0, Math.min(location, textLen)); - // Highest score beyond which we give up. - let currentThreshold = threshold; - // Is there a nearby exact match? (speedup) - let bestLocation = expectedLocation; - - // Performance: only computer matches when the minMatchCharLength > 1 - // OR if `includeMatches` is true. - const computeMatches = minMatchCharLength > 1 || includeMatches; - // A mask of the matches, used for building the indices - const matchMask = computeMatches ? Array(textLen) : []; - - let index; - - // Get all exact matches, here for speed up - while ((index = text.indexOf(pattern, bestLocation)) > -1) { - let score = computeScore$1(pattern, { - currentLocation: index, - expectedLocation, - distance, - ignoreLocation - }); - - currentThreshold = Math.min(score, currentThreshold); - bestLocation = index + patternLen; - - if (computeMatches) { - let i = 0; - while (i < patternLen) { - matchMask[index + i] = 1; - i += 1; - } - } - } - - // Reset the best location - bestLocation = -1; - - let lastBitArr = []; - let finalScore = 1; - let binMax = patternLen + textLen; - - const mask = 1 << (patternLen - 1); - - for (let i = 0; i < patternLen; i += 1) { - // Scan for the best match; each iteration allows for one more error. - // Run a binary search to determine how far from the match location we can stray - // at this error level. - let binMin = 0; - let binMid = binMax; - - while (binMin < binMid) { - const score = computeScore$1(pattern, { - errors: i, - currentLocation: expectedLocation + binMid, - expectedLocation, - distance, - ignoreLocation - }); - - if (score <= currentThreshold) { - binMin = binMid; - } else { - binMax = binMid; - } - - binMid = Math.floor((binMax - binMin) / 2 + binMin); - } - - // Use the result from this iteration as the maximum for the next. - binMax = binMid; - - let start = Math.max(1, expectedLocation - binMid + 1); - let finish = findAllMatches - ? textLen - : Math.min(expectedLocation + binMid, textLen) + patternLen; - - // Initialize the bit array - let bitArr = Array(finish + 2); - - bitArr[finish + 1] = (1 << i) - 1; - - for (let j = finish; j >= start; j -= 1) { - let currentLocation = j - 1; - let charMatch = patternAlphabet[text.charAt(currentLocation)]; - - if (computeMatches) { - // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`) - matchMask[currentLocation] = +!!charMatch; - } - - // First pass: exact match - bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch; - - // Subsequent passes: fuzzy match - if (i) { - bitArr[j] |= - ((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1 | lastBitArr[j + 1]; - } - - if (bitArr[j] & mask) { - finalScore = computeScore$1(pattern, { - errors: i, - currentLocation, - expectedLocation, - distance, - ignoreLocation - }); - - // This match will almost certainly be better than any existing match. - // But check anyway. - if (finalScore <= currentThreshold) { - // Indeed it is - currentThreshold = finalScore; - bestLocation = currentLocation; - - // Already passed `loc`, downhill from here on in. - if (bestLocation <= expectedLocation) { - break - } - - // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`. - start = Math.max(1, 2 * expectedLocation - bestLocation); - } - } - } - - // No hope for a (better) match at greater error levels. - const score = computeScore$1(pattern, { - errors: i + 1, - currentLocation: expectedLocation, - expectedLocation, - distance, - ignoreLocation - }); - - if (score > currentThreshold) { - break - } - - lastBitArr = bitArr; - } - - const result = { - isMatch: bestLocation >= 0, - // Count exact matches (those with a score of 0) to be "almost" exact - score: Math.max(0.001, finalScore) - }; - - if (computeMatches) { - const indices = convertMaskToIndices(matchMask, minMatchCharLength); - if (!indices.length) { - result.isMatch = false; - } else if (includeMatches) { - result.indices = indices; - } - } - - return result -} - -function createPatternAlphabet(pattern) { - let mask = {}; - - for (let i = 0, len = pattern.length; i < len; i += 1) { - const char = pattern.charAt(i); - mask[char] = (mask[char] || 0) | (1 << (len - i - 1)); - } - - return mask -} - -class BitapSearch { - constructor( - pattern, - { - location = Config.location, - threshold = Config.threshold, - distance = Config.distance, - includeMatches = Config.includeMatches, - findAllMatches = Config.findAllMatches, - minMatchCharLength = Config.minMatchCharLength, - isCaseSensitive = Config.isCaseSensitive, - ignoreLocation = Config.ignoreLocation - } = {} - ) { - this.options = { - location, - threshold, - distance, - includeMatches, - findAllMatches, - minMatchCharLength, - isCaseSensitive, - ignoreLocation - }; - - this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); - - this.chunks = []; - - if (!this.pattern.length) { - return - } - - const addChunk = (pattern, startIndex) => { - this.chunks.push({ - pattern, - alphabet: createPatternAlphabet(pattern), - startIndex - }); - }; - - const len = this.pattern.length; - - if (len > MAX_BITS) { - let i = 0; - const remainder = len % MAX_BITS; - const end = len - remainder; - - while (i < end) { - addChunk(this.pattern.substr(i, MAX_BITS), i); - i += MAX_BITS; - } - - if (remainder) { - const startIndex = len - MAX_BITS; - addChunk(this.pattern.substr(startIndex), startIndex); - } - } else { - addChunk(this.pattern, 0); - } - } - - searchIn(text) { - const { isCaseSensitive, includeMatches } = this.options; - - if (!isCaseSensitive) { - text = text.toLowerCase(); - } - - // Exact match - if (this.pattern === text) { - let result = { - isMatch: true, - score: 0 - }; - - if (includeMatches) { - result.indices = [[0, text.length - 1]]; - } - - return result - } - - // Otherwise, use Bitap algorithm - const { - location, - distance, - threshold, - findAllMatches, - minMatchCharLength, - ignoreLocation - } = this.options; - - let allIndices = []; - let totalScore = 0; - let hasMatches = false; - - this.chunks.forEach(({ pattern, alphabet, startIndex }) => { - const { isMatch, score, indices } = search(text, pattern, alphabet, { - location: location + startIndex, - distance, - threshold, - findAllMatches, - minMatchCharLength, - includeMatches, - ignoreLocation - }); - - if (isMatch) { - hasMatches = true; - } - - totalScore += score; - - if (isMatch && indices) { - allIndices = [...allIndices, ...indices]; - } - }); - - let result = { - isMatch: hasMatches, - score: hasMatches ? totalScore / this.chunks.length : 1 - }; - - if (hasMatches && includeMatches) { - result.indices = allIndices; - } - - return result - } -} - -class BaseMatch { - constructor(pattern) { - this.pattern = pattern; - } - static isMultiMatch(pattern) { - return getMatch(pattern, this.multiRegex) - } - static isSingleMatch(pattern) { - return getMatch(pattern, this.singleRegex) - } - search(/*text*/) {} -} - -function getMatch(pattern, exp) { - const matches = pattern.match(exp); - return matches ? matches[1] : null -} - -// Token: 'file - -class ExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'exact' - } - static get multiRegex() { - return /^="(.*)"$/ - } - static get singleRegex() { - return /^=(.*)$/ - } - search(text) { - const isMatch = text === this.pattern; - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, this.pattern.length - 1] - } - } -} - -// Token: !fire - -class InverseExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'inverse-exact' - } - static get multiRegex() { - return /^!"(.*)"$/ - } - static get singleRegex() { - return /^!(.*)$/ - } - search(text) { - const index = text.indexOf(this.pattern); - const isMatch = index === -1; - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, text.length - 1] - } - } -} - -// Token: ^file - -class PrefixExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'prefix-exact' - } - static get multiRegex() { - return /^\^"(.*)"$/ - } - static get singleRegex() { - return /^\^(.*)$/ - } - search(text) { - const isMatch = text.startsWith(this.pattern); - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, this.pattern.length - 1] - } - } -} - -// Token: !^fire - -class InversePrefixExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'inverse-prefix-exact' - } - static get multiRegex() { - return /^!\^"(.*)"$/ - } - static get singleRegex() { - return /^!\^(.*)$/ - } - search(text) { - const isMatch = !text.startsWith(this.pattern); - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, text.length - 1] - } - } -} - -// Token: .file$ - -class SuffixExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'suffix-exact' - } - static get multiRegex() { - return /^"(.*)"\$$/ - } - static get singleRegex() { - return /^(.*)\$$/ - } - search(text) { - const isMatch = text.endsWith(this.pattern); - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [text.length - this.pattern.length, text.length - 1] - } - } -} - -// Token: !.file$ - -class InverseSuffixExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'inverse-suffix-exact' - } - static get multiRegex() { - return /^!"(.*)"\$$/ - } - static get singleRegex() { - return /^!(.*)\$$/ - } - search(text) { - const isMatch = !text.endsWith(this.pattern); - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, text.length - 1] - } - } -} - -class FuzzyMatch extends BaseMatch { - constructor( - pattern, - { - location = Config.location, - threshold = Config.threshold, - distance = Config.distance, - includeMatches = Config.includeMatches, - findAllMatches = Config.findAllMatches, - minMatchCharLength = Config.minMatchCharLength, - isCaseSensitive = Config.isCaseSensitive, - ignoreLocation = Config.ignoreLocation - } = {} - ) { - super(pattern); - this._bitapSearch = new BitapSearch(pattern, { - location, - threshold, - distance, - includeMatches, - findAllMatches, - minMatchCharLength, - isCaseSensitive, - ignoreLocation - }); - } - static get type() { - return 'fuzzy' - } - static get multiRegex() { - return /^"(.*)"$/ - } - static get singleRegex() { - return /^(.*)$/ - } - search(text) { - return this._bitapSearch.searchIn(text) - } -} - -// Token: 'file - -class IncludeMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'include' - } - static get multiRegex() { - return /^'"(.*)"$/ - } - static get singleRegex() { - return /^'(.*)$/ - } - search(text) { - let location = 0; - let index; - - const indices = []; - const patternLen = this.pattern.length; - - // Get all exact matches - while ((index = text.indexOf(this.pattern, location)) > -1) { - location = index + patternLen; - indices.push([index, location - 1]); - } - - const isMatch = !!indices.length; - - return { - isMatch, - score: isMatch ? 0 : 1, - indices - } - } -} - -// ❗Order is important. DO NOT CHANGE. -const searchers = [ - ExactMatch, - IncludeMatch, - PrefixExactMatch, - InversePrefixExactMatch, - InverseSuffixExactMatch, - SuffixExactMatch, - InverseExactMatch, - FuzzyMatch -]; - -const searchersLen = searchers.length; - -// Regex to split by spaces, but keep anything in quotes together -const SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/; -const OR_TOKEN = '|'; - -// Return a 2D array representation of the query, for simpler parsing. -// Example: -// "^core go$ | rb$ | py$ xy$" => [["^core", "go$"], ["rb$"], ["py$", "xy$"]] -function parseQuery(pattern, options = {}) { - return pattern.split(OR_TOKEN).map((item) => { - let query = item - .trim() - .split(SPACE_RE) - .filter((item) => item && !!item.trim()); - - let results = []; - for (let i = 0, len = query.length; i < len; i += 1) { - const queryItem = query[i]; - - // 1. Handle multiple query match (i.e, once that are quoted, like `"hello world"`) - let found = false; - let idx = -1; - while (!found && ++idx < searchersLen) { - const searcher = searchers[idx]; - let token = searcher.isMultiMatch(queryItem); - if (token) { - results.push(new searcher(token, options)); - found = true; - } - } - - if (found) { - continue - } - - // 2. Handle single query matches (i.e, once that are *not* quoted) - idx = -1; - while (++idx < searchersLen) { - const searcher = searchers[idx]; - let token = searcher.isSingleMatch(queryItem); - if (token) { - results.push(new searcher(token, options)); - break - } - } - } - - return results - }) -} - -// These extended matchers can return an array of matches, as opposed -// to a singl match -const MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]); - -/** - * Command-like searching - * ====================== - * - * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`, - * search in a given text. - * - * Search syntax: - * - * | Token | Match type | Description | - * | ----------- | -------------------------- | -------------------------------------- | - * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` | - * | `=scheme` | exact-match | Items that are `scheme` | - * | `'python` | include-match | Items that include `python` | - * | `!ruby` | inverse-exact-match | Items that do not include `ruby` | - * | `^java` | prefix-exact-match | Items that start with `java` | - * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` | - * | `.js$` | suffix-exact-match | Items that end with `.js` | - * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` | - * - * A single pipe character acts as an OR operator. For example, the following - * query matches entries that start with `core` and end with either`go`, `rb`, - * or`py`. - * - * ``` - * ^core go$ | rb$ | py$ - * ``` - */ -class ExtendedSearch { - constructor( - pattern, - { - isCaseSensitive = Config.isCaseSensitive, - includeMatches = Config.includeMatches, - minMatchCharLength = Config.minMatchCharLength, - ignoreLocation = Config.ignoreLocation, - findAllMatches = Config.findAllMatches, - location = Config.location, - threshold = Config.threshold, - distance = Config.distance - } = {} - ) { - this.query = null; - this.options = { - isCaseSensitive, - includeMatches, - minMatchCharLength, - findAllMatches, - ignoreLocation, - location, - threshold, - distance - }; - - this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); - this.query = parseQuery(this.pattern, this.options); - } - - static condition(_, options) { - return options.useExtendedSearch - } - - searchIn(text) { - const query = this.query; - - if (!query) { - return { - isMatch: false, - score: 1 - } - } - - const { includeMatches, isCaseSensitive } = this.options; - - text = isCaseSensitive ? text : text.toLowerCase(); - - let numMatches = 0; - let allIndices = []; - let totalScore = 0; - - // ORs - for (let i = 0, qLen = query.length; i < qLen; i += 1) { - const searchers = query[i]; - - // Reset indices - allIndices.length = 0; - numMatches = 0; - - // ANDs - for (let j = 0, pLen = searchers.length; j < pLen; j += 1) { - const searcher = searchers[j]; - const { isMatch, indices, score } = searcher.search(text); - - if (isMatch) { - numMatches += 1; - totalScore += score; - if (includeMatches) { - const type = searcher.constructor.type; - if (MultiMatchSet.has(type)) { - allIndices = [...allIndices, ...indices]; - } else { - allIndices.push(indices); + Choices.prototype.destroy = function () { + if (!this.initialised) { + return; + } + this._removeEventListeners(); + this.passedElement.reveal(); + this.containerOuter.unwrap(this.passedElement.element); + this._store._listeners = []; // prevents select/input value being wiped + this.clearStore(); + this._stopSearch(); + this._templates = Choices.defaults.templates; + this.initialised = false; + this.initialisedOK = undefined; + }; + Choices.prototype.enable = function () { + if (this.passedElement.isDisabled) { + this.passedElement.enable(); + } + if (this.containerOuter.isDisabled) { + this._addEventListeners(); + this.input.enable(); + this.containerOuter.enable(); + } + return this; + }; + Choices.prototype.disable = function () { + if (!this.passedElement.isDisabled) { + this.passedElement.disable(); + } + if (!this.containerOuter.isDisabled) { + this._removeEventListeners(); + this.input.disable(); + this.containerOuter.disable(); + } + return this; + }; + Choices.prototype.highlightItem = function (item, runEvent) { + if (runEvent === void 0) { runEvent = true; } + if (!item || !item.id) { + return this; + } + var choice = this._store.items.find(function (c) { return c.id === item.id; }); + if (!choice || choice.highlighted) { + return this; + } + this._store.dispatch(highlightItem(choice, true)); + if (runEvent) { + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice)); + } + return this; + }; + Choices.prototype.unhighlightItem = function (item, runEvent) { + if (runEvent === void 0) { runEvent = true; } + if (!item || !item.id) { + return this; + } + var choice = this._store.items.find(function (c) { return c.id === item.id; }); + if (!choice || !choice.highlighted) { + return this; + } + this._store.dispatch(highlightItem(choice, false)); + if (runEvent) { + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice)); + } + return this; + }; + Choices.prototype.highlightAll = function () { + var _this = this; + this._store.withTxn(function () { + _this._store.items.forEach(function (item) { + if (!item.highlighted) { + _this._store.dispatch(highlightItem(item, true)); + _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item)); + } + }); + }); + return this; + }; + Choices.prototype.unhighlightAll = function () { + var _this = this; + this._store.withTxn(function () { + _this._store.items.forEach(function (item) { + if (item.highlighted) { + _this._store.dispatch(highlightItem(item, false)); + _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item)); + } + }); + }); + return this; + }; + Choices.prototype.removeActiveItemsByValue = function (value) { + var _this = this; + this._store.withTxn(function () { + _this._store.items.filter(function (item) { return item.value === value; }).forEach(function (item) { return _this._removeItem(item); }); + }); + return this; + }; + Choices.prototype.removeActiveItems = function (excludedId) { + var _this = this; + this._store.withTxn(function () { + _this._store.items.filter(function (_a) { + var id = _a.id; + return id !== excludedId; + }).forEach(function (item) { return _this._removeItem(item); }); + }); + return this; + }; + Choices.prototype.removeHighlightedItems = function (runEvent) { + var _this = this; + if (runEvent === void 0) { runEvent = false; } + this._store.withTxn(function () { + _this._store.highlightedActiveItems.forEach(function (item) { + _this._removeItem(item); + // If this action was performed by the user + // trigger the event + if (runEvent) { + _this._triggerChange(item.value); + } + }); + }); + return this; + }; + Choices.prototype.showDropdown = function (preventInputFocus) { + var _this = this; + if (this.dropdown.isActive) { + return this; + } + requestAnimationFrame(function () { + _this.dropdown.show(); + var rect = _this.dropdown.element.getBoundingClientRect(); + _this.containerOuter.open(rect.bottom, rect.height); + if (!preventInputFocus && _this._canSearch) { + _this.input.focus(); + } + _this.passedElement.triggerEvent(EventType.showDropdown); + }); + return this; + }; + Choices.prototype.hideDropdown = function (preventInputBlur) { + var _this = this; + if (!this.dropdown.isActive) { + return this; + } + requestAnimationFrame(function () { + _this.dropdown.hide(); + _this.containerOuter.close(); + if (!preventInputBlur && _this._canSearch) { + _this.input.removeActiveDescendant(); + _this.input.blur(); + } + _this.passedElement.triggerEvent(EventType.hideDropdown); + }); + return this; + }; + Choices.prototype.getValue = function (valueOnly) { + var _this = this; + if (valueOnly === void 0) { valueOnly = false; } + var values = this._store.items.reduce(function (selectedItems, item) { + var itemValue = valueOnly ? item.value : _this._getChoiceForOutput(item); + selectedItems.push(itemValue); + return selectedItems; + }, []); + return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values; + }; + Choices.prototype.setValue = function (items) { + var _this = this; + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setValue'); + return this; + } + this._store.withTxn(function () { + items.forEach(function (value) { + if (value) { + _this._addChoice(mapInputToChoice(value, false)); + } + }); + }); + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + Choices.prototype.setChoiceByValue = function (value) { + var _this = this; + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setChoiceByValue'); + return this; + } + if (this._isTextElement) { + return this; + } + this._store.withTxn(function () { + // If only one value has been passed, convert to array + var choiceValue = Array.isArray(value) ? value : [value]; + // Loop through each value and + choiceValue.forEach(function (val) { return _this._findAndSelectChoiceByValue(val); }); + _this.unhighlightAll(); + }); + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + /** + * Set choices of select input via an array of objects (or function that returns array of object or promise of it), + * a value field name and a label field name. + * This behaves the same as passing items via the choices option but can be called after initialising Choices. + * This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices. + * Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc). + * + * **Input types affected:** select-one, select-multiple + * + * @example + * ```js + * const example = new Choices(element); + * + * example.setChoices([ + * {value: 'One', label: 'Label One', disabled: true}, + * {value: 'Two', label: 'Label Two', selected: true}, + * {value: 'Three', label: 'Label Three'}, + * ], 'value', 'label', false); + * ``` + * + * @example + * ```js + * const example = new Choices(element); + * + * example.setChoices(async () => { + * try { + * const items = await fetch('/items'); + * return items.json() + * } catch(err) { + * console.error(err) + * } + * }); + * ``` + * + * @example + * ```js + * const example = new Choices(element); + * + * example.setChoices([{ + * label: 'Group one', + * id: 1, + * disabled: false, + * choices: [ + * {value: 'Child One', label: 'Child One', selected: true}, + * {value: 'Child Two', label: 'Child Two', disabled: true}, + * {value: 'Child Three', label: 'Child Three'}, + * ] + * }, + * { + * label: 'Group two', + * id: 2, + * disabled: false, + * choices: [ + * {value: 'Child Four', label: 'Child Four', disabled: true}, + * {value: 'Child Five', label: 'Child Five'}, + * {value: 'Child Six', label: 'Child Six', customProperties: { + * description: 'Custom description about child six', + * random: 'Another random custom property' + * }}, + * ] + * }], 'value', 'label', false); + * ``` + */ + Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices) { + var _this = this; + if (choicesArrayOrFetcher === void 0) { choicesArrayOrFetcher = []; } + if (value === void 0) { value = 'value'; } + if (label === void 0) { label = 'label'; } + if (replaceChoices === void 0) { replaceChoices = false; } + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setChoices'); + return this; + } + if (!this._isSelectElement) { + throw new TypeError("setChoices can't be used with INPUT based Choices"); + } + if (typeof value !== 'string' || !value) { + throw new TypeError("value parameter must be a name of 'value' field in passed objects"); + } + // Clear choices if needed + if (replaceChoices) { + this.clearChoices(); + } + if (typeof choicesArrayOrFetcher === 'function') { + // it's a choices fetcher function + var fetcher_1 = choicesArrayOrFetcher(this); + if (typeof Promise === 'function' && fetcher_1 instanceof Promise) { + // that's a promise + // eslint-disable-next-line no-promise-executor-return + return new Promise(function (resolve) { return requestAnimationFrame(resolve); }) + .then(function () { return _this._handleLoadingState(true); }) + .then(function () { return fetcher_1; }) + .then(function (data) { return _this.setChoices(data, value, label, replaceChoices); }) + .catch(function (err) { + if (!_this.config.silent) { + console.error(err); + } + }) + .then(function () { return _this._handleLoadingState(false); }) + .then(function () { return _this; }); + } + // function returned something else than promise, let's check if it's an array of choices + if (!Array.isArray(fetcher_1)) { + throw new TypeError(".setChoices first argument function must return either array of choices or Promise, got: ".concat(typeof fetcher_1)); + } + // recursion with results, it's sync and choices were cleared already + return this.setChoices(fetcher_1, value, label, false); + } + if (!Array.isArray(choicesArrayOrFetcher)) { + throw new TypeError(".setChoices must be called either with array of choices with a function resulting into Promise of array of choices"); + } + this.containerOuter.removeLoadingState(); + this._store.withTxn(function () { + var isDefaultValue = value === 'value'; + var isDefaultLabel = label === 'label'; + choicesArrayOrFetcher.forEach(function (groupOrChoice) { + if ('choices' in groupOrChoice) { + var group = groupOrChoice; + if (!isDefaultLabel) { + group = __assign(__assign({}, group), { label: group[label] }); + } + _this._addGroup(mapInputToChoice(group, true)); + } + else { + var choice = groupOrChoice; + if (!isDefaultLabel || !isDefaultValue) { + choice = __assign(__assign({}, choice), { value: choice[value], label: choice[label] }); + } + _this._addChoice(mapInputToChoice(choice, false)); + } + }); + _this.unhighlightAll(); + }); + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + Choices.prototype.refresh = function (withEvents, selectFirstOption, deselectAll) { + var _this = this; + if (withEvents === void 0) { withEvents = false; } + if (selectFirstOption === void 0) { selectFirstOption = false; } + if (deselectAll === void 0) { deselectAll = false; } + if (!this._isSelectElement) { + if (!this.config.silent) { + console.warn('refresh method can only be used on choices backed by a element'); + } + return this; + } + this._store.withTxn(function () { + var choicesFromOptions = _this.passedElement.optionsAsChoices(); + // Build the list of items which require preserving + var existingItems = {}; + if (!deselectAll) { + _this._store.items.forEach(function (choice) { + if (choice.id && choice.active && choice.selected && !choice.disabled) { + existingItems[choice.value] = true; + } + }); + } + _this.clearStore(); + choicesFromOptions.forEach(function (groupOrChoice) { + if ('choices' in groupOrChoice) { + return; + } + var choice = groupOrChoice; + if (deselectAll) { + _this._store.dispatch(removeItem$1(choice)); + } + else if (existingItems[choice.value]) { + choice.selected = true; + } + }); + /* @todo only generate add events for the added options instead of all + if (withEvents) { + items.forEach((choice) => { + if (existingItems[choice.value]) { + this.passedElement.triggerEvent( + EventType.removeItem, + this._getChoiceForEvent(choice), + ); + } + }); + } + */ + // load new choices & items + _this._addPredefinedChoices(choicesFromOptions, selectFirstOption, withEvents); + // re-do search if required + if (_this._isSearching) { + _this._searchChoices(_this.input.value); + } + }); + return this; + }; + Choices.prototype.removeChoice = function (value) { + var choice = this._store.choices.find(function (c) { return c.value === value; }); + if (!choice) { + return this; + } + this._store.dispatch(removeChoice(choice)); + // @todo integrate with Store + this._searcher.reset(); + if (choice.selected) { + this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(choice)); + } + return this; + }; + Choices.prototype.clearChoices = function () { + this.passedElement.element.replaceChildren(''); + return this.clearStore(); + }; + Choices.prototype.clearStore = function () { + this.itemList.element.replaceChildren(''); + this.choiceList.element.replaceChildren(''); + this._clearNotice(); + this._store.reset(); + this._lastAddedChoiceId = 0; + this._lastAddedGroupId = 0; + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + Choices.prototype.clearInput = function () { + var shouldSetInputWidth = !this._isSelectOneElement; + this.input.clear(shouldSetInputWidth); + this._clearNotice(); + if (this._isSearching) { + this._stopSearch(); + } + return this; + }; + Choices.prototype._validateConfig = function () { + var config = this.config; + var invalidConfigOptions = diff(config, DEFAULT_CONFIG); + if (invalidConfigOptions.length) { + console.warn('Unknown config option(s) passed', invalidConfigOptions.join(', ')); + } + if (config.allowHTML && config.allowHtmlUserInput) { + if (config.addItems) { + console.warn('Warning: allowHTML/allowHtmlUserInput/addItems all being true is strongly not recommended and may lead to XSS attacks'); + } + if (config.addChoices) { + console.warn('Warning: allowHTML/allowHtmlUserInput/addChoices all being true is strongly not recommended and may lead to XSS attacks'); + } + } + }; + Choices.prototype._render = function (changes) { + if (changes === void 0) { changes = { choices: true, groups: true, items: true }; } + if (this._store.inTxn()) { + return; + } + if (this._isSelectElement) { + if (changes.choices || changes.groups) { + this._renderChoices(); + } + } + if (changes.items) { + this._renderItems(); + } + }; + Choices.prototype._renderChoices = function () { + var _this = this; + if (!this._canAddItems()) { + return; // block rendering choices if the input limit is reached. + } + var _a = this, config = _a.config, isSearching = _a._isSearching; + var _b = this._store, activeGroups = _b.activeGroups, activeChoices = _b.activeChoices; + var renderLimit = 0; + if (isSearching && config.searchResultLimit > 0) { + renderLimit = config.searchResultLimit; + } + else if (config.renderChoiceLimit > 0) { + renderLimit = config.renderChoiceLimit; + } + if (this._isSelectElement) { + var backingOptions = activeChoices.filter(function (choice) { return !choice.element; }); + if (backingOptions.length) { + this.passedElement.addOptions(backingOptions); + } + } + var fragment = document.createDocumentFragment(); + var renderableChoices = function (choices) { + return choices.filter(function (choice) { + return !choice.placeholder && (isSearching ? !!choice.rank : config.renderSelectedChoices || !choice.selected); + }); + }; + var selectableChoices = this._isSelectOneElement; + var renderChoices = function (choices, withinGroup, groupLabel) { + if (isSearching) { + // sortByRank is used to ensure stable sorting, as scores are non-unique + // this additionally ensures fuseOptions.sortFn is not ignored + choices.sort(sortByRank); + } + else if (config.shouldSort) { + choices.sort(config.sorter); + } + var choiceLimit = choices.length; + choiceLimit = !withinGroup && renderLimit && choiceLimit > renderLimit ? renderLimit : choiceLimit; + choiceLimit--; + choices.every(function (choice, index) { + // choiceEl being empty signals the contents has probably significantly changed + var dropdownItem = choice.choiceEl || _this._templates.choice(config, choice, config.itemSelectText, groupLabel); + choice.choiceEl = dropdownItem; + fragment.appendChild(dropdownItem); + if (isSearching || !choice.selected) { + selectableChoices = true; + } + return index < choiceLimit; + }); + }; + if (activeChoices.length) { + if (config.resetScrollPosition) { + requestAnimationFrame(function () { return _this.choiceList.scrollToTop(); }); + } + if (!this._hasNonChoicePlaceholder && !isSearching && this._isSelectOneElement) { + // If we have a placeholder choice along with groups + renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.groupId; }), false, undefined); + } + // If we have grouped options + if (activeGroups.length && !isSearching) { + if (config.shouldSort) { + activeGroups.sort(config.sorter); + } + activeGroups.forEach(function (group) { + var groupChoices = renderableChoices(group.choices); + if (groupChoices.length) { + if (group.label) { + var dropdownGroup = group.groupEl || _this._templates.choiceGroup(_this.config, group); + group.groupEl = dropdownGroup; + dropdownGroup.remove(); + fragment.appendChild(dropdownGroup); + } + renderChoices(groupChoices, true, config.appendGroupInSearch && isSearching ? group.label : undefined); + } + }); + } + else { + renderChoices(renderableChoices(activeChoices), false, undefined); + } + } + var notice = this._notice; + if (!selectableChoices) { + if (!notice) { + this._notice = { + text: resolveStringFunction(config.noChoicesText), + type: NoticeTypes.noChoices, + }; + } + fragment.replaceChildren(''); + } + else if (notice && notice.type === NoticeTypes.noChoices) { + this._notice = undefined; + } + this._renderNotice(fragment); + this.choiceList.element.replaceChildren(fragment); + if (selectableChoices) { + this._highlightChoice(); + } + }; + Choices.prototype._renderItems = function () { + var _this = this; + var items = this._store.items || []; + var itemList = this.itemList.element; + var config = this.config; + var fragment = document.createDocumentFragment(); + var itemFromList = function (item) { + return itemList.querySelector("[data-item][data-id=\"".concat(item.id, "\"]")); + }; + var addItemToFragment = function (item) { + var el = item.itemEl; + if (el && el.parentElement) { + return; + } + el = itemFromList(item) || _this._templates.item(config, item, config.removeItemButton); + item.itemEl = el; + fragment.appendChild(el); + }; + // new items + items.forEach(addItemToFragment); + var addItems = !!fragment.childNodes.length; + if (this._isSelectOneElement && this._hasNonChoicePlaceholder) { + var existingItems = itemList.children.length; + if (addItems || existingItems > 1) { + var placeholder = itemList.querySelector(getClassNamesSelector(config.classNames.placeholder)); + if (placeholder) { + placeholder.remove(); + } + } + else if (!existingItems) { + addItems = true; + addItemToFragment(mapInputToChoice({ + selected: true, + value: '', + label: config.placeholderValue || '', + placeholder: true, + }, false)); + } + } + if (addItems) { + itemList.append(fragment); + if (config.shouldSortItems && !this._isSelectOneElement) { + items.sort(config.sorter); + // push sorting into the DOM + items.forEach(function (item) { + var el = itemFromList(item); + if (el) { + el.remove(); + fragment.append(el); + } + }); + itemList.append(fragment); + } + } + if (this._isTextElement) { + // Update the value of the hidden input + this.passedElement.value = items.map(function (_a) { + var value = _a.value; + return value; + }).join(config.delimiter); + } + }; + Choices.prototype._displayNotice = function (text, type, openDropdown) { + if (openDropdown === void 0) { openDropdown = true; } + var oldNotice = this._notice; + if (oldNotice && + ((oldNotice.type === type && oldNotice.text === text) || + (oldNotice.type === NoticeTypes.addChoice && + (type === NoticeTypes.noResults || type === NoticeTypes.noChoices)))) { + if (openDropdown) { + this.showDropdown(true); + } + return; + } + this._clearNotice(); + this._notice = text + ? { + text: text, + type: type, + } + : undefined; + this._renderNotice(); + if (openDropdown && text) { + this.showDropdown(true); + } + }; + Choices.prototype._clearNotice = function () { + if (!this._notice) { + return; + } + var noticeElement = this.choiceList.element.querySelector(getClassNamesSelector(this.config.classNames.notice)); + if (noticeElement) { + noticeElement.remove(); + } + this._notice = undefined; + }; + Choices.prototype._renderNotice = function (fragment) { + var noticeConf = this._notice; + if (noticeConf) { + var notice = this._templates.notice(this.config, noticeConf.text, noticeConf.type); + if (fragment) { + fragment.append(notice); + } + else { + this.choiceList.prepend(notice); + } + } + }; + Choices.prototype._getChoiceForOutput = function (choice, keyCode) { + if (!choice) { + return undefined; + } + var group = choice.groupId ? this._store.getGroupById(choice.groupId) : null; + return { + id: choice.id, + highlighted: choice.highlighted, + labelClass: choice.labelClass, + labelDescription: choice.labelDescription, + customProperties: choice.customProperties, + disabled: choice.disabled, + active: choice.active, + label: choice.label, + placeholder: choice.placeholder, + value: choice.value, + groupValue: group && group.label ? group.label : undefined, + element: choice.element, + keyCode: keyCode, + }; + }; + Choices.prototype._triggerChange = function (value) { + if (value === undefined || value === null) { + return; + } + this.passedElement.triggerEvent(EventType.change, { + value: value, + }); + }; + Choices.prototype._handleButtonAction = function (element) { + var _this = this; + var items = this._store.items; + if (!items.length || !this.config.removeItems || !this.config.removeItemButton) { + return; + } + var id = element && parseDataSetId(element.parentNode); + var itemToRemove = id && items.find(function (item) { return item.id === id; }); + if (!itemToRemove) { + return; + } + this._store.withTxn(function () { + // Remove item associated with button + _this._removeItem(itemToRemove); + _this._triggerChange(itemToRemove.value); + if (_this._isSelectOneElement && !_this._hasNonChoicePlaceholder) { + var placeholderChoice = _this._store.choices + .reverse() + .find(function (choice) { return !choice.disabled && choice.placeholder; }); + if (placeholderChoice) { + _this._addItem(placeholderChoice); + _this.unhighlightAll(); + if (placeholderChoice.value) { + _this._triggerChange(placeholderChoice.value); + } + } + } + }); + }; + Choices.prototype._handleItemAction = function (element, hasShiftKey) { + var _this = this; + if (hasShiftKey === void 0) { hasShiftKey = false; } + var items = this._store.items; + if (!items.length || !this.config.removeItems || this._isSelectOneElement) { + return; + } + var id = parseDataSetId(element); + if (!id) { + return; + } + // We only want to select one item with a click + // so we deselect any items that aren't the target + // unless shift is being pressed + items.forEach(function (item) { + if (item.id === id && !item.highlighted) { + _this.highlightItem(item); + } + else if (!hasShiftKey && item.highlighted) { + _this.unhighlightItem(item); + } + }); + // Focus input as without focus, a user cannot do anything with a + // highlighted item + this.input.focus(); + }; + Choices.prototype._handleChoiceAction = function (element) { + var _this = this; + // If we are clicking on an option + var id = parseDataSetId(element); + var choice = id && this._store.getChoiceById(id); + if (!choice || choice.disabled) { + return false; + } + var hasActiveDropdown = this.dropdown.isActive; + if (!choice.selected) { + if (!this._canAddItems()) { + return true; // causes _onEnterKey to early out + } + this._store.withTxn(function () { + _this._addItem(choice, true, true); + _this.clearInput(); + _this.unhighlightAll(); + }); + this._triggerChange(choice.value); + } + // We want to close the dropdown if we are dealing with a single select box + if (hasActiveDropdown && this.config.closeDropdownOnSelect) { + this.hideDropdown(true); + this.containerOuter.element.focus(); + } + return true; + }; + Choices.prototype._handleBackspace = function (items) { + var config = this.config; + if (!config.removeItems || !items.length) { + return; + } + var lastItem = items[items.length - 1]; + var hasHighlightedItems = items.some(function (item) { return item.highlighted; }); + // If editing the last item is allowed and there are not other selected items, + // we can edit the item value. Otherwise if we can remove items, remove all selected items + if (config.editItems && !hasHighlightedItems && lastItem) { + this.input.value = lastItem.value; + this.input.setWidth(); + this._removeItem(lastItem); + this._triggerChange(lastItem.value); + } + else { + if (!hasHighlightedItems) { + // Highlight last item if none already highlighted + this.highlightItem(lastItem, false); + } + this.removeHighlightedItems(true); + } + }; + Choices.prototype._loadChoices = function () { + var _a; + var config = this.config; + if (this._isTextElement) { + // Assign preset items from passed object first + this._presetChoices = config.items.map(function (e) { return mapInputToChoice(e, false); }); + // Add any values passed from attribute + if (this.passedElement.value) { + var elementItems = this.passedElement.value + .split(config.delimiter) + .map(function (e) { return mapInputToChoice(e, false); }); + this._presetChoices = this._presetChoices.concat(elementItems); + } + this._presetChoices.forEach(function (choice) { + choice.selected = true; + }); + } + else if (this._isSelectElement) { + // Assign preset choices from passed object + this._presetChoices = config.choices.map(function (e) { return mapInputToChoice(e, true); }); + // Create array of choices from option elements + var choicesFromOptions = this.passedElement.optionsAsChoices(); + if (choicesFromOptions) { + (_a = this._presetChoices).push.apply(_a, choicesFromOptions); + } + } + }; + Choices.prototype._handleLoadingState = function (setLoading) { + if (setLoading === void 0) { setLoading = true; } + var el = this.itemList.element; + if (setLoading) { + this.disable(); + this.containerOuter.addLoadingState(); + if (this._isSelectOneElement) { + el.replaceChildren(this._templates.placeholder(this.config, this.config.loadingText)); + } + else { + this.input.placeholder = this.config.loadingText; + } + } + else { + this.enable(); + this.containerOuter.removeLoadingState(); + if (this._isSelectOneElement) { + el.replaceChildren(''); + this._render(); + } + else { + this.input.placeholder = this._placeholderValue || ''; + } + } + }; + Choices.prototype._handleSearch = function (value) { + if (!this.input.isFocussed) { + return; + } + // Check that we have a value to search and the input was an alphanumeric character + if (value !== null && typeof value !== 'undefined' && value.length >= this.config.searchFloor) { + var resultCount = this.config.searchChoices ? this._searchChoices(value) : 0; + if (resultCount !== null) { + // Trigger search event + this.passedElement.triggerEvent(EventType.search, { + value: value, + resultCount: resultCount, + }); + } + } + else if (this._store.choices.some(function (option) { return !option.active; })) { + this._stopSearch(); + } + }; + Choices.prototype._canAddItems = function () { + var config = this.config; + var maxItemCount = config.maxItemCount, maxItemText = config.maxItemText; + if (!config.singleModeForMultiSelect && maxItemCount > 0 && maxItemCount <= this._store.items.length) { + this.choiceList.element.replaceChildren(''); + this._displayNotice(typeof maxItemText === 'function' ? maxItemText(maxItemCount) : maxItemText, NoticeTypes.addChoice); + return false; + } + return true; + }; + Choices.prototype._canCreateItem = function (value) { + var config = this.config; + var canAddItem = true; + var notice = ''; + if (canAddItem && typeof config.addItemFilter === 'function' && !config.addItemFilter(value)) { + canAddItem = false; + notice = resolveNoticeFunction(config.customAddItemText, value); + } + if (canAddItem) { + var foundChoice = this._store.choices.find(function (choice) { return config.valueComparer(choice.value, value); }); + if (this._isSelectElement) { + // for exact matches, do not prompt to add it as a custom choice + if (foundChoice) { + this._displayNotice('', NoticeTypes.addChoice); + return false; + } + } + else if (this._isTextElement && !config.duplicateItemsAllowed) { + if (foundChoice) { + canAddItem = false; + notice = resolveNoticeFunction(config.uniqueItemText, value); + } + } + } + if (canAddItem) { + notice = resolveNoticeFunction(config.addItemText, value); + } + if (notice) { + this._displayNotice(notice, NoticeTypes.addChoice); + } + return canAddItem; + }; + Choices.prototype._searchChoices = function (value) { + var newValue = value.trim().replace(/\s{2,}/, ' '); + // signal input didn't change search + if (!newValue.length || newValue === this._currentValue) { + return null; + } + var searcher = this._searcher; + if (searcher.isEmptyIndex()) { + searcher.index(this._store.searchableChoices); + } + // If new value matches the desired length and is not the same as the current value with a space + var results = searcher.search(newValue); + this._currentValue = newValue; + this._highlightPosition = 0; + this._isSearching = true; + var notice = this._notice; + var noticeType = notice && notice.type; + if (noticeType !== NoticeTypes.addChoice) { + if (!results.length) { + this._displayNotice(resolveStringFunction(this.config.noResultsText), NoticeTypes.noResults); + } + else if (noticeType === NoticeTypes.noResults) { + this._clearNotice(); + } + } + this._store.dispatch(filterChoices(results)); + return results.length; + }; + Choices.prototype._stopSearch = function () { + var wasSearching = this._isSearching; + this._currentValue = ''; + this._isSearching = false; + if (wasSearching) { + this._store.dispatch(activateChoices(true)); + this.passedElement.triggerEvent(EventType.search, { + value: '', + resultCount: 0, + }); + } + }; + Choices.prototype._addEventListeners = function () { + var documentElement = this._docRoot; + var outerElement = this.containerOuter.element; + var inputElement = this.input.element; + // capture events - can cancel event processing or propagation + documentElement.addEventListener('touchend', this._onTouchEnd, true); + outerElement.addEventListener('keydown', this._onKeyDown, true); + outerElement.addEventListener('mousedown', this._onMouseDown, true); + // passive events - doesn't call `preventDefault` or `stopPropagation` + documentElement.addEventListener('click', this._onClick, { passive: true }); + documentElement.addEventListener('touchmove', this._onTouchMove, { + passive: true, + }); + this.dropdown.element.addEventListener('mouseover', this._onMouseOver, { + passive: true, + }); + if (this._isSelectOneElement) { + outerElement.addEventListener('focus', this._onFocus, { + passive: true, + }); + outerElement.addEventListener('blur', this._onBlur, { + passive: true, + }); + } + inputElement.addEventListener('keyup', this._onKeyUp, { + passive: true, + }); + inputElement.addEventListener('input', this._onInput, { + passive: true, + }); + inputElement.addEventListener('focus', this._onFocus, { + passive: true, + }); + inputElement.addEventListener('blur', this._onBlur, { + passive: true, + }); + if (inputElement.form) { + inputElement.form.addEventListener('reset', this._onFormReset, { + passive: true, + }); + } + this.input.addEventListeners(); + }; + Choices.prototype._removeEventListeners = function () { + var documentElement = this._docRoot; + var outerElement = this.containerOuter.element; + var inputElement = this.input.element; + documentElement.removeEventListener('touchend', this._onTouchEnd, true); + outerElement.removeEventListener('keydown', this._onKeyDown, true); + outerElement.removeEventListener('mousedown', this._onMouseDown, true); + documentElement.removeEventListener('click', this._onClick); + documentElement.removeEventListener('touchmove', this._onTouchMove); + this.dropdown.element.removeEventListener('mouseover', this._onMouseOver); + if (this._isSelectOneElement) { + outerElement.removeEventListener('focus', this._onFocus); + outerElement.removeEventListener('blur', this._onBlur); + } + inputElement.removeEventListener('keyup', this._onKeyUp); + inputElement.removeEventListener('input', this._onInput); + inputElement.removeEventListener('focus', this._onFocus); + inputElement.removeEventListener('blur', this._onBlur); + if (inputElement.form) { + inputElement.form.removeEventListener('reset', this._onFormReset); + } + this.input.removeEventListeners(); + }; + Choices.prototype._onKeyDown = function (event) { + var keyCode = event.keyCode; + var hasActiveDropdown = this.dropdown.isActive; + /* + See: + https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key + https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values + https://en.wikipedia.org/wiki/UTF-16#Code_points_from_U+010000_to_U+10FFFF - UTF-16 surrogate pairs + https://stackoverflow.com/a/70866532 - "Unidentified" for mobile + http://www.unicode.org/versions/Unicode5.2.0/ch16.pdf#G19635 - U+FFFF is reserved (Section 16.7) + + Logic: when a key event is sent, `event.key` represents its printable value _or_ one + of a large list of special values indicating meta keys/functionality. In addition, + key events for compose functionality contain a value of `Dead` when mid-composition. + + I can't quite verify it, but non-English IMEs may also be able to generate key codes + for code points in the surrogate-pair range, which could potentially be seen as having + key.length > 1. Since `Fn` is one of the special keys, we can't distinguish by that + alone. + + Here, key.length === 1 means we know for sure the input was printable and not a special + `key` value. When the length is greater than 1, it could be either a printable surrogate + pair or a special `key` value. We can tell the difference by checking if the _character + code_ value (not code point!) is in the "surrogate pair" range or not. + + We don't use .codePointAt because an invalid code point would return 65535, which wouldn't + pass the >= 0x10000 check we would otherwise use. + + > ...The Unicode Standard sets aside 66 noncharacter code points. The last two code points + > of each plane are noncharacters: U+FFFE and U+FFFF on the BMP... + */ + var wasPrintableChar = event.key.length === 1 || + (event.key.length === 2 && event.key.charCodeAt(0) >= 0xd800) || + event.key === 'Unidentified'; + if (!this._isTextElement && !hasActiveDropdown) { + this.showDropdown(); + if (!this.input.isFocussed && wasPrintableChar) { + /* + We update the input value with the pressed key as + the input was not focussed at the time of key press + therefore does not have the value of the key. + */ + this.input.value += event.key; + // browsers interpret a space as pagedown + if (event.key === ' ') { + event.preventDefault(); + } + } + } + switch (keyCode) { + case 65 /* KeyCodeMap.A_KEY */: + return this._onSelectKey(event, this.itemList.element.hasChildNodes()); + case 13 /* KeyCodeMap.ENTER_KEY */: + return this._onEnterKey(event, hasActiveDropdown); + case 27 /* KeyCodeMap.ESC_KEY */: + return this._onEscapeKey(event, hasActiveDropdown); + case 38 /* KeyCodeMap.UP_KEY */: + case 33 /* KeyCodeMap.PAGE_UP_KEY */: + case 40 /* KeyCodeMap.DOWN_KEY */: + case 34 /* KeyCodeMap.PAGE_DOWN_KEY */: + return this._onDirectionKey(event, hasActiveDropdown); + case 8 /* KeyCodeMap.DELETE_KEY */: + case 46 /* KeyCodeMap.BACK_KEY */: + return this._onDeleteKey(event, this._store.items, this.input.isFocussed); + } + }; + Choices.prototype._onKeyUp = function ( /* event: KeyboardEvent */) { + this._canSearch = this.config.searchEnabled; + }; + Choices.prototype._onInput = function ( /* event: InputEvent */) { + var value = this.input.value; + if (!value) { + if (this._isTextElement) { + this.hideDropdown(true); + } + else { + this._stopSearch(); + } + this._clearNotice(); + return; + } + if (!this._canAddItems()) { + return; + } + if (this._canSearch) { + // do the search even if the entered text can not be added + this._handleSearch(value); + } + if (!this._canAddUserChoices) { + return; + } + // determine if a notice needs to be displayed for why a search result can't be added + this._canCreateItem(value); + if (this._isSelectElement) { + this._highlightPosition = 0; // reset to select the notice and/or exact match + this._highlightChoice(); + } + }; + Choices.prototype._onSelectKey = function (event, hasItems) { + // If CTRL + A or CMD + A have been pressed and there are items to select + if ((event.ctrlKey || event.metaKey) && hasItems) { + this._canSearch = false; + var shouldHightlightAll = this.config.removeItems && !this.input.value && this.input.element === document.activeElement; + if (shouldHightlightAll) { + this.highlightAll(); + } + } + }; + Choices.prototype._onEnterKey = function (event, hasActiveDropdown) { + var _this = this; + var value = this.input.value; + var target = event.target; + event.preventDefault(); + if (target && target.hasAttribute('data-button')) { + this._handleButtonAction(target); + return; + } + if (!hasActiveDropdown) { + if (this._isSelectElement || this._notice) { + this.showDropdown(); + } + return; + } + var highlightedChoice = this.dropdown.element.querySelector(getClassNamesSelector(this.config.classNames.highlightedState)); + if (highlightedChoice && this._handleChoiceAction(highlightedChoice)) { + return; + } + if (!target || !value) { + this.hideDropdown(true); + return; + } + if (!this._canAddItems()) { + return; + } + var addedItem = false; + this._store.withTxn(function () { + addedItem = _this._findAndSelectChoiceByValue(value, true); + if (!addedItem) { + if (!_this._canAddUserChoices) { + return; + } + if (!_this._canCreateItem(value)) { + return; + } + var sanitisedValue = sanitise(value); + var userValue = _this.config.allowHtmlUserInput || sanitisedValue === value ? value : { escaped: sanitisedValue, raw: value }; + _this._addChoice(mapInputToChoice({ + value: userValue, + label: userValue, + selected: true, + }, false), true, true); + addedItem = true; + } + _this.clearInput(); + _this.unhighlightAll(); + }); + if (!addedItem) { + return; + } + this._triggerChange(value); + if (this.config.closeDropdownOnSelect) { + this.hideDropdown(true); + } + }; + Choices.prototype._onEscapeKey = function (event, hasActiveDropdown) { + if (hasActiveDropdown) { + event.stopPropagation(); + this.hideDropdown(true); + this.containerOuter.element.focus(); + } + }; + Choices.prototype._onDirectionKey = function (event, hasActiveDropdown) { + var keyCode = event.keyCode; + // If up or down key is pressed, traverse through options + if (hasActiveDropdown || this._isSelectOneElement) { + this.showDropdown(); + this._canSearch = false; + var directionInt = keyCode === 40 /* KeyCodeMap.DOWN_KEY */ || keyCode === 34 /* KeyCodeMap.PAGE_DOWN_KEY */ ? 1 : -1; + var skipKey = event.metaKey || keyCode === 34 /* KeyCodeMap.PAGE_DOWN_KEY */ || keyCode === 33 /* KeyCodeMap.PAGE_UP_KEY */; + var nextEl = void 0; + if (skipKey) { + if (directionInt > 0) { + nextEl = this.dropdown.element.querySelector("".concat(selectableChoiceIdentifier, ":last-of-type")); + } + else { + nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); + } + } + else { + var currentEl = this.dropdown.element.querySelector(getClassNamesSelector(this.config.classNames.highlightedState)); + if (currentEl) { + nextEl = getAdjacentEl(currentEl, selectableChoiceIdentifier, directionInt); + } + else { + nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); + } + } + if (nextEl) { + // We prevent default to stop the cursor moving + // when pressing the arrow + if (!isScrolledIntoView(nextEl, this.choiceList.element, directionInt)) { + this.choiceList.scrollToChildElement(nextEl, directionInt); + } + this._highlightChoice(nextEl); + } + // Prevent default to maintain cursor position whilst + // traversing dropdown options + event.preventDefault(); + } + }; + Choices.prototype._onDeleteKey = function (event, items, hasFocusedInput) { + // If backspace or delete key is pressed and the input has no value + if (!this._isSelectOneElement && !event.target.value && hasFocusedInput) { + this._handleBackspace(items); + event.preventDefault(); + } + }; + Choices.prototype._onTouchMove = function () { + if (this._wasTap) { + this._wasTap = false; + } + }; + Choices.prototype._onTouchEnd = function (event) { + var target = (event || event.touches[0]).target; + var touchWasWithinContainer = this._wasTap && this.containerOuter.element.contains(target); + if (touchWasWithinContainer) { + var containerWasExactTarget = target === this.containerOuter.element || target === this.containerInner.element; + if (containerWasExactTarget) { + if (this._isTextElement) { + this.input.focus(); + } + else if (this._isSelectMultipleElement) { + this.showDropdown(); + } + } + // Prevents focus event firing + event.stopPropagation(); + } + this._wasTap = true; + }; + /** + * Handles mousedown event in capture mode for containetOuter.element + */ + Choices.prototype._onMouseDown = function (event) { + var target = event.target; + if (!(target instanceof HTMLElement)) { + return; + } + // If we have our mouse down on the scrollbar and are on IE11... + if (IS_IE11 && this.choiceList.element.contains(target)) { + // check if click was on a scrollbar area + var firstChoice = this.choiceList.element.firstElementChild; + this._isScrollingOnIe = + this._direction === 'ltr' ? event.offsetX >= firstChoice.offsetWidth : event.offsetX < firstChoice.offsetLeft; + } + if (target === this.input.element) { + return; + } + var item = target.closest('[data-button],[data-item],[data-choice]'); + if (item instanceof HTMLElement) { + if ('button' in item.dataset) { + this._handleButtonAction(item); + } + else if ('item' in item.dataset) { + this._handleItemAction(item, event.shiftKey); + } + else if ('choice' in item.dataset) { + this._handleChoiceAction(item); + } + } + event.preventDefault(); + }; + /** + * Handles mouseover event over this.dropdown + * @param {MouseEvent} event + */ + Choices.prototype._onMouseOver = function (_a) { + var target = _a.target; + if (target instanceof HTMLElement && 'choice' in target.dataset) { + this._highlightChoice(target); + } + }; + Choices.prototype._onClick = function (_a) { + var target = _a.target; + var containerOuter = this.containerOuter; + var clickWasWithinContainer = containerOuter.element.contains(target); + if (clickWasWithinContainer) { + if (!this.dropdown.isActive && !containerOuter.isDisabled) { + if (this._isTextElement) { + if (document.activeElement !== this.input.element) { + this.input.focus(); + } + } + else { + this.showDropdown(); + containerOuter.element.focus(); + } + } + else if (this._isSelectOneElement && + target !== this.input.element && + !this.dropdown.element.contains(target)) { + this.hideDropdown(); + } + } + else { + containerOuter.removeFocusState(); + this.hideDropdown(true); + this.unhighlightAll(); + } + }; + Choices.prototype._onFocus = function (_a) { + var target = _a.target; + var containerOuter = this.containerOuter; + var focusWasWithinContainer = target && containerOuter.element.contains(target); + if (!focusWasWithinContainer) { + return; + } + var targetIsInput = target === this.input.element; + if (this._isTextElement) { + if (targetIsInput) { + containerOuter.addFocusState(); + } + } + else if (this._isSelectMultipleElement) { + if (targetIsInput) { + this.showDropdown(true); + // If element is a select box, the focused element is the container and the dropdown + // isn't already open, focus and show dropdown + containerOuter.addFocusState(); + } + } + else { + containerOuter.addFocusState(); + if (targetIsInput) { + this.showDropdown(true); + } + } + }; + Choices.prototype._onBlur = function (_a) { + var target = _a.target; + var containerOuter = this.containerOuter; + var blurWasWithinContainer = target && containerOuter.element.contains(target); + if (blurWasWithinContainer && !this._isScrollingOnIe) { + var targetIsInput = target === this.input.element; + if (this._isTextElement || this._isSelectMultipleElement) { + if (targetIsInput) { + containerOuter.removeFocusState(); + this.hideDropdown(true); + this.unhighlightAll(); + } + } + else { + containerOuter.removeFocusState(); + if (targetIsInput || (target === containerOuter.element && !this._canSearch)) { + this.hideDropdown(true); + } + } + } + else { + // On IE11, clicking the scollbar blurs our input and thus + // closes the dropdown. To stop this, we refocus our input + // if we know we are on IE *and* are scrolling. + this._isScrollingOnIe = false; + this.input.element.focus(); + } + }; + Choices.prototype._onFormReset = function () { + var _this = this; + this._store.withTxn(function () { + _this.clearInput(); + _this.hideDropdown(); + _this.refresh(false, false, true); + if (_this._initialItems.length) { + _this.setChoiceByValue(_this._initialItems); + } + }); + }; + Choices.prototype._highlightChoice = function (el) { + if (el === void 0) { el = null; } + var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier)); + if (!choices.length) { + return; + } + var passedEl = el; + var highlightedState = this.config.classNames.highlightedState; + var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(getClassNamesSelector(highlightedState))); + // Remove any highlighted choices + highlightedChoices.forEach(function (choice) { + removeClassesFromElement(choice, highlightedState); + choice.setAttribute('aria-selected', 'false'); + }); + if (passedEl) { + this._highlightPosition = choices.indexOf(passedEl); + } + else { + // Highlight choice based on last known highlight location + if (choices.length > this._highlightPosition) { + // If we have an option to highlight + passedEl = choices[this._highlightPosition]; + } + else { + // Otherwise highlight the option before + passedEl = choices[choices.length - 1]; + } + if (!passedEl) { + passedEl = choices[0]; + } + } + addClassesToElement(passedEl, highlightedState); + passedEl.setAttribute('aria-selected', 'true'); + this.passedElement.triggerEvent(EventType.highlightChoice, { + el: passedEl, + }); + if (this.dropdown.isActive) { + // IE11 ignores aria-label and blocks virtual keyboard + // if aria-activedescendant is set without a dropdown + this.input.setActiveDescendant(passedEl.id); + this.containerOuter.setActiveDescendant(passedEl.id); + } + }; + Choices.prototype._addItem = function (item, withEvents, userTriggered) { + if (withEvents === void 0) { withEvents = true; } + if (userTriggered === void 0) { userTriggered = false; } + if (!item.id) { + throw new TypeError('item.id must be set before _addItem is called for a choice/item'); + } + if (this.config.singleModeForMultiSelect || this._isSelectOneElement) { + this.removeActiveItems(item.id); + } + this._store.dispatch(addItem(item)); + if (withEvents) { + this.passedElement.triggerEvent(EventType.addItem, this._getChoiceForOutput(item)); + if (userTriggered) { + this.passedElement.triggerEvent(EventType.choice, this._getChoiceForOutput(item)); + } + } + }; + Choices.prototype._removeItem = function (item) { + if (!item.id) { + return; + } + this._store.dispatch(removeItem$1(item)); + this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(item)); + }; + Choices.prototype._addChoice = function (choice, withEvents, userTriggered) { + if (withEvents === void 0) { withEvents = true; } + if (userTriggered === void 0) { userTriggered = false; } + if (choice.id) { + throw new TypeError('Can not re-add a choice which has already been added'); + } + // Generate unique id, in-place update is required so chaining _addItem works as expected + this._lastAddedChoiceId++; + choice.id = this._lastAddedChoiceId; + choice.elementId = "".concat(this._baseId, "-").concat(this._idNames.itemChoice, "-").concat(choice.id); + var _a = this.config, prependValue = _a.prependValue, appendValue = _a.appendValue; + if (prependValue) { + choice.value = prependValue + choice.value; + } + if (appendValue) { + choice.value += appendValue.toString(); + } + if ((prependValue || appendValue) && choice.element) { + choice.element.value = choice.value; + } + this._store.dispatch(addChoice(choice)); + if (choice.selected) { + this._addItem(choice, withEvents, userTriggered); + } + }; + Choices.prototype._addGroup = function (group, withEvents) { + var _this = this; + if (withEvents === void 0) { withEvents = true; } + if (group.id) { + throw new TypeError('Can not re-add a group which has already been added'); + } + this._store.dispatch(addGroup(group)); + if (!group.choices) { + return; + } + // add unique id for the group(s), and do not store the full list of choices in this group + this._lastAddedGroupId++; + group.id = this._lastAddedGroupId; + group.choices.forEach(function (item) { + item.groupId = group.id; + if (group.disabled) { + item.disabled = true; + } + _this._addChoice(item, withEvents); + }); + }; + Choices.prototype._createTemplates = function () { + var _this = this; + var callbackOnCreateTemplates = this.config.callbackOnCreateTemplates; + var userTemplates = {}; + if (typeof callbackOnCreateTemplates === 'function') { + userTemplates = callbackOnCreateTemplates.call(this, strToEl, escapeForTemplate); + } + var templating = {}; + Object.keys(this._templates).forEach(function (name) { + if (name in userTemplates) { + templating[name] = userTemplates[name].bind(_this); + } + else { + templating[name] = _this._templates[name].bind(_this); + } + }); + this._templates = templating; + }; + Choices.prototype._createElements = function () { + var templating = this._templates; + var _a = this, config = _a.config, isSelectOneElement = _a._isSelectOneElement; + var position = config.position, classNames = config.classNames; + var elementType = this._elementType; + this.containerOuter = new Container({ + element: templating.containerOuter(config, this._direction, this._isSelectElement, isSelectOneElement, config.searchEnabled, elementType, config.labelId), + classNames: classNames, + type: elementType, + position: position, + }); + this.containerInner = new Container({ + element: templating.containerInner(config), + classNames: classNames, + type: elementType, + position: position, + }); + this.input = new Input({ + element: templating.input(config, this._placeholderValue), + classNames: classNames, + type: elementType, + preventPaste: !config.paste, + }); + this.choiceList = new List({ + element: templating.choiceList(config, isSelectOneElement), + }); + this.itemList = new List({ + element: templating.itemList(config, isSelectOneElement), + }); + this.dropdown = new Dropdown({ + element: templating.dropdown(config), + classNames: classNames, + type: elementType, + }); + }; + Choices.prototype._createStructure = function () { + var _a = this, containerInner = _a.containerInner, containerOuter = _a.containerOuter, passedElement = _a.passedElement; + var dropdownElement = this.dropdown.element; + // Hide original element + passedElement.conceal(); + // Wrap input in container preserving DOM ordering + containerInner.wrap(passedElement.element); + // Wrapper inner container with outer container + containerOuter.wrap(containerInner.element); + if (this._isSelectOneElement) { + this.input.placeholder = this.config.searchPlaceholderValue || ''; + } + else { + if (this._placeholderValue) { + this.input.placeholder = this._placeholderValue; + } + this.input.setWidth(); + } + containerOuter.element.appendChild(containerInner.element); + containerOuter.element.appendChild(dropdownElement); + containerInner.element.appendChild(this.itemList.element); + dropdownElement.appendChild(this.choiceList.element); + if (!this._isSelectOneElement) { + containerInner.element.appendChild(this.input.element); + } + else if (this.config.searchEnabled) { + dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild); + } + this._highlightPosition = 0; + this._isSearching = false; + }; + Choices.prototype._initStore = function () { + var _this = this; + this._store.subscribe(this._render); + this._store.withTxn(function () { + _this._addPredefinedChoices(_this._presetChoices, _this._isSelectOneElement && !_this._hasNonChoicePlaceholder, false); + }); + if (this._isSelectOneElement && this._hasNonChoicePlaceholder) { + this._render({ choices: false, groups: false, items: true }); + } + }; + Choices.prototype._addPredefinedChoices = function (choices, selectFirstOption, withEvents) { + var _this = this; + if (selectFirstOption === void 0) { selectFirstOption = false; } + if (withEvents === void 0) { withEvents = true; } + if (selectFirstOption) { + /** + * If there is a selected choice already or the choice is not the first in + * the array, add each choice normally. + * + * Otherwise we pre-select the first enabled choice in the array ("select-one" only) + */ + var noSelectedChoices = choices.findIndex(function (choice) { return choice.selected; }) === -1; + if (noSelectedChoices) { + choices.some(function (choice) { + if (choice.disabled || 'choices' in choice) { + return false; + } + choice.selected = true; + return true; + }); + } + } + choices.forEach(function (item) { + if ('choices' in item) { + if (_this._isSelectElement) { + _this._addGroup(item, withEvents); + } + } + else { + _this._addChoice(item, withEvents); + } + }); + }; + Choices.prototype._findAndSelectChoiceByValue = function (value, userTriggered) { + var _this = this; + if (userTriggered === void 0) { userTriggered = false; } + // Check 'value' property exists and the choice isn't already selected + var foundChoice = this._store.choices.find(function (choice) { return _this.config.valueComparer(choice.value, value); }); + if (foundChoice && !foundChoice.disabled && !foundChoice.selected) { + this._addItem(foundChoice, true, userTriggered); + return true; + } + return false; + }; + Choices.prototype._generatePlaceholderValue = function () { + var config = this.config; + if (!config.placeholder) { + return null; + } + if (this._hasNonChoicePlaceholder) { + return config.placeholderValue; + } + if (this._isSelectElement) { + var placeholderOption = this.passedElement.placeholderOption; + return placeholderOption ? placeholderOption.text : null; + } + return null; + }; + Choices.prototype._warnChoicesInitFailed = function (caller) { + if (this.config.silent) { + return; + } + if (!this.initialised) { + throw new TypeError("".concat(caller, " called on a non-initialised instance of Choices")); + } + else if (!this.initialisedOK) { + throw new TypeError("".concat(caller, " called for an element which has multiple instances of Choices initialised on it")); + } + }; + Choices.version = '11.0.1'; + return Choices; +}()); + +export { Choices as default }; diff --git a/assets/extensions/choices.js/public/assets/scripts/choices.search-basic.js b/assets/extensions/choices.js/public/assets/scripts/choices.search-basic.js new file mode 100644 index 00000000..ec27ce36 --- /dev/null +++ b/assets/extensions/choices.js/public/assets/scripts/choices.search-basic.js @@ -0,0 +1,4685 @@ +/*! choices.js v11.0.1 | © 2024 Josh Johnson | https://github.com/jshjohnson/Choices#readme */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Choices = factory()); +})(this, (function () { 'use strict'; + + /****************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise, SuppressedError, Symbol */ + + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + }; + return extendStatics(d, b); + }; + function __extends(d, b) { + if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); + } + typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + + var ActionType = { + ADD_CHOICE: 'ADD_CHOICE', + REMOVE_CHOICE: 'REMOVE_CHOICE', + FILTER_CHOICES: 'FILTER_CHOICES', + ACTIVATE_CHOICES: 'ACTIVATE_CHOICES', + CLEAR_CHOICES: 'CLEAR_CHOICES', + ADD_GROUP: 'ADD_GROUP', + ADD_ITEM: 'ADD_ITEM', + REMOVE_ITEM: 'REMOVE_ITEM', + HIGHLIGHT_ITEM: 'HIGHLIGHT_ITEM', + }; + + var EventType = { + showDropdown: 'showDropdown', + hideDropdown: 'hideDropdown', + change: 'change', + choice: 'choice', + search: 'search', + addItem: 'addItem', + removeItem: 'removeItem', + highlightItem: 'highlightItem', + highlightChoice: 'highlightChoice', + unhighlightItem: 'unhighlightItem', + }; + + var ObjectsInConfig = ['fuseOptions', 'classNames']; + + var PassedElementTypes = { + Text: 'text', + SelectOne: 'select-one', + SelectMultiple: 'select-multiple', + }; + + var addChoice = function (choice) { return ({ + type: ActionType.ADD_CHOICE, + choice: choice, + }); }; + var removeChoice = function (choice) { return ({ + type: ActionType.REMOVE_CHOICE, + choice: choice, + }); }; + var filterChoices = function (results) { return ({ + type: ActionType.FILTER_CHOICES, + results: results, + }); }; + var activateChoices = function (active) { + return ({ + type: ActionType.ACTIVATE_CHOICES, + active: active, + }); + }; + + var addGroup = function (group) { return ({ + type: ActionType.ADD_GROUP, + group: group, + }); }; + + var addItem = function (item) { return ({ + type: ActionType.ADD_ITEM, + item: item, + }); }; + var removeItem$1 = function (item) { return ({ + type: ActionType.REMOVE_ITEM, + item: item, + }); }; + var highlightItem = function (item, highlighted) { return ({ + type: ActionType.HIGHLIGHT_ITEM, + item: item, + highlighted: highlighted, + }); }; + + /* eslint-disable @typescript-eslint/no-explicit-any */ + var getRandomNumber = function (min, max) { return Math.floor(Math.random() * (max - min) + min); }; + var generateChars = function (length) { + return Array.from({ length: length }, function () { return getRandomNumber(0, 36).toString(36); }).join(''); + }; + var generateId = function (element, prefix) { + var id = element.id || (element.name && "".concat(element.name, "-").concat(generateChars(2))) || generateChars(4); + id = id.replace(/(:|\.|\[|\]|,)/g, ''); + id = "".concat(prefix, "-").concat(id); + return id; + }; + var getAdjacentEl = function (startEl, selector, direction) { + if (direction === void 0) { direction = 1; } + var prop = "".concat(direction > 0 ? 'next' : 'previous', "ElementSibling"); + var sibling = startEl[prop]; + while (sibling) { + if (sibling.matches(selector)) { + return sibling; + } + sibling = sibling[prop]; + } + return null; + }; + var isScrolledIntoView = function (element, parent, direction) { + if (direction === void 0) { direction = 1; } + var isVisible; + if (direction > 0) { + // In view from bottom + isVisible = parent.scrollTop + parent.offsetHeight >= element.offsetTop + element.offsetHeight; + } + else { + // In view from top + isVisible = element.offsetTop >= parent.scrollTop; + } + return isVisible; + }; + var sanitise = function (value) { + if (typeof value !== 'string') { + if (value === null || value === undefined) { + return ''; + } + if (typeof value === 'object') { + if ('raw' in value) { + return sanitise(value.raw); + } + if ('trusted' in value) { + return value.trusted; + } + } + return value; + } + return value + .replace(/&/g, '&') + .replace(/>/g, '>') + .replace(/= 0 && + !window.matchMedia("(min-height: ".concat(dropdownPos + 1, "px)")).matches; + } + else if (this.position === 'top') { + shouldFlip = true; + } + return shouldFlip; + }; + Container.prototype.setActiveDescendant = function (activeDescendantID) { + this.element.setAttribute('aria-activedescendant', activeDescendantID); + }; + Container.prototype.removeActiveDescendant = function () { + this.element.removeAttribute('aria-activedescendant'); + }; + Container.prototype.open = function (dropdownPos, dropdownHeight) { + addClassesToElement(this.element, this.classNames.openState); + this.element.setAttribute('aria-expanded', 'true'); + this.isOpen = true; + if (this.shouldFlip(dropdownPos, dropdownHeight)) { + addClassesToElement(this.element, this.classNames.flippedState); + this.isFlipped = true; + } + }; + Container.prototype.close = function () { + removeClassesFromElement(this.element, this.classNames.openState); + this.element.setAttribute('aria-expanded', 'false'); + this.removeActiveDescendant(); + this.isOpen = false; + // A dropdown flips if it does not have space within the page + if (this.isFlipped) { + removeClassesFromElement(this.element, this.classNames.flippedState); + this.isFlipped = false; + } + }; + Container.prototype.addFocusState = function () { + addClassesToElement(this.element, this.classNames.focusState); + }; + Container.prototype.removeFocusState = function () { + removeClassesFromElement(this.element, this.classNames.focusState); + }; + Container.prototype.enable = function () { + removeClassesFromElement(this.element, this.classNames.disabledState); + this.element.removeAttribute('aria-disabled'); + if (this.type === PassedElementTypes.SelectOne) { + this.element.setAttribute('tabindex', '0'); + } + this.isDisabled = false; + }; + Container.prototype.disable = function () { + addClassesToElement(this.element, this.classNames.disabledState); + this.element.setAttribute('aria-disabled', 'true'); + if (this.type === PassedElementTypes.SelectOne) { + this.element.setAttribute('tabindex', '-1'); + } + this.isDisabled = true; + }; + Container.prototype.wrap = function (element) { + var el = this.element; + var parentNode = element.parentNode; + if (parentNode) { + if (element.nextSibling) { + parentNode.insertBefore(el, element.nextSibling); + } + else { + parentNode.appendChild(el); + } + } + el.appendChild(element); + }; + Container.prototype.unwrap = function (element) { + var el = this.element; + var parentNode = el.parentNode; + if (parentNode) { + // Move passed element outside this element + parentNode.insertBefore(element, el); + // Remove this element + parentNode.removeChild(el); + } + }; + Container.prototype.addLoadingState = function () { + addClassesToElement(this.element, this.classNames.loadingState); + this.element.setAttribute('aria-busy', 'true'); + this.isLoading = true; + }; + Container.prototype.removeLoadingState = function () { + removeClassesFromElement(this.element, this.classNames.loadingState); + this.element.removeAttribute('aria-busy'); + this.isLoading = false; + }; + return Container; + }()); + + var Input = /** @class */ (function () { + function Input(_a) { + var element = _a.element, type = _a.type, classNames = _a.classNames, preventPaste = _a.preventPaste; + this.element = element; + this.type = type; + this.classNames = classNames; + this.preventPaste = preventPaste; + this.isFocussed = this.element.isEqualNode(document.activeElement); + this.isDisabled = element.disabled; + this._onPaste = this._onPaste.bind(this); + this._onInput = this._onInput.bind(this); + this._onFocus = this._onFocus.bind(this); + this._onBlur = this._onBlur.bind(this); + } + Object.defineProperty(Input.prototype, "placeholder", { + set: function (placeholder) { + this.element.placeholder = placeholder; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Input.prototype, "value", { + get: function () { + return this.element.value; + }, + set: function (value) { + this.element.value = value; + }, + enumerable: false, + configurable: true + }); + Input.prototype.addEventListeners = function () { + var el = this.element; + el.addEventListener('paste', this._onPaste); + el.addEventListener('input', this._onInput, { + passive: true, + }); + el.addEventListener('focus', this._onFocus, { + passive: true, + }); + el.addEventListener('blur', this._onBlur, { + passive: true, + }); + }; + Input.prototype.removeEventListeners = function () { + var el = this.element; + el.removeEventListener('input', this._onInput); + el.removeEventListener('paste', this._onPaste); + el.removeEventListener('focus', this._onFocus); + el.removeEventListener('blur', this._onBlur); + }; + Input.prototype.enable = function () { + var el = this.element; + el.removeAttribute('disabled'); + this.isDisabled = false; + }; + Input.prototype.disable = function () { + var el = this.element; + el.setAttribute('disabled', ''); + this.isDisabled = true; + }; + Input.prototype.focus = function () { + if (!this.isFocussed) { + this.element.focus(); + } + }; + Input.prototype.blur = function () { + if (this.isFocussed) { + this.element.blur(); + } + }; + Input.prototype.clear = function (setWidth) { + if (setWidth === void 0) { setWidth = true; } + this.element.value = ''; + if (setWidth) { + this.setWidth(); + } + return this; + }; + /** + * Set the correct input width based on placeholder + * value or input value + */ + Input.prototype.setWidth = function () { + // Resize input to contents or placeholder + var element = this.element; + element.style.minWidth = "".concat(element.placeholder.length + 1, "ch"); + element.style.width = "".concat(element.value.length + 1, "ch"); + }; + Input.prototype.setActiveDescendant = function (activeDescendantID) { + this.element.setAttribute('aria-activedescendant', activeDescendantID); + }; + Input.prototype.removeActiveDescendant = function () { + this.element.removeAttribute('aria-activedescendant'); + }; + Input.prototype._onInput = function () { + if (this.type !== PassedElementTypes.SelectOne) { + this.setWidth(); + } + }; + Input.prototype._onPaste = function (event) { + if (this.preventPaste) { + event.preventDefault(); + } + }; + Input.prototype._onFocus = function () { + this.isFocussed = true; + }; + Input.prototype._onBlur = function () { + this.isFocussed = false; + }; + return Input; + }()); + + var SCROLLING_SPEED = 4; + + var List = /** @class */ (function () { + function List(_a) { + var element = _a.element; + this.element = element; + this.scrollPos = this.element.scrollTop; + this.height = this.element.offsetHeight; + } + List.prototype.prepend = function (node) { + var child = this.element.firstElementChild; + if (child) { + this.element.insertBefore(node, child); + } + else { + this.element.append(node); + } + }; + List.prototype.scrollToTop = function () { + this.element.scrollTop = 0; + }; + List.prototype.scrollToChildElement = function (element, direction) { + var _this = this; + if (!element) { + return; + } + var listHeight = this.element.offsetHeight; + // Scroll position of dropdown + var listScrollPosition = this.element.scrollTop + listHeight; + var elementHeight = element.offsetHeight; + // Distance from bottom of element to top of parent + var elementPos = element.offsetTop + elementHeight; + // Difference between the element and scroll position + var destination = direction > 0 ? this.element.scrollTop + elementPos - listScrollPosition : element.offsetTop; + requestAnimationFrame(function () { + _this._animateScroll(destination, direction); + }); + }; + List.prototype._scrollDown = function (scrollPos, strength, destination) { + var easing = (destination - scrollPos) / strength; + var distance = easing > 1 ? easing : 1; + this.element.scrollTop = scrollPos + distance; + }; + List.prototype._scrollUp = function (scrollPos, strength, destination) { + var easing = (scrollPos - destination) / strength; + var distance = easing > 1 ? easing : 1; + this.element.scrollTop = scrollPos - distance; + }; + List.prototype._animateScroll = function (destination, direction) { + var _this = this; + var strength = SCROLLING_SPEED; + var choiceListScrollTop = this.element.scrollTop; + var continueAnimation = false; + if (direction > 0) { + this._scrollDown(choiceListScrollTop, strength, destination); + if (choiceListScrollTop < destination) { + continueAnimation = true; + } + } + else { + this._scrollUp(choiceListScrollTop, strength, destination); + if (choiceListScrollTop > destination) { + continueAnimation = true; + } + } + if (continueAnimation) { + requestAnimationFrame(function () { + _this._animateScroll(destination, direction); + }); + } + }; + return List; + }()); + + var WrappedElement = /** @class */ (function () { + function WrappedElement(_a) { + var element = _a.element, classNames = _a.classNames; + this.element = element; + this.classNames = classNames; + this.isDisabled = false; + } + Object.defineProperty(WrappedElement.prototype, "isActive", { + get: function () { + return this.element.dataset.choice === 'active'; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(WrappedElement.prototype, "dir", { + get: function () { + return this.element.dir; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(WrappedElement.prototype, "value", { + get: function () { + return this.element.value; + }, + set: function (value) { + this.element.setAttribute('value', value); + this.element.value = value; + }, + enumerable: false, + configurable: true + }); + WrappedElement.prototype.conceal = function () { + var el = this.element; + // Hide passed input + addClassesToElement(el, this.classNames.input); + el.hidden = true; + // Remove element from tab index + el.tabIndex = -1; + // Backup original styles if any + var origStyle = el.getAttribute('style'); + if (origStyle) { + el.setAttribute('data-choice-orig-style', origStyle); + } + el.setAttribute('data-choice', 'active'); + }; + WrappedElement.prototype.reveal = function () { + var el = this.element; + // Reinstate passed element + removeClassesFromElement(el, this.classNames.input); + el.hidden = false; + el.removeAttribute('tabindex'); + // Recover original styles if any + var origStyle = el.getAttribute('data-choice-orig-style'); + if (origStyle) { + el.removeAttribute('data-choice-orig-style'); + el.setAttribute('style', origStyle); + } + else { + el.removeAttribute('style'); + } + el.removeAttribute('data-choice'); + }; + WrappedElement.prototype.enable = function () { + this.element.removeAttribute('disabled'); + this.element.disabled = false; + this.isDisabled = false; + }; + WrappedElement.prototype.disable = function () { + this.element.setAttribute('disabled', ''); + this.element.disabled = true; + this.isDisabled = true; + }; + WrappedElement.prototype.triggerEvent = function (eventType, data) { + dispatchEvent(this.element, eventType, data || {}); + }; + return WrappedElement; + }()); + + var WrappedInput = /** @class */ (function (_super) { + __extends(WrappedInput, _super); + function WrappedInput() { + return _super !== null && _super.apply(this, arguments) || this; + } + return WrappedInput; + }(WrappedElement)); + + var coerceBool = function (arg, defaultValue) { + if (defaultValue === void 0) { defaultValue = true; } + return typeof arg === 'undefined' ? defaultValue : !!arg; + }; + var stringToHtmlClass = function (input) { + if (typeof input === 'string') { + // eslint-disable-next-line no-param-reassign + input = input.split(' ').filter(function (s) { return s.length; }); + } + if (Array.isArray(input) && input.length) { + return input; + } + return undefined; + }; + var mapInputToChoice = function (value, allowGroup) { + if (typeof value === 'string') { + var result_1 = mapInputToChoice({ + value: value, + label: value, + }, false); + return result_1; + } + var groupOrChoice = value; + if ('choices' in groupOrChoice) { + if (!allowGroup) { + // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup + throw new TypeError("optGroup is not allowed"); + } + var group = groupOrChoice; + var choices = group.choices.map(function (e) { return mapInputToChoice(e, false); }); + var result_2 = { + id: 0, // actual ID will be assigned during _addGroup + label: unwrapStringForRaw(group.label) || group.value, + active: !!choices.length, + disabled: !!group.disabled, + choices: choices, + }; + return result_2; + } + var choice = groupOrChoice; + var result = { + id: 0, // actual ID will be assigned during _addChoice + groupId: 0, // actual ID will be assigned during _addGroup but before _addChoice + score: 0, // used in search + rank: 0, // used in search, stable sort order + value: choice.value, + label: choice.label || choice.value, + active: coerceBool(choice.active), + selected: coerceBool(choice.selected, false), + disabled: coerceBool(choice.disabled, false), + placeholder: coerceBool(choice.placeholder, false), + highlighted: false, + labelClass: stringToHtmlClass(choice.labelClass), + labelDescription: choice.labelDescription, + customProperties: choice.customProperties, + }; + return result; + }; + + var isHtmlInputElement = function (e) { return e.tagName === 'INPUT'; }; + var isHtmlSelectElement = function (e) { return e.tagName === 'SELECT'; }; + var isHtmlOption = function (e) { return e.tagName === 'OPTION'; }; + var isHtmlOptgroup = function (e) { return e.tagName === 'OPTGROUP'; }; + + var WrappedSelect = /** @class */ (function (_super) { + __extends(WrappedSelect, _super); + function WrappedSelect(_a) { + var element = _a.element, classNames = _a.classNames, template = _a.template, extractPlaceholder = _a.extractPlaceholder; + var _this = _super.call(this, { element: element, classNames: classNames }) || this; + _this.template = template; + _this.extractPlaceholder = extractPlaceholder; + return _this; + } + Object.defineProperty(WrappedSelect.prototype, "placeholderOption", { + get: function () { + return (this.element.querySelector('option[value=""]') || + // Backward compatibility layer for the non-standard placeholder attribute supported in older versions. + this.element.querySelector('option[placeholder]')); + }, + enumerable: false, + configurable: true + }); + WrappedSelect.prototype.addOptions = function (choices) { + var _this = this; + var fragment = document.createDocumentFragment(); + choices.forEach(function (obj) { + var choice = obj; + if (choice.element) { + return; + } + var option = _this.template(choice); + fragment.appendChild(option); + choice.element = option; + }); + this.element.appendChild(fragment); + }; + WrappedSelect.prototype.optionsAsChoices = function () { + var _this = this; + var choices = []; + this.element.querySelectorAll(':scope > option, :scope > optgroup').forEach(function (e) { + if (isHtmlOption(e)) { + choices.push(_this._optionToChoice(e)); + } + else if (isHtmlOptgroup(e)) { + choices.push(_this._optgroupToChoice(e)); + } + // todo: hr as empty optgroup, requires displaying empty opt-groups to be useful + }); + return choices; + }; + // eslint-disable-next-line class-methods-use-this + WrappedSelect.prototype._optionToChoice = function (option) { + // option.value returns the label if there is no value attribute, which can break legacy placeholder attribute support + if (!option.hasAttribute('value') && option.hasAttribute('placeholder')) { + option.setAttribute('value', ''); + option.value = ''; + } + return { + id: 0, + groupId: 0, + score: 0, + rank: 0, + value: option.value, + label: option.innerHTML, + element: option, + active: true, + // this returns true if nothing is selected on initial load, which will break placeholder support + selected: this.extractPlaceholder ? option.selected : option.hasAttribute('selected'), + disabled: option.disabled, + highlighted: false, + placeholder: this.extractPlaceholder && (!option.value || option.hasAttribute('placeholder')), + labelClass: typeof option.dataset.labelClass !== 'undefined' ? stringToHtmlClass(option.dataset.labelClass) : undefined, + labelDescription: typeof option.dataset.labelDescription !== 'undefined' ? option.dataset.labelDescription : undefined, + customProperties: parseCustomProperties(option.dataset.customProperties), + }; + }; + WrappedSelect.prototype._optgroupToChoice = function (optgroup) { + var _this = this; + var options = optgroup.querySelectorAll('option'); + var choices = Array.from(options).map(function (option) { return _this._optionToChoice(option); }); + return { + id: 0, + label: optgroup.label || '', + element: optgroup, + active: !!choices.length, + disabled: optgroup.disabled, + choices: choices, + }; + }; + return WrappedSelect; + }(WrappedElement)); + + var DEFAULT_CLASSNAMES = { + containerOuter: ['choices'], + containerInner: ['choices__inner'], + input: ['choices__input'], + inputCloned: ['choices__input--cloned'], + list: ['choices__list'], + listItems: ['choices__list--multiple'], + listSingle: ['choices__list--single'], + listDropdown: ['choices__list--dropdown'], + item: ['choices__item'], + itemSelectable: ['choices__item--selectable'], + itemDisabled: ['choices__item--disabled'], + itemChoice: ['choices__item--choice'], + description: ['choices__description'], + placeholder: ['choices__placeholder'], + group: ['choices__group'], + groupHeading: ['choices__heading'], + button: ['choices__button'], + activeState: ['is-active'], + focusState: ['is-focused'], + openState: ['is-open'], + disabledState: ['is-disabled'], + highlightedState: ['is-highlighted'], + selectedState: ['is-selected'], + flippedState: ['is-flipped'], + loadingState: ['is-loading'], + notice: ['choices__notice'], + addChoice: ['choices__item--selectable', 'add-choice'], + noResults: ['has-no-results'], + noChoices: ['has-no-choices'], + }; + var DEFAULT_CONFIG = { + items: [], + choices: [], + silent: false, + renderChoiceLimit: -1, + maxItemCount: -1, + closeDropdownOnSelect: 'auto', + singleModeForMultiSelect: false, + addChoices: false, + addItems: true, + addItemFilter: function (value) { return !!value && value !== ''; }, + removeItems: true, + removeItemButton: false, + removeItemButtonAlignLeft: false, + editItems: false, + allowHTML: false, + allowHtmlUserInput: false, + duplicateItemsAllowed: true, + delimiter: ',', + paste: true, + searchEnabled: true, + searchChoices: true, + searchFloor: 1, + searchResultLimit: 4, + searchFields: ['label', 'value'], + position: 'auto', + resetScrollPosition: true, + shouldSort: true, + shouldSortItems: false, + sorter: sortByAlpha, + shadowRoot: null, + placeholder: true, + placeholderValue: null, + searchPlaceholderValue: null, + prependValue: null, + appendValue: null, + renderSelectedChoices: 'auto', + loadingText: 'Loading...', + noResultsText: 'No results found', + noChoicesText: 'No choices to choose from', + itemSelectText: 'Press to select', + uniqueItemText: 'Only unique values can be added', + customAddItemText: 'Only values matching specific conditions can be added', + addItemText: function (value) { return "Press Enter to add \"".concat(value, "\""); }, + removeItemIconText: function () { return "Remove item"; }, + removeItemLabelText: function (value) { return "Remove item: ".concat(value); }, + maxItemText: function (maxItemCount) { return "Only ".concat(maxItemCount, " values can be added"); }, + valueComparer: function (value1, value2) { return value1 === value2; }, + fuseOptions: { + includeScore: true, + }, + labelId: '', + callbackOnInit: null, + callbackOnCreateTemplates: null, + classNames: DEFAULT_CLASSNAMES, + appendGroupInSearch: false, + }; + + var removeItem = function (item) { + var itemEl = item.itemEl; + if (itemEl) { + itemEl.remove(); + item.itemEl = undefined; + } + }; + function items(s, action, context) { + var state = s; + var update = true; + switch (action.type) { + case ActionType.ADD_ITEM: { + action.item.selected = true; + var el = action.item.element; + if (el) { + el.selected = true; + el.setAttribute('selected', ''); + } + state.push(action.item); + break; + } + case ActionType.REMOVE_ITEM: { + action.item.selected = false; + var el = action.item.element; + if (el) { + el.selected = false; + el.removeAttribute('selected'); + // For a select-one, if all options are deselected, the first item is selected. To set a black value, select.value needs to be set + var select = el.parentElement; + if (select && isHtmlSelectElement(select) && select.type === PassedElementTypes.SelectOne) { + select.value = ''; + } + } + // this is mixing concerns, but this is *so much faster* + removeItem(action.item); + state = state.filter(function (choice) { return choice.id !== action.item.id; }); + break; + } + case ActionType.REMOVE_CHOICE: { + state = state.filter(function (item) { return item.id !== action.choice.id; }); + removeItem(action.choice); + break; + } + case ActionType.HIGHLIGHT_ITEM: { + var highlighted = action.highlighted; + var item = state.find(function (obj) { return obj.id === action.item.id; }); + if (item && item.highlighted !== highlighted) { + item.highlighted = highlighted; + if (context) { + updateClassList(item, highlighted ? context.classNames.highlightedState : context.classNames.selectedState, highlighted ? context.classNames.selectedState : context.classNames.highlightedState); + } + } + break; + } + default: { + update = false; + break; + } + } + return { state: state, update: update }; + } + + function groups(s, action) { + var state = s; + var update = true; + switch (action.type) { + case ActionType.ADD_GROUP: { + state.push(action.group); + break; + } + case ActionType.CLEAR_CHOICES: { + state = []; + break; + } + default: { + update = false; + break; + } + } + return { state: state, update: update }; + } + + /* eslint-disable */ + function choices(s, action, context) { + var state = s; + var update = true; + switch (action.type) { + case ActionType.ADD_CHOICE: { + /* + A disabled choice appears in the choice dropdown but cannot be selected + A selected choice has been added to the passed input's value (added as an item) + An active choice appears within the choice dropdown + */ + state.push(action.choice); + break; + } + case ActionType.REMOVE_CHOICE: { + action.choice.choiceEl = undefined; + state = state.filter(function (obj) { return obj.id !== action.choice.id; }); + break; + } + case ActionType.ADD_ITEM: + case ActionType.REMOVE_ITEM: { + action.item.choiceEl = undefined; + break; + } + case ActionType.FILTER_CHOICES: { + // avoid O(n^2) algorithm complexity when searching/filtering choices + var scoreLookup_1 = []; + action.results.forEach(function (result) { + scoreLookup_1[result.item.id] = result; + }); + state.forEach(function (choice) { + var result = scoreLookup_1[choice.id]; + if (result !== undefined) { + choice.score = result.score; + choice.rank = result.rank; + choice.active = true; + } + else { + choice.score = 0; + choice.rank = 0; + choice.active = false; + } + if (context && context.appendGroupInSearch) { + choice.choiceEl = undefined; + } + }); + break; + } + case ActionType.ACTIVATE_CHOICES: { + state.forEach(function (choice) { + choice.active = action.active; + if (context && context.appendGroupInSearch) { + choice.choiceEl = undefined; + } + }); + break; + } + case ActionType.CLEAR_CHOICES: { + state = []; + break; + } + default: { + update = false; + break; + } + } + return { state: state, update: update }; + } + + var reducers = { + groups: groups, + items: items, + choices: choices, + }; + var Store = /** @class */ (function () { + function Store(context) { + this._state = this.defaultState; + this._listeners = []; + this._txn = 0; + this._context = context; + } + Object.defineProperty(Store.prototype, "defaultState", { + // eslint-disable-next-line class-methods-use-this + get: function () { + return { + groups: [], + items: [], + choices: [], + }; + }, + enumerable: false, + configurable: true + }); + // eslint-disable-next-line class-methods-use-this + Store.prototype.changeSet = function (init) { + return { + groups: init, + items: init, + choices: init, + }; + }; + Store.prototype.reset = function () { + this._state = this.defaultState; + var changes = this.changeSet(true); + if (this._txn) { + this._changeSet = changes; + } + else { + this._listeners.forEach(function (l) { return l(changes); }); + } + }; + Store.prototype.subscribe = function (onChange) { + this._listeners.push(onChange); + }; + Store.prototype.dispatch = function (action) { + var _this = this; + var state = this._state; + var hasChanges = false; + var changes = this._changeSet || this.changeSet(false); + Object.keys(reducers).forEach(function (key) { + var stateUpdate = reducers[key](state[key], action, _this._context); + if (stateUpdate.update) { + hasChanges = true; + changes[key] = true; + state[key] = stateUpdate.state; + } + }); + if (hasChanges) { + if (this._txn) { + this._changeSet = changes; + } + else { + this._listeners.forEach(function (l) { return l(changes); }); + } + } + }; + Store.prototype.withTxn = function (func) { + this._txn++; + try { + func(); + } + finally { + this._txn = Math.max(0, this._txn - 1); + if (!this._txn) { + var changeSet_1 = this._changeSet; + if (changeSet_1) { + this._changeSet = undefined; + this._listeners.forEach(function (l) { return l(changeSet_1); }); + } + } + } + }; + Object.defineProperty(Store.prototype, "state", { + /** + * Get store object + */ + get: function () { + return this._state; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "items", { + /** + * Get items from store + */ + get: function () { + return this.state.items; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "highlightedActiveItems", { + /** + * Get highlighted items from store + */ + get: function () { + return this.items.filter(function (item) { return !item.disabled && item.active && item.highlighted; }); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "choices", { + /** + * Get choices from store + */ + get: function () { + return this.state.choices; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "activeChoices", { + /** + * Get active choices from store + */ + get: function () { + return this.choices.filter(function (choice) { return choice.active; }); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "searchableChoices", { + /** + * Get choices that can be searched (excluding placeholders) + */ + get: function () { + return this.choices.filter(function (choice) { return !choice.disabled && !choice.placeholder; }); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "groups", { + /** + * Get groups from store + */ + get: function () { + return this.state.groups; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "activeGroups", { + /** + * Get active groups from store + */ + get: function () { + var _this = this; + return this.state.groups.filter(function (group) { + var isActive = group.active && !group.disabled; + var hasActiveOptions = _this.state.choices.some(function (choice) { return choice.active && !choice.disabled; }); + return isActive && hasActiveOptions; + }, []); + }, + enumerable: false, + configurable: true + }); + Store.prototype.inTxn = function () { + return this._txn > 0; + }; + /** + * Get single choice by it's ID + */ + Store.prototype.getChoiceById = function (id) { + return this.activeChoices.find(function (choice) { return choice.id === id; }); + }; + /** + * Get group by group id + */ + Store.prototype.getGroupById = function (id) { + return this.groups.find(function (group) { return group.id === id; }); + }; + return Store; + }()); + + var NoticeTypes = { + noChoices: 'no-choices', + noResults: 'no-results', + addChoice: 'add-choice', + generic: '', + }; + + function _defineProperty(e, r, t) { + return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { + value: t, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[r] = t, e; + } + function ownKeys(e, r) { + var t = Object.keys(e); + if (Object.getOwnPropertySymbols) { + var o = Object.getOwnPropertySymbols(e); + r && (o = o.filter(function (r) { + return Object.getOwnPropertyDescriptor(e, r).enumerable; + })), t.push.apply(t, o); + } + return t; + } + function _objectSpread2(e) { + for (var r = 1; r < arguments.length; r++) { + var t = null != arguments[r] ? arguments[r] : {}; + r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { + _defineProperty(e, r, t[r]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { + Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); + }); + } + return e; + } + function _toPrimitive(t, r) { + if ("object" != typeof t || !t) return t; + var e = t[Symbol.toPrimitive]; + if (void 0 !== e) { + var i = e.call(t, r || "default"); + if ("object" != typeof i) return i; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return ("string" === r ? String : Number)(t); + } + function _toPropertyKey(t) { + var i = _toPrimitive(t, "string"); + return "symbol" == typeof i ? i : i + ""; + } + + /** + * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2023 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + function isArray(value) { + return !Array.isArray ? getTag(value) === '[object Array]' : Array.isArray(value); + } + + // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js + const INFINITY = 1 / 0; + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + let result = value + ''; + return result == '0' && 1 / value == -INFINITY ? '-0' : result; + } + function toString(value) { + return value == null ? '' : baseToString(value); + } + function isString(value) { + return typeof value === 'string'; + } + function isNumber(value) { + return typeof value === 'number'; + } + + // Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js + function isBoolean(value) { + return value === true || value === false || isObjectLike(value) && getTag(value) == '[object Boolean]'; + } + function isObject(value) { + return typeof value === 'object'; + } + + // Checks if `value` is object-like. + function isObjectLike(value) { + return isObject(value) && value !== null; + } + function isDefined(value) { + return value !== undefined && value !== null; + } + function isBlank(value) { + return !value.trim().length; + } + + // Gets the `toStringTag` of `value`. + // Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js + function getTag(value) { + return value == null ? value === undefined ? '[object Undefined]' : '[object Null]' : Object.prototype.toString.call(value); + } + const EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available'; + const LOGICAL_SEARCH_UNAVAILABLE = 'Logical search is not available'; + const INCORRECT_INDEX_TYPE = "Incorrect 'index' type"; + const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = key => `Invalid value for key ${key}`; + const PATTERN_LENGTH_TOO_LARGE = max => `Pattern length exceeds max of ${max}.`; + const MISSING_KEY_PROPERTY = name => `Missing ${name} property in key`; + const INVALID_KEY_WEIGHT_VALUE = key => `Property 'weight' in key '${key}' must be a positive integer`; + const hasOwn = Object.prototype.hasOwnProperty; + class KeyStore { + constructor(keys) { + this._keys = []; + this._keyMap = {}; + let totalWeight = 0; + keys.forEach(key => { + let obj = createKey(key); + this._keys.push(obj); + this._keyMap[obj.id] = obj; + totalWeight += obj.weight; + }); + + // Normalize weights so that their sum is equal to 1 + this._keys.forEach(key => { + key.weight /= totalWeight; + }); + } + get(keyId) { + return this._keyMap[keyId]; + } + keys() { + return this._keys; + } + toJSON() { + return JSON.stringify(this._keys); + } + } + function createKey(key) { + let path = null; + let id = null; + let src = null; + let weight = 1; + let getFn = null; + if (isString(key) || isArray(key)) { + src = key; + path = createKeyPath(key); + id = createKeyId(key); + } else { + if (!hasOwn.call(key, 'name')) { + throw new Error(MISSING_KEY_PROPERTY('name')); + } + const name = key.name; + src = name; + if (hasOwn.call(key, 'weight')) { + weight = key.weight; + if (weight <= 0) { + throw new Error(INVALID_KEY_WEIGHT_VALUE(name)); + } + } + path = createKeyPath(name); + id = createKeyId(name); + getFn = key.getFn; + } + return { + path, + id, + weight, + src, + getFn + }; + } + function createKeyPath(key) { + return isArray(key) ? key : key.split('.'); + } + function createKeyId(key) { + return isArray(key) ? key.join('.') : key; + } + function get(obj, path) { + let list = []; + let arr = false; + const deepGet = (obj, path, index) => { + if (!isDefined(obj)) { + return; + } + if (!path[index]) { + // If there's no path left, we've arrived at the object we care about. + list.push(obj); + } else { + let key = path[index]; + const value = obj[key]; + if (!isDefined(value)) { + return; + } + + // If we're at the last value in the path, and if it's a string/number/bool, + // add it to the list + if (index === path.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) { + list.push(toString(value)); + } else if (isArray(value)) { + arr = true; + // Search each item in the array. + for (let i = 0, len = value.length; i < len; i += 1) { + deepGet(value[i], path, index + 1); + } + } else if (path.length) { + // An object. Recurse further. + deepGet(value, path, index + 1); + } + } + }; + + // Backwards compatibility (since path used to be a string) + deepGet(obj, isString(path) ? path.split('.') : path, 0); + return arr ? list : list[0]; + } + const MatchOptions = { + // Whether the matches should be included in the result set. When `true`, each record in the result + // set will include the indices of the matched characters. + // These can consequently be used for highlighting purposes. + includeMatches: false, + // When `true`, the matching function will continue to the end of a search pattern even if + // a perfect match has already been located in the string. + findAllMatches: false, + // Minimum number of characters that must be matched before a result is considered a match + minMatchCharLength: 1 + }; + const BasicOptions = { + // When `true`, the algorithm continues searching to the end of the input even if a perfect + // match is found before the end of the same input. + isCaseSensitive: false, + // When true, the matching function will continue to the end of a search pattern even if + includeScore: false, + // List of properties that will be searched. This also supports nested properties. + keys: [], + // Whether to sort the result list, by score + shouldSort: true, + // Default sort function: sort by ascending score, ascending index + sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1 + }; + const FuzzyOptions = { + // Approximately where in the text is the pattern expected to be found? + location: 0, + // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match + // (of both letters and location), a threshold of '1.0' would match anything. + threshold: 0.6, + // Determines how close the match must be to the fuzzy location (specified above). + // An exact letter match which is 'distance' characters away from the fuzzy location + // would score as a complete mismatch. A distance of '0' requires the match be at + // the exact location specified, a threshold of '1000' would require a perfect match + // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold. + distance: 100 + }; + const AdvancedOptions = { + // When `true`, it enables the use of unix-like search commands + useExtendedSearch: false, + // The get function to use when fetching an object's properties. + // The default will search nested paths *ie foo.bar.baz* + getFn: get, + // When `true`, search will ignore `location` and `distance`, so it won't matter + // where in the string the pattern appears. + // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score + ignoreLocation: false, + // When `true`, the calculation for the relevance score (used for sorting) will + // ignore the field-length norm. + // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm + ignoreFieldNorm: false, + // The weight to determine how much field length norm effects scoring. + fieldNormWeight: 1 + }; + var Config = _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, BasicOptions), MatchOptions), FuzzyOptions), AdvancedOptions); + const SPACE = /[^ ]+/g; + + // Field-length norm: the shorter the field, the higher the weight. + // Set to 3 decimals to reduce index size. + function norm(weight = 1, mantissa = 3) { + const cache = new Map(); + const m = Math.pow(10, mantissa); + return { + get(value) { + const numTokens = value.match(SPACE).length; + if (cache.has(numTokens)) { + return cache.get(numTokens); + } + + // Default function is 1/sqrt(x), weight makes that variable + const norm = 1 / Math.pow(numTokens, 0.5 * weight); + + // In place of `toFixed(mantissa)`, for faster computation + const n = parseFloat(Math.round(norm * m) / m); + cache.set(numTokens, n); + return n; + }, + clear() { + cache.clear(); + } + }; + } + class FuseIndex { + constructor({ + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight + } = {}) { + this.norm = norm(fieldNormWeight, 3); + this.getFn = getFn; + this.isCreated = false; + this.setIndexRecords(); + } + setSources(docs = []) { + this.docs = docs; + } + setIndexRecords(records = []) { + this.records = records; + } + setKeys(keys = []) { + this.keys = keys; + this._keysMap = {}; + keys.forEach((key, idx) => { + this._keysMap[key.id] = idx; + }); + } + create() { + if (this.isCreated || !this.docs.length) { + return; + } + this.isCreated = true; + + // List is Array + if (isString(this.docs[0])) { + this.docs.forEach((doc, docIndex) => { + this._addString(doc, docIndex); + }); + } else { + // List is Array + this.docs.forEach((doc, docIndex) => { + this._addObject(doc, docIndex); + }); + } + this.norm.clear(); + } + // Adds a doc to the end of the index + add(doc) { + const idx = this.size(); + if (isString(doc)) { + this._addString(doc, idx); + } else { + this._addObject(doc, idx); + } + } + // Removes the doc at the specified index of the index + removeAt(idx) { + this.records.splice(idx, 1); + + // Change ref index of every subsquent doc + for (let i = idx, len = this.size(); i < len; i += 1) { + this.records[i].i -= 1; + } + } + getValueForItemAtKeyId(item, keyId) { + return item[this._keysMap[keyId]]; + } + size() { + return this.records.length; + } + _addString(doc, docIndex) { + if (!isDefined(doc) || isBlank(doc)) { + return; + } + let record = { + v: doc, + i: docIndex, + n: this.norm.get(doc) + }; + this.records.push(record); + } + _addObject(doc, docIndex) { + let record = { + i: docIndex, + $: {} + }; + + // Iterate over every key (i.e, path), and fetch the value at that key + this.keys.forEach((key, keyIndex) => { + let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path); + if (!isDefined(value)) { + return; + } + if (isArray(value)) { + let subRecords = []; + const stack = [{ + nestedArrIndex: -1, + value + }]; + while (stack.length) { + const { + nestedArrIndex, + value + } = stack.pop(); + if (!isDefined(value)) { + continue; + } + if (isString(value) && !isBlank(value)) { + let subRecord = { + v: value, + i: nestedArrIndex, + n: this.norm.get(value) + }; + subRecords.push(subRecord); + } else if (isArray(value)) { + value.forEach((item, k) => { + stack.push({ + nestedArrIndex: k, + value: item + }); + }); + } else ; + } + record.$[keyIndex] = subRecords; + } else if (isString(value) && !isBlank(value)) { + let subRecord = { + v: value, + n: this.norm.get(value) + }; + record.$[keyIndex] = subRecord; + } + }); + this.records.push(record); + } + toJSON() { + return { + keys: this.keys, + records: this.records + }; + } + } + function createIndex(keys, docs, { + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight + } = {}) { + const myIndex = new FuseIndex({ + getFn, + fieldNormWeight + }); + myIndex.setKeys(keys.map(createKey)); + myIndex.setSources(docs); + myIndex.create(); + return myIndex; + } + function parseIndex(data, { + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight + } = {}) { + const { + keys, + records + } = data; + const myIndex = new FuseIndex({ + getFn, + fieldNormWeight + }); + myIndex.setKeys(keys); + myIndex.setIndexRecords(records); + return myIndex; + } + function computeScore$1(pattern, { + errors = 0, + currentLocation = 0, + expectedLocation = 0, + distance = Config.distance, + ignoreLocation = Config.ignoreLocation + } = {}) { + const accuracy = errors / pattern.length; + if (ignoreLocation) { + return accuracy; + } + const proximity = Math.abs(expectedLocation - currentLocation); + if (!distance) { + // Dodge divide by zero error. + return proximity ? 1.0 : accuracy; + } + return accuracy + proximity / distance; + } + function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) { + let indices = []; + let start = -1; + let end = -1; + let i = 0; + for (let len = matchmask.length; i < len; i += 1) { + let match = matchmask[i]; + if (match && start === -1) { + start = i; + } else if (!match && start !== -1) { + end = i - 1; + if (end - start + 1 >= minMatchCharLength) { + indices.push([start, end]); + } + start = -1; + } + } + + // (i-1 - start) + 1 => i - start + if (matchmask[i - 1] && i - start >= minMatchCharLength) { + indices.push([start, i - 1]); + } + return indices; + } + + // Machine word size + const MAX_BITS = 32; + function search(text, pattern, patternAlphabet, { + location = Config.location, + distance = Config.distance, + threshold = Config.threshold, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + includeMatches = Config.includeMatches, + ignoreLocation = Config.ignoreLocation + } = {}) { + if (pattern.length > MAX_BITS) { + throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS)); + } + const patternLen = pattern.length; + // Set starting location at beginning text and initialize the alphabet. + const textLen = text.length; + // Handle the case when location > text.length + const expectedLocation = Math.max(0, Math.min(location, textLen)); + // Highest score beyond which we give up. + let currentThreshold = threshold; + // Is there a nearby exact match? (speedup) + let bestLocation = expectedLocation; + + // Performance: only computer matches when the minMatchCharLength > 1 + // OR if `includeMatches` is true. + const computeMatches = minMatchCharLength > 1 || includeMatches; + // A mask of the matches, used for building the indices + const matchMask = computeMatches ? Array(textLen) : []; + let index; + + // Get all exact matches, here for speed up + while ((index = text.indexOf(pattern, bestLocation)) > -1) { + let score = computeScore$1(pattern, { + currentLocation: index, + expectedLocation, + distance, + ignoreLocation + }); + currentThreshold = Math.min(score, currentThreshold); + bestLocation = index + patternLen; + if (computeMatches) { + let i = 0; + while (i < patternLen) { + matchMask[index + i] = 1; + i += 1; + } + } + } + + // Reset the best location + bestLocation = -1; + let lastBitArr = []; + let finalScore = 1; + let binMax = patternLen + textLen; + const mask = 1 << patternLen - 1; + for (let i = 0; i < patternLen; i += 1) { + // Scan for the best match; each iteration allows for one more error. + // Run a binary search to determine how far from the match location we can stray + // at this error level. + let binMin = 0; + let binMid = binMax; + while (binMin < binMid) { + const score = computeScore$1(pattern, { + errors: i, + currentLocation: expectedLocation + binMid, + expectedLocation, + distance, + ignoreLocation + }); + if (score <= currentThreshold) { + binMin = binMid; + } else { + binMax = binMid; + } + binMid = Math.floor((binMax - binMin) / 2 + binMin); + } + + // Use the result from this iteration as the maximum for the next. + binMax = binMid; + let start = Math.max(1, expectedLocation - binMid + 1); + let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen; + + // Initialize the bit array + let bitArr = Array(finish + 2); + bitArr[finish + 1] = (1 << i) - 1; + for (let j = finish; j >= start; j -= 1) { + let currentLocation = j - 1; + let charMatch = patternAlphabet[text.charAt(currentLocation)]; + if (computeMatches) { + // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`) + matchMask[currentLocation] = +!!charMatch; + } + + // First pass: exact match + bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch; + + // Subsequent passes: fuzzy match + if (i) { + bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1]; + } + if (bitArr[j] & mask) { + finalScore = computeScore$1(pattern, { + errors: i, + currentLocation, + expectedLocation, + distance, + ignoreLocation + }); + + // This match will almost certainly be better than any existing match. + // But check anyway. + if (finalScore <= currentThreshold) { + // Indeed it is + currentThreshold = finalScore; + bestLocation = currentLocation; + + // Already passed `loc`, downhill from here on in. + if (bestLocation <= expectedLocation) { + break; + } + + // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`. + start = Math.max(1, 2 * expectedLocation - bestLocation); + } + } + } + + // No hope for a (better) match at greater error levels. + const score = computeScore$1(pattern, { + errors: i + 1, + currentLocation: expectedLocation, + expectedLocation, + distance, + ignoreLocation + }); + if (score > currentThreshold) { + break; + } + lastBitArr = bitArr; + } + const result = { + isMatch: bestLocation >= 0, + // Count exact matches (those with a score of 0) to be "almost" exact + score: Math.max(0.001, finalScore) + }; + if (computeMatches) { + const indices = convertMaskToIndices(matchMask, minMatchCharLength); + if (!indices.length) { + result.isMatch = false; + } else if (includeMatches) { + result.indices = indices; + } + } + return result; + } + function createPatternAlphabet(pattern) { + let mask = {}; + for (let i = 0, len = pattern.length; i < len; i += 1) { + const char = pattern.charAt(i); + mask[char] = (mask[char] || 0) | 1 << len - i - 1; + } + return mask; + } + class BitapSearch { + constructor(pattern, { + location = Config.location, + threshold = Config.threshold, + distance = Config.distance, + includeMatches = Config.includeMatches, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + isCaseSensitive = Config.isCaseSensitive, + ignoreLocation = Config.ignoreLocation + } = {}) { + this.options = { + location, + threshold, + distance, + includeMatches, + findAllMatches, + minMatchCharLength, + isCaseSensitive, + ignoreLocation + }; + this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); + this.chunks = []; + if (!this.pattern.length) { + return; + } + const addChunk = (pattern, startIndex) => { + this.chunks.push({ + pattern, + alphabet: createPatternAlphabet(pattern), + startIndex + }); + }; + const len = this.pattern.length; + if (len > MAX_BITS) { + let i = 0; + const remainder = len % MAX_BITS; + const end = len - remainder; + while (i < end) { + addChunk(this.pattern.substr(i, MAX_BITS), i); + i += MAX_BITS; + } + if (remainder) { + const startIndex = len - MAX_BITS; + addChunk(this.pattern.substr(startIndex), startIndex); + } + } else { + addChunk(this.pattern, 0); + } + } + searchIn(text) { + const { + isCaseSensitive, + includeMatches + } = this.options; + if (!isCaseSensitive) { + text = text.toLowerCase(); + } + + // Exact match + if (this.pattern === text) { + let result = { + isMatch: true, + score: 0 + }; + if (includeMatches) { + result.indices = [[0, text.length - 1]]; + } + return result; + } + + // Otherwise, use Bitap algorithm + const { + location, + distance, + threshold, + findAllMatches, + minMatchCharLength, + ignoreLocation + } = this.options; + let allIndices = []; + let totalScore = 0; + let hasMatches = false; + this.chunks.forEach(({ + pattern, + alphabet, + startIndex + }) => { + const { + isMatch, + score, + indices + } = search(text, pattern, alphabet, { + location: location + startIndex, + distance, + threshold, + findAllMatches, + minMatchCharLength, + includeMatches, + ignoreLocation + }); + if (isMatch) { + hasMatches = true; + } + totalScore += score; + if (isMatch && indices) { + allIndices = [...allIndices, ...indices]; + } + }); + let result = { + isMatch: hasMatches, + score: hasMatches ? totalScore / this.chunks.length : 1 + }; + if (hasMatches && includeMatches) { + result.indices = allIndices; + } + return result; + } + } + const registeredSearchers = []; + function createSearcher(pattern, options) { + for (let i = 0, len = registeredSearchers.length; i < len; i += 1) { + let searcherClass = registeredSearchers[i]; + if (searcherClass.condition(pattern, options)) { + return new searcherClass(pattern, options); + } + } + return new BitapSearch(pattern, options); + } + const LogicalOperator = { + AND: '$and', + OR: '$or' + }; + const KeyType = { + PATH: '$path', + PATTERN: '$val' + }; + const isExpression = query => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]); + const isPath = query => !!query[KeyType.PATH]; + const isLeaf = query => !isArray(query) && isObject(query) && !isExpression(query); + const convertToExplicit = query => ({ + [LogicalOperator.AND]: Object.keys(query).map(key => ({ + [key]: query[key] + })) + }); + + // When `auto` is `true`, the parse function will infer and initialize and add + // the appropriate `Searcher` instance + function parse(query, options, { + auto = true + } = {}) { + const next = query => { + let keys = Object.keys(query); + const isQueryPath = isPath(query); + if (!isQueryPath && keys.length > 1 && !isExpression(query)) { + return next(convertToExplicit(query)); + } + if (isLeaf(query)) { + const key = isQueryPath ? query[KeyType.PATH] : keys[0]; + const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key]; + if (!isString(pattern)) { + throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key)); + } + const obj = { + keyId: createKeyId(key), + pattern + }; + if (auto) { + obj.searcher = createSearcher(pattern, options); + } + return obj; + } + let node = { + children: [], + operator: keys[0] + }; + keys.forEach(key => { + const value = query[key]; + if (isArray(value)) { + value.forEach(item => { + node.children.push(next(item)); + }); + } + }); + return node; + }; + if (!isExpression(query)) { + query = convertToExplicit(query); + } + return next(query); + } + + // Practical scoring function + function computeScore(results, { + ignoreFieldNorm = Config.ignoreFieldNorm + }) { + results.forEach(result => { + let totalScore = 1; + result.matches.forEach(({ + key, + norm, + score + }) => { + const weight = key ? key.weight : null; + totalScore *= Math.pow(score === 0 && weight ? Number.EPSILON : score, (weight || 1) * (ignoreFieldNorm ? 1 : norm)); + }); + result.score = totalScore; + }); + } + function transformMatches(result, data) { + const matches = result.matches; + data.matches = []; + if (!isDefined(matches)) { + return; + } + matches.forEach(match => { + if (!isDefined(match.indices) || !match.indices.length) { + return; + } + const { + indices, + value + } = match; + let obj = { + indices, + value + }; + if (match.key) { + obj.key = match.key.src; + } + if (match.idx > -1) { + obj.refIndex = match.idx; + } + data.matches.push(obj); + }); + } + function transformScore(result, data) { + data.score = result.score; + } + function format(results, docs, { + includeMatches = Config.includeMatches, + includeScore = Config.includeScore + } = {}) { + const transformers = []; + if (includeMatches) transformers.push(transformMatches); + if (includeScore) transformers.push(transformScore); + return results.map(result => { + const { + idx + } = result; + const data = { + item: docs[idx], + refIndex: idx + }; + if (transformers.length) { + transformers.forEach(transformer => { + transformer(result, data); + }); + } + return data; + }); + } + class Fuse { + constructor(docs, options = {}, index) { + this.options = _objectSpread2(_objectSpread2({}, Config), options); + if (this.options.useExtendedSearch && !false) { + throw new Error(EXTENDED_SEARCH_UNAVAILABLE); + } + this._keyStore = new KeyStore(this.options.keys); + this.setCollection(docs, index); + } + setCollection(docs, index) { + this._docs = docs; + if (index && !(index instanceof FuseIndex)) { + throw new Error(INCORRECT_INDEX_TYPE); + } + this._myIndex = index || createIndex(this.options.keys, this._docs, { + getFn: this.options.getFn, + fieldNormWeight: this.options.fieldNormWeight + }); + } + add(doc) { + if (!isDefined(doc)) { + return; + } + this._docs.push(doc); + this._myIndex.add(doc); + } + remove(predicate = ( /* doc, idx */) => false) { + const results = []; + for (let i = 0, len = this._docs.length; i < len; i += 1) { + const doc = this._docs[i]; + if (predicate(doc, i)) { + this.removeAt(i); + i -= 1; + len -= 1; + results.push(doc); + } + } + return results; + } + removeAt(idx) { + this._docs.splice(idx, 1); + this._myIndex.removeAt(idx); + } + getIndex() { + return this._myIndex; + } + search(query, { + limit = -1 + } = {}) { + const { + includeMatches, + includeScore, + shouldSort, + sortFn, + ignoreFieldNorm + } = this.options; + let results = isString(query) ? isString(this._docs[0]) ? this._searchStringList(query) : this._searchObjectList(query) : this._searchLogical(query); + computeScore(results, { + ignoreFieldNorm + }); + if (shouldSort) { + results.sort(sortFn); + } + if (isNumber(limit) && limit > -1) { + results = results.slice(0, limit); + } + return format(results, this._docs, { + includeMatches, + includeScore + }); + } + _searchStringList(query) { + const searcher = createSearcher(query, this.options); + const { + records + } = this._myIndex; + const results = []; + + // Iterate over every string in the index + records.forEach(({ + v: text, + i: idx, + n: norm + }) => { + if (!isDefined(text)) { + return; + } + const { + isMatch, + score, + indices + } = searcher.searchIn(text); + if (isMatch) { + results.push({ + item: text, + idx, + matches: [{ + score, + value: text, + norm, + indices + }] + }); + } + }); + return results; + } + _searchLogical(query) { + { + throw new Error(LOGICAL_SEARCH_UNAVAILABLE); + } + } + _searchObjectList(query) { + const searcher = createSearcher(query, this.options); + const { + keys, + records + } = this._myIndex; + const results = []; + + // List is Array + records.forEach(({ + $: item, + i: idx + }) => { + if (!isDefined(item)) { + return; + } + let matches = []; + + // Iterate over every key (i.e, path), and fetch the value at that key + keys.forEach((key, keyIndex) => { + matches.push(...this._findMatches({ + key, + value: item[keyIndex], + searcher + })); + }); + if (matches.length) { + results.push({ + idx, + item, + matches + }); + } + }); + return results; + } + _findMatches({ + key, + value, + searcher + }) { + if (!isDefined(value)) { + return []; + } + let matches = []; + if (isArray(value)) { + value.forEach(({ + v: text, + i: idx, + n: norm + }) => { + if (!isDefined(text)) { + return; + } + const { + isMatch, + score, + indices + } = searcher.searchIn(text); + if (isMatch) { + matches.push({ + score, + key, + value: text, + idx, + norm, + indices + }); + } + }); + } else { + const { + v: text, + n: norm + } = value; + const { + isMatch, + score, + indices + } = searcher.searchIn(text); + if (isMatch) { + matches.push({ + score, + key, + value: text, + norm, + indices + }); + } + } + return matches; + } + } + Fuse.version = '7.0.0'; + Fuse.createIndex = createIndex; + Fuse.parseIndex = parseIndex; + Fuse.config = Config; + { + Fuse.parseQuery = parse; + } + + var SearchByFuse = /** @class */ (function () { + function SearchByFuse(config) { + this._haystack = []; + this._fuseOptions = __assign(__assign({}, config.fuseOptions), { keys: __spreadArray([], config.searchFields, true), includeMatches: true }); + } + SearchByFuse.prototype.index = function (data) { + this._haystack = data; + if (this._fuse) { + this._fuse.setCollection(data); + } + }; + SearchByFuse.prototype.reset = function () { + this._haystack = []; + this._fuse = undefined; + }; + SearchByFuse.prototype.isEmptyIndex = function () { + return !this._haystack.length; + }; + SearchByFuse.prototype.search = function (needle) { + if (!this._fuse) { + { + this._fuse = new Fuse(this._haystack, this._fuseOptions); + } + } + var results = this._fuse.search(needle); + return results.map(function (value, i) { + return { + item: value.item, + score: value.score || 0, + rank: i + 1, // If value.score is used for sorting, this can create non-stable sorts! + }; + }); + }; + return SearchByFuse; + }()); + + function getSearcher(config) { + { + return new SearchByFuse(config); + } + } + + /** + * Helpers to create HTML elements used by Choices + * Can be overridden by providing `callbackOnCreateTemplates` option. + * `Choices.defaults.templates` allows access to the default template methods from `callbackOnCreateTemplates` + */ + var isEmptyObject = function (obj) { + // eslint-disable-next-line no-restricted-syntax + for (var prop in obj) { + if (Object.prototype.hasOwnProperty.call(obj, prop)) { + return false; + } + } + return true; + }; + var assignCustomProperties = function (el, choice, withCustomProperties) { + var dataset = el.dataset; + var customProperties = choice.customProperties, labelClass = choice.labelClass, labelDescription = choice.labelDescription; + if (labelClass) { + dataset.labelClass = getClassNames(labelClass).join(' '); + } + if (labelDescription) { + dataset.labelDescription = labelDescription; + } + if (withCustomProperties && customProperties) { + if (typeof customProperties === 'string') { + dataset.customProperties = customProperties; + } + else if (typeof customProperties === 'object' && !isEmptyObject(customProperties)) { + dataset.customProperties = JSON.stringify(customProperties); + } + } + }; + var addAriaLabel = function (docRoot, id, element) { + var label = id && docRoot.querySelector("label[for='".concat(id, "']")); + var text = label && label.innerText; + if (text) { + element.setAttribute('aria-label', text); + } + }; + var templates = { + containerOuter: function (_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType, labelId) { + var containerOuter = _a.classNames.containerOuter; + var div = document.createElement('div'); + addClassesToElement(div, containerOuter); + div.dataset.type = passedElementType; + if (dir) { + div.dir = dir; + } + if (isSelectOneElement) { + div.tabIndex = 0; + } + if (isSelectElement) { + div.setAttribute('role', searchEnabled ? 'combobox' : 'listbox'); + if (searchEnabled) { + div.setAttribute('aria-autocomplete', 'list'); + } + else if (!labelId) { + addAriaLabel(this._docRoot, this.passedElement.element.id, div); + } + div.setAttribute('aria-haspopup', 'true'); + div.setAttribute('aria-expanded', 'false'); + } + if (labelId) { + div.setAttribute('aria-labelledby', labelId); + } + return div; + }, + containerInner: function (_a) { + var containerInner = _a.classNames.containerInner; + var div = document.createElement('div'); + addClassesToElement(div, containerInner); + return div; + }, + itemList: function (_a, isSelectOneElement) { + var searchEnabled = _a.searchEnabled, _b = _a.classNames, list = _b.list, listSingle = _b.listSingle, listItems = _b.listItems; + var div = document.createElement('div'); + addClassesToElement(div, list); + addClassesToElement(div, isSelectOneElement ? listSingle : listItems); + if (this._isSelectElement && searchEnabled) { + div.setAttribute('role', 'listbox'); + } + return div; + }, + placeholder: function (_a, value) { + var allowHTML = _a.allowHTML, placeholder = _a.classNames.placeholder; + var div = document.createElement('div'); + addClassesToElement(div, placeholder); + setElementHtml(div, allowHTML, value); + return div; + }, + item: function (_a, choice, removeItemButton) { + var allowHTML = _a.allowHTML, removeItemButtonAlignLeft = _a.removeItemButtonAlignLeft, removeItemIconText = _a.removeItemIconText, removeItemLabelText = _a.removeItemLabelText, _b = _a.classNames, item = _b.item, button = _b.button, highlightedState = _b.highlightedState, itemSelectable = _b.itemSelectable, placeholder = _b.placeholder; + var rawValue = unwrapStringForRaw(choice.value); + var div = document.createElement('div'); + addClassesToElement(div, item); + if (choice.labelClass) { + var spanLabel = document.createElement('span'); + setElementHtml(spanLabel, allowHTML, choice.label); + addClassesToElement(spanLabel, choice.labelClass); + div.appendChild(spanLabel); + } + else { + setElementHtml(div, allowHTML, choice.label); + } + div.dataset.item = ''; + div.dataset.id = choice.id; + div.dataset.value = rawValue; + assignCustomProperties(div, choice, true); + if (choice.disabled || this.containerOuter.isDisabled) { + div.setAttribute('aria-disabled', 'true'); + } + if (this._isSelectElement) { + div.setAttribute('aria-selected', 'true'); + div.setAttribute('role', 'option'); + } + if (choice.placeholder) { + addClassesToElement(div, placeholder); + div.dataset.placeholder = ''; + } + addClassesToElement(div, choice.highlighted ? highlightedState : itemSelectable); + if (removeItemButton) { + if (choice.disabled) { + removeClassesFromElement(div, itemSelectable); + } + div.dataset.deletable = ''; + var removeButton = document.createElement('button'); + removeButton.type = 'button'; + addClassesToElement(removeButton, button); + setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value)); + var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value); + if (REMOVE_ITEM_LABEL) { + removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL); + } + removeButton.dataset.button = ''; + if (removeItemButtonAlignLeft) { + div.insertAdjacentElement('afterbegin', removeButton); + } + else { + div.appendChild(removeButton); + } + } + return div; + }, + choiceList: function (_a, isSelectOneElement) { + var list = _a.classNames.list; + var div = document.createElement('div'); + addClassesToElement(div, list); + if (!isSelectOneElement) { + div.setAttribute('aria-multiselectable', 'true'); + } + div.setAttribute('role', 'listbox'); + return div; + }, + choiceGroup: function (_a, _b) { + var allowHTML = _a.allowHTML, _c = _a.classNames, group = _c.group, groupHeading = _c.groupHeading, itemDisabled = _c.itemDisabled; + var id = _b.id, label = _b.label, disabled = _b.disabled; + var rawLabel = unwrapStringForRaw(label); + var div = document.createElement('div'); + addClassesToElement(div, group); + if (disabled) { + addClassesToElement(div, itemDisabled); + } + div.setAttribute('role', 'group'); + div.dataset.group = ''; + div.dataset.id = id; + div.dataset.value = rawLabel; + if (disabled) { + div.setAttribute('aria-disabled', 'true'); + } + var heading = document.createElement('div'); + addClassesToElement(heading, groupHeading); + setElementHtml(heading, allowHTML, label || ''); + div.appendChild(heading); + return div; + }, + choice: function (_a, choice, selectText, groupName) { + var allowHTML = _a.allowHTML, _b = _a.classNames, item = _b.item, itemChoice = _b.itemChoice, itemSelectable = _b.itemSelectable, selectedState = _b.selectedState, itemDisabled = _b.itemDisabled, description = _b.description, placeholder = _b.placeholder; + // eslint-disable-next-line prefer-destructuring + var label = choice.label; + var rawValue = unwrapStringForRaw(choice.value); + var div = document.createElement('div'); + div.id = choice.elementId; + addClassesToElement(div, item); + addClassesToElement(div, itemChoice); + if (groupName && typeof label === 'string') { + label = escapeForTemplate(allowHTML, label); + label += " (".concat(groupName, ")"); + label = { trusted: label }; + div.dataset.groupId = "".concat(choice.groupId); + } + var describedBy = div; + if (choice.labelClass) { + var spanLabel = document.createElement('span'); + setElementHtml(spanLabel, allowHTML, label); + addClassesToElement(spanLabel, choice.labelClass); + describedBy = spanLabel; + div.appendChild(spanLabel); + } + else { + setElementHtml(div, allowHTML, label); + } + if (choice.labelDescription) { + var descId = "".concat(choice.elementId, "-description"); + describedBy.setAttribute('aria-describedby', descId); + var spanDesc = document.createElement('span'); + setElementHtml(spanDesc, allowHTML, choice.labelDescription); + spanDesc.id = descId; + addClassesToElement(spanDesc, description); + div.appendChild(spanDesc); + } + if (choice.selected) { + addClassesToElement(div, selectedState); + } + if (choice.placeholder) { + addClassesToElement(div, placeholder); + } + div.setAttribute('role', choice.groupId ? 'treeitem' : 'option'); + div.dataset.choice = ''; + div.dataset.id = choice.id; + div.dataset.value = rawValue; + if (selectText) { + div.dataset.selectText = selectText; + } + assignCustomProperties(div, choice, false); + if (choice.disabled) { + addClassesToElement(div, itemDisabled); + div.dataset.choiceDisabled = ''; + div.setAttribute('aria-disabled', 'true'); + } + else { + addClassesToElement(div, itemSelectable); + div.dataset.choiceSelectable = ''; + } + return div; + }, + input: function (_a, placeholderValue) { + var _b = _a.classNames, input = _b.input, inputCloned = _b.inputCloned, labelId = _a.labelId; + var inp = document.createElement('input'); + inp.type = 'search'; + addClassesToElement(inp, input); + addClassesToElement(inp, inputCloned); + inp.autocomplete = 'off'; + inp.autocapitalize = 'off'; + inp.spellcheck = false; + inp.setAttribute('role', 'textbox'); + inp.setAttribute('aria-autocomplete', 'list'); + if (placeholderValue) { + inp.setAttribute('aria-label', placeholderValue); + } + else if (!labelId) { + addAriaLabel(this._docRoot, this.passedElement.element.id, inp); + } + return inp; + }, + dropdown: function (_a) { + var _b = _a.classNames, list = _b.list, listDropdown = _b.listDropdown; + var div = document.createElement('div'); + addClassesToElement(div, list); + addClassesToElement(div, listDropdown); + div.setAttribute('aria-expanded', 'false'); + return div; + }, + notice: function (_a, innerHTML, type) { + var _b = _a.classNames, item = _b.item, itemChoice = _b.itemChoice, addChoice = _b.addChoice, noResults = _b.noResults, noChoices = _b.noChoices, noticeItem = _b.notice; + if (type === void 0) { type = NoticeTypes.generic; } + var notice = document.createElement('div'); + setElementHtml(notice, true, innerHTML); + addClassesToElement(notice, item); + addClassesToElement(notice, itemChoice); + addClassesToElement(notice, noticeItem); + // eslint-disable-next-line default-case + switch (type) { + case NoticeTypes.addChoice: + addClassesToElement(notice, addChoice); + break; + case NoticeTypes.noResults: + addClassesToElement(notice, noResults); + break; + case NoticeTypes.noChoices: + addClassesToElement(notice, noChoices); + break; + } + if (type === NoticeTypes.addChoice) { + notice.dataset.choiceSelectable = ''; + notice.dataset.choice = ''; + } + return notice; + }, + option: function (choice) { + // HtmlOptionElement's label value does not support HTML, so the avoid double escaping unwrap the untrusted string. + var labelValue = unwrapStringForRaw(choice.label); + var opt = new Option(labelValue, choice.value, false, choice.selected); + assignCustomProperties(opt, choice, true); + opt.disabled = choice.disabled; + if (choice.selected) { + opt.setAttribute('selected', ''); + } + return opt; + }, + }; + + /** @see {@link http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c} */ + var IS_IE11 = '-ms-scroll-limit' in document.documentElement.style && + '-ms-ime-align' in document.documentElement.style; + var USER_DEFAULTS = {}; + var parseDataSetId = function (element) { + if (!element) { + return undefined; + } + return element.dataset.id ? parseInt(element.dataset.id, 10) : undefined; + }; + var selectableChoiceIdentifier = '[data-choice-selectable]'; + /** + * Choices + * @author Josh Johnson + */ + var Choices = /** @class */ (function () { + function Choices(element, userConfig) { + if (element === void 0) { element = '[data-choice]'; } + if (userConfig === void 0) { userConfig = {}; } + var _this = this; + this.initialisedOK = undefined; + this._hasNonChoicePlaceholder = false; + this._lastAddedChoiceId = 0; + this._lastAddedGroupId = 0; + var defaults = Choices.defaults; + this.config = __assign(__assign(__assign({}, defaults.allOptions), defaults.options), userConfig); + ObjectsInConfig.forEach(function (key) { + _this.config[key] = __assign(__assign(__assign({}, defaults.allOptions[key]), defaults.options[key]), userConfig[key]); + }); + var config = this.config; + if (!config.silent) { + this._validateConfig(); + } + var docRoot = config.shadowRoot || document.documentElement; + this._docRoot = docRoot; + var passedElement = typeof element === 'string' ? docRoot.querySelector(element) : element; + if (!passedElement || + typeof passedElement !== 'object' || + !(isHtmlInputElement(passedElement) || isHtmlSelectElement(passedElement))) { + if (!passedElement && typeof element === 'string') { + throw TypeError("Selector ".concat(element, " failed to find an element")); + } + throw TypeError("Expected one of the following types text|select-one|select-multiple"); + } + var elementType = passedElement.type; + var isText = elementType === PassedElementTypes.Text; + if (isText || config.maxItemCount !== 1) { + config.singleModeForMultiSelect = false; + } + if (config.singleModeForMultiSelect) { + elementType = PassedElementTypes.SelectMultiple; + } + var isSelectOne = elementType === PassedElementTypes.SelectOne; + var isSelectMultiple = elementType === PassedElementTypes.SelectMultiple; + var isSelect = isSelectOne || isSelectMultiple; + this._elementType = elementType; + this._isTextElement = isText; + this._isSelectOneElement = isSelectOne; + this._isSelectMultipleElement = isSelectMultiple; + this._isSelectElement = isSelectOne || isSelectMultiple; + this._canAddUserChoices = (isText && config.addItems) || (isSelect && config.addChoices); + if (typeof config.renderSelectedChoices !== 'boolean') { + config.renderSelectedChoices = config.renderSelectedChoices === 'always' || isSelectOne; + } + if (config.closeDropdownOnSelect === 'auto') { + config.closeDropdownOnSelect = isText || isSelectOne || config.singleModeForMultiSelect; + } + else { + config.closeDropdownOnSelect = coerceBool(config.closeDropdownOnSelect); + } + if (config.placeholder) { + if (config.placeholderValue) { + this._hasNonChoicePlaceholder = true; + } + else if (passedElement.dataset.placeholder) { + this._hasNonChoicePlaceholder = true; + config.placeholderValue = passedElement.dataset.placeholder; + } + } + if (userConfig.addItemFilter && typeof userConfig.addItemFilter !== 'function') { + var re = userConfig.addItemFilter instanceof RegExp ? userConfig.addItemFilter : new RegExp(userConfig.addItemFilter); + config.addItemFilter = re.test.bind(re); + } + if (this._isTextElement) { + this.passedElement = new WrappedInput({ + element: passedElement, + classNames: config.classNames, + }); + } + else { + var selectEl = passedElement; + this.passedElement = new WrappedSelect({ + element: selectEl, + classNames: config.classNames, + template: function (data) { return _this._templates.option(data); }, + extractPlaceholder: config.placeholder && !this._hasNonChoicePlaceholder, + }); + } + this.initialised = false; + this._store = new Store(config); + this._currentValue = ''; + config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple; + this._canSearch = config.searchEnabled; + this._isScrollingOnIe = false; + this._highlightPosition = 0; + this._wasTap = true; + this._placeholderValue = this._generatePlaceholderValue(); + this._baseId = generateId(passedElement, 'choices-'); + /** + * setting direction in cases where it's explicitly set on passedElement + * or when calculated direction is different from the document + */ + this._direction = passedElement.dir; + if (!this._direction) { + var elementDirection = window.getComputedStyle(passedElement).direction; + var documentDirection = window.getComputedStyle(document.documentElement).direction; + if (elementDirection !== documentDirection) { + this._direction = elementDirection; + } + } + this._idNames = { + itemChoice: 'item-choice', + }; + this._templates = defaults.templates; + this._render = this._render.bind(this); + this._onFocus = this._onFocus.bind(this); + this._onBlur = this._onBlur.bind(this); + this._onKeyUp = this._onKeyUp.bind(this); + this._onKeyDown = this._onKeyDown.bind(this); + this._onInput = this._onInput.bind(this); + this._onClick = this._onClick.bind(this); + this._onTouchMove = this._onTouchMove.bind(this); + this._onTouchEnd = this._onTouchEnd.bind(this); + this._onMouseDown = this._onMouseDown.bind(this); + this._onMouseOver = this._onMouseOver.bind(this); + this._onFormReset = this._onFormReset.bind(this); + this._onSelectKey = this._onSelectKey.bind(this); + this._onEnterKey = this._onEnterKey.bind(this); + this._onEscapeKey = this._onEscapeKey.bind(this); + this._onDirectionKey = this._onDirectionKey.bind(this); + this._onDeleteKey = this._onDeleteKey.bind(this); + // If element has already been initialised with Choices, fail silently + if (this.passedElement.isActive) { + if (!config.silent) { + console.warn('Trying to initialise Choices on element already initialised', { element: element }); + } + this.initialised = true; + this.initialisedOK = false; + return; + } + // Let's go + this.init(); + // preserve the selected item list after setup for form reset + this._initialItems = this._store.items.map(function (choice) { return choice.value; }); + } + Object.defineProperty(Choices, "defaults", { + get: function () { + return Object.preventExtensions({ + get options() { + return USER_DEFAULTS; + }, + get allOptions() { + return DEFAULT_CONFIG; + }, + get templates() { + return templates; + }, + }); + }, + enumerable: false, + configurable: true + }); + Choices.prototype.init = function () { + if (this.initialised || this.initialisedOK !== undefined) { + return; + } + this._searcher = getSearcher(this.config); + this._loadChoices(); + this._createTemplates(); + this._createElements(); + this._createStructure(); + if ((this._isTextElement && !this.config.addItems) || + this.passedElement.element.hasAttribute('disabled') || + !!this.passedElement.element.closest('fieldset:disabled')) { + this.disable(); + } + else { + this.enable(); + this._addEventListeners(); + } + // should be triggered **after** disabled state to avoid additional re-draws + this._initStore(); + this.initialised = true; + this.initialisedOK = true; + var callbackOnInit = this.config.callbackOnInit; + // Run callback if it is a function + if (typeof callbackOnInit === 'function') { + callbackOnInit.call(this); + } + }; + Choices.prototype.destroy = function () { + if (!this.initialised) { + return; + } + this._removeEventListeners(); + this.passedElement.reveal(); + this.containerOuter.unwrap(this.passedElement.element); + this._store._listeners = []; // prevents select/input value being wiped + this.clearStore(); + this._stopSearch(); + this._templates = Choices.defaults.templates; + this.initialised = false; + this.initialisedOK = undefined; + }; + Choices.prototype.enable = function () { + if (this.passedElement.isDisabled) { + this.passedElement.enable(); + } + if (this.containerOuter.isDisabled) { + this._addEventListeners(); + this.input.enable(); + this.containerOuter.enable(); + } + return this; + }; + Choices.prototype.disable = function () { + if (!this.passedElement.isDisabled) { + this.passedElement.disable(); + } + if (!this.containerOuter.isDisabled) { + this._removeEventListeners(); + this.input.disable(); + this.containerOuter.disable(); + } + return this; + }; + Choices.prototype.highlightItem = function (item, runEvent) { + if (runEvent === void 0) { runEvent = true; } + if (!item || !item.id) { + return this; + } + var choice = this._store.items.find(function (c) { return c.id === item.id; }); + if (!choice || choice.highlighted) { + return this; + } + this._store.dispatch(highlightItem(choice, true)); + if (runEvent) { + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice)); + } + return this; + }; + Choices.prototype.unhighlightItem = function (item, runEvent) { + if (runEvent === void 0) { runEvent = true; } + if (!item || !item.id) { + return this; + } + var choice = this._store.items.find(function (c) { return c.id === item.id; }); + if (!choice || !choice.highlighted) { + return this; + } + this._store.dispatch(highlightItem(choice, false)); + if (runEvent) { + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice)); + } + return this; + }; + Choices.prototype.highlightAll = function () { + var _this = this; + this._store.withTxn(function () { + _this._store.items.forEach(function (item) { + if (!item.highlighted) { + _this._store.dispatch(highlightItem(item, true)); + _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item)); + } + }); + }); + return this; + }; + Choices.prototype.unhighlightAll = function () { + var _this = this; + this._store.withTxn(function () { + _this._store.items.forEach(function (item) { + if (item.highlighted) { + _this._store.dispatch(highlightItem(item, false)); + _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item)); + } + }); + }); + return this; + }; + Choices.prototype.removeActiveItemsByValue = function (value) { + var _this = this; + this._store.withTxn(function () { + _this._store.items.filter(function (item) { return item.value === value; }).forEach(function (item) { return _this._removeItem(item); }); + }); + return this; + }; + Choices.prototype.removeActiveItems = function (excludedId) { + var _this = this; + this._store.withTxn(function () { + _this._store.items.filter(function (_a) { + var id = _a.id; + return id !== excludedId; + }).forEach(function (item) { return _this._removeItem(item); }); + }); + return this; + }; + Choices.prototype.removeHighlightedItems = function (runEvent) { + var _this = this; + if (runEvent === void 0) { runEvent = false; } + this._store.withTxn(function () { + _this._store.highlightedActiveItems.forEach(function (item) { + _this._removeItem(item); + // If this action was performed by the user + // trigger the event + if (runEvent) { + _this._triggerChange(item.value); + } + }); + }); + return this; + }; + Choices.prototype.showDropdown = function (preventInputFocus) { + var _this = this; + if (this.dropdown.isActive) { + return this; + } + requestAnimationFrame(function () { + _this.dropdown.show(); + var rect = _this.dropdown.element.getBoundingClientRect(); + _this.containerOuter.open(rect.bottom, rect.height); + if (!preventInputFocus && _this._canSearch) { + _this.input.focus(); + } + _this.passedElement.triggerEvent(EventType.showDropdown); + }); + return this; + }; + Choices.prototype.hideDropdown = function (preventInputBlur) { + var _this = this; + if (!this.dropdown.isActive) { + return this; + } + requestAnimationFrame(function () { + _this.dropdown.hide(); + _this.containerOuter.close(); + if (!preventInputBlur && _this._canSearch) { + _this.input.removeActiveDescendant(); + _this.input.blur(); + } + _this.passedElement.triggerEvent(EventType.hideDropdown); + }); + return this; + }; + Choices.prototype.getValue = function (valueOnly) { + var _this = this; + if (valueOnly === void 0) { valueOnly = false; } + var values = this._store.items.reduce(function (selectedItems, item) { + var itemValue = valueOnly ? item.value : _this._getChoiceForOutput(item); + selectedItems.push(itemValue); + return selectedItems; + }, []); + return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values; + }; + Choices.prototype.setValue = function (items) { + var _this = this; + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setValue'); + return this; + } + this._store.withTxn(function () { + items.forEach(function (value) { + if (value) { + _this._addChoice(mapInputToChoice(value, false)); + } + }); + }); + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + Choices.prototype.setChoiceByValue = function (value) { + var _this = this; + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setChoiceByValue'); + return this; + } + if (this._isTextElement) { + return this; + } + this._store.withTxn(function () { + // If only one value has been passed, convert to array + var choiceValue = Array.isArray(value) ? value : [value]; + // Loop through each value and + choiceValue.forEach(function (val) { return _this._findAndSelectChoiceByValue(val); }); + _this.unhighlightAll(); + }); + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + /** + * Set choices of select input via an array of objects (or function that returns array of object or promise of it), + * a value field name and a label field name. + * This behaves the same as passing items via the choices option but can be called after initialising Choices. + * This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices. + * Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc). + * + * **Input types affected:** select-one, select-multiple + * + * @example + * ```js + * const example = new Choices(element); + * + * example.setChoices([ + * {value: 'One', label: 'Label One', disabled: true}, + * {value: 'Two', label: 'Label Two', selected: true}, + * {value: 'Three', label: 'Label Three'}, + * ], 'value', 'label', false); + * ``` + * + * @example + * ```js + * const example = new Choices(element); + * + * example.setChoices(async () => { + * try { + * const items = await fetch('/items'); + * return items.json() + * } catch(err) { + * console.error(err) + * } + * }); + * ``` + * + * @example + * ```js + * const example = new Choices(element); + * + * example.setChoices([{ + * label: 'Group one', + * id: 1, + * disabled: false, + * choices: [ + * {value: 'Child One', label: 'Child One', selected: true}, + * {value: 'Child Two', label: 'Child Two', disabled: true}, + * {value: 'Child Three', label: 'Child Three'}, + * ] + * }, + * { + * label: 'Group two', + * id: 2, + * disabled: false, + * choices: [ + * {value: 'Child Four', label: 'Child Four', disabled: true}, + * {value: 'Child Five', label: 'Child Five'}, + * {value: 'Child Six', label: 'Child Six', customProperties: { + * description: 'Custom description about child six', + * random: 'Another random custom property' + * }}, + * ] + * }], 'value', 'label', false); + * ``` + */ + Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices) { + var _this = this; + if (choicesArrayOrFetcher === void 0) { choicesArrayOrFetcher = []; } + if (value === void 0) { value = 'value'; } + if (label === void 0) { label = 'label'; } + if (replaceChoices === void 0) { replaceChoices = false; } + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setChoices'); + return this; + } + if (!this._isSelectElement) { + throw new TypeError("setChoices can't be used with INPUT based Choices"); + } + if (typeof value !== 'string' || !value) { + throw new TypeError("value parameter must be a name of 'value' field in passed objects"); + } + // Clear choices if needed + if (replaceChoices) { + this.clearChoices(); + } + if (typeof choicesArrayOrFetcher === 'function') { + // it's a choices fetcher function + var fetcher_1 = choicesArrayOrFetcher(this); + if (typeof Promise === 'function' && fetcher_1 instanceof Promise) { + // that's a promise + // eslint-disable-next-line no-promise-executor-return + return new Promise(function (resolve) { return requestAnimationFrame(resolve); }) + .then(function () { return _this._handleLoadingState(true); }) + .then(function () { return fetcher_1; }) + .then(function (data) { return _this.setChoices(data, value, label, replaceChoices); }) + .catch(function (err) { + if (!_this.config.silent) { + console.error(err); + } + }) + .then(function () { return _this._handleLoadingState(false); }) + .then(function () { return _this; }); + } + // function returned something else than promise, let's check if it's an array of choices + if (!Array.isArray(fetcher_1)) { + throw new TypeError(".setChoices first argument function must return either array of choices or Promise, got: ".concat(typeof fetcher_1)); + } + // recursion with results, it's sync and choices were cleared already + return this.setChoices(fetcher_1, value, label, false); + } + if (!Array.isArray(choicesArrayOrFetcher)) { + throw new TypeError(".setChoices must be called either with array of choices with a function resulting into Promise of array of choices"); + } + this.containerOuter.removeLoadingState(); + this._store.withTxn(function () { + var isDefaultValue = value === 'value'; + var isDefaultLabel = label === 'label'; + choicesArrayOrFetcher.forEach(function (groupOrChoice) { + if ('choices' in groupOrChoice) { + var group = groupOrChoice; + if (!isDefaultLabel) { + group = __assign(__assign({}, group), { label: group[label] }); + } + _this._addGroup(mapInputToChoice(group, true)); + } + else { + var choice = groupOrChoice; + if (!isDefaultLabel || !isDefaultValue) { + choice = __assign(__assign({}, choice), { value: choice[value], label: choice[label] }); + } + _this._addChoice(mapInputToChoice(choice, false)); + } + }); + _this.unhighlightAll(); + }); + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + Choices.prototype.refresh = function (withEvents, selectFirstOption, deselectAll) { + var _this = this; + if (withEvents === void 0) { withEvents = false; } + if (selectFirstOption === void 0) { selectFirstOption = false; } + if (deselectAll === void 0) { deselectAll = false; } + if (!this._isSelectElement) { + if (!this.config.silent) { + console.warn('refresh method can only be used on choices backed by a element"),this)},e.prototype.removeChoice=function(e){var t=this._store.choices.find((function(t){return t.value===e}));return t?(this._store.dispatch(function(e){return{type:r,choice:e}}(t)),this._searcher.reset(),t.selected&&this.passedElement.triggerEvent(m,this._getChoiceForOutput(t)),this):this},e.prototype.clearChoices=function(){return this.passedElement.element.replaceChildren(""),this.clearStore()},e.prototype.clearStore=function(){return this.itemList.element.replaceChildren(""),this.choiceList.element.replaceChildren(""),this._clearNotice(),this._store.reset(),this._lastAddedChoiceId=0,this._lastAddedGroupId=0,this._searcher.reset(),this},e.prototype.clearInput=function(){return this.input.clear(!this._isSelectOneElement),this._clearNotice(),this._isSearching&&this._stopSearch(),this},e.prototype._validateConfig=function(){var e,t,i,n=this.config,s=(e=$,t=Object.keys(n).sort(),i=Object.keys(e).sort(),t.filter((function(e){return i.indexOf(e)<0})));s.length&&console.warn("Unknown config option(s) passed",s.join(", ")),n.allowHTML&&n.allowHtmlUserInput&&(n.addItems&&console.warn("Warning: allowHTML/allowHtmlUserInput/addItems all being true is strongly not recommended and may lead to XSS attacks"),n.addChoices&&console.warn("Warning: allowHTML/allowHtmlUserInput/addChoices all being true is strongly not recommended and may lead to XSS attacks"))},e.prototype._render=function(e){void 0===e&&(e={choices:!0,groups:!0,items:!0}),this._store.inTxn()||(this._isSelectElement&&(e.choices||e.groups)&&this._renderChoices(),e.items&&this._renderItems())},e.prototype._renderChoices=function(){var e=this;if(this._canAddItems()){var t=this.config,i=this._isSearching,n=this._store,s=n.activeGroups,o=n.activeChoices,r=0;if(i&&t.searchResultLimit>0?r=t.searchResultLimit:t.renderChoiceLimit>0&&(r=t.renderChoiceLimit),this._isSelectElement){var a=o.filter((function(e){return!e.element}));a.length&&this.passedElement.addOptions(a)}var c=document.createDocumentFragment(),l=function(e){return e.filter((function(e){return!e.placeholder&&(i?!!e.rank:t.renderSelectedChoices||!e.selected)}))},h=this._isSelectOneElement,u=function(n,s,o){i?n.sort(T):t.shouldSort&&n.sort(t.sorter);var a=n.length;a=!s&&r&&a>r?r:a,a--,n.every((function(n,s){var r=n.choiceEl||e._templates.choice(t,n,t.itemSelectText,o);return n.choiceEl=r,c.appendChild(r),!i&&n.selected||(h=!0),s1){var l=i.querySelector(M(n.classNames.placeholder));l&&l.remove()}else c||(a=!0,r(G({selected:!0,value:"",label:n.placeholderValue||"",placeholder:!0},!1)))}a&&(i.append(s),n.shouldSortItems&&!this._isSelectOneElement&&(t.sort(n.sorter),t.forEach((function(e){var t=o(e);t&&(t.remove(),s.append(t))})),i.append(s))),this._isTextElement&&(this.passedElement.value=t.map((function(e){return e.value})).join(n.delimiter))},e.prototype._displayNotice=function(e,t,i){void 0===i&&(i=!0);var n=this._notice;n&&(n.type===t&&n.text===e||n.type===Z&&(t===Y||t===Q))?i&&this.showDropdown(!0):(this._clearNotice(),this._notice=e?{text:e,type:t}:void 0,this._renderNotice(),i&&e&&this.showDropdown(!0))},e.prototype._clearNotice=function(){if(this._notice){var e=this.choiceList.element.querySelector(M(this.config.classNames.notice));e&&e.remove(),this._notice=void 0}},e.prototype._renderNotice=function(e){var t=this._notice;if(t){var i=this._templates.notice(this.config,t.text,t.type);e?e.append(i):this.choiceList.prepend(i)}},e.prototype._getChoiceForOutput=function(e,t){if(e){var i=e.groupId?this._store.getGroupById(e.groupId):null;return{id:e.id,highlighted:e.highlighted,labelClass:e.labelClass,labelDescription:e.labelDescription,customProperties:e.customProperties,disabled:e.disabled,active:e.active,label:e.label,placeholder:e.placeholder,value:e.value,groupValue:i&&i.label?i.label:void 0,element:e.element,keyCode:t}}},e.prototype._triggerChange=function(e){null!=e&&this.passedElement.triggerEvent("change",{value:e})},e.prototype._handleButtonAction=function(e){var t=this,i=this._store.items;if(i.length&&this.config.removeItems&&this.config.removeItemButton){var n=e&&He(e.parentNode),s=n&&i.find((function(e){return e.id===n}));s&&this._store.withTxn((function(){if(t._removeItem(s),t._triggerChange(s.value),t._isSelectOneElement&&!t._hasNonChoicePlaceholder){var e=t._store.choices.reverse().find((function(e){return!e.disabled&&e.placeholder}));e&&(t._addItem(e),t.unhighlightAll(),e.value&&t._triggerChange(e.value))}}))}},e.prototype._handleItemAction=function(e,t){var i=this;void 0===t&&(t=!1);var n=this._store.items;if(n.length&&this.config.removeItems&&!this._isSelectOneElement){var s=He(e);s&&(n.forEach((function(e){e.id!==s||e.highlighted?!t&&e.highlighted&&i.unhighlightItem(e):i.highlightItem(e)})),this.input.focus())}},e.prototype._handleChoiceAction=function(e){var t=this,i=He(e),n=i&&this._store.getChoiceById(i);if(!n||n.disabled)return!1;var s=this.dropdown.isActive;if(!n.selected){if(!this._canAddItems())return!0;this._store.withTxn((function(){t._addItem(n,!0,!0),t.clearInput(),t.unhighlightAll()})),this._triggerChange(n.value)}return s&&this.config.closeDropdownOnSelect&&(this.hideDropdown(!0),this.containerOuter.element.focus()),!0},e.prototype._handleBackspace=function(e){var t=this.config;if(t.removeItems&&e.length){var i=e[e.length-1],n=e.some((function(e){return e.highlighted}));t.editItems&&!n&&i?(this.input.value=i.value,this.input.setWidth(),this._removeItem(i),this._triggerChange(i.value)):(n||this.highlightItem(i,!1),this.removeHighlightedItems(!0))}},e.prototype._loadChoices=function(){var e,t=this.config;if(this._isTextElement){if(this._presetChoices=t.items.map((function(e){return G(e,!1)})),this.passedElement.value){var i=this.passedElement.value.split(t.delimiter).map((function(e){return G(e,!1)}));this._presetChoices=this._presetChoices.concat(i)}this._presetChoices.forEach((function(e){e.selected=!0}))}else if(this._isSelectElement){this._presetChoices=t.choices.map((function(e){return G(e,!0)}));var n=this.passedElement.optionsAsChoices();n&&(e=this._presetChoices).push.apply(e,n)}},e.prototype._handleLoadingState=function(e){void 0===e&&(e=!0);var t=this.itemList.element;e?(this.disable(),this.containerOuter.addLoadingState(),this._isSelectOneElement?t.replaceChildren(this._templates.placeholder(this.config,this.config.loadingText)):this.input.placeholder=this.config.loadingText):(this.enable(),this.containerOuter.removeLoadingState(),this._isSelectOneElement?(t.replaceChildren(""),this._render()):this.input.placeholder=this._placeholderValue||"")},e.prototype._handleSearch=function(e){if(this.input.isFocussed)if(null!=e&&e.length>=this.config.searchFloor){var t=this.config.searchChoices?this._searchChoices(e):0;null!==t&&this.passedElement.triggerEvent(f,{value:e,resultCount:t})}else this._store.choices.some((function(e){return!e.active}))&&this._stopSearch()},e.prototype._canAddItems=function(){var e=this.config,t=e.maxItemCount,i=e.maxItemText;return!(!e.singleModeForMultiSelect&&t>0&&t<=this._store.items.length&&(this.choiceList.element.replaceChildren(""),this._displayNotice("function"==typeof i?i(t):i,Z),1))},e.prototype._canCreateItem=function(e){var t=this.config,i=!0,n="";if(i&&"function"==typeof t.addItemFilter&&!t.addItemFilter(e)&&(i=!1,n=I(t.customAddItemText,e)),i){var s=this._store.choices.find((function(i){return t.valueComparer(i.value,e)}));if(this._isSelectElement){if(s)return this._displayNotice("",Z),!1}else this._isTextElement&&!t.duplicateItemsAllowed&&s&&(i=!1,n=I(t.uniqueItemText,e))}return i&&(n=I(t.addItemText,e)),n&&this._displayNotice(n,Z),i},e.prototype._searchChoices=function(e){var t=e.trim().replace(/\s{2,}/," ");if(!t.length||t===this._currentValue)return null;var i=this._searcher;i.isEmptyIndex()&&i.index(this._store.searchableChoices);var n=i.search(t);this._currentValue=t,this._highlightPosition=0,this._isSearching=!0;var s=this._notice,o=s&&s.type;return o!==Z&&(n.length?o===Y&&this._clearNotice():this._displayNotice(A(this.config.noResultsText),Y)),this._store.dispatch(function(e){return{type:a,results:e}}(n)),n.length},e.prototype._stopSearch=function(){var e=this._isSearching;this._currentValue="",this._isSearching=!1,e&&(this._store.dispatch({type:c,active:!0}),this.passedElement.triggerEvent(f,{value:"",resultCount:0}))},e.prototype._addEventListeners=function(){var e=this._docRoot,t=this.containerOuter.element,i=this.input.element;e.addEventListener("touchend",this._onTouchEnd,!0),t.addEventListener("keydown",this._onKeyDown,!0),t.addEventListener("mousedown",this._onMouseDown,!0),e.addEventListener("click",this._onClick,{passive:!0}),e.addEventListener("touchmove",this._onTouchMove,{passive:!0}),this.dropdown.element.addEventListener("mouseover",this._onMouseOver,{passive:!0}),this._isSelectOneElement&&(t.addEventListener("focus",this._onFocus,{passive:!0}),t.addEventListener("blur",this._onBlur,{passive:!0})),i.addEventListener("keyup",this._onKeyUp,{passive:!0}),i.addEventListener("input",this._onInput,{passive:!0}),i.addEventListener("focus",this._onFocus,{passive:!0}),i.addEventListener("blur",this._onBlur,{passive:!0}),i.form&&i.form.addEventListener("reset",this._onFormReset,{passive:!0}),this.input.addEventListeners()},e.prototype._removeEventListeners=function(){var e=this._docRoot,t=this.containerOuter.element,i=this.input.element;e.removeEventListener("touchend",this._onTouchEnd,!0),t.removeEventListener("keydown",this._onKeyDown,!0),t.removeEventListener("mousedown",this._onMouseDown,!0),e.removeEventListener("click",this._onClick),e.removeEventListener("touchmove",this._onTouchMove),this.dropdown.element.removeEventListener("mouseover",this._onMouseOver),this._isSelectOneElement&&(t.removeEventListener("focus",this._onFocus),t.removeEventListener("blur",this._onBlur)),i.removeEventListener("keyup",this._onKeyUp),i.removeEventListener("input",this._onInput),i.removeEventListener("focus",this._onFocus),i.removeEventListener("blur",this._onBlur),i.form&&i.form.removeEventListener("reset",this._onFormReset),this.input.removeEventListeners()},e.prototype._onKeyDown=function(e){var t=e.keyCode,i=this.dropdown.isActive,n=1===e.key.length||2===e.key.length&&e.key.charCodeAt(0)>=55296||"Unidentified"===e.key;switch(this._isTextElement||i||(this.showDropdown(),!this.input.isFocussed&&n&&(this.input.value+=e.key," "===e.key&&e.preventDefault())),t){case 65:return this._onSelectKey(e,this.itemList.element.hasChildNodes());case 13:return this._onEnterKey(e,i);case 27:return this._onEscapeKey(e,i);case 38:case 33:case 40:case 34:return this._onDirectionKey(e,i);case 8:case 46:return this._onDeleteKey(e,this._store.items,this.input.isFocussed)}},e.prototype._onKeyUp=function(){this._canSearch=this.config.searchEnabled},e.prototype._onInput=function(){var e=this.input.value;if(!e)return this._isTextElement?this.hideDropdown(!0):this._stopSearch(),void this._clearNotice();this._canAddItems()&&(this._canSearch&&this._handleSearch(e),this._canAddUserChoices&&(this._canCreateItem(e),this._isSelectElement&&(this._highlightPosition=0,this._highlightChoice())))},e.prototype._onSelectKey=function(e,t){(e.ctrlKey||e.metaKey)&&t&&(this._canSearch=!1,this.config.removeItems&&!this.input.value&&this.input.element===document.activeElement&&this.highlightAll())},e.prototype._onEnterKey=function(e,t){var i=this,n=this.input.value,s=e.target;if(e.preventDefault(),s&&s.hasAttribute("data-button"))this._handleButtonAction(s);else if(t){var o=this.dropdown.element.querySelector(M(this.config.classNames.highlightedState));if(!o||!this._handleChoiceAction(o))if(s&&n){if(this._canAddItems()){var r=!1;this._store.withTxn((function(){if(!(r=i._findAndSelectChoiceByValue(n,!0))){if(!i._canAddUserChoices)return;if(!i._canCreateItem(n))return;var e=w(n),t=i.config.allowHtmlUserInput||e===n?n:{escaped:e,raw:n};i._addChoice(G({value:t,label:t,selected:!0},!1),!0,!0),r=!0}i.clearInput(),i.unhighlightAll()})),r&&(this._triggerChange(n),this.config.closeDropdownOnSelect&&this.hideDropdown(!0))}}else this.hideDropdown(!0)}else(this._isSelectElement||this._notice)&&this.showDropdown()},e.prototype._onEscapeKey=function(e,t){t&&(e.stopPropagation(),this.hideDropdown(!0),this.containerOuter.element.focus())},e.prototype._onDirectionKey=function(e,t){var i,n,s,o=e.keyCode;if(t||this._isSelectOneElement){this.showDropdown(),this._canSearch=!1;var r=40===o||34===o?1:-1,a=void 0;if(e.metaKey||34===o||33===o)a=this.dropdown.element.querySelector(r>0?"".concat(Re,":last-of-type"):Re);else{var c=this.dropdown.element.querySelector(M(this.config.classNames.highlightedState));a=c?function(e,t,i){void 0===i&&(i=1);for(var n="".concat(i>0?"next":"previous","ElementSibling"),s=e[n];s;){if(s.matches(t))return s;s=s[n]}return null}(c,Re,r):this.dropdown.element.querySelector(Re)}a&&(i=a,n=this.choiceList.element,void 0===(s=r)&&(s=1),(s>0?n.scrollTop+n.offsetHeight>=i.offsetTop+i.offsetHeight:i.offsetTop>=n.scrollTop)||this.choiceList.scrollToChildElement(a,r),this._highlightChoice(a)),e.preventDefault()}},e.prototype._onDeleteKey=function(e,t,i){this._isSelectOneElement||e.target.value||!i||(this._handleBackspace(t),e.preventDefault())},e.prototype._onTouchMove=function(){this._wasTap&&(this._wasTap=!1)},e.prototype._onTouchEnd=function(e){var t=(e||e.touches[0]).target;this._wasTap&&this.containerOuter.element.contains(t)&&((t===this.containerOuter.element||t===this.containerInner.element)&&(this._isTextElement?this.input.focus():this._isSelectMultipleElement&&this.showDropdown()),e.stopPropagation()),this._wasTap=!0},e.prototype._onMouseDown=function(e){var t=e.target;if(t instanceof HTMLElement){if(Be&&this.choiceList.element.contains(t)){var i=this.choiceList.element.firstElementChild;this._isScrollingOnIe="ltr"===this._direction?e.offsetX>=i.offsetWidth:e.offsetXthis._highlightPosition?t[this._highlightPosition]:t[t.length-1])||(i=t[0]),F(i,n),i.setAttribute("aria-selected","true"),this.passedElement.triggerEvent("highlightChoice",{el:i}),this.dropdown.isActive&&(this.input.setActiveDescendant(i.id),this.containerOuter.setActiveDescendant(i.id))}},e.prototype._addItem=function(e,t,i){if(void 0===t&&(t=!0),void 0===i&&(i=!1),!e.id)throw new TypeError("item.id must be set before _addItem is called for a choice/item");(this.config.singleModeForMultiSelect||this._isSelectOneElement)&&this.removeActiveItems(e.id),this._store.dispatch(function(e){return{type:u,item:e}}(e)),t&&(this.passedElement.triggerEvent("addItem",this._getChoiceForOutput(e)),i&&this.passedElement.triggerEvent("choice",this._getChoiceForOutput(e)))},e.prototype._removeItem=function(e){e.id&&(this._store.dispatch(b(e)),this.passedElement.triggerEvent(m,this._getChoiceForOutput(e)))},e.prototype._addChoice=function(e,t,i){if(void 0===t&&(t=!0),void 0===i&&(i=!1),e.id)throw new TypeError("Can not re-add a choice which has already been added");this._lastAddedChoiceId++,e.id=this._lastAddedChoiceId,e.elementId="".concat(this._baseId,"-").concat(this._idNames.itemChoice,"-").concat(e.id);var n=this.config,s=n.prependValue,r=n.appendValue;s&&(e.value=s+e.value),r&&(e.value+=r.toString()),(s||r)&&e.element&&(e.element.value=e.value),this._store.dispatch(function(e){return{type:o,choice:e}}(e)),e.selected&&this._addItem(e,t,i)},e.prototype._addGroup=function(e,t){var i=this;if(void 0===t&&(t=!0),e.id)throw new TypeError("Can not re-add a group which has already been added");this._store.dispatch(function(e){return{type:h,group:e}}(e)),e.choices&&(this._lastAddedGroupId++,e.id=this._lastAddedGroupId,e.choices.forEach((function(n){n.groupId=e.id,e.disabled&&(n.disabled=!0),i._addChoice(n,t)})))},e.prototype._createTemplates=function(){var e=this,t=this.config.callbackOnCreateTemplates,i={};"function"==typeof t&&(i=t.call(this,S,x));var n={};Object.keys(this._templates).forEach((function(t){n[t]=t in i?i[t].bind(e):e._templates[t].bind(e)})),this._templates=n},e.prototype._createElements=function(){var e=this._templates,t=this.config,i=this._isSelectOneElement,n=t.position,s=t.classNames,o=this._elementType;this.containerOuter=new j({element:e.containerOuter(t,this._direction,this._isSelectElement,i,t.searchEnabled,o,t.labelId),classNames:s,type:o,position:n}),this.containerInner=new j({element:e.containerInner(t),classNames:s,type:o,position:n}),this.input=new K({element:e.input(t,this._placeholderValue),classNames:s,type:o,preventPaste:!t.paste}),this.choiceList=new B({element:e.choiceList(t,i)}),this.itemList=new B({element:e.itemList(t,i)}),this.dropdown=new P({element:e.dropdown(t),classNames:s,type:o})},e.prototype._createStructure=function(){var e=this,t=e.containerInner,i=e.containerOuter,n=e.passedElement,s=this.dropdown.element;n.conceal(),t.wrap(n.element),i.wrap(t.element),this._isSelectOneElement?this.input.placeholder=this.config.searchPlaceholderValue||"":(this._placeholderValue&&(this.input.placeholder=this._placeholderValue),this.input.setWidth()),i.element.appendChild(t.element),i.element.appendChild(s),t.element.appendChild(this.itemList.element),s.appendChild(this.choiceList.element),this._isSelectOneElement?this.config.searchEnabled&&s.insertBefore(this.input.element,s.firstChild):t.element.appendChild(this.input.element),this._highlightPosition=0,this._isSearching=!1},e.prototype._initStore=function(){var e=this;this._store.subscribe(this._render),this._store.withTxn((function(){e._addPredefinedChoices(e._presetChoices,e._isSelectOneElement&&!e._hasNonChoicePlaceholder,!1)})),this._isSelectOneElement&&this._hasNonChoicePlaceholder&&this._render({choices:!1,groups:!1,items:!0})},e.prototype._addPredefinedChoices=function(e,t,i){var n=this;void 0===t&&(t=!1),void 0===i&&(i=!0),t&&-1===e.findIndex((function(e){return e.selected}))&&e.some((function(e){return!e.disabled&&!("choices"in e)&&(e.selected=!0,!0)})),e.forEach((function(e){"choices"in e?n._isSelectElement&&n._addGroup(e,i):n._addChoice(e,i)}))},e.prototype._findAndSelectChoiceByValue=function(e,t){var i=this;void 0===t&&(t=!1);var n=this._store.choices.find((function(t){return i.config.valueComparer(t.value,e)}));return!(!n||n.disabled||n.selected||(this._addItem(n,!0,t),0))},e.prototype._generatePlaceholderValue=function(){var e=this.config;if(!e.placeholder)return null;if(this._hasNonChoicePlaceholder)return e.placeholderValue;if(this._isSelectElement){var t=this.passedElement.placeholderOption;return t?t.text:null}return null},e.prototype._warnChoicesInitFailed=function(e){if(!this.config.silent){if(!this.initialised)throw new TypeError("".concat(e," called on a non-initialised instance of Choices"));if(!this.initialisedOK)throw new TypeError("".concat(e," called for an element which has multiple instances of Choices initialised on it"))}},e.version="11.0.1",e}()})); diff --git a/assets/extensions/choices.js/public/assets/scripts/choices.search-basic.mjs b/assets/extensions/choices.js/public/assets/scripts/choices.search-basic.mjs new file mode 100644 index 00000000..de10c20f --- /dev/null +++ b/assets/extensions/choices.js/public/assets/scripts/choices.search-basic.mjs @@ -0,0 +1,4677 @@ +/*! choices.js v11.0.1 | © 2024 Josh Johnson | https://github.com/jshjohnson/Choices#readme */ + +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global Reflect, Promise, SuppressedError, Symbol */ + +var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + }; + return extendStatics(d, b); +}; +function __extends(d, b) { + if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} +var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +} +typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +var ActionType = { + ADD_CHOICE: 'ADD_CHOICE', + REMOVE_CHOICE: 'REMOVE_CHOICE', + FILTER_CHOICES: 'FILTER_CHOICES', + ACTIVATE_CHOICES: 'ACTIVATE_CHOICES', + CLEAR_CHOICES: 'CLEAR_CHOICES', + ADD_GROUP: 'ADD_GROUP', + ADD_ITEM: 'ADD_ITEM', + REMOVE_ITEM: 'REMOVE_ITEM', + HIGHLIGHT_ITEM: 'HIGHLIGHT_ITEM', +}; + +var EventType = { + showDropdown: 'showDropdown', + hideDropdown: 'hideDropdown', + change: 'change', + choice: 'choice', + search: 'search', + addItem: 'addItem', + removeItem: 'removeItem', + highlightItem: 'highlightItem', + highlightChoice: 'highlightChoice', + unhighlightItem: 'unhighlightItem', +}; + +var ObjectsInConfig = ['fuseOptions', 'classNames']; + +var PassedElementTypes = { + Text: 'text', + SelectOne: 'select-one', + SelectMultiple: 'select-multiple', +}; + +var addChoice = function (choice) { return ({ + type: ActionType.ADD_CHOICE, + choice: choice, +}); }; +var removeChoice = function (choice) { return ({ + type: ActionType.REMOVE_CHOICE, + choice: choice, +}); }; +var filterChoices = function (results) { return ({ + type: ActionType.FILTER_CHOICES, + results: results, +}); }; +var activateChoices = function (active) { + return ({ + type: ActionType.ACTIVATE_CHOICES, + active: active, + }); +}; + +var addGroup = function (group) { return ({ + type: ActionType.ADD_GROUP, + group: group, +}); }; + +var addItem = function (item) { return ({ + type: ActionType.ADD_ITEM, + item: item, +}); }; +var removeItem$1 = function (item) { return ({ + type: ActionType.REMOVE_ITEM, + item: item, +}); }; +var highlightItem = function (item, highlighted) { return ({ + type: ActionType.HIGHLIGHT_ITEM, + item: item, + highlighted: highlighted, +}); }; + +/* eslint-disable @typescript-eslint/no-explicit-any */ +var getRandomNumber = function (min, max) { return Math.floor(Math.random() * (max - min) + min); }; +var generateChars = function (length) { + return Array.from({ length: length }, function () { return getRandomNumber(0, 36).toString(36); }).join(''); +}; +var generateId = function (element, prefix) { + var id = element.id || (element.name && "".concat(element.name, "-").concat(generateChars(2))) || generateChars(4); + id = id.replace(/(:|\.|\[|\]|,)/g, ''); + id = "".concat(prefix, "-").concat(id); + return id; +}; +var getAdjacentEl = function (startEl, selector, direction) { + if (direction === void 0) { direction = 1; } + var prop = "".concat(direction > 0 ? 'next' : 'previous', "ElementSibling"); + var sibling = startEl[prop]; + while (sibling) { + if (sibling.matches(selector)) { + return sibling; + } + sibling = sibling[prop]; + } + return null; +}; +var isScrolledIntoView = function (element, parent, direction) { + if (direction === void 0) { direction = 1; } + var isVisible; + if (direction > 0) { + // In view from bottom + isVisible = parent.scrollTop + parent.offsetHeight >= element.offsetTop + element.offsetHeight; + } + else { + // In view from top + isVisible = element.offsetTop >= parent.scrollTop; + } + return isVisible; +}; +var sanitise = function (value) { + if (typeof value !== 'string') { + if (value === null || value === undefined) { + return ''; + } + if (typeof value === 'object') { + if ('raw' in value) { + return sanitise(value.raw); + } + if ('trusted' in value) { + return value.trusted; + } + } + return value; + } + return value + .replace(/&/g, '&') + .replace(/>/g, '>') + .replace(/= 0 && + !window.matchMedia("(min-height: ".concat(dropdownPos + 1, "px)")).matches; + } + else if (this.position === 'top') { + shouldFlip = true; + } + return shouldFlip; + }; + Container.prototype.setActiveDescendant = function (activeDescendantID) { + this.element.setAttribute('aria-activedescendant', activeDescendantID); + }; + Container.prototype.removeActiveDescendant = function () { + this.element.removeAttribute('aria-activedescendant'); + }; + Container.prototype.open = function (dropdownPos, dropdownHeight) { + addClassesToElement(this.element, this.classNames.openState); + this.element.setAttribute('aria-expanded', 'true'); + this.isOpen = true; + if (this.shouldFlip(dropdownPos, dropdownHeight)) { + addClassesToElement(this.element, this.classNames.flippedState); + this.isFlipped = true; + } + }; + Container.prototype.close = function () { + removeClassesFromElement(this.element, this.classNames.openState); + this.element.setAttribute('aria-expanded', 'false'); + this.removeActiveDescendant(); + this.isOpen = false; + // A dropdown flips if it does not have space within the page + if (this.isFlipped) { + removeClassesFromElement(this.element, this.classNames.flippedState); + this.isFlipped = false; + } + }; + Container.prototype.addFocusState = function () { + addClassesToElement(this.element, this.classNames.focusState); + }; + Container.prototype.removeFocusState = function () { + removeClassesFromElement(this.element, this.classNames.focusState); + }; + Container.prototype.enable = function () { + removeClassesFromElement(this.element, this.classNames.disabledState); + this.element.removeAttribute('aria-disabled'); + if (this.type === PassedElementTypes.SelectOne) { + this.element.setAttribute('tabindex', '0'); + } + this.isDisabled = false; + }; + Container.prototype.disable = function () { + addClassesToElement(this.element, this.classNames.disabledState); + this.element.setAttribute('aria-disabled', 'true'); + if (this.type === PassedElementTypes.SelectOne) { + this.element.setAttribute('tabindex', '-1'); + } + this.isDisabled = true; + }; + Container.prototype.wrap = function (element) { + var el = this.element; + var parentNode = element.parentNode; + if (parentNode) { + if (element.nextSibling) { + parentNode.insertBefore(el, element.nextSibling); + } + else { + parentNode.appendChild(el); + } + } + el.appendChild(element); + }; + Container.prototype.unwrap = function (element) { + var el = this.element; + var parentNode = el.parentNode; + if (parentNode) { + // Move passed element outside this element + parentNode.insertBefore(element, el); + // Remove this element + parentNode.removeChild(el); + } + }; + Container.prototype.addLoadingState = function () { + addClassesToElement(this.element, this.classNames.loadingState); + this.element.setAttribute('aria-busy', 'true'); + this.isLoading = true; + }; + Container.prototype.removeLoadingState = function () { + removeClassesFromElement(this.element, this.classNames.loadingState); + this.element.removeAttribute('aria-busy'); + this.isLoading = false; + }; + return Container; +}()); + +var Input = /** @class */ (function () { + function Input(_a) { + var element = _a.element, type = _a.type, classNames = _a.classNames, preventPaste = _a.preventPaste; + this.element = element; + this.type = type; + this.classNames = classNames; + this.preventPaste = preventPaste; + this.isFocussed = this.element.isEqualNode(document.activeElement); + this.isDisabled = element.disabled; + this._onPaste = this._onPaste.bind(this); + this._onInput = this._onInput.bind(this); + this._onFocus = this._onFocus.bind(this); + this._onBlur = this._onBlur.bind(this); + } + Object.defineProperty(Input.prototype, "placeholder", { + set: function (placeholder) { + this.element.placeholder = placeholder; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Input.prototype, "value", { + get: function () { + return this.element.value; + }, + set: function (value) { + this.element.value = value; + }, + enumerable: false, + configurable: true + }); + Input.prototype.addEventListeners = function () { + var el = this.element; + el.addEventListener('paste', this._onPaste); + el.addEventListener('input', this._onInput, { + passive: true, + }); + el.addEventListener('focus', this._onFocus, { + passive: true, + }); + el.addEventListener('blur', this._onBlur, { + passive: true, + }); + }; + Input.prototype.removeEventListeners = function () { + var el = this.element; + el.removeEventListener('input', this._onInput); + el.removeEventListener('paste', this._onPaste); + el.removeEventListener('focus', this._onFocus); + el.removeEventListener('blur', this._onBlur); + }; + Input.prototype.enable = function () { + var el = this.element; + el.removeAttribute('disabled'); + this.isDisabled = false; + }; + Input.prototype.disable = function () { + var el = this.element; + el.setAttribute('disabled', ''); + this.isDisabled = true; + }; + Input.prototype.focus = function () { + if (!this.isFocussed) { + this.element.focus(); + } + }; + Input.prototype.blur = function () { + if (this.isFocussed) { + this.element.blur(); + } + }; + Input.prototype.clear = function (setWidth) { + if (setWidth === void 0) { setWidth = true; } + this.element.value = ''; + if (setWidth) { + this.setWidth(); + } + return this; + }; + /** + * Set the correct input width based on placeholder + * value or input value + */ + Input.prototype.setWidth = function () { + // Resize input to contents or placeholder + var element = this.element; + element.style.minWidth = "".concat(element.placeholder.length + 1, "ch"); + element.style.width = "".concat(element.value.length + 1, "ch"); + }; + Input.prototype.setActiveDescendant = function (activeDescendantID) { + this.element.setAttribute('aria-activedescendant', activeDescendantID); + }; + Input.prototype.removeActiveDescendant = function () { + this.element.removeAttribute('aria-activedescendant'); + }; + Input.prototype._onInput = function () { + if (this.type !== PassedElementTypes.SelectOne) { + this.setWidth(); + } + }; + Input.prototype._onPaste = function (event) { + if (this.preventPaste) { + event.preventDefault(); + } + }; + Input.prototype._onFocus = function () { + this.isFocussed = true; + }; + Input.prototype._onBlur = function () { + this.isFocussed = false; + }; + return Input; +}()); + +var SCROLLING_SPEED = 4; + +var List = /** @class */ (function () { + function List(_a) { + var element = _a.element; + this.element = element; + this.scrollPos = this.element.scrollTop; + this.height = this.element.offsetHeight; + } + List.prototype.prepend = function (node) { + var child = this.element.firstElementChild; + if (child) { + this.element.insertBefore(node, child); + } + else { + this.element.append(node); + } + }; + List.prototype.scrollToTop = function () { + this.element.scrollTop = 0; + }; + List.prototype.scrollToChildElement = function (element, direction) { + var _this = this; + if (!element) { + return; + } + var listHeight = this.element.offsetHeight; + // Scroll position of dropdown + var listScrollPosition = this.element.scrollTop + listHeight; + var elementHeight = element.offsetHeight; + // Distance from bottom of element to top of parent + var elementPos = element.offsetTop + elementHeight; + // Difference between the element and scroll position + var destination = direction > 0 ? this.element.scrollTop + elementPos - listScrollPosition : element.offsetTop; + requestAnimationFrame(function () { + _this._animateScroll(destination, direction); + }); + }; + List.prototype._scrollDown = function (scrollPos, strength, destination) { + var easing = (destination - scrollPos) / strength; + var distance = easing > 1 ? easing : 1; + this.element.scrollTop = scrollPos + distance; + }; + List.prototype._scrollUp = function (scrollPos, strength, destination) { + var easing = (scrollPos - destination) / strength; + var distance = easing > 1 ? easing : 1; + this.element.scrollTop = scrollPos - distance; + }; + List.prototype._animateScroll = function (destination, direction) { + var _this = this; + var strength = SCROLLING_SPEED; + var choiceListScrollTop = this.element.scrollTop; + var continueAnimation = false; + if (direction > 0) { + this._scrollDown(choiceListScrollTop, strength, destination); + if (choiceListScrollTop < destination) { + continueAnimation = true; + } + } + else { + this._scrollUp(choiceListScrollTop, strength, destination); + if (choiceListScrollTop > destination) { + continueAnimation = true; + } + } + if (continueAnimation) { + requestAnimationFrame(function () { + _this._animateScroll(destination, direction); + }); + } + }; + return List; +}()); + +var WrappedElement = /** @class */ (function () { + function WrappedElement(_a) { + var element = _a.element, classNames = _a.classNames; + this.element = element; + this.classNames = classNames; + this.isDisabled = false; + } + Object.defineProperty(WrappedElement.prototype, "isActive", { + get: function () { + return this.element.dataset.choice === 'active'; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(WrappedElement.prototype, "dir", { + get: function () { + return this.element.dir; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(WrappedElement.prototype, "value", { + get: function () { + return this.element.value; + }, + set: function (value) { + this.element.setAttribute('value', value); + this.element.value = value; + }, + enumerable: false, + configurable: true + }); + WrappedElement.prototype.conceal = function () { + var el = this.element; + // Hide passed input + addClassesToElement(el, this.classNames.input); + el.hidden = true; + // Remove element from tab index + el.tabIndex = -1; + // Backup original styles if any + var origStyle = el.getAttribute('style'); + if (origStyle) { + el.setAttribute('data-choice-orig-style', origStyle); + } + el.setAttribute('data-choice', 'active'); + }; + WrappedElement.prototype.reveal = function () { + var el = this.element; + // Reinstate passed element + removeClassesFromElement(el, this.classNames.input); + el.hidden = false; + el.removeAttribute('tabindex'); + // Recover original styles if any + var origStyle = el.getAttribute('data-choice-orig-style'); + if (origStyle) { + el.removeAttribute('data-choice-orig-style'); + el.setAttribute('style', origStyle); + } + else { + el.removeAttribute('style'); + } + el.removeAttribute('data-choice'); + }; + WrappedElement.prototype.enable = function () { + this.element.removeAttribute('disabled'); + this.element.disabled = false; + this.isDisabled = false; + }; + WrappedElement.prototype.disable = function () { + this.element.setAttribute('disabled', ''); + this.element.disabled = true; + this.isDisabled = true; + }; + WrappedElement.prototype.triggerEvent = function (eventType, data) { + dispatchEvent(this.element, eventType, data || {}); + }; + return WrappedElement; +}()); + +var WrappedInput = /** @class */ (function (_super) { + __extends(WrappedInput, _super); + function WrappedInput() { + return _super !== null && _super.apply(this, arguments) || this; + } + return WrappedInput; +}(WrappedElement)); + +var coerceBool = function (arg, defaultValue) { + if (defaultValue === void 0) { defaultValue = true; } + return typeof arg === 'undefined' ? defaultValue : !!arg; +}; +var stringToHtmlClass = function (input) { + if (typeof input === 'string') { + // eslint-disable-next-line no-param-reassign + input = input.split(' ').filter(function (s) { return s.length; }); + } + if (Array.isArray(input) && input.length) { + return input; + } + return undefined; +}; +var mapInputToChoice = function (value, allowGroup) { + if (typeof value === 'string') { + var result_1 = mapInputToChoice({ + value: value, + label: value, + }, false); + return result_1; + } + var groupOrChoice = value; + if ('choices' in groupOrChoice) { + if (!allowGroup) { + // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup + throw new TypeError("optGroup is not allowed"); + } + var group = groupOrChoice; + var choices = group.choices.map(function (e) { return mapInputToChoice(e, false); }); + var result_2 = { + id: 0, // actual ID will be assigned during _addGroup + label: unwrapStringForRaw(group.label) || group.value, + active: !!choices.length, + disabled: !!group.disabled, + choices: choices, + }; + return result_2; + } + var choice = groupOrChoice; + var result = { + id: 0, // actual ID will be assigned during _addChoice + groupId: 0, // actual ID will be assigned during _addGroup but before _addChoice + score: 0, // used in search + rank: 0, // used in search, stable sort order + value: choice.value, + label: choice.label || choice.value, + active: coerceBool(choice.active), + selected: coerceBool(choice.selected, false), + disabled: coerceBool(choice.disabled, false), + placeholder: coerceBool(choice.placeholder, false), + highlighted: false, + labelClass: stringToHtmlClass(choice.labelClass), + labelDescription: choice.labelDescription, + customProperties: choice.customProperties, + }; + return result; +}; + +var isHtmlInputElement = function (e) { return e.tagName === 'INPUT'; }; +var isHtmlSelectElement = function (e) { return e.tagName === 'SELECT'; }; +var isHtmlOption = function (e) { return e.tagName === 'OPTION'; }; +var isHtmlOptgroup = function (e) { return e.tagName === 'OPTGROUP'; }; + +var WrappedSelect = /** @class */ (function (_super) { + __extends(WrappedSelect, _super); + function WrappedSelect(_a) { + var element = _a.element, classNames = _a.classNames, template = _a.template, extractPlaceholder = _a.extractPlaceholder; + var _this = _super.call(this, { element: element, classNames: classNames }) || this; + _this.template = template; + _this.extractPlaceholder = extractPlaceholder; + return _this; + } + Object.defineProperty(WrappedSelect.prototype, "placeholderOption", { + get: function () { + return (this.element.querySelector('option[value=""]') || + // Backward compatibility layer for the non-standard placeholder attribute supported in older versions. + this.element.querySelector('option[placeholder]')); + }, + enumerable: false, + configurable: true + }); + WrappedSelect.prototype.addOptions = function (choices) { + var _this = this; + var fragment = document.createDocumentFragment(); + choices.forEach(function (obj) { + var choice = obj; + if (choice.element) { + return; + } + var option = _this.template(choice); + fragment.appendChild(option); + choice.element = option; + }); + this.element.appendChild(fragment); + }; + WrappedSelect.prototype.optionsAsChoices = function () { + var _this = this; + var choices = []; + this.element.querySelectorAll(':scope > option, :scope > optgroup').forEach(function (e) { + if (isHtmlOption(e)) { + choices.push(_this._optionToChoice(e)); + } + else if (isHtmlOptgroup(e)) { + choices.push(_this._optgroupToChoice(e)); + } + // todo: hr as empty optgroup, requires displaying empty opt-groups to be useful + }); + return choices; + }; + // eslint-disable-next-line class-methods-use-this + WrappedSelect.prototype._optionToChoice = function (option) { + // option.value returns the label if there is no value attribute, which can break legacy placeholder attribute support + if (!option.hasAttribute('value') && option.hasAttribute('placeholder')) { + option.setAttribute('value', ''); + option.value = ''; + } + return { + id: 0, + groupId: 0, + score: 0, + rank: 0, + value: option.value, + label: option.innerHTML, + element: option, + active: true, + // this returns true if nothing is selected on initial load, which will break placeholder support + selected: this.extractPlaceholder ? option.selected : option.hasAttribute('selected'), + disabled: option.disabled, + highlighted: false, + placeholder: this.extractPlaceholder && (!option.value || option.hasAttribute('placeholder')), + labelClass: typeof option.dataset.labelClass !== 'undefined' ? stringToHtmlClass(option.dataset.labelClass) : undefined, + labelDescription: typeof option.dataset.labelDescription !== 'undefined' ? option.dataset.labelDescription : undefined, + customProperties: parseCustomProperties(option.dataset.customProperties), + }; + }; + WrappedSelect.prototype._optgroupToChoice = function (optgroup) { + var _this = this; + var options = optgroup.querySelectorAll('option'); + var choices = Array.from(options).map(function (option) { return _this._optionToChoice(option); }); + return { + id: 0, + label: optgroup.label || '', + element: optgroup, + active: !!choices.length, + disabled: optgroup.disabled, + choices: choices, + }; + }; + return WrappedSelect; +}(WrappedElement)); + +var DEFAULT_CLASSNAMES = { + containerOuter: ['choices'], + containerInner: ['choices__inner'], + input: ['choices__input'], + inputCloned: ['choices__input--cloned'], + list: ['choices__list'], + listItems: ['choices__list--multiple'], + listSingle: ['choices__list--single'], + listDropdown: ['choices__list--dropdown'], + item: ['choices__item'], + itemSelectable: ['choices__item--selectable'], + itemDisabled: ['choices__item--disabled'], + itemChoice: ['choices__item--choice'], + description: ['choices__description'], + placeholder: ['choices__placeholder'], + group: ['choices__group'], + groupHeading: ['choices__heading'], + button: ['choices__button'], + activeState: ['is-active'], + focusState: ['is-focused'], + openState: ['is-open'], + disabledState: ['is-disabled'], + highlightedState: ['is-highlighted'], + selectedState: ['is-selected'], + flippedState: ['is-flipped'], + loadingState: ['is-loading'], + notice: ['choices__notice'], + addChoice: ['choices__item--selectable', 'add-choice'], + noResults: ['has-no-results'], + noChoices: ['has-no-choices'], +}; +var DEFAULT_CONFIG = { + items: [], + choices: [], + silent: false, + renderChoiceLimit: -1, + maxItemCount: -1, + closeDropdownOnSelect: 'auto', + singleModeForMultiSelect: false, + addChoices: false, + addItems: true, + addItemFilter: function (value) { return !!value && value !== ''; }, + removeItems: true, + removeItemButton: false, + removeItemButtonAlignLeft: false, + editItems: false, + allowHTML: false, + allowHtmlUserInput: false, + duplicateItemsAllowed: true, + delimiter: ',', + paste: true, + searchEnabled: true, + searchChoices: true, + searchFloor: 1, + searchResultLimit: 4, + searchFields: ['label', 'value'], + position: 'auto', + resetScrollPosition: true, + shouldSort: true, + shouldSortItems: false, + sorter: sortByAlpha, + shadowRoot: null, + placeholder: true, + placeholderValue: null, + searchPlaceholderValue: null, + prependValue: null, + appendValue: null, + renderSelectedChoices: 'auto', + loadingText: 'Loading...', + noResultsText: 'No results found', + noChoicesText: 'No choices to choose from', + itemSelectText: 'Press to select', + uniqueItemText: 'Only unique values can be added', + customAddItemText: 'Only values matching specific conditions can be added', + addItemText: function (value) { return "Press Enter to add \"".concat(value, "\""); }, + removeItemIconText: function () { return "Remove item"; }, + removeItemLabelText: function (value) { return "Remove item: ".concat(value); }, + maxItemText: function (maxItemCount) { return "Only ".concat(maxItemCount, " values can be added"); }, + valueComparer: function (value1, value2) { return value1 === value2; }, + fuseOptions: { + includeScore: true, + }, + labelId: '', + callbackOnInit: null, + callbackOnCreateTemplates: null, + classNames: DEFAULT_CLASSNAMES, + appendGroupInSearch: false, +}; + +var removeItem = function (item) { + var itemEl = item.itemEl; + if (itemEl) { + itemEl.remove(); + item.itemEl = undefined; + } +}; +function items(s, action, context) { + var state = s; + var update = true; + switch (action.type) { + case ActionType.ADD_ITEM: { + action.item.selected = true; + var el = action.item.element; + if (el) { + el.selected = true; + el.setAttribute('selected', ''); + } + state.push(action.item); + break; + } + case ActionType.REMOVE_ITEM: { + action.item.selected = false; + var el = action.item.element; + if (el) { + el.selected = false; + el.removeAttribute('selected'); + // For a select-one, if all options are deselected, the first item is selected. To set a black value, select.value needs to be set + var select = el.parentElement; + if (select && isHtmlSelectElement(select) && select.type === PassedElementTypes.SelectOne) { + select.value = ''; + } + } + // this is mixing concerns, but this is *so much faster* + removeItem(action.item); + state = state.filter(function (choice) { return choice.id !== action.item.id; }); + break; + } + case ActionType.REMOVE_CHOICE: { + state = state.filter(function (item) { return item.id !== action.choice.id; }); + removeItem(action.choice); + break; + } + case ActionType.HIGHLIGHT_ITEM: { + var highlighted = action.highlighted; + var item = state.find(function (obj) { return obj.id === action.item.id; }); + if (item && item.highlighted !== highlighted) { + item.highlighted = highlighted; + if (context) { + updateClassList(item, highlighted ? context.classNames.highlightedState : context.classNames.selectedState, highlighted ? context.classNames.selectedState : context.classNames.highlightedState); + } + } + break; + } + default: { + update = false; + break; + } + } + return { state: state, update: update }; +} + +function groups(s, action) { + var state = s; + var update = true; + switch (action.type) { + case ActionType.ADD_GROUP: { + state.push(action.group); + break; + } + case ActionType.CLEAR_CHOICES: { + state = []; + break; + } + default: { + update = false; + break; + } + } + return { state: state, update: update }; +} + +/* eslint-disable */ +function choices(s, action, context) { + var state = s; + var update = true; + switch (action.type) { + case ActionType.ADD_CHOICE: { + /* + A disabled choice appears in the choice dropdown but cannot be selected + A selected choice has been added to the passed input's value (added as an item) + An active choice appears within the choice dropdown + */ + state.push(action.choice); + break; + } + case ActionType.REMOVE_CHOICE: { + action.choice.choiceEl = undefined; + state = state.filter(function (obj) { return obj.id !== action.choice.id; }); + break; + } + case ActionType.ADD_ITEM: + case ActionType.REMOVE_ITEM: { + action.item.choiceEl = undefined; + break; + } + case ActionType.FILTER_CHOICES: { + // avoid O(n^2) algorithm complexity when searching/filtering choices + var scoreLookup_1 = []; + action.results.forEach(function (result) { + scoreLookup_1[result.item.id] = result; + }); + state.forEach(function (choice) { + var result = scoreLookup_1[choice.id]; + if (result !== undefined) { + choice.score = result.score; + choice.rank = result.rank; + choice.active = true; + } + else { + choice.score = 0; + choice.rank = 0; + choice.active = false; + } + if (context && context.appendGroupInSearch) { + choice.choiceEl = undefined; + } + }); + break; + } + case ActionType.ACTIVATE_CHOICES: { + state.forEach(function (choice) { + choice.active = action.active; + if (context && context.appendGroupInSearch) { + choice.choiceEl = undefined; + } + }); + break; + } + case ActionType.CLEAR_CHOICES: { + state = []; + break; + } + default: { + update = false; + break; + } + } + return { state: state, update: update }; +} + +var reducers = { + groups: groups, + items: items, + choices: choices, +}; +var Store = /** @class */ (function () { + function Store(context) { + this._state = this.defaultState; + this._listeners = []; + this._txn = 0; + this._context = context; + } + Object.defineProperty(Store.prototype, "defaultState", { + // eslint-disable-next-line class-methods-use-this + get: function () { + return { + groups: [], + items: [], + choices: [], + }; + }, + enumerable: false, + configurable: true + }); + // eslint-disable-next-line class-methods-use-this + Store.prototype.changeSet = function (init) { + return { + groups: init, + items: init, + choices: init, + }; + }; + Store.prototype.reset = function () { + this._state = this.defaultState; + var changes = this.changeSet(true); + if (this._txn) { + this._changeSet = changes; + } + else { + this._listeners.forEach(function (l) { return l(changes); }); + } + }; + Store.prototype.subscribe = function (onChange) { + this._listeners.push(onChange); + }; + Store.prototype.dispatch = function (action) { + var _this = this; + var state = this._state; + var hasChanges = false; + var changes = this._changeSet || this.changeSet(false); + Object.keys(reducers).forEach(function (key) { + var stateUpdate = reducers[key](state[key], action, _this._context); + if (stateUpdate.update) { + hasChanges = true; + changes[key] = true; + state[key] = stateUpdate.state; + } + }); + if (hasChanges) { + if (this._txn) { + this._changeSet = changes; + } + else { + this._listeners.forEach(function (l) { return l(changes); }); + } + } + }; + Store.prototype.withTxn = function (func) { + this._txn++; + try { + func(); + } + finally { + this._txn = Math.max(0, this._txn - 1); + if (!this._txn) { + var changeSet_1 = this._changeSet; + if (changeSet_1) { + this._changeSet = undefined; + this._listeners.forEach(function (l) { return l(changeSet_1); }); + } + } + } + }; + Object.defineProperty(Store.prototype, "state", { + /** + * Get store object + */ + get: function () { + return this._state; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "items", { + /** + * Get items from store + */ + get: function () { + return this.state.items; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "highlightedActiveItems", { + /** + * Get highlighted items from store + */ + get: function () { + return this.items.filter(function (item) { return !item.disabled && item.active && item.highlighted; }); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "choices", { + /** + * Get choices from store + */ + get: function () { + return this.state.choices; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "activeChoices", { + /** + * Get active choices from store + */ + get: function () { + return this.choices.filter(function (choice) { return choice.active; }); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "searchableChoices", { + /** + * Get choices that can be searched (excluding placeholders) + */ + get: function () { + return this.choices.filter(function (choice) { return !choice.disabled && !choice.placeholder; }); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "groups", { + /** + * Get groups from store + */ + get: function () { + return this.state.groups; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Store.prototype, "activeGroups", { + /** + * Get active groups from store + */ + get: function () { + var _this = this; + return this.state.groups.filter(function (group) { + var isActive = group.active && !group.disabled; + var hasActiveOptions = _this.state.choices.some(function (choice) { return choice.active && !choice.disabled; }); + return isActive && hasActiveOptions; + }, []); + }, + enumerable: false, + configurable: true + }); + Store.prototype.inTxn = function () { + return this._txn > 0; + }; + /** + * Get single choice by it's ID + */ + Store.prototype.getChoiceById = function (id) { + return this.activeChoices.find(function (choice) { return choice.id === id; }); + }; + /** + * Get group by group id + */ + Store.prototype.getGroupById = function (id) { + return this.groups.find(function (group) { return group.id === id; }); + }; + return Store; +}()); + +var NoticeTypes = { + noChoices: 'no-choices', + noResults: 'no-results', + addChoice: 'add-choice', + generic: '', +}; + +function _defineProperty(e, r, t) { + return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { + value: t, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[r] = t, e; +} +function ownKeys(e, r) { + var t = Object.keys(e); + if (Object.getOwnPropertySymbols) { + var o = Object.getOwnPropertySymbols(e); + r && (o = o.filter(function (r) { + return Object.getOwnPropertyDescriptor(e, r).enumerable; + })), t.push.apply(t, o); + } + return t; +} +function _objectSpread2(e) { + for (var r = 1; r < arguments.length; r++) { + var t = null != arguments[r] ? arguments[r] : {}; + r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { + _defineProperty(e, r, t[r]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { + Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); + }); + } + return e; +} +function _toPrimitive(t, r) { + if ("object" != typeof t || !t) return t; + var e = t[Symbol.toPrimitive]; + if (void 0 !== e) { + var i = e.call(t, r || "default"); + if ("object" != typeof i) return i; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return ("string" === r ? String : Number)(t); +} +function _toPropertyKey(t) { + var i = _toPrimitive(t, "string"); + return "symbol" == typeof i ? i : i + ""; +} + +/** + * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2023 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +function isArray(value) { + return !Array.isArray ? getTag(value) === '[object Array]' : Array.isArray(value); +} + +// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js +const INFINITY = 1 / 0; +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + let result = value + ''; + return result == '0' && 1 / value == -INFINITY ? '-0' : result; +} +function toString(value) { + return value == null ? '' : baseToString(value); +} +function isString(value) { + return typeof value === 'string'; +} +function isNumber(value) { + return typeof value === 'number'; +} + +// Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js +function isBoolean(value) { + return value === true || value === false || isObjectLike(value) && getTag(value) == '[object Boolean]'; +} +function isObject(value) { + return typeof value === 'object'; +} + +// Checks if `value` is object-like. +function isObjectLike(value) { + return isObject(value) && value !== null; +} +function isDefined(value) { + return value !== undefined && value !== null; +} +function isBlank(value) { + return !value.trim().length; +} + +// Gets the `toStringTag` of `value`. +// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js +function getTag(value) { + return value == null ? value === undefined ? '[object Undefined]' : '[object Null]' : Object.prototype.toString.call(value); +} +const EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available'; +const LOGICAL_SEARCH_UNAVAILABLE = 'Logical search is not available'; +const INCORRECT_INDEX_TYPE = "Incorrect 'index' type"; +const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = key => `Invalid value for key ${key}`; +const PATTERN_LENGTH_TOO_LARGE = max => `Pattern length exceeds max of ${max}.`; +const MISSING_KEY_PROPERTY = name => `Missing ${name} property in key`; +const INVALID_KEY_WEIGHT_VALUE = key => `Property 'weight' in key '${key}' must be a positive integer`; +const hasOwn = Object.prototype.hasOwnProperty; +class KeyStore { + constructor(keys) { + this._keys = []; + this._keyMap = {}; + let totalWeight = 0; + keys.forEach(key => { + let obj = createKey(key); + this._keys.push(obj); + this._keyMap[obj.id] = obj; + totalWeight += obj.weight; + }); + + // Normalize weights so that their sum is equal to 1 + this._keys.forEach(key => { + key.weight /= totalWeight; + }); + } + get(keyId) { + return this._keyMap[keyId]; + } + keys() { + return this._keys; + } + toJSON() { + return JSON.stringify(this._keys); + } +} +function createKey(key) { + let path = null; + let id = null; + let src = null; + let weight = 1; + let getFn = null; + if (isString(key) || isArray(key)) { + src = key; + path = createKeyPath(key); + id = createKeyId(key); + } else { + if (!hasOwn.call(key, 'name')) { + throw new Error(MISSING_KEY_PROPERTY('name')); + } + const name = key.name; + src = name; + if (hasOwn.call(key, 'weight')) { + weight = key.weight; + if (weight <= 0) { + throw new Error(INVALID_KEY_WEIGHT_VALUE(name)); + } + } + path = createKeyPath(name); + id = createKeyId(name); + getFn = key.getFn; + } + return { + path, + id, + weight, + src, + getFn + }; +} +function createKeyPath(key) { + return isArray(key) ? key : key.split('.'); +} +function createKeyId(key) { + return isArray(key) ? key.join('.') : key; +} +function get(obj, path) { + let list = []; + let arr = false; + const deepGet = (obj, path, index) => { + if (!isDefined(obj)) { + return; + } + if (!path[index]) { + // If there's no path left, we've arrived at the object we care about. + list.push(obj); + } else { + let key = path[index]; + const value = obj[key]; + if (!isDefined(value)) { + return; + } + + // If we're at the last value in the path, and if it's a string/number/bool, + // add it to the list + if (index === path.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) { + list.push(toString(value)); + } else if (isArray(value)) { + arr = true; + // Search each item in the array. + for (let i = 0, len = value.length; i < len; i += 1) { + deepGet(value[i], path, index + 1); + } + } else if (path.length) { + // An object. Recurse further. + deepGet(value, path, index + 1); + } + } + }; + + // Backwards compatibility (since path used to be a string) + deepGet(obj, isString(path) ? path.split('.') : path, 0); + return arr ? list : list[0]; +} +const MatchOptions = { + // Whether the matches should be included in the result set. When `true`, each record in the result + // set will include the indices of the matched characters. + // These can consequently be used for highlighting purposes. + includeMatches: false, + // When `true`, the matching function will continue to the end of a search pattern even if + // a perfect match has already been located in the string. + findAllMatches: false, + // Minimum number of characters that must be matched before a result is considered a match + minMatchCharLength: 1 +}; +const BasicOptions = { + // When `true`, the algorithm continues searching to the end of the input even if a perfect + // match is found before the end of the same input. + isCaseSensitive: false, + // When true, the matching function will continue to the end of a search pattern even if + includeScore: false, + // List of properties that will be searched. This also supports nested properties. + keys: [], + // Whether to sort the result list, by score + shouldSort: true, + // Default sort function: sort by ascending score, ascending index + sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1 +}; +const FuzzyOptions = { + // Approximately where in the text is the pattern expected to be found? + location: 0, + // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match + // (of both letters and location), a threshold of '1.0' would match anything. + threshold: 0.6, + // Determines how close the match must be to the fuzzy location (specified above). + // An exact letter match which is 'distance' characters away from the fuzzy location + // would score as a complete mismatch. A distance of '0' requires the match be at + // the exact location specified, a threshold of '1000' would require a perfect match + // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold. + distance: 100 +}; +const AdvancedOptions = { + // When `true`, it enables the use of unix-like search commands + useExtendedSearch: false, + // The get function to use when fetching an object's properties. + // The default will search nested paths *ie foo.bar.baz* + getFn: get, + // When `true`, search will ignore `location` and `distance`, so it won't matter + // where in the string the pattern appears. + // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score + ignoreLocation: false, + // When `true`, the calculation for the relevance score (used for sorting) will + // ignore the field-length norm. + // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm + ignoreFieldNorm: false, + // The weight to determine how much field length norm effects scoring. + fieldNormWeight: 1 +}; +var Config = _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, BasicOptions), MatchOptions), FuzzyOptions), AdvancedOptions); +const SPACE = /[^ ]+/g; + +// Field-length norm: the shorter the field, the higher the weight. +// Set to 3 decimals to reduce index size. +function norm(weight = 1, mantissa = 3) { + const cache = new Map(); + const m = Math.pow(10, mantissa); + return { + get(value) { + const numTokens = value.match(SPACE).length; + if (cache.has(numTokens)) { + return cache.get(numTokens); + } + + // Default function is 1/sqrt(x), weight makes that variable + const norm = 1 / Math.pow(numTokens, 0.5 * weight); + + // In place of `toFixed(mantissa)`, for faster computation + const n = parseFloat(Math.round(norm * m) / m); + cache.set(numTokens, n); + return n; + }, + clear() { + cache.clear(); + } + }; +} +class FuseIndex { + constructor({ + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight + } = {}) { + this.norm = norm(fieldNormWeight, 3); + this.getFn = getFn; + this.isCreated = false; + this.setIndexRecords(); + } + setSources(docs = []) { + this.docs = docs; + } + setIndexRecords(records = []) { + this.records = records; + } + setKeys(keys = []) { + this.keys = keys; + this._keysMap = {}; + keys.forEach((key, idx) => { + this._keysMap[key.id] = idx; + }); + } + create() { + if (this.isCreated || !this.docs.length) { + return; + } + this.isCreated = true; + + // List is Array + if (isString(this.docs[0])) { + this.docs.forEach((doc, docIndex) => { + this._addString(doc, docIndex); + }); + } else { + // List is Array + this.docs.forEach((doc, docIndex) => { + this._addObject(doc, docIndex); + }); + } + this.norm.clear(); + } + // Adds a doc to the end of the index + add(doc) { + const idx = this.size(); + if (isString(doc)) { + this._addString(doc, idx); + } else { + this._addObject(doc, idx); + } + } + // Removes the doc at the specified index of the index + removeAt(idx) { + this.records.splice(idx, 1); + + // Change ref index of every subsquent doc + for (let i = idx, len = this.size(); i < len; i += 1) { + this.records[i].i -= 1; + } + } + getValueForItemAtKeyId(item, keyId) { + return item[this._keysMap[keyId]]; + } + size() { + return this.records.length; + } + _addString(doc, docIndex) { + if (!isDefined(doc) || isBlank(doc)) { + return; + } + let record = { + v: doc, + i: docIndex, + n: this.norm.get(doc) + }; + this.records.push(record); + } + _addObject(doc, docIndex) { + let record = { + i: docIndex, + $: {} + }; + + // Iterate over every key (i.e, path), and fetch the value at that key + this.keys.forEach((key, keyIndex) => { + let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path); + if (!isDefined(value)) { + return; + } + if (isArray(value)) { + let subRecords = []; + const stack = [{ + nestedArrIndex: -1, + value + }]; + while (stack.length) { + const { + nestedArrIndex, + value + } = stack.pop(); + if (!isDefined(value)) { + continue; + } + if (isString(value) && !isBlank(value)) { + let subRecord = { + v: value, + i: nestedArrIndex, + n: this.norm.get(value) + }; + subRecords.push(subRecord); + } else if (isArray(value)) { + value.forEach((item, k) => { + stack.push({ + nestedArrIndex: k, + value: item + }); + }); + } else ; + } + record.$[keyIndex] = subRecords; + } else if (isString(value) && !isBlank(value)) { + let subRecord = { + v: value, + n: this.norm.get(value) + }; + record.$[keyIndex] = subRecord; + } + }); + this.records.push(record); + } + toJSON() { + return { + keys: this.keys, + records: this.records + }; + } +} +function createIndex(keys, docs, { + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight +} = {}) { + const myIndex = new FuseIndex({ + getFn, + fieldNormWeight + }); + myIndex.setKeys(keys.map(createKey)); + myIndex.setSources(docs); + myIndex.create(); + return myIndex; +} +function parseIndex(data, { + getFn = Config.getFn, + fieldNormWeight = Config.fieldNormWeight +} = {}) { + const { + keys, + records + } = data; + const myIndex = new FuseIndex({ + getFn, + fieldNormWeight + }); + myIndex.setKeys(keys); + myIndex.setIndexRecords(records); + return myIndex; +} +function computeScore$1(pattern, { + errors = 0, + currentLocation = 0, + expectedLocation = 0, + distance = Config.distance, + ignoreLocation = Config.ignoreLocation +} = {}) { + const accuracy = errors / pattern.length; + if (ignoreLocation) { + return accuracy; + } + const proximity = Math.abs(expectedLocation - currentLocation); + if (!distance) { + // Dodge divide by zero error. + return proximity ? 1.0 : accuracy; + } + return accuracy + proximity / distance; +} +function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) { + let indices = []; + let start = -1; + let end = -1; + let i = 0; + for (let len = matchmask.length; i < len; i += 1) { + let match = matchmask[i]; + if (match && start === -1) { + start = i; + } else if (!match && start !== -1) { + end = i - 1; + if (end - start + 1 >= minMatchCharLength) { + indices.push([start, end]); + } + start = -1; + } + } + + // (i-1 - start) + 1 => i - start + if (matchmask[i - 1] && i - start >= minMatchCharLength) { + indices.push([start, i - 1]); + } + return indices; +} + +// Machine word size +const MAX_BITS = 32; +function search(text, pattern, patternAlphabet, { + location = Config.location, + distance = Config.distance, + threshold = Config.threshold, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + includeMatches = Config.includeMatches, + ignoreLocation = Config.ignoreLocation +} = {}) { + if (pattern.length > MAX_BITS) { + throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS)); + } + const patternLen = pattern.length; + // Set starting location at beginning text and initialize the alphabet. + const textLen = text.length; + // Handle the case when location > text.length + const expectedLocation = Math.max(0, Math.min(location, textLen)); + // Highest score beyond which we give up. + let currentThreshold = threshold; + // Is there a nearby exact match? (speedup) + let bestLocation = expectedLocation; + + // Performance: only computer matches when the minMatchCharLength > 1 + // OR if `includeMatches` is true. + const computeMatches = minMatchCharLength > 1 || includeMatches; + // A mask of the matches, used for building the indices + const matchMask = computeMatches ? Array(textLen) : []; + let index; + + // Get all exact matches, here for speed up + while ((index = text.indexOf(pattern, bestLocation)) > -1) { + let score = computeScore$1(pattern, { + currentLocation: index, + expectedLocation, + distance, + ignoreLocation + }); + currentThreshold = Math.min(score, currentThreshold); + bestLocation = index + patternLen; + if (computeMatches) { + let i = 0; + while (i < patternLen) { + matchMask[index + i] = 1; + i += 1; + } + } + } + + // Reset the best location + bestLocation = -1; + let lastBitArr = []; + let finalScore = 1; + let binMax = patternLen + textLen; + const mask = 1 << patternLen - 1; + for (let i = 0; i < patternLen; i += 1) { + // Scan for the best match; each iteration allows for one more error. + // Run a binary search to determine how far from the match location we can stray + // at this error level. + let binMin = 0; + let binMid = binMax; + while (binMin < binMid) { + const score = computeScore$1(pattern, { + errors: i, + currentLocation: expectedLocation + binMid, + expectedLocation, + distance, + ignoreLocation + }); + if (score <= currentThreshold) { + binMin = binMid; + } else { + binMax = binMid; + } + binMid = Math.floor((binMax - binMin) / 2 + binMin); + } + + // Use the result from this iteration as the maximum for the next. + binMax = binMid; + let start = Math.max(1, expectedLocation - binMid + 1); + let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen; + + // Initialize the bit array + let bitArr = Array(finish + 2); + bitArr[finish + 1] = (1 << i) - 1; + for (let j = finish; j >= start; j -= 1) { + let currentLocation = j - 1; + let charMatch = patternAlphabet[text.charAt(currentLocation)]; + if (computeMatches) { + // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`) + matchMask[currentLocation] = +!!charMatch; + } + + // First pass: exact match + bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch; + + // Subsequent passes: fuzzy match + if (i) { + bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1]; + } + if (bitArr[j] & mask) { + finalScore = computeScore$1(pattern, { + errors: i, + currentLocation, + expectedLocation, + distance, + ignoreLocation + }); + + // This match will almost certainly be better than any existing match. + // But check anyway. + if (finalScore <= currentThreshold) { + // Indeed it is + currentThreshold = finalScore; + bestLocation = currentLocation; + + // Already passed `loc`, downhill from here on in. + if (bestLocation <= expectedLocation) { + break; + } + + // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`. + start = Math.max(1, 2 * expectedLocation - bestLocation); + } + } + } + + // No hope for a (better) match at greater error levels. + const score = computeScore$1(pattern, { + errors: i + 1, + currentLocation: expectedLocation, + expectedLocation, + distance, + ignoreLocation + }); + if (score > currentThreshold) { + break; + } + lastBitArr = bitArr; + } + const result = { + isMatch: bestLocation >= 0, + // Count exact matches (those with a score of 0) to be "almost" exact + score: Math.max(0.001, finalScore) + }; + if (computeMatches) { + const indices = convertMaskToIndices(matchMask, minMatchCharLength); + if (!indices.length) { + result.isMatch = false; + } else if (includeMatches) { + result.indices = indices; + } + } + return result; +} +function createPatternAlphabet(pattern) { + let mask = {}; + for (let i = 0, len = pattern.length; i < len; i += 1) { + const char = pattern.charAt(i); + mask[char] = (mask[char] || 0) | 1 << len - i - 1; + } + return mask; +} +class BitapSearch { + constructor(pattern, { + location = Config.location, + threshold = Config.threshold, + distance = Config.distance, + includeMatches = Config.includeMatches, + findAllMatches = Config.findAllMatches, + minMatchCharLength = Config.minMatchCharLength, + isCaseSensitive = Config.isCaseSensitive, + ignoreLocation = Config.ignoreLocation + } = {}) { + this.options = { + location, + threshold, + distance, + includeMatches, + findAllMatches, + minMatchCharLength, + isCaseSensitive, + ignoreLocation + }; + this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); + this.chunks = []; + if (!this.pattern.length) { + return; + } + const addChunk = (pattern, startIndex) => { + this.chunks.push({ + pattern, + alphabet: createPatternAlphabet(pattern), + startIndex + }); + }; + const len = this.pattern.length; + if (len > MAX_BITS) { + let i = 0; + const remainder = len % MAX_BITS; + const end = len - remainder; + while (i < end) { + addChunk(this.pattern.substr(i, MAX_BITS), i); + i += MAX_BITS; + } + if (remainder) { + const startIndex = len - MAX_BITS; + addChunk(this.pattern.substr(startIndex), startIndex); + } + } else { + addChunk(this.pattern, 0); + } + } + searchIn(text) { + const { + isCaseSensitive, + includeMatches + } = this.options; + if (!isCaseSensitive) { + text = text.toLowerCase(); + } + + // Exact match + if (this.pattern === text) { + let result = { + isMatch: true, + score: 0 + }; + if (includeMatches) { + result.indices = [[0, text.length - 1]]; + } + return result; + } + + // Otherwise, use Bitap algorithm + const { + location, + distance, + threshold, + findAllMatches, + minMatchCharLength, + ignoreLocation + } = this.options; + let allIndices = []; + let totalScore = 0; + let hasMatches = false; + this.chunks.forEach(({ + pattern, + alphabet, + startIndex + }) => { + const { + isMatch, + score, + indices + } = search(text, pattern, alphabet, { + location: location + startIndex, + distance, + threshold, + findAllMatches, + minMatchCharLength, + includeMatches, + ignoreLocation + }); + if (isMatch) { + hasMatches = true; + } + totalScore += score; + if (isMatch && indices) { + allIndices = [...allIndices, ...indices]; + } + }); + let result = { + isMatch: hasMatches, + score: hasMatches ? totalScore / this.chunks.length : 1 + }; + if (hasMatches && includeMatches) { + result.indices = allIndices; + } + return result; + } +} +const registeredSearchers = []; +function createSearcher(pattern, options) { + for (let i = 0, len = registeredSearchers.length; i < len; i += 1) { + let searcherClass = registeredSearchers[i]; + if (searcherClass.condition(pattern, options)) { + return new searcherClass(pattern, options); + } + } + return new BitapSearch(pattern, options); +} +const LogicalOperator = { + AND: '$and', + OR: '$or' +}; +const KeyType = { + PATH: '$path', + PATTERN: '$val' +}; +const isExpression = query => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]); +const isPath = query => !!query[KeyType.PATH]; +const isLeaf = query => !isArray(query) && isObject(query) && !isExpression(query); +const convertToExplicit = query => ({ + [LogicalOperator.AND]: Object.keys(query).map(key => ({ + [key]: query[key] + })) +}); + +// When `auto` is `true`, the parse function will infer and initialize and add +// the appropriate `Searcher` instance +function parse(query, options, { + auto = true +} = {}) { + const next = query => { + let keys = Object.keys(query); + const isQueryPath = isPath(query); + if (!isQueryPath && keys.length > 1 && !isExpression(query)) { + return next(convertToExplicit(query)); + } + if (isLeaf(query)) { + const key = isQueryPath ? query[KeyType.PATH] : keys[0]; + const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key]; + if (!isString(pattern)) { + throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key)); + } + const obj = { + keyId: createKeyId(key), + pattern + }; + if (auto) { + obj.searcher = createSearcher(pattern, options); + } + return obj; + } + let node = { + children: [], + operator: keys[0] + }; + keys.forEach(key => { + const value = query[key]; + if (isArray(value)) { + value.forEach(item => { + node.children.push(next(item)); + }); + } + }); + return node; + }; + if (!isExpression(query)) { + query = convertToExplicit(query); + } + return next(query); +} + +// Practical scoring function +function computeScore(results, { + ignoreFieldNorm = Config.ignoreFieldNorm +}) { + results.forEach(result => { + let totalScore = 1; + result.matches.forEach(({ + key, + norm, + score + }) => { + const weight = key ? key.weight : null; + totalScore *= Math.pow(score === 0 && weight ? Number.EPSILON : score, (weight || 1) * (ignoreFieldNorm ? 1 : norm)); + }); + result.score = totalScore; + }); +} +function transformMatches(result, data) { + const matches = result.matches; + data.matches = []; + if (!isDefined(matches)) { + return; + } + matches.forEach(match => { + if (!isDefined(match.indices) || !match.indices.length) { + return; + } + const { + indices, + value + } = match; + let obj = { + indices, + value + }; + if (match.key) { + obj.key = match.key.src; + } + if (match.idx > -1) { + obj.refIndex = match.idx; + } + data.matches.push(obj); + }); +} +function transformScore(result, data) { + data.score = result.score; +} +function format(results, docs, { + includeMatches = Config.includeMatches, + includeScore = Config.includeScore +} = {}) { + const transformers = []; + if (includeMatches) transformers.push(transformMatches); + if (includeScore) transformers.push(transformScore); + return results.map(result => { + const { + idx + } = result; + const data = { + item: docs[idx], + refIndex: idx + }; + if (transformers.length) { + transformers.forEach(transformer => { + transformer(result, data); + }); + } + return data; + }); +} +class Fuse { + constructor(docs, options = {}, index) { + this.options = _objectSpread2(_objectSpread2({}, Config), options); + if (this.options.useExtendedSearch && !false) { + throw new Error(EXTENDED_SEARCH_UNAVAILABLE); + } + this._keyStore = new KeyStore(this.options.keys); + this.setCollection(docs, index); + } + setCollection(docs, index) { + this._docs = docs; + if (index && !(index instanceof FuseIndex)) { + throw new Error(INCORRECT_INDEX_TYPE); + } + this._myIndex = index || createIndex(this.options.keys, this._docs, { + getFn: this.options.getFn, + fieldNormWeight: this.options.fieldNormWeight + }); + } + add(doc) { + if (!isDefined(doc)) { + return; + } + this._docs.push(doc); + this._myIndex.add(doc); + } + remove(predicate = ( /* doc, idx */) => false) { + const results = []; + for (let i = 0, len = this._docs.length; i < len; i += 1) { + const doc = this._docs[i]; + if (predicate(doc, i)) { + this.removeAt(i); + i -= 1; + len -= 1; + results.push(doc); + } + } + return results; + } + removeAt(idx) { + this._docs.splice(idx, 1); + this._myIndex.removeAt(idx); + } + getIndex() { + return this._myIndex; + } + search(query, { + limit = -1 + } = {}) { + const { + includeMatches, + includeScore, + shouldSort, + sortFn, + ignoreFieldNorm + } = this.options; + let results = isString(query) ? isString(this._docs[0]) ? this._searchStringList(query) : this._searchObjectList(query) : this._searchLogical(query); + computeScore(results, { + ignoreFieldNorm + }); + if (shouldSort) { + results.sort(sortFn); + } + if (isNumber(limit) && limit > -1) { + results = results.slice(0, limit); + } + return format(results, this._docs, { + includeMatches, + includeScore + }); + } + _searchStringList(query) { + const searcher = createSearcher(query, this.options); + const { + records + } = this._myIndex; + const results = []; + + // Iterate over every string in the index + records.forEach(({ + v: text, + i: idx, + n: norm + }) => { + if (!isDefined(text)) { + return; + } + const { + isMatch, + score, + indices + } = searcher.searchIn(text); + if (isMatch) { + results.push({ + item: text, + idx, + matches: [{ + score, + value: text, + norm, + indices + }] + }); + } + }); + return results; + } + _searchLogical(query) { + { + throw new Error(LOGICAL_SEARCH_UNAVAILABLE); + } + } + _searchObjectList(query) { + const searcher = createSearcher(query, this.options); + const { + keys, + records + } = this._myIndex; + const results = []; + + // List is Array + records.forEach(({ + $: item, + i: idx + }) => { + if (!isDefined(item)) { + return; + } + let matches = []; + + // Iterate over every key (i.e, path), and fetch the value at that key + keys.forEach((key, keyIndex) => { + matches.push(...this._findMatches({ + key, + value: item[keyIndex], + searcher + })); + }); + if (matches.length) { + results.push({ + idx, + item, + matches + }); + } + }); + return results; + } + _findMatches({ + key, + value, + searcher + }) { + if (!isDefined(value)) { + return []; + } + let matches = []; + if (isArray(value)) { + value.forEach(({ + v: text, + i: idx, + n: norm + }) => { + if (!isDefined(text)) { + return; + } + const { + isMatch, + score, + indices + } = searcher.searchIn(text); + if (isMatch) { + matches.push({ + score, + key, + value: text, + idx, + norm, + indices + }); + } + }); + } else { + const { + v: text, + n: norm + } = value; + const { + isMatch, + score, + indices + } = searcher.searchIn(text); + if (isMatch) { + matches.push({ + score, + key, + value: text, + norm, + indices + }); + } + } + return matches; + } +} +Fuse.version = '7.0.0'; +Fuse.createIndex = createIndex; +Fuse.parseIndex = parseIndex; +Fuse.config = Config; +{ + Fuse.parseQuery = parse; +} + +var SearchByFuse = /** @class */ (function () { + function SearchByFuse(config) { + this._haystack = []; + this._fuseOptions = __assign(__assign({}, config.fuseOptions), { keys: __spreadArray([], config.searchFields, true), includeMatches: true }); + } + SearchByFuse.prototype.index = function (data) { + this._haystack = data; + if (this._fuse) { + this._fuse.setCollection(data); + } + }; + SearchByFuse.prototype.reset = function () { + this._haystack = []; + this._fuse = undefined; + }; + SearchByFuse.prototype.isEmptyIndex = function () { + return !this._haystack.length; + }; + SearchByFuse.prototype.search = function (needle) { + if (!this._fuse) { + { + this._fuse = new Fuse(this._haystack, this._fuseOptions); + } + } + var results = this._fuse.search(needle); + return results.map(function (value, i) { + return { + item: value.item, + score: value.score || 0, + rank: i + 1, // If value.score is used for sorting, this can create non-stable sorts! + }; + }); + }; + return SearchByFuse; +}()); + +function getSearcher(config) { + { + return new SearchByFuse(config); + } +} + +/** + * Helpers to create HTML elements used by Choices + * Can be overridden by providing `callbackOnCreateTemplates` option. + * `Choices.defaults.templates` allows access to the default template methods from `callbackOnCreateTemplates` + */ +var isEmptyObject = function (obj) { + // eslint-disable-next-line no-restricted-syntax + for (var prop in obj) { + if (Object.prototype.hasOwnProperty.call(obj, prop)) { + return false; + } + } + return true; +}; +var assignCustomProperties = function (el, choice, withCustomProperties) { + var dataset = el.dataset; + var customProperties = choice.customProperties, labelClass = choice.labelClass, labelDescription = choice.labelDescription; + if (labelClass) { + dataset.labelClass = getClassNames(labelClass).join(' '); + } + if (labelDescription) { + dataset.labelDescription = labelDescription; + } + if (withCustomProperties && customProperties) { + if (typeof customProperties === 'string') { + dataset.customProperties = customProperties; + } + else if (typeof customProperties === 'object' && !isEmptyObject(customProperties)) { + dataset.customProperties = JSON.stringify(customProperties); + } + } +}; +var addAriaLabel = function (docRoot, id, element) { + var label = id && docRoot.querySelector("label[for='".concat(id, "']")); + var text = label && label.innerText; + if (text) { + element.setAttribute('aria-label', text); + } +}; +var templates = { + containerOuter: function (_a, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType, labelId) { + var containerOuter = _a.classNames.containerOuter; + var div = document.createElement('div'); + addClassesToElement(div, containerOuter); + div.dataset.type = passedElementType; + if (dir) { + div.dir = dir; + } + if (isSelectOneElement) { + div.tabIndex = 0; + } + if (isSelectElement) { + div.setAttribute('role', searchEnabled ? 'combobox' : 'listbox'); + if (searchEnabled) { + div.setAttribute('aria-autocomplete', 'list'); + } + else if (!labelId) { + addAriaLabel(this._docRoot, this.passedElement.element.id, div); + } + div.setAttribute('aria-haspopup', 'true'); + div.setAttribute('aria-expanded', 'false'); + } + if (labelId) { + div.setAttribute('aria-labelledby', labelId); + } + return div; + }, + containerInner: function (_a) { + var containerInner = _a.classNames.containerInner; + var div = document.createElement('div'); + addClassesToElement(div, containerInner); + return div; + }, + itemList: function (_a, isSelectOneElement) { + var searchEnabled = _a.searchEnabled, _b = _a.classNames, list = _b.list, listSingle = _b.listSingle, listItems = _b.listItems; + var div = document.createElement('div'); + addClassesToElement(div, list); + addClassesToElement(div, isSelectOneElement ? listSingle : listItems); + if (this._isSelectElement && searchEnabled) { + div.setAttribute('role', 'listbox'); + } + return div; + }, + placeholder: function (_a, value) { + var allowHTML = _a.allowHTML, placeholder = _a.classNames.placeholder; + var div = document.createElement('div'); + addClassesToElement(div, placeholder); + setElementHtml(div, allowHTML, value); + return div; + }, + item: function (_a, choice, removeItemButton) { + var allowHTML = _a.allowHTML, removeItemButtonAlignLeft = _a.removeItemButtonAlignLeft, removeItemIconText = _a.removeItemIconText, removeItemLabelText = _a.removeItemLabelText, _b = _a.classNames, item = _b.item, button = _b.button, highlightedState = _b.highlightedState, itemSelectable = _b.itemSelectable, placeholder = _b.placeholder; + var rawValue = unwrapStringForRaw(choice.value); + var div = document.createElement('div'); + addClassesToElement(div, item); + if (choice.labelClass) { + var spanLabel = document.createElement('span'); + setElementHtml(spanLabel, allowHTML, choice.label); + addClassesToElement(spanLabel, choice.labelClass); + div.appendChild(spanLabel); + } + else { + setElementHtml(div, allowHTML, choice.label); + } + div.dataset.item = ''; + div.dataset.id = choice.id; + div.dataset.value = rawValue; + assignCustomProperties(div, choice, true); + if (choice.disabled || this.containerOuter.isDisabled) { + div.setAttribute('aria-disabled', 'true'); + } + if (this._isSelectElement) { + div.setAttribute('aria-selected', 'true'); + div.setAttribute('role', 'option'); + } + if (choice.placeholder) { + addClassesToElement(div, placeholder); + div.dataset.placeholder = ''; + } + addClassesToElement(div, choice.highlighted ? highlightedState : itemSelectable); + if (removeItemButton) { + if (choice.disabled) { + removeClassesFromElement(div, itemSelectable); + } + div.dataset.deletable = ''; + var removeButton = document.createElement('button'); + removeButton.type = 'button'; + addClassesToElement(removeButton, button); + setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value)); + var REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value); + if (REMOVE_ITEM_LABEL) { + removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL); + } + removeButton.dataset.button = ''; + if (removeItemButtonAlignLeft) { + div.insertAdjacentElement('afterbegin', removeButton); + } + else { + div.appendChild(removeButton); + } + } + return div; + }, + choiceList: function (_a, isSelectOneElement) { + var list = _a.classNames.list; + var div = document.createElement('div'); + addClassesToElement(div, list); + if (!isSelectOneElement) { + div.setAttribute('aria-multiselectable', 'true'); + } + div.setAttribute('role', 'listbox'); + return div; + }, + choiceGroup: function (_a, _b) { + var allowHTML = _a.allowHTML, _c = _a.classNames, group = _c.group, groupHeading = _c.groupHeading, itemDisabled = _c.itemDisabled; + var id = _b.id, label = _b.label, disabled = _b.disabled; + var rawLabel = unwrapStringForRaw(label); + var div = document.createElement('div'); + addClassesToElement(div, group); + if (disabled) { + addClassesToElement(div, itemDisabled); + } + div.setAttribute('role', 'group'); + div.dataset.group = ''; + div.dataset.id = id; + div.dataset.value = rawLabel; + if (disabled) { + div.setAttribute('aria-disabled', 'true'); + } + var heading = document.createElement('div'); + addClassesToElement(heading, groupHeading); + setElementHtml(heading, allowHTML, label || ''); + div.appendChild(heading); + return div; + }, + choice: function (_a, choice, selectText, groupName) { + var allowHTML = _a.allowHTML, _b = _a.classNames, item = _b.item, itemChoice = _b.itemChoice, itemSelectable = _b.itemSelectable, selectedState = _b.selectedState, itemDisabled = _b.itemDisabled, description = _b.description, placeholder = _b.placeholder; + // eslint-disable-next-line prefer-destructuring + var label = choice.label; + var rawValue = unwrapStringForRaw(choice.value); + var div = document.createElement('div'); + div.id = choice.elementId; + addClassesToElement(div, item); + addClassesToElement(div, itemChoice); + if (groupName && typeof label === 'string') { + label = escapeForTemplate(allowHTML, label); + label += " (".concat(groupName, ")"); + label = { trusted: label }; + div.dataset.groupId = "".concat(choice.groupId); + } + var describedBy = div; + if (choice.labelClass) { + var spanLabel = document.createElement('span'); + setElementHtml(spanLabel, allowHTML, label); + addClassesToElement(spanLabel, choice.labelClass); + describedBy = spanLabel; + div.appendChild(spanLabel); + } + else { + setElementHtml(div, allowHTML, label); + } + if (choice.labelDescription) { + var descId = "".concat(choice.elementId, "-description"); + describedBy.setAttribute('aria-describedby', descId); + var spanDesc = document.createElement('span'); + setElementHtml(spanDesc, allowHTML, choice.labelDescription); + spanDesc.id = descId; + addClassesToElement(spanDesc, description); + div.appendChild(spanDesc); + } + if (choice.selected) { + addClassesToElement(div, selectedState); + } + if (choice.placeholder) { + addClassesToElement(div, placeholder); + } + div.setAttribute('role', choice.groupId ? 'treeitem' : 'option'); + div.dataset.choice = ''; + div.dataset.id = choice.id; + div.dataset.value = rawValue; + if (selectText) { + div.dataset.selectText = selectText; + } + assignCustomProperties(div, choice, false); + if (choice.disabled) { + addClassesToElement(div, itemDisabled); + div.dataset.choiceDisabled = ''; + div.setAttribute('aria-disabled', 'true'); + } + else { + addClassesToElement(div, itemSelectable); + div.dataset.choiceSelectable = ''; + } + return div; + }, + input: function (_a, placeholderValue) { + var _b = _a.classNames, input = _b.input, inputCloned = _b.inputCloned, labelId = _a.labelId; + var inp = document.createElement('input'); + inp.type = 'search'; + addClassesToElement(inp, input); + addClassesToElement(inp, inputCloned); + inp.autocomplete = 'off'; + inp.autocapitalize = 'off'; + inp.spellcheck = false; + inp.setAttribute('role', 'textbox'); + inp.setAttribute('aria-autocomplete', 'list'); + if (placeholderValue) { + inp.setAttribute('aria-label', placeholderValue); + } + else if (!labelId) { + addAriaLabel(this._docRoot, this.passedElement.element.id, inp); + } + return inp; + }, + dropdown: function (_a) { + var _b = _a.classNames, list = _b.list, listDropdown = _b.listDropdown; + var div = document.createElement('div'); + addClassesToElement(div, list); + addClassesToElement(div, listDropdown); + div.setAttribute('aria-expanded', 'false'); + return div; + }, + notice: function (_a, innerHTML, type) { + var _b = _a.classNames, item = _b.item, itemChoice = _b.itemChoice, addChoice = _b.addChoice, noResults = _b.noResults, noChoices = _b.noChoices, noticeItem = _b.notice; + if (type === void 0) { type = NoticeTypes.generic; } + var notice = document.createElement('div'); + setElementHtml(notice, true, innerHTML); + addClassesToElement(notice, item); + addClassesToElement(notice, itemChoice); + addClassesToElement(notice, noticeItem); + // eslint-disable-next-line default-case + switch (type) { + case NoticeTypes.addChoice: + addClassesToElement(notice, addChoice); + break; + case NoticeTypes.noResults: + addClassesToElement(notice, noResults); + break; + case NoticeTypes.noChoices: + addClassesToElement(notice, noChoices); + break; + } + if (type === NoticeTypes.addChoice) { + notice.dataset.choiceSelectable = ''; + notice.dataset.choice = ''; + } + return notice; + }, + option: function (choice) { + // HtmlOptionElement's label value does not support HTML, so the avoid double escaping unwrap the untrusted string. + var labelValue = unwrapStringForRaw(choice.label); + var opt = new Option(labelValue, choice.value, false, choice.selected); + assignCustomProperties(opt, choice, true); + opt.disabled = choice.disabled; + if (choice.selected) { + opt.setAttribute('selected', ''); + } + return opt; + }, +}; + +/** @see {@link http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c} */ +var IS_IE11 = '-ms-scroll-limit' in document.documentElement.style && + '-ms-ime-align' in document.documentElement.style; +var USER_DEFAULTS = {}; +var parseDataSetId = function (element) { + if (!element) { + return undefined; + } + return element.dataset.id ? parseInt(element.dataset.id, 10) : undefined; +}; +var selectableChoiceIdentifier = '[data-choice-selectable]'; +/** + * Choices + * @author Josh Johnson + */ +var Choices = /** @class */ (function () { + function Choices(element, userConfig) { + if (element === void 0) { element = '[data-choice]'; } + if (userConfig === void 0) { userConfig = {}; } + var _this = this; + this.initialisedOK = undefined; + this._hasNonChoicePlaceholder = false; + this._lastAddedChoiceId = 0; + this._lastAddedGroupId = 0; + var defaults = Choices.defaults; + this.config = __assign(__assign(__assign({}, defaults.allOptions), defaults.options), userConfig); + ObjectsInConfig.forEach(function (key) { + _this.config[key] = __assign(__assign(__assign({}, defaults.allOptions[key]), defaults.options[key]), userConfig[key]); + }); + var config = this.config; + if (!config.silent) { + this._validateConfig(); + } + var docRoot = config.shadowRoot || document.documentElement; + this._docRoot = docRoot; + var passedElement = typeof element === 'string' ? docRoot.querySelector(element) : element; + if (!passedElement || + typeof passedElement !== 'object' || + !(isHtmlInputElement(passedElement) || isHtmlSelectElement(passedElement))) { + if (!passedElement && typeof element === 'string') { + throw TypeError("Selector ".concat(element, " failed to find an element")); + } + throw TypeError("Expected one of the following types text|select-one|select-multiple"); + } + var elementType = passedElement.type; + var isText = elementType === PassedElementTypes.Text; + if (isText || config.maxItemCount !== 1) { + config.singleModeForMultiSelect = false; + } + if (config.singleModeForMultiSelect) { + elementType = PassedElementTypes.SelectMultiple; + } + var isSelectOne = elementType === PassedElementTypes.SelectOne; + var isSelectMultiple = elementType === PassedElementTypes.SelectMultiple; + var isSelect = isSelectOne || isSelectMultiple; + this._elementType = elementType; + this._isTextElement = isText; + this._isSelectOneElement = isSelectOne; + this._isSelectMultipleElement = isSelectMultiple; + this._isSelectElement = isSelectOne || isSelectMultiple; + this._canAddUserChoices = (isText && config.addItems) || (isSelect && config.addChoices); + if (typeof config.renderSelectedChoices !== 'boolean') { + config.renderSelectedChoices = config.renderSelectedChoices === 'always' || isSelectOne; + } + if (config.closeDropdownOnSelect === 'auto') { + config.closeDropdownOnSelect = isText || isSelectOne || config.singleModeForMultiSelect; + } + else { + config.closeDropdownOnSelect = coerceBool(config.closeDropdownOnSelect); + } + if (config.placeholder) { + if (config.placeholderValue) { + this._hasNonChoicePlaceholder = true; + } + else if (passedElement.dataset.placeholder) { + this._hasNonChoicePlaceholder = true; + config.placeholderValue = passedElement.dataset.placeholder; + } + } + if (userConfig.addItemFilter && typeof userConfig.addItemFilter !== 'function') { + var re = userConfig.addItemFilter instanceof RegExp ? userConfig.addItemFilter : new RegExp(userConfig.addItemFilter); + config.addItemFilter = re.test.bind(re); + } + if (this._isTextElement) { + this.passedElement = new WrappedInput({ + element: passedElement, + classNames: config.classNames, + }); + } + else { + var selectEl = passedElement; + this.passedElement = new WrappedSelect({ + element: selectEl, + classNames: config.classNames, + template: function (data) { return _this._templates.option(data); }, + extractPlaceholder: config.placeholder && !this._hasNonChoicePlaceholder, + }); + } + this.initialised = false; + this._store = new Store(config); + this._currentValue = ''; + config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple; + this._canSearch = config.searchEnabled; + this._isScrollingOnIe = false; + this._highlightPosition = 0; + this._wasTap = true; + this._placeholderValue = this._generatePlaceholderValue(); + this._baseId = generateId(passedElement, 'choices-'); + /** + * setting direction in cases where it's explicitly set on passedElement + * or when calculated direction is different from the document + */ + this._direction = passedElement.dir; + if (!this._direction) { + var elementDirection = window.getComputedStyle(passedElement).direction; + var documentDirection = window.getComputedStyle(document.documentElement).direction; + if (elementDirection !== documentDirection) { + this._direction = elementDirection; + } + } + this._idNames = { + itemChoice: 'item-choice', + }; + this._templates = defaults.templates; + this._render = this._render.bind(this); + this._onFocus = this._onFocus.bind(this); + this._onBlur = this._onBlur.bind(this); + this._onKeyUp = this._onKeyUp.bind(this); + this._onKeyDown = this._onKeyDown.bind(this); + this._onInput = this._onInput.bind(this); + this._onClick = this._onClick.bind(this); + this._onTouchMove = this._onTouchMove.bind(this); + this._onTouchEnd = this._onTouchEnd.bind(this); + this._onMouseDown = this._onMouseDown.bind(this); + this._onMouseOver = this._onMouseOver.bind(this); + this._onFormReset = this._onFormReset.bind(this); + this._onSelectKey = this._onSelectKey.bind(this); + this._onEnterKey = this._onEnterKey.bind(this); + this._onEscapeKey = this._onEscapeKey.bind(this); + this._onDirectionKey = this._onDirectionKey.bind(this); + this._onDeleteKey = this._onDeleteKey.bind(this); + // If element has already been initialised with Choices, fail silently + if (this.passedElement.isActive) { + if (!config.silent) { + console.warn('Trying to initialise Choices on element already initialised', { element: element }); + } + this.initialised = true; + this.initialisedOK = false; + return; + } + // Let's go + this.init(); + // preserve the selected item list after setup for form reset + this._initialItems = this._store.items.map(function (choice) { return choice.value; }); + } + Object.defineProperty(Choices, "defaults", { + get: function () { + return Object.preventExtensions({ + get options() { + return USER_DEFAULTS; + }, + get allOptions() { + return DEFAULT_CONFIG; + }, + get templates() { + return templates; + }, + }); + }, + enumerable: false, + configurable: true + }); + Choices.prototype.init = function () { + if (this.initialised || this.initialisedOK !== undefined) { + return; + } + this._searcher = getSearcher(this.config); + this._loadChoices(); + this._createTemplates(); + this._createElements(); + this._createStructure(); + if ((this._isTextElement && !this.config.addItems) || + this.passedElement.element.hasAttribute('disabled') || + !!this.passedElement.element.closest('fieldset:disabled')) { + this.disable(); + } + else { + this.enable(); + this._addEventListeners(); + } + // should be triggered **after** disabled state to avoid additional re-draws + this._initStore(); + this.initialised = true; + this.initialisedOK = true; + var callbackOnInit = this.config.callbackOnInit; + // Run callback if it is a function + if (typeof callbackOnInit === 'function') { + callbackOnInit.call(this); + } + }; + Choices.prototype.destroy = function () { + if (!this.initialised) { + return; + } + this._removeEventListeners(); + this.passedElement.reveal(); + this.containerOuter.unwrap(this.passedElement.element); + this._store._listeners = []; // prevents select/input value being wiped + this.clearStore(); + this._stopSearch(); + this._templates = Choices.defaults.templates; + this.initialised = false; + this.initialisedOK = undefined; + }; + Choices.prototype.enable = function () { + if (this.passedElement.isDisabled) { + this.passedElement.enable(); + } + if (this.containerOuter.isDisabled) { + this._addEventListeners(); + this.input.enable(); + this.containerOuter.enable(); + } + return this; + }; + Choices.prototype.disable = function () { + if (!this.passedElement.isDisabled) { + this.passedElement.disable(); + } + if (!this.containerOuter.isDisabled) { + this._removeEventListeners(); + this.input.disable(); + this.containerOuter.disable(); + } + return this; + }; + Choices.prototype.highlightItem = function (item, runEvent) { + if (runEvent === void 0) { runEvent = true; } + if (!item || !item.id) { + return this; + } + var choice = this._store.items.find(function (c) { return c.id === item.id; }); + if (!choice || choice.highlighted) { + return this; + } + this._store.dispatch(highlightItem(choice, true)); + if (runEvent) { + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice)); + } + return this; + }; + Choices.prototype.unhighlightItem = function (item, runEvent) { + if (runEvent === void 0) { runEvent = true; } + if (!item || !item.id) { + return this; + } + var choice = this._store.items.find(function (c) { return c.id === item.id; }); + if (!choice || !choice.highlighted) { + return this; + } + this._store.dispatch(highlightItem(choice, false)); + if (runEvent) { + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice)); + } + return this; + }; + Choices.prototype.highlightAll = function () { + var _this = this; + this._store.withTxn(function () { + _this._store.items.forEach(function (item) { + if (!item.highlighted) { + _this._store.dispatch(highlightItem(item, true)); + _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item)); + } + }); + }); + return this; + }; + Choices.prototype.unhighlightAll = function () { + var _this = this; + this._store.withTxn(function () { + _this._store.items.forEach(function (item) { + if (item.highlighted) { + _this._store.dispatch(highlightItem(item, false)); + _this.passedElement.triggerEvent(EventType.highlightItem, _this._getChoiceForOutput(item)); + } + }); + }); + return this; + }; + Choices.prototype.removeActiveItemsByValue = function (value) { + var _this = this; + this._store.withTxn(function () { + _this._store.items.filter(function (item) { return item.value === value; }).forEach(function (item) { return _this._removeItem(item); }); + }); + return this; + }; + Choices.prototype.removeActiveItems = function (excludedId) { + var _this = this; + this._store.withTxn(function () { + _this._store.items.filter(function (_a) { + var id = _a.id; + return id !== excludedId; + }).forEach(function (item) { return _this._removeItem(item); }); + }); + return this; + }; + Choices.prototype.removeHighlightedItems = function (runEvent) { + var _this = this; + if (runEvent === void 0) { runEvent = false; } + this._store.withTxn(function () { + _this._store.highlightedActiveItems.forEach(function (item) { + _this._removeItem(item); + // If this action was performed by the user + // trigger the event + if (runEvent) { + _this._triggerChange(item.value); + } + }); + }); + return this; + }; + Choices.prototype.showDropdown = function (preventInputFocus) { + var _this = this; + if (this.dropdown.isActive) { + return this; + } + requestAnimationFrame(function () { + _this.dropdown.show(); + var rect = _this.dropdown.element.getBoundingClientRect(); + _this.containerOuter.open(rect.bottom, rect.height); + if (!preventInputFocus && _this._canSearch) { + _this.input.focus(); + } + _this.passedElement.triggerEvent(EventType.showDropdown); + }); + return this; + }; + Choices.prototype.hideDropdown = function (preventInputBlur) { + var _this = this; + if (!this.dropdown.isActive) { + return this; + } + requestAnimationFrame(function () { + _this.dropdown.hide(); + _this.containerOuter.close(); + if (!preventInputBlur && _this._canSearch) { + _this.input.removeActiveDescendant(); + _this.input.blur(); + } + _this.passedElement.triggerEvent(EventType.hideDropdown); + }); + return this; + }; + Choices.prototype.getValue = function (valueOnly) { + var _this = this; + if (valueOnly === void 0) { valueOnly = false; } + var values = this._store.items.reduce(function (selectedItems, item) { + var itemValue = valueOnly ? item.value : _this._getChoiceForOutput(item); + selectedItems.push(itemValue); + return selectedItems; + }, []); + return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values; + }; + Choices.prototype.setValue = function (items) { + var _this = this; + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setValue'); + return this; + } + this._store.withTxn(function () { + items.forEach(function (value) { + if (value) { + _this._addChoice(mapInputToChoice(value, false)); + } + }); + }); + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + Choices.prototype.setChoiceByValue = function (value) { + var _this = this; + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setChoiceByValue'); + return this; + } + if (this._isTextElement) { + return this; + } + this._store.withTxn(function () { + // If only one value has been passed, convert to array + var choiceValue = Array.isArray(value) ? value : [value]; + // Loop through each value and + choiceValue.forEach(function (val) { return _this._findAndSelectChoiceByValue(val); }); + _this.unhighlightAll(); + }); + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + /** + * Set choices of select input via an array of objects (or function that returns array of object or promise of it), + * a value field name and a label field name. + * This behaves the same as passing items via the choices option but can be called after initialising Choices. + * This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices. + * Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc). + * + * **Input types affected:** select-one, select-multiple + * + * @example + * ```js + * const example = new Choices(element); + * + * example.setChoices([ + * {value: 'One', label: 'Label One', disabled: true}, + * {value: 'Two', label: 'Label Two', selected: true}, + * {value: 'Three', label: 'Label Three'}, + * ], 'value', 'label', false); + * ``` + * + * @example + * ```js + * const example = new Choices(element); + * + * example.setChoices(async () => { + * try { + * const items = await fetch('/items'); + * return items.json() + * } catch(err) { + * console.error(err) + * } + * }); + * ``` + * + * @example + * ```js + * const example = new Choices(element); + * + * example.setChoices([{ + * label: 'Group one', + * id: 1, + * disabled: false, + * choices: [ + * {value: 'Child One', label: 'Child One', selected: true}, + * {value: 'Child Two', label: 'Child Two', disabled: true}, + * {value: 'Child Three', label: 'Child Three'}, + * ] + * }, + * { + * label: 'Group two', + * id: 2, + * disabled: false, + * choices: [ + * {value: 'Child Four', label: 'Child Four', disabled: true}, + * {value: 'Child Five', label: 'Child Five'}, + * {value: 'Child Six', label: 'Child Six', customProperties: { + * description: 'Custom description about child six', + * random: 'Another random custom property' + * }}, + * ] + * }], 'value', 'label', false); + * ``` + */ + Choices.prototype.setChoices = function (choicesArrayOrFetcher, value, label, replaceChoices) { + var _this = this; + if (choicesArrayOrFetcher === void 0) { choicesArrayOrFetcher = []; } + if (value === void 0) { value = 'value'; } + if (label === void 0) { label = 'label'; } + if (replaceChoices === void 0) { replaceChoices = false; } + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setChoices'); + return this; + } + if (!this._isSelectElement) { + throw new TypeError("setChoices can't be used with INPUT based Choices"); + } + if (typeof value !== 'string' || !value) { + throw new TypeError("value parameter must be a name of 'value' field in passed objects"); + } + // Clear choices if needed + if (replaceChoices) { + this.clearChoices(); + } + if (typeof choicesArrayOrFetcher === 'function') { + // it's a choices fetcher function + var fetcher_1 = choicesArrayOrFetcher(this); + if (typeof Promise === 'function' && fetcher_1 instanceof Promise) { + // that's a promise + // eslint-disable-next-line no-promise-executor-return + return new Promise(function (resolve) { return requestAnimationFrame(resolve); }) + .then(function () { return _this._handleLoadingState(true); }) + .then(function () { return fetcher_1; }) + .then(function (data) { return _this.setChoices(data, value, label, replaceChoices); }) + .catch(function (err) { + if (!_this.config.silent) { + console.error(err); + } + }) + .then(function () { return _this._handleLoadingState(false); }) + .then(function () { return _this; }); + } + // function returned something else than promise, let's check if it's an array of choices + if (!Array.isArray(fetcher_1)) { + throw new TypeError(".setChoices first argument function must return either array of choices or Promise, got: ".concat(typeof fetcher_1)); + } + // recursion with results, it's sync and choices were cleared already + return this.setChoices(fetcher_1, value, label, false); + } + if (!Array.isArray(choicesArrayOrFetcher)) { + throw new TypeError(".setChoices must be called either with array of choices with a function resulting into Promise of array of choices"); + } + this.containerOuter.removeLoadingState(); + this._store.withTxn(function () { + var isDefaultValue = value === 'value'; + var isDefaultLabel = label === 'label'; + choicesArrayOrFetcher.forEach(function (groupOrChoice) { + if ('choices' in groupOrChoice) { + var group = groupOrChoice; + if (!isDefaultLabel) { + group = __assign(__assign({}, group), { label: group[label] }); + } + _this._addGroup(mapInputToChoice(group, true)); + } + else { + var choice = groupOrChoice; + if (!isDefaultLabel || !isDefaultValue) { + choice = __assign(__assign({}, choice), { value: choice[value], label: choice[label] }); + } + _this._addChoice(mapInputToChoice(choice, false)); + } + }); + _this.unhighlightAll(); + }); + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + Choices.prototype.refresh = function (withEvents, selectFirstOption, deselectAll) { + var _this = this; + if (withEvents === void 0) { withEvents = false; } + if (selectFirstOption === void 0) { selectFirstOption = false; } + if (deselectAll === void 0) { deselectAll = false; } + if (!this._isSelectElement) { + if (!this.config.silent) { + console.warn('refresh method can only be used on choices backed by a element'); + } + return this; + } + this._store.withTxn(function () { + var choicesFromOptions = _this.passedElement.optionsAsChoices(); + // Build the list of items which require preserving + var existingItems = {}; + if (!deselectAll) { + _this._store.items.forEach(function (choice) { + if (choice.id && choice.active && choice.selected && !choice.disabled) { + existingItems[choice.value] = true; + } + }); + } + _this.clearStore(); + choicesFromOptions.forEach(function (groupOrChoice) { + if ('choices' in groupOrChoice) { + return; + } + var choice = groupOrChoice; + if (deselectAll) { + _this._store.dispatch(removeItem$1(choice)); + } + else if (existingItems[choice.value]) { + choice.selected = true; + } + }); + /* @todo only generate add events for the added options instead of all + if (withEvents) { + items.forEach((choice) => { + if (existingItems[choice.value]) { + this.passedElement.triggerEvent( + EventType.removeItem, + this._getChoiceForEvent(choice), + ); + } + }); + } + */ + // load new choices & items + _this._addPredefinedChoices(choicesFromOptions, selectFirstOption, withEvents); + // re-do search if required + if (_this._isSearching) { + _this._searchChoices(_this.input.value); + } + }); + return this; + }; + Choices.prototype.removeChoice = function (value) { + var choice = this._store.choices.find(function (c) { return c.value === value; }); + if (!choice) { + return this; + } + this._store.dispatch(removeChoice(choice)); + // @todo integrate with Store + this._searcher.reset(); + if (choice.selected) { + this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(choice)); + } + return this; + }; + Choices.prototype.clearChoices = function () { + this.passedElement.element.replaceChildren(''); + return this.clearStore(); + }; + Choices.prototype.clearStore = function () { + this.itemList.element.replaceChildren(''); + this.choiceList.element.replaceChildren(''); + this._clearNotice(); + this._store.reset(); + this._lastAddedChoiceId = 0; + this._lastAddedGroupId = 0; + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + Choices.prototype.clearInput = function () { + var shouldSetInputWidth = !this._isSelectOneElement; + this.input.clear(shouldSetInputWidth); + this._clearNotice(); + if (this._isSearching) { + this._stopSearch(); + } + return this; + }; + Choices.prototype._validateConfig = function () { + var config = this.config; + var invalidConfigOptions = diff(config, DEFAULT_CONFIG); + if (invalidConfigOptions.length) { + console.warn('Unknown config option(s) passed', invalidConfigOptions.join(', ')); + } + if (config.allowHTML && config.allowHtmlUserInput) { + if (config.addItems) { + console.warn('Warning: allowHTML/allowHtmlUserInput/addItems all being true is strongly not recommended and may lead to XSS attacks'); + } + if (config.addChoices) { + console.warn('Warning: allowHTML/allowHtmlUserInput/addChoices all being true is strongly not recommended and may lead to XSS attacks'); + } + } + }; + Choices.prototype._render = function (changes) { + if (changes === void 0) { changes = { choices: true, groups: true, items: true }; } + if (this._store.inTxn()) { + return; + } + if (this._isSelectElement) { + if (changes.choices || changes.groups) { + this._renderChoices(); + } + } + if (changes.items) { + this._renderItems(); + } + }; + Choices.prototype._renderChoices = function () { + var _this = this; + if (!this._canAddItems()) { + return; // block rendering choices if the input limit is reached. + } + var _a = this, config = _a.config, isSearching = _a._isSearching; + var _b = this._store, activeGroups = _b.activeGroups, activeChoices = _b.activeChoices; + var renderLimit = 0; + if (isSearching && config.searchResultLimit > 0) { + renderLimit = config.searchResultLimit; + } + else if (config.renderChoiceLimit > 0) { + renderLimit = config.renderChoiceLimit; + } + if (this._isSelectElement) { + var backingOptions = activeChoices.filter(function (choice) { return !choice.element; }); + if (backingOptions.length) { + this.passedElement.addOptions(backingOptions); + } + } + var fragment = document.createDocumentFragment(); + var renderableChoices = function (choices) { + return choices.filter(function (choice) { + return !choice.placeholder && (isSearching ? !!choice.rank : config.renderSelectedChoices || !choice.selected); + }); + }; + var selectableChoices = this._isSelectOneElement; + var renderChoices = function (choices, withinGroup, groupLabel) { + if (isSearching) { + // sortByRank is used to ensure stable sorting, as scores are non-unique + // this additionally ensures fuseOptions.sortFn is not ignored + choices.sort(sortByRank); + } + else if (config.shouldSort) { + choices.sort(config.sorter); + } + var choiceLimit = choices.length; + choiceLimit = !withinGroup && renderLimit && choiceLimit > renderLimit ? renderLimit : choiceLimit; + choiceLimit--; + choices.every(function (choice, index) { + // choiceEl being empty signals the contents has probably significantly changed + var dropdownItem = choice.choiceEl || _this._templates.choice(config, choice, config.itemSelectText, groupLabel); + choice.choiceEl = dropdownItem; + fragment.appendChild(dropdownItem); + if (isSearching || !choice.selected) { + selectableChoices = true; + } + return index < choiceLimit; + }); + }; + if (activeChoices.length) { + if (config.resetScrollPosition) { + requestAnimationFrame(function () { return _this.choiceList.scrollToTop(); }); + } + if (!this._hasNonChoicePlaceholder && !isSearching && this._isSelectOneElement) { + // If we have a placeholder choice along with groups + renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.groupId; }), false, undefined); + } + // If we have grouped options + if (activeGroups.length && !isSearching) { + if (config.shouldSort) { + activeGroups.sort(config.sorter); + } + activeGroups.forEach(function (group) { + var groupChoices = renderableChoices(group.choices); + if (groupChoices.length) { + if (group.label) { + var dropdownGroup = group.groupEl || _this._templates.choiceGroup(_this.config, group); + group.groupEl = dropdownGroup; + dropdownGroup.remove(); + fragment.appendChild(dropdownGroup); + } + renderChoices(groupChoices, true, config.appendGroupInSearch && isSearching ? group.label : undefined); + } + }); + } + else { + renderChoices(renderableChoices(activeChoices), false, undefined); + } + } + var notice = this._notice; + if (!selectableChoices) { + if (!notice) { + this._notice = { + text: resolveStringFunction(config.noChoicesText), + type: NoticeTypes.noChoices, + }; + } + fragment.replaceChildren(''); + } + else if (notice && notice.type === NoticeTypes.noChoices) { + this._notice = undefined; + } + this._renderNotice(fragment); + this.choiceList.element.replaceChildren(fragment); + if (selectableChoices) { + this._highlightChoice(); + } + }; + Choices.prototype._renderItems = function () { + var _this = this; + var items = this._store.items || []; + var itemList = this.itemList.element; + var config = this.config; + var fragment = document.createDocumentFragment(); + var itemFromList = function (item) { + return itemList.querySelector("[data-item][data-id=\"".concat(item.id, "\"]")); + }; + var addItemToFragment = function (item) { + var el = item.itemEl; + if (el && el.parentElement) { + return; + } + el = itemFromList(item) || _this._templates.item(config, item, config.removeItemButton); + item.itemEl = el; + fragment.appendChild(el); + }; + // new items + items.forEach(addItemToFragment); + var addItems = !!fragment.childNodes.length; + if (this._isSelectOneElement && this._hasNonChoicePlaceholder) { + var existingItems = itemList.children.length; + if (addItems || existingItems > 1) { + var placeholder = itemList.querySelector(getClassNamesSelector(config.classNames.placeholder)); + if (placeholder) { + placeholder.remove(); + } + } + else if (!existingItems) { + addItems = true; + addItemToFragment(mapInputToChoice({ + selected: true, + value: '', + label: config.placeholderValue || '', + placeholder: true, + }, false)); + } + } + if (addItems) { + itemList.append(fragment); + if (config.shouldSortItems && !this._isSelectOneElement) { + items.sort(config.sorter); + // push sorting into the DOM + items.forEach(function (item) { + var el = itemFromList(item); + if (el) { + el.remove(); + fragment.append(el); + } + }); + itemList.append(fragment); + } + } + if (this._isTextElement) { + // Update the value of the hidden input + this.passedElement.value = items.map(function (_a) { + var value = _a.value; + return value; + }).join(config.delimiter); + } + }; + Choices.prototype._displayNotice = function (text, type, openDropdown) { + if (openDropdown === void 0) { openDropdown = true; } + var oldNotice = this._notice; + if (oldNotice && + ((oldNotice.type === type && oldNotice.text === text) || + (oldNotice.type === NoticeTypes.addChoice && + (type === NoticeTypes.noResults || type === NoticeTypes.noChoices)))) { + if (openDropdown) { + this.showDropdown(true); + } + return; + } + this._clearNotice(); + this._notice = text + ? { + text: text, + type: type, + } + : undefined; + this._renderNotice(); + if (openDropdown && text) { + this.showDropdown(true); + } + }; + Choices.prototype._clearNotice = function () { + if (!this._notice) { + return; + } + var noticeElement = this.choiceList.element.querySelector(getClassNamesSelector(this.config.classNames.notice)); + if (noticeElement) { + noticeElement.remove(); + } + this._notice = undefined; + }; + Choices.prototype._renderNotice = function (fragment) { + var noticeConf = this._notice; + if (noticeConf) { + var notice = this._templates.notice(this.config, noticeConf.text, noticeConf.type); + if (fragment) { + fragment.append(notice); + } + else { + this.choiceList.prepend(notice); + } + } + }; + Choices.prototype._getChoiceForOutput = function (choice, keyCode) { + if (!choice) { + return undefined; + } + var group = choice.groupId ? this._store.getGroupById(choice.groupId) : null; + return { + id: choice.id, + highlighted: choice.highlighted, + labelClass: choice.labelClass, + labelDescription: choice.labelDescription, + customProperties: choice.customProperties, + disabled: choice.disabled, + active: choice.active, + label: choice.label, + placeholder: choice.placeholder, + value: choice.value, + groupValue: group && group.label ? group.label : undefined, + element: choice.element, + keyCode: keyCode, + }; + }; + Choices.prototype._triggerChange = function (value) { + if (value === undefined || value === null) { + return; + } + this.passedElement.triggerEvent(EventType.change, { + value: value, + }); + }; + Choices.prototype._handleButtonAction = function (element) { + var _this = this; + var items = this._store.items; + if (!items.length || !this.config.removeItems || !this.config.removeItemButton) { + return; + } + var id = element && parseDataSetId(element.parentNode); + var itemToRemove = id && items.find(function (item) { return item.id === id; }); + if (!itemToRemove) { + return; + } + this._store.withTxn(function () { + // Remove item associated with button + _this._removeItem(itemToRemove); + _this._triggerChange(itemToRemove.value); + if (_this._isSelectOneElement && !_this._hasNonChoicePlaceholder) { + var placeholderChoice = _this._store.choices + .reverse() + .find(function (choice) { return !choice.disabled && choice.placeholder; }); + if (placeholderChoice) { + _this._addItem(placeholderChoice); + _this.unhighlightAll(); + if (placeholderChoice.value) { + _this._triggerChange(placeholderChoice.value); + } + } + } + }); + }; + Choices.prototype._handleItemAction = function (element, hasShiftKey) { + var _this = this; + if (hasShiftKey === void 0) { hasShiftKey = false; } + var items = this._store.items; + if (!items.length || !this.config.removeItems || this._isSelectOneElement) { + return; + } + var id = parseDataSetId(element); + if (!id) { + return; + } + // We only want to select one item with a click + // so we deselect any items that aren't the target + // unless shift is being pressed + items.forEach(function (item) { + if (item.id === id && !item.highlighted) { + _this.highlightItem(item); + } + else if (!hasShiftKey && item.highlighted) { + _this.unhighlightItem(item); + } + }); + // Focus input as without focus, a user cannot do anything with a + // highlighted item + this.input.focus(); + }; + Choices.prototype._handleChoiceAction = function (element) { + var _this = this; + // If we are clicking on an option + var id = parseDataSetId(element); + var choice = id && this._store.getChoiceById(id); + if (!choice || choice.disabled) { + return false; + } + var hasActiveDropdown = this.dropdown.isActive; + if (!choice.selected) { + if (!this._canAddItems()) { + return true; // causes _onEnterKey to early out + } + this._store.withTxn(function () { + _this._addItem(choice, true, true); + _this.clearInput(); + _this.unhighlightAll(); + }); + this._triggerChange(choice.value); + } + // We want to close the dropdown if we are dealing with a single select box + if (hasActiveDropdown && this.config.closeDropdownOnSelect) { + this.hideDropdown(true); + this.containerOuter.element.focus(); + } + return true; + }; + Choices.prototype._handleBackspace = function (items) { + var config = this.config; + if (!config.removeItems || !items.length) { + return; + } + var lastItem = items[items.length - 1]; + var hasHighlightedItems = items.some(function (item) { return item.highlighted; }); + // If editing the last item is allowed and there are not other selected items, + // we can edit the item value. Otherwise if we can remove items, remove all selected items + if (config.editItems && !hasHighlightedItems && lastItem) { + this.input.value = lastItem.value; + this.input.setWidth(); + this._removeItem(lastItem); + this._triggerChange(lastItem.value); + } + else { + if (!hasHighlightedItems) { + // Highlight last item if none already highlighted + this.highlightItem(lastItem, false); + } + this.removeHighlightedItems(true); + } + }; + Choices.prototype._loadChoices = function () { + var _a; + var config = this.config; + if (this._isTextElement) { + // Assign preset items from passed object first + this._presetChoices = config.items.map(function (e) { return mapInputToChoice(e, false); }); + // Add any values passed from attribute + if (this.passedElement.value) { + var elementItems = this.passedElement.value + .split(config.delimiter) + .map(function (e) { return mapInputToChoice(e, false); }); + this._presetChoices = this._presetChoices.concat(elementItems); + } + this._presetChoices.forEach(function (choice) { + choice.selected = true; + }); + } + else if (this._isSelectElement) { + // Assign preset choices from passed object + this._presetChoices = config.choices.map(function (e) { return mapInputToChoice(e, true); }); + // Create array of choices from option elements + var choicesFromOptions = this.passedElement.optionsAsChoices(); + if (choicesFromOptions) { + (_a = this._presetChoices).push.apply(_a, choicesFromOptions); + } + } + }; + Choices.prototype._handleLoadingState = function (setLoading) { + if (setLoading === void 0) { setLoading = true; } + var el = this.itemList.element; + if (setLoading) { + this.disable(); + this.containerOuter.addLoadingState(); + if (this._isSelectOneElement) { + el.replaceChildren(this._templates.placeholder(this.config, this.config.loadingText)); + } + else { + this.input.placeholder = this.config.loadingText; + } + } + else { + this.enable(); + this.containerOuter.removeLoadingState(); + if (this._isSelectOneElement) { + el.replaceChildren(''); + this._render(); + } + else { + this.input.placeholder = this._placeholderValue || ''; + } + } + }; + Choices.prototype._handleSearch = function (value) { + if (!this.input.isFocussed) { + return; + } + // Check that we have a value to search and the input was an alphanumeric character + if (value !== null && typeof value !== 'undefined' && value.length >= this.config.searchFloor) { + var resultCount = this.config.searchChoices ? this._searchChoices(value) : 0; + if (resultCount !== null) { + // Trigger search event + this.passedElement.triggerEvent(EventType.search, { + value: value, + resultCount: resultCount, + }); + } + } + else if (this._store.choices.some(function (option) { return !option.active; })) { + this._stopSearch(); + } + }; + Choices.prototype._canAddItems = function () { + var config = this.config; + var maxItemCount = config.maxItemCount, maxItemText = config.maxItemText; + if (!config.singleModeForMultiSelect && maxItemCount > 0 && maxItemCount <= this._store.items.length) { + this.choiceList.element.replaceChildren(''); + this._displayNotice(typeof maxItemText === 'function' ? maxItemText(maxItemCount) : maxItemText, NoticeTypes.addChoice); + return false; + } + return true; + }; + Choices.prototype._canCreateItem = function (value) { + var config = this.config; + var canAddItem = true; + var notice = ''; + if (canAddItem && typeof config.addItemFilter === 'function' && !config.addItemFilter(value)) { + canAddItem = false; + notice = resolveNoticeFunction(config.customAddItemText, value); + } + if (canAddItem) { + var foundChoice = this._store.choices.find(function (choice) { return config.valueComparer(choice.value, value); }); + if (this._isSelectElement) { + // for exact matches, do not prompt to add it as a custom choice + if (foundChoice) { + this._displayNotice('', NoticeTypes.addChoice); + return false; + } + } + else if (this._isTextElement && !config.duplicateItemsAllowed) { + if (foundChoice) { + canAddItem = false; + notice = resolveNoticeFunction(config.uniqueItemText, value); + } + } + } + if (canAddItem) { + notice = resolveNoticeFunction(config.addItemText, value); + } + if (notice) { + this._displayNotice(notice, NoticeTypes.addChoice); + } + return canAddItem; + }; + Choices.prototype._searchChoices = function (value) { + var newValue = value.trim().replace(/\s{2,}/, ' '); + // signal input didn't change search + if (!newValue.length || newValue === this._currentValue) { + return null; + } + var searcher = this._searcher; + if (searcher.isEmptyIndex()) { + searcher.index(this._store.searchableChoices); + } + // If new value matches the desired length and is not the same as the current value with a space + var results = searcher.search(newValue); + this._currentValue = newValue; + this._highlightPosition = 0; + this._isSearching = true; + var notice = this._notice; + var noticeType = notice && notice.type; + if (noticeType !== NoticeTypes.addChoice) { + if (!results.length) { + this._displayNotice(resolveStringFunction(this.config.noResultsText), NoticeTypes.noResults); + } + else if (noticeType === NoticeTypes.noResults) { + this._clearNotice(); + } + } + this._store.dispatch(filterChoices(results)); + return results.length; + }; + Choices.prototype._stopSearch = function () { + var wasSearching = this._isSearching; + this._currentValue = ''; + this._isSearching = false; + if (wasSearching) { + this._store.dispatch(activateChoices(true)); + this.passedElement.triggerEvent(EventType.search, { + value: '', + resultCount: 0, + }); + } + }; + Choices.prototype._addEventListeners = function () { + var documentElement = this._docRoot; + var outerElement = this.containerOuter.element; + var inputElement = this.input.element; + // capture events - can cancel event processing or propagation + documentElement.addEventListener('touchend', this._onTouchEnd, true); + outerElement.addEventListener('keydown', this._onKeyDown, true); + outerElement.addEventListener('mousedown', this._onMouseDown, true); + // passive events - doesn't call `preventDefault` or `stopPropagation` + documentElement.addEventListener('click', this._onClick, { passive: true }); + documentElement.addEventListener('touchmove', this._onTouchMove, { + passive: true, + }); + this.dropdown.element.addEventListener('mouseover', this._onMouseOver, { + passive: true, + }); + if (this._isSelectOneElement) { + outerElement.addEventListener('focus', this._onFocus, { + passive: true, + }); + outerElement.addEventListener('blur', this._onBlur, { + passive: true, + }); + } + inputElement.addEventListener('keyup', this._onKeyUp, { + passive: true, + }); + inputElement.addEventListener('input', this._onInput, { + passive: true, + }); + inputElement.addEventListener('focus', this._onFocus, { + passive: true, + }); + inputElement.addEventListener('blur', this._onBlur, { + passive: true, + }); + if (inputElement.form) { + inputElement.form.addEventListener('reset', this._onFormReset, { + passive: true, + }); + } + this.input.addEventListeners(); + }; + Choices.prototype._removeEventListeners = function () { + var documentElement = this._docRoot; + var outerElement = this.containerOuter.element; + var inputElement = this.input.element; + documentElement.removeEventListener('touchend', this._onTouchEnd, true); + outerElement.removeEventListener('keydown', this._onKeyDown, true); + outerElement.removeEventListener('mousedown', this._onMouseDown, true); + documentElement.removeEventListener('click', this._onClick); + documentElement.removeEventListener('touchmove', this._onTouchMove); + this.dropdown.element.removeEventListener('mouseover', this._onMouseOver); + if (this._isSelectOneElement) { + outerElement.removeEventListener('focus', this._onFocus); + outerElement.removeEventListener('blur', this._onBlur); + } + inputElement.removeEventListener('keyup', this._onKeyUp); + inputElement.removeEventListener('input', this._onInput); + inputElement.removeEventListener('focus', this._onFocus); + inputElement.removeEventListener('blur', this._onBlur); + if (inputElement.form) { + inputElement.form.removeEventListener('reset', this._onFormReset); + } + this.input.removeEventListeners(); + }; + Choices.prototype._onKeyDown = function (event) { + var keyCode = event.keyCode; + var hasActiveDropdown = this.dropdown.isActive; + /* + See: + https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key + https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values + https://en.wikipedia.org/wiki/UTF-16#Code_points_from_U+010000_to_U+10FFFF - UTF-16 surrogate pairs + https://stackoverflow.com/a/70866532 - "Unidentified" for mobile + http://www.unicode.org/versions/Unicode5.2.0/ch16.pdf#G19635 - U+FFFF is reserved (Section 16.7) + + Logic: when a key event is sent, `event.key` represents its printable value _or_ one + of a large list of special values indicating meta keys/functionality. In addition, + key events for compose functionality contain a value of `Dead` when mid-composition. + + I can't quite verify it, but non-English IMEs may also be able to generate key codes + for code points in the surrogate-pair range, which could potentially be seen as having + key.length > 1. Since `Fn` is one of the special keys, we can't distinguish by that + alone. + + Here, key.length === 1 means we know for sure the input was printable and not a special + `key` value. When the length is greater than 1, it could be either a printable surrogate + pair or a special `key` value. We can tell the difference by checking if the _character + code_ value (not code point!) is in the "surrogate pair" range or not. + + We don't use .codePointAt because an invalid code point would return 65535, which wouldn't + pass the >= 0x10000 check we would otherwise use. + + > ...The Unicode Standard sets aside 66 noncharacter code points. The last two code points + > of each plane are noncharacters: U+FFFE and U+FFFF on the BMP... + */ + var wasPrintableChar = event.key.length === 1 || + (event.key.length === 2 && event.key.charCodeAt(0) >= 0xd800) || + event.key === 'Unidentified'; + if (!this._isTextElement && !hasActiveDropdown) { + this.showDropdown(); + if (!this.input.isFocussed && wasPrintableChar) { + /* + We update the input value with the pressed key as + the input was not focussed at the time of key press + therefore does not have the value of the key. + */ + this.input.value += event.key; + // browsers interpret a space as pagedown + if (event.key === ' ') { + event.preventDefault(); + } + } + } + switch (keyCode) { + case 65 /* KeyCodeMap.A_KEY */: + return this._onSelectKey(event, this.itemList.element.hasChildNodes()); + case 13 /* KeyCodeMap.ENTER_KEY */: + return this._onEnterKey(event, hasActiveDropdown); + case 27 /* KeyCodeMap.ESC_KEY */: + return this._onEscapeKey(event, hasActiveDropdown); + case 38 /* KeyCodeMap.UP_KEY */: + case 33 /* KeyCodeMap.PAGE_UP_KEY */: + case 40 /* KeyCodeMap.DOWN_KEY */: + case 34 /* KeyCodeMap.PAGE_DOWN_KEY */: + return this._onDirectionKey(event, hasActiveDropdown); + case 8 /* KeyCodeMap.DELETE_KEY */: + case 46 /* KeyCodeMap.BACK_KEY */: + return this._onDeleteKey(event, this._store.items, this.input.isFocussed); + } + }; + Choices.prototype._onKeyUp = function ( /* event: KeyboardEvent */) { + this._canSearch = this.config.searchEnabled; + }; + Choices.prototype._onInput = function ( /* event: InputEvent */) { + var value = this.input.value; + if (!value) { + if (this._isTextElement) { + this.hideDropdown(true); + } + else { + this._stopSearch(); + } + this._clearNotice(); + return; + } + if (!this._canAddItems()) { + return; + } + if (this._canSearch) { + // do the search even if the entered text can not be added + this._handleSearch(value); + } + if (!this._canAddUserChoices) { + return; + } + // determine if a notice needs to be displayed for why a search result can't be added + this._canCreateItem(value); + if (this._isSelectElement) { + this._highlightPosition = 0; // reset to select the notice and/or exact match + this._highlightChoice(); + } + }; + Choices.prototype._onSelectKey = function (event, hasItems) { + // If CTRL + A or CMD + A have been pressed and there are items to select + if ((event.ctrlKey || event.metaKey) && hasItems) { + this._canSearch = false; + var shouldHightlightAll = this.config.removeItems && !this.input.value && this.input.element === document.activeElement; + if (shouldHightlightAll) { + this.highlightAll(); + } + } + }; + Choices.prototype._onEnterKey = function (event, hasActiveDropdown) { + var _this = this; + var value = this.input.value; + var target = event.target; + event.preventDefault(); + if (target && target.hasAttribute('data-button')) { + this._handleButtonAction(target); + return; + } + if (!hasActiveDropdown) { + if (this._isSelectElement || this._notice) { + this.showDropdown(); + } + return; + } + var highlightedChoice = this.dropdown.element.querySelector(getClassNamesSelector(this.config.classNames.highlightedState)); + if (highlightedChoice && this._handleChoiceAction(highlightedChoice)) { + return; + } + if (!target || !value) { + this.hideDropdown(true); + return; + } + if (!this._canAddItems()) { + return; + } + var addedItem = false; + this._store.withTxn(function () { + addedItem = _this._findAndSelectChoiceByValue(value, true); + if (!addedItem) { + if (!_this._canAddUserChoices) { + return; + } + if (!_this._canCreateItem(value)) { + return; + } + var sanitisedValue = sanitise(value); + var userValue = _this.config.allowHtmlUserInput || sanitisedValue === value ? value : { escaped: sanitisedValue, raw: value }; + _this._addChoice(mapInputToChoice({ + value: userValue, + label: userValue, + selected: true, + }, false), true, true); + addedItem = true; + } + _this.clearInput(); + _this.unhighlightAll(); + }); + if (!addedItem) { + return; + } + this._triggerChange(value); + if (this.config.closeDropdownOnSelect) { + this.hideDropdown(true); + } + }; + Choices.prototype._onEscapeKey = function (event, hasActiveDropdown) { + if (hasActiveDropdown) { + event.stopPropagation(); + this.hideDropdown(true); + this.containerOuter.element.focus(); + } + }; + Choices.prototype._onDirectionKey = function (event, hasActiveDropdown) { + var keyCode = event.keyCode; + // If up or down key is pressed, traverse through options + if (hasActiveDropdown || this._isSelectOneElement) { + this.showDropdown(); + this._canSearch = false; + var directionInt = keyCode === 40 /* KeyCodeMap.DOWN_KEY */ || keyCode === 34 /* KeyCodeMap.PAGE_DOWN_KEY */ ? 1 : -1; + var skipKey = event.metaKey || keyCode === 34 /* KeyCodeMap.PAGE_DOWN_KEY */ || keyCode === 33 /* KeyCodeMap.PAGE_UP_KEY */; + var nextEl = void 0; + if (skipKey) { + if (directionInt > 0) { + nextEl = this.dropdown.element.querySelector("".concat(selectableChoiceIdentifier, ":last-of-type")); + } + else { + nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); + } + } + else { + var currentEl = this.dropdown.element.querySelector(getClassNamesSelector(this.config.classNames.highlightedState)); + if (currentEl) { + nextEl = getAdjacentEl(currentEl, selectableChoiceIdentifier, directionInt); + } + else { + nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); + } + } + if (nextEl) { + // We prevent default to stop the cursor moving + // when pressing the arrow + if (!isScrolledIntoView(nextEl, this.choiceList.element, directionInt)) { + this.choiceList.scrollToChildElement(nextEl, directionInt); + } + this._highlightChoice(nextEl); + } + // Prevent default to maintain cursor position whilst + // traversing dropdown options + event.preventDefault(); + } + }; + Choices.prototype._onDeleteKey = function (event, items, hasFocusedInput) { + // If backspace or delete key is pressed and the input has no value + if (!this._isSelectOneElement && !event.target.value && hasFocusedInput) { + this._handleBackspace(items); + event.preventDefault(); + } + }; + Choices.prototype._onTouchMove = function () { + if (this._wasTap) { + this._wasTap = false; + } + }; + Choices.prototype._onTouchEnd = function (event) { + var target = (event || event.touches[0]).target; + var touchWasWithinContainer = this._wasTap && this.containerOuter.element.contains(target); + if (touchWasWithinContainer) { + var containerWasExactTarget = target === this.containerOuter.element || target === this.containerInner.element; + if (containerWasExactTarget) { + if (this._isTextElement) { + this.input.focus(); + } + else if (this._isSelectMultipleElement) { + this.showDropdown(); + } + } + // Prevents focus event firing + event.stopPropagation(); + } + this._wasTap = true; + }; + /** + * Handles mousedown event in capture mode for containetOuter.element + */ + Choices.prototype._onMouseDown = function (event) { + var target = event.target; + if (!(target instanceof HTMLElement)) { + return; + } + // If we have our mouse down on the scrollbar and are on IE11... + if (IS_IE11 && this.choiceList.element.contains(target)) { + // check if click was on a scrollbar area + var firstChoice = this.choiceList.element.firstElementChild; + this._isScrollingOnIe = + this._direction === 'ltr' ? event.offsetX >= firstChoice.offsetWidth : event.offsetX < firstChoice.offsetLeft; + } + if (target === this.input.element) { + return; + } + var item = target.closest('[data-button],[data-item],[data-choice]'); + if (item instanceof HTMLElement) { + if ('button' in item.dataset) { + this._handleButtonAction(item); + } + else if ('item' in item.dataset) { + this._handleItemAction(item, event.shiftKey); + } + else if ('choice' in item.dataset) { + this._handleChoiceAction(item); + } + } + event.preventDefault(); + }; + /** + * Handles mouseover event over this.dropdown + * @param {MouseEvent} event + */ + Choices.prototype._onMouseOver = function (_a) { + var target = _a.target; + if (target instanceof HTMLElement && 'choice' in target.dataset) { + this._highlightChoice(target); + } + }; + Choices.prototype._onClick = function (_a) { + var target = _a.target; + var containerOuter = this.containerOuter; + var clickWasWithinContainer = containerOuter.element.contains(target); + if (clickWasWithinContainer) { + if (!this.dropdown.isActive && !containerOuter.isDisabled) { + if (this._isTextElement) { + if (document.activeElement !== this.input.element) { + this.input.focus(); + } + } + else { + this.showDropdown(); + containerOuter.element.focus(); + } + } + else if (this._isSelectOneElement && + target !== this.input.element && + !this.dropdown.element.contains(target)) { + this.hideDropdown(); + } + } + else { + containerOuter.removeFocusState(); + this.hideDropdown(true); + this.unhighlightAll(); + } + }; + Choices.prototype._onFocus = function (_a) { + var target = _a.target; + var containerOuter = this.containerOuter; + var focusWasWithinContainer = target && containerOuter.element.contains(target); + if (!focusWasWithinContainer) { + return; + } + var targetIsInput = target === this.input.element; + if (this._isTextElement) { + if (targetIsInput) { + containerOuter.addFocusState(); + } + } + else if (this._isSelectMultipleElement) { + if (targetIsInput) { + this.showDropdown(true); + // If element is a select box, the focused element is the container and the dropdown + // isn't already open, focus and show dropdown + containerOuter.addFocusState(); + } + } + else { + containerOuter.addFocusState(); + if (targetIsInput) { + this.showDropdown(true); + } + } + }; + Choices.prototype._onBlur = function (_a) { + var target = _a.target; + var containerOuter = this.containerOuter; + var blurWasWithinContainer = target && containerOuter.element.contains(target); + if (blurWasWithinContainer && !this._isScrollingOnIe) { + var targetIsInput = target === this.input.element; + if (this._isTextElement || this._isSelectMultipleElement) { + if (targetIsInput) { + containerOuter.removeFocusState(); + this.hideDropdown(true); + this.unhighlightAll(); + } + } + else { + containerOuter.removeFocusState(); + if (targetIsInput || (target === containerOuter.element && !this._canSearch)) { + this.hideDropdown(true); + } + } + } + else { + // On IE11, clicking the scollbar blurs our input and thus + // closes the dropdown. To stop this, we refocus our input + // if we know we are on IE *and* are scrolling. + this._isScrollingOnIe = false; + this.input.element.focus(); + } + }; + Choices.prototype._onFormReset = function () { + var _this = this; + this._store.withTxn(function () { + _this.clearInput(); + _this.hideDropdown(); + _this.refresh(false, false, true); + if (_this._initialItems.length) { + _this.setChoiceByValue(_this._initialItems); + } + }); + }; + Choices.prototype._highlightChoice = function (el) { + if (el === void 0) { el = null; } + var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier)); + if (!choices.length) { + return; + } + var passedEl = el; + var highlightedState = this.config.classNames.highlightedState; + var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(getClassNamesSelector(highlightedState))); + // Remove any highlighted choices + highlightedChoices.forEach(function (choice) { + removeClassesFromElement(choice, highlightedState); + choice.setAttribute('aria-selected', 'false'); + }); + if (passedEl) { + this._highlightPosition = choices.indexOf(passedEl); + } + else { + // Highlight choice based on last known highlight location + if (choices.length > this._highlightPosition) { + // If we have an option to highlight + passedEl = choices[this._highlightPosition]; + } + else { + // Otherwise highlight the option before + passedEl = choices[choices.length - 1]; + } + if (!passedEl) { + passedEl = choices[0]; + } + } + addClassesToElement(passedEl, highlightedState); + passedEl.setAttribute('aria-selected', 'true'); + this.passedElement.triggerEvent(EventType.highlightChoice, { + el: passedEl, + }); + if (this.dropdown.isActive) { + // IE11 ignores aria-label and blocks virtual keyboard + // if aria-activedescendant is set without a dropdown + this.input.setActiveDescendant(passedEl.id); + this.containerOuter.setActiveDescendant(passedEl.id); + } + }; + Choices.prototype._addItem = function (item, withEvents, userTriggered) { + if (withEvents === void 0) { withEvents = true; } + if (userTriggered === void 0) { userTriggered = false; } + if (!item.id) { + throw new TypeError('item.id must be set before _addItem is called for a choice/item'); + } + if (this.config.singleModeForMultiSelect || this._isSelectOneElement) { + this.removeActiveItems(item.id); + } + this._store.dispatch(addItem(item)); + if (withEvents) { + this.passedElement.triggerEvent(EventType.addItem, this._getChoiceForOutput(item)); + if (userTriggered) { + this.passedElement.triggerEvent(EventType.choice, this._getChoiceForOutput(item)); + } + } + }; + Choices.prototype._removeItem = function (item) { + if (!item.id) { + return; + } + this._store.dispatch(removeItem$1(item)); + this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(item)); + }; + Choices.prototype._addChoice = function (choice, withEvents, userTriggered) { + if (withEvents === void 0) { withEvents = true; } + if (userTriggered === void 0) { userTriggered = false; } + if (choice.id) { + throw new TypeError('Can not re-add a choice which has already been added'); + } + // Generate unique id, in-place update is required so chaining _addItem works as expected + this._lastAddedChoiceId++; + choice.id = this._lastAddedChoiceId; + choice.elementId = "".concat(this._baseId, "-").concat(this._idNames.itemChoice, "-").concat(choice.id); + var _a = this.config, prependValue = _a.prependValue, appendValue = _a.appendValue; + if (prependValue) { + choice.value = prependValue + choice.value; + } + if (appendValue) { + choice.value += appendValue.toString(); + } + if ((prependValue || appendValue) && choice.element) { + choice.element.value = choice.value; + } + this._store.dispatch(addChoice(choice)); + if (choice.selected) { + this._addItem(choice, withEvents, userTriggered); + } + }; + Choices.prototype._addGroup = function (group, withEvents) { + var _this = this; + if (withEvents === void 0) { withEvents = true; } + if (group.id) { + throw new TypeError('Can not re-add a group which has already been added'); + } + this._store.dispatch(addGroup(group)); + if (!group.choices) { + return; + } + // add unique id for the group(s), and do not store the full list of choices in this group + this._lastAddedGroupId++; + group.id = this._lastAddedGroupId; + group.choices.forEach(function (item) { + item.groupId = group.id; + if (group.disabled) { + item.disabled = true; + } + _this._addChoice(item, withEvents); + }); + }; + Choices.prototype._createTemplates = function () { + var _this = this; + var callbackOnCreateTemplates = this.config.callbackOnCreateTemplates; + var userTemplates = {}; + if (typeof callbackOnCreateTemplates === 'function') { + userTemplates = callbackOnCreateTemplates.call(this, strToEl, escapeForTemplate); + } + var templating = {}; + Object.keys(this._templates).forEach(function (name) { + if (name in userTemplates) { + templating[name] = userTemplates[name].bind(_this); + } + else { + templating[name] = _this._templates[name].bind(_this); + } + }); + this._templates = templating; + }; + Choices.prototype._createElements = function () { + var templating = this._templates; + var _a = this, config = _a.config, isSelectOneElement = _a._isSelectOneElement; + var position = config.position, classNames = config.classNames; + var elementType = this._elementType; + this.containerOuter = new Container({ + element: templating.containerOuter(config, this._direction, this._isSelectElement, isSelectOneElement, config.searchEnabled, elementType, config.labelId), + classNames: classNames, + type: elementType, + position: position, + }); + this.containerInner = new Container({ + element: templating.containerInner(config), + classNames: classNames, + type: elementType, + position: position, + }); + this.input = new Input({ + element: templating.input(config, this._placeholderValue), + classNames: classNames, + type: elementType, + preventPaste: !config.paste, + }); + this.choiceList = new List({ + element: templating.choiceList(config, isSelectOneElement), + }); + this.itemList = new List({ + element: templating.itemList(config, isSelectOneElement), + }); + this.dropdown = new Dropdown({ + element: templating.dropdown(config), + classNames: classNames, + type: elementType, + }); + }; + Choices.prototype._createStructure = function () { + var _a = this, containerInner = _a.containerInner, containerOuter = _a.containerOuter, passedElement = _a.passedElement; + var dropdownElement = this.dropdown.element; + // Hide original element + passedElement.conceal(); + // Wrap input in container preserving DOM ordering + containerInner.wrap(passedElement.element); + // Wrapper inner container with outer container + containerOuter.wrap(containerInner.element); + if (this._isSelectOneElement) { + this.input.placeholder = this.config.searchPlaceholderValue || ''; + } + else { + if (this._placeholderValue) { + this.input.placeholder = this._placeholderValue; + } + this.input.setWidth(); + } + containerOuter.element.appendChild(containerInner.element); + containerOuter.element.appendChild(dropdownElement); + containerInner.element.appendChild(this.itemList.element); + dropdownElement.appendChild(this.choiceList.element); + if (!this._isSelectOneElement) { + containerInner.element.appendChild(this.input.element); + } + else if (this.config.searchEnabled) { + dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild); + } + this._highlightPosition = 0; + this._isSearching = false; + }; + Choices.prototype._initStore = function () { + var _this = this; + this._store.subscribe(this._render); + this._store.withTxn(function () { + _this._addPredefinedChoices(_this._presetChoices, _this._isSelectOneElement && !_this._hasNonChoicePlaceholder, false); + }); + if (this._isSelectOneElement && this._hasNonChoicePlaceholder) { + this._render({ choices: false, groups: false, items: true }); + } + }; + Choices.prototype._addPredefinedChoices = function (choices, selectFirstOption, withEvents) { + var _this = this; + if (selectFirstOption === void 0) { selectFirstOption = false; } + if (withEvents === void 0) { withEvents = true; } + if (selectFirstOption) { + /** + * If there is a selected choice already or the choice is not the first in + * the array, add each choice normally. + * + * Otherwise we pre-select the first enabled choice in the array ("select-one" only) + */ + var noSelectedChoices = choices.findIndex(function (choice) { return choice.selected; }) === -1; + if (noSelectedChoices) { + choices.some(function (choice) { + if (choice.disabled || 'choices' in choice) { + return false; + } + choice.selected = true; + return true; + }); + } + } + choices.forEach(function (item) { + if ('choices' in item) { + if (_this._isSelectElement) { + _this._addGroup(item, withEvents); + } + } + else { + _this._addChoice(item, withEvents); + } + }); + }; + Choices.prototype._findAndSelectChoiceByValue = function (value, userTriggered) { + var _this = this; + if (userTriggered === void 0) { userTriggered = false; } + // Check 'value' property exists and the choice isn't already selected + var foundChoice = this._store.choices.find(function (choice) { return _this.config.valueComparer(choice.value, value); }); + if (foundChoice && !foundChoice.disabled && !foundChoice.selected) { + this._addItem(foundChoice, true, userTriggered); + return true; + } + return false; + }; + Choices.prototype._generatePlaceholderValue = function () { + var config = this.config; + if (!config.placeholder) { + return null; + } + if (this._hasNonChoicePlaceholder) { + return config.placeholderValue; + } + if (this._isSelectElement) { + var placeholderOption = this.passedElement.placeholderOption; + return placeholderOption ? placeholderOption.text : null; + } + return null; + }; + Choices.prototype._warnChoicesInitFailed = function (caller) { + if (this.config.silent) { + return; + } + if (!this.initialised) { + throw new TypeError("".concat(caller, " called on a non-initialised instance of Choices")); + } + else if (!this.initialisedOK) { + throw new TypeError("".concat(caller, " called for an element which has multiple instances of Choices initialised on it")); + } + }; + Choices.version = '11.0.1'; + return Choices; + }()); + + return Choices; + +})); diff --git a/assets/extensions/choices.js/public/assets/scripts/choices.search-prefix.min.js b/assets/extensions/choices.js/public/assets/scripts/choices.search-prefix.min.js new file mode 100644 index 00000000..31dba5c8 --- /dev/null +++ b/assets/extensions/choices.js/public/assets/scripts/choices.search-prefix.min.js @@ -0,0 +1,2 @@ +/*! choices.js v11.0.1 | © 2024 Josh Johnson | https://github.com/jshjohnson/Choices#readme */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Choices=t()}(this,(function(){"use strict";var e=function(t,i){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])},e(t,i)};function t(t,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function n(){this.constructor=t}e(t,i),t.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}var i=function(){return i=Object.assign||function(e){for(var t,i=1,n=arguments.length;i/g,">").replace(/=0&&!window.matchMedia("(min-height: ".concat(e+1,"px)")).matches:"top"===this.position&&(i=!0),i},e.prototype.setActiveDescendant=function(e){this.element.setAttribute("aria-activedescendant",e)},e.prototype.removeActiveDescendant=function(){this.element.removeAttribute("aria-activedescendant")},e.prototype.open=function(e,t){N(this.element,this.classNames.openState),this.element.setAttribute("aria-expanded","true"),this.isOpen=!0,this.shouldFlip(e,t)&&(N(this.element,this.classNames.flippedState),this.isFlipped=!0)},e.prototype.close=function(){P(this.element,this.classNames.openState),this.element.setAttribute("aria-expanded","false"),this.removeActiveDescendant(),this.isOpen=!1,this.isFlipped&&(P(this.element,this.classNames.flippedState),this.isFlipped=!1)},e.prototype.addFocusState=function(){N(this.element,this.classNames.focusState)},e.prototype.removeFocusState=function(){P(this.element,this.classNames.focusState)},e.prototype.enable=function(){P(this.element,this.classNames.disabledState),this.element.removeAttribute("aria-disabled"),this.type===_&&this.element.setAttribute("tabindex","0"),this.isDisabled=!1},e.prototype.disable=function(){N(this.element,this.classNames.disabledState),this.element.setAttribute("aria-disabled","true"),this.type===_&&this.element.setAttribute("tabindex","-1"),this.isDisabled=!0},e.prototype.wrap=function(e){var t=this.element,i=e.parentNode;i&&(e.nextSibling?i.insertBefore(t,e.nextSibling):i.appendChild(t)),t.appendChild(e)},e.prototype.unwrap=function(e){var t=this.element,i=t.parentNode;i&&(i.insertBefore(e,t),i.removeChild(t))},e.prototype.addLoadingState=function(){N(this.element,this.classNames.loadingState),this.element.setAttribute("aria-busy","true"),this.isLoading=!0},e.prototype.removeLoadingState=function(){P(this.element,this.classNames.loadingState),this.element.removeAttribute("aria-busy"),this.isLoading=!1},e}(),K=function(){function e(e){var t=e.element,i=e.type,n=e.classNames,s=e.preventPaste;this.element=t,this.type=i,this.classNames=n,this.preventPaste=s,this.isFocussed=this.element.isEqualNode(document.activeElement),this.isDisabled=t.disabled,this._onPaste=this._onPaste.bind(this),this._onInput=this._onInput.bind(this),this._onFocus=this._onFocus.bind(this),this._onBlur=this._onBlur.bind(this)}return Object.defineProperty(e.prototype,"placeholder",{set:function(e){this.element.placeholder=e},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"value",{get:function(){return this.element.value},set:function(e){this.element.value=e},enumerable:!1,configurable:!0}),e.prototype.addEventListeners=function(){var e=this.element;e.addEventListener("paste",this._onPaste),e.addEventListener("input",this._onInput,{passive:!0}),e.addEventListener("focus",this._onFocus,{passive:!0}),e.addEventListener("blur",this._onBlur,{passive:!0})},e.prototype.removeEventListeners=function(){var e=this.element;e.removeEventListener("input",this._onInput),e.removeEventListener("paste",this._onPaste),e.removeEventListener("focus",this._onFocus),e.removeEventListener("blur",this._onBlur)},e.prototype.enable=function(){this.element.removeAttribute("disabled"),this.isDisabled=!1},e.prototype.disable=function(){this.element.setAttribute("disabled",""),this.isDisabled=!0},e.prototype.focus=function(){this.isFocussed||this.element.focus()},e.prototype.blur=function(){this.isFocussed&&this.element.blur()},e.prototype.clear=function(e){return void 0===e&&(e=!0),this.element.value="",e&&this.setWidth(),this},e.prototype.setWidth=function(){var e=this.element;e.style.minWidth="".concat(e.placeholder.length+1,"ch"),e.style.width="".concat(e.value.length+1,"ch")},e.prototype.setActiveDescendant=function(e){this.element.setAttribute("aria-activedescendant",e)},e.prototype.removeActiveDescendant=function(){this.element.removeAttribute("aria-activedescendant")},e.prototype._onInput=function(){this.type!==_&&this.setWidth()},e.prototype._onPaste=function(e){this.preventPaste&&e.preventDefault()},e.prototype._onFocus=function(){this.isFocussed=!0},e.prototype._onBlur=function(){this.isFocussed=!1},e}(),j=function(){function e(e){this.element=e.element,this.scrollPos=this.element.scrollTop,this.height=this.element.offsetHeight}return e.prototype.prepend=function(e){var t=this.element.firstElementChild;t?this.element.insertBefore(e,t):this.element.append(e)},e.prototype.scrollToTop=function(){this.element.scrollTop=0},e.prototype.scrollToChildElement=function(e,t){var i=this;if(e){var n=t>0?this.element.scrollTop+(e.offsetTop+e.offsetHeight)-(this.element.scrollTop+this.element.offsetHeight):e.offsetTop;requestAnimationFrame((function(){i._animateScroll(n,t)}))}},e.prototype._scrollDown=function(e,t,i){var n=(i-e)/t;this.element.scrollTop=e+(n>1?n:1)},e.prototype._scrollUp=function(e,t,i){var n=(e-i)/t;this.element.scrollTop=e-(n>1?n:1)},e.prototype._animateScroll=function(e,t){var i=this,n=this.element.scrollTop,s=!1;t>0?(this._scrollDown(n,4,e),ne&&(s=!0)),s&&requestAnimationFrame((function(){i._animateScroll(e,t)}))},e}(),B=function(){function e(e){var t=e.classNames;this.element=e.element,this.classNames=t,this.isDisabled=!1}return Object.defineProperty(e.prototype,"isActive",{get:function(){return"active"===this.element.dataset.choice},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"dir",{get:function(){return this.element.dir},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"value",{get:function(){return this.element.value},set:function(e){this.element.setAttribute("value",e),this.element.value=e},enumerable:!1,configurable:!0}),e.prototype.conceal=function(){var e=this.element;N(e,this.classNames.input),e.hidden=!0,e.tabIndex=-1;var t=e.getAttribute("style");t&&e.setAttribute("data-choice-orig-style",t),e.setAttribute("data-choice","active")},e.prototype.reveal=function(){var e=this.element;P(e,this.classNames.input),e.hidden=!1,e.removeAttribute("tabindex");var t=e.getAttribute("data-choice-orig-style");t?(e.removeAttribute("data-choice-orig-style"),e.setAttribute("style",t)):e.removeAttribute("style"),e.removeAttribute("data-choice")},e.prototype.enable=function(){this.element.removeAttribute("disabled"),this.element.disabled=!1,this.isDisabled=!1},e.prototype.disable=function(){this.element.setAttribute("disabled",""),this.element.disabled=!0,this.isDisabled=!0},e.prototype.triggerEvent=function(e,t){var i;void 0===(i=t||{})&&(i=null),this.element.dispatchEvent(new CustomEvent(e,{detail:i,bubbles:!0,cancelable:!0}))},e}(),H=function(e){function i(){return null!==e&&e.apply(this,arguments)||this}return t(i,e),i}(B),V=function(e,t){return void 0===t&&(t=!0),void 0===e?t:!!e},R=function(e){if("string"==typeof e&&(e=e.split(" ").filter((function(e){return e.length}))),Array.isArray(e)&&e.length)return e},q=function(e,t){if("string"==typeof e)return q({value:e,label:e},!1);var i=e;if("choices"in i){if(!t)throw new TypeError("optGroup is not allowed");var n=i,s=n.choices.map((function(e){return q(e,!1)}));return{id:0,label:A(n.label)||n.value,active:!!s.length,disabled:!!n.disabled,choices:s}}var o=i;return{id:0,groupId:0,score:0,rank:0,value:o.value,label:o.label||o.value,active:V(o.active),selected:V(o.selected,!1),disabled:V(o.disabled,!1),placeholder:V(o.placeholder,!1),highlighted:!1,labelClass:R(o.labelClass),labelDescription:o.labelDescription,customProperties:o.customProperties}},G=function(e){return"SELECT"===e.tagName},U=function(e){function i(t){var i=t.template,n=t.extractPlaceholder,s=e.call(this,{element:t.element,classNames:t.classNames})||this;return s.template=i,s.extractPlaceholder=n,s}return t(i,e),Object.defineProperty(i.prototype,"placeholderOption",{get:function(){return this.element.querySelector('option[value=""]')||this.element.querySelector("option[placeholder]")},enumerable:!1,configurable:!0}),i.prototype.addOptions=function(e){var t=this,i=document.createDocumentFragment();e.forEach((function(e){var n=e;if(!n.element){var s=t.template(n);i.appendChild(s),n.element=s}})),this.element.appendChild(i)},i.prototype.optionsAsChoices=function(){var e=this,t=[];return this.element.querySelectorAll(":scope > option, :scope > optgroup").forEach((function(i){!function(e){return"OPTION"===e.tagName}(i)?function(e){return"OPTGROUP"===e.tagName}(i)&&t.push(e._optgroupToChoice(i)):t.push(e._optionToChoice(i))})),t},i.prototype._optionToChoice=function(e){return!e.hasAttribute("value")&&e.hasAttribute("placeholder")&&(e.setAttribute("value",""),e.value=""),{id:0,groupId:0,score:0,rank:0,value:e.value,label:e.innerHTML,element:e,active:!0,selected:this.extractPlaceholder?e.selected:e.hasAttribute("selected"),disabled:e.disabled,highlighted:!1,placeholder:this.extractPlaceholder&&(!e.value||e.hasAttribute("placeholder")),labelClass:void 0!==e.dataset.labelClass?R(e.dataset.labelClass):void 0,labelDescription:void 0!==e.dataset.labelDescription?e.dataset.labelDescription:void 0,customProperties:F(e.dataset.customProperties)}},i.prototype._optgroupToChoice=function(e){var t=this,i=e.querySelectorAll("option"),n=Array.from(i).map((function(e){return t._optionToChoice(e)}));return{id:0,label:e.label||"",element:e,active:!!n.length,disabled:e.disabled,choices:n}},i}(B),W={items:[],choices:[],silent:!1,renderChoiceLimit:-1,maxItemCount:-1,closeDropdownOnSelect:"auto",singleModeForMultiSelect:!1,addChoices:!1,addItems:!0,addItemFilter:function(e){return!!e&&""!==e},removeItems:!0,removeItemButton:!1,removeItemButtonAlignLeft:!1,editItems:!1,allowHTML:!1,allowHtmlUserInput:!1,duplicateItemsAllowed:!0,delimiter:",",paste:!0,searchEnabled:!0,searchChoices:!0,searchFloor:1,searchResultLimit:4,searchFields:["label","value"],position:"auto",resetScrollPosition:!0,shouldSort:!0,shouldSortItems:!1,sorter:function(e,t){var i=e.label,n=t.label,s=void 0===n?t.value:n;return A(void 0===i?e.value:i).localeCompare(A(s),[],{sensitivity:"base",ignorePunctuation:!0,numeric:!0})},shadowRoot:null,placeholder:!0,placeholderValue:null,searchPlaceholderValue:null,prependValue:null,appendValue:null,renderSelectedChoices:"auto",loadingText:"Loading...",noResultsText:"No results found",noChoicesText:"No choices to choose from",itemSelectText:"Press to select",uniqueItemText:"Only unique values can be added",customAddItemText:"Only values matching specific conditions can be added",addItemText:function(e){return'Press Enter to add "'.concat(e,'"')},removeItemIconText:function(){return"Remove item"},removeItemLabelText:function(e){return"Remove item: ".concat(e)},maxItemText:function(e){return"Only ".concat(e," values can be added")},valueComparer:function(e,t){return e===t},fuseOptions:{includeScore:!0},labelId:"",callbackOnInit:null,callbackOnCreateTemplates:null,classNames:{containerOuter:["choices"],containerInner:["choices__inner"],input:["choices__input"],inputCloned:["choices__input--cloned"],list:["choices__list"],listItems:["choices__list--multiple"],listSingle:["choices__list--single"],listDropdown:["choices__list--dropdown"],item:["choices__item"],itemSelectable:["choices__item--selectable"],itemDisabled:["choices__item--disabled"],itemChoice:["choices__item--choice"],description:["choices__description"],placeholder:["choices__placeholder"],group:["choices__group"],groupHeading:["choices__heading"],button:["choices__button"],activeState:["is-active"],focusState:["is-focused"],openState:["is-open"],disabledState:["is-disabled"],highlightedState:["is-highlighted"],selectedState:["is-selected"],flippedState:["is-flipped"],loadingState:["is-loading"],notice:["choices__notice"],addChoice:["choices__item--selectable","add-choice"],noResults:["has-no-results"],noChoices:["has-no-choices"]},appendGroupInSearch:!1},X=function(e){var t=e.itemEl;t&&(t.remove(),e.itemEl=void 0)},J={groups:function(e,t){var i=e,n=!0;switch(t.type){case l:i.push(t.group);break;case c:i=[];break;default:n=!1}return{state:i,update:n}},items:function(e,t,i){var n=e,s=!0;switch(t.type){case h:t.item.selected=!0,(r=t.item.element)&&(r.selected=!0,r.setAttribute("selected","")),n.push(t.item);break;case u:var r;if(t.item.selected=!1,r=t.item.element){r.selected=!1,r.removeAttribute("selected");var a=r.parentElement;a&&G(a)&&a.type===_&&(a.value="")}X(t.item),n=n.filter((function(e){return e.id!==t.item.id}));break;case o:n=n.filter((function(e){return e.id!==t.choice.id})),X(t.choice);break;case d:var c=t.highlighted,l=n.find((function(e){return e.id===t.item.id}));l&&l.highlighted!==c&&(l.highlighted=c,i&&function(e,t,i){var n=e.itemEl;n&&(P(n,i),N(n,t))}(l,c?i.classNames.highlightedState:i.classNames.selectedState,c?i.classNames.selectedState:i.classNames.highlightedState));break;default:s=!1}return{state:n,update:s}},choices:function(e,t,i){var n=e,l=!0;switch(t.type){case s:n.push(t.choice);break;case o:t.choice.choiceEl=void 0,n=n.filter((function(e){return e.id!==t.choice.id}));break;case h:case u:t.item.choiceEl=void 0;break;case r:var d=[];t.results.forEach((function(e){d[e.item.id]=e})),n.forEach((function(e){var t=d[e.id];void 0!==t?(e.score=t.score,e.rank=t.rank,e.active=!0):(e.score=0,e.rank=0,e.active=!1),i&&i.appendGroupInSearch&&(e.choiceEl=void 0)}));break;case a:n.forEach((function(e){e.active=t.active,i&&i.appendGroupInSearch&&(e.choiceEl=void 0)}));break;case c:n=[];break;default:l=!1}return{state:n,update:l}}},z=function(){function e(e){this._state=this.defaultState,this._listeners=[],this._txn=0,this._context=e}return Object.defineProperty(e.prototype,"defaultState",{get:function(){return{groups:[],items:[],choices:[]}},enumerable:!1,configurable:!0}),e.prototype.changeSet=function(e){return{groups:e,items:e,choices:e}},e.prototype.reset=function(){this._state=this.defaultState;var e=this.changeSet(!0);this._txn?this._changeSet=e:this._listeners.forEach((function(t){return t(e)}))},e.prototype.subscribe=function(e){this._listeners.push(e)},e.prototype.dispatch=function(e){var t=this,i=this._state,n=!1,s=this._changeSet||this.changeSet(!1);Object.keys(J).forEach((function(o){var r=J[o](i[o],e,t._context);r.update&&(n=!0,s[o]=!0,i[o]=r.state)})),n&&(this._txn?this._changeSet=s:this._listeners.forEach((function(e){return e(s)})))},e.prototype.withTxn=function(e){this._txn++;try{e()}finally{if(this._txn=Math.max(0,this._txn-1),!this._txn){var t=this._changeSet;t&&(this._changeSet=void 0,this._listeners.forEach((function(e){return e(t)})))}}},Object.defineProperty(e.prototype,"state",{get:function(){return this._state},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"items",{get:function(){return this.state.items},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"highlightedActiveItems",{get:function(){return this.items.filter((function(e){return!e.disabled&&e.active&&e.highlighted}))},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"choices",{get:function(){return this.state.choices},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"activeChoices",{get:function(){return this.choices.filter((function(e){return e.active}))},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"searchableChoices",{get:function(){return this.choices.filter((function(e){return!e.disabled&&!e.placeholder}))},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"groups",{get:function(){return this.state.groups},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"activeGroups",{get:function(){var e=this;return this.state.groups.filter((function(t){var i=t.active&&!t.disabled,n=e.state.choices.some((function(e){return e.active&&!e.disabled}));return i&&n}),[])},enumerable:!1,configurable:!0}),e.prototype.inTxn=function(){return this._txn>0},e.prototype.getChoiceById=function(e){return this.activeChoices.find((function(t){return t.id===e}))},e.prototype.getGroupById=function(e){return this.groups.find((function(t){return t.id===e}))},e}(),Q="no-choices",Y="no-results",Z="add-choice",$=function(){function e(e){this._haystack=[],this._fields=e.searchFields}return e.prototype.index=function(e){this._haystack=e},e.prototype.reset=function(){this._haystack=[]},e.prototype.isEmptyIndex=function(){return!this._haystack.length},e.prototype.search=function(e){var t=this._fields;if(!t||!t.length||!e)return[];var i=e.toLowerCase();return this._haystack.filter((function(e){return t.some((function(t){return t in e&&e[t].toLowerCase().startsWith(i)}))})).map((function(e,t){return{item:e,score:t,rank:t+1}}))},e}(),ee=function(e,t,i){var n=e.dataset,s=t.customProperties,o=t.labelClass,r=t.labelDescription;o&&(n.labelClass=L(o).join(" ")),r&&(n.labelDescription=r),i&&s&&("string"==typeof s?n.customProperties=s:"object"!=typeof s||function(e){for(var t in e)if(Object.prototype.hasOwnProperty.call(e,t))return!1;return!0}(s)||(n.customProperties=JSON.stringify(s)))},te=function(e,t,i){var n=t&&e.querySelector("label[for='".concat(t,"']")),s=n&&n.innerText;s&&i.setAttribute("aria-label",s)},ie={containerOuter:function(e,t,i,n,s,o,r){var a=e.classNames.containerOuter,c=document.createElement("div");return N(c,a),c.dataset.type=o,t&&(c.dir=t),n&&(c.tabIndex=0),i&&(c.setAttribute("role",s?"combobox":"listbox"),s?c.setAttribute("aria-autocomplete","list"):r||te(this._docRoot,this.passedElement.element.id,c),c.setAttribute("aria-haspopup","true"),c.setAttribute("aria-expanded","false")),r&&c.setAttribute("aria-labelledby",r),c},containerInner:function(e){var t=e.classNames.containerInner,i=document.createElement("div");return N(i,t),i},itemList:function(e,t){var i=e.searchEnabled,n=e.classNames,s=n.list,o=n.listSingle,r=n.listItems,a=document.createElement("div");return N(a,s),N(a,t?o:r),this._isSelectElement&&i&&a.setAttribute("role","listbox"),a},placeholder:function(e,t){var i=e.allowHTML,n=e.classNames.placeholder,s=document.createElement("div");return N(s,n),T(s,i,t),s},item:function(e,t,i){var n=e.allowHTML,s=e.removeItemButtonAlignLeft,o=e.removeItemIconText,r=e.removeItemLabelText,a=e.classNames,c=a.item,l=a.button,h=a.highlightedState,u=a.itemSelectable,d=a.placeholder,p=A(t.value),m=document.createElement("div");if(N(m,c),t.labelClass){var f=document.createElement("span");T(f,n,t.label),N(f,t.labelClass),m.appendChild(f)}else T(m,n,t.label);if(m.dataset.item="",m.dataset.id=t.id,m.dataset.value=p,ee(m,t,!0),(t.disabled||this.containerOuter.isDisabled)&&m.setAttribute("aria-disabled","true"),this._isSelectElement&&(m.setAttribute("aria-selected","true"),m.setAttribute("role","option")),t.placeholder&&(N(m,d),m.dataset.placeholder=""),N(m,t.highlighted?h:u),i){t.disabled&&P(m,u),m.dataset.deletable="";var v=document.createElement("button");v.type="button",N(v,l),T(v,!0,w(o,t.value));var _=w(r,t.value);_&&v.setAttribute("aria-label",_),v.dataset.button="",s?m.insertAdjacentElement("afterbegin",v):m.appendChild(v)}return m},choiceList:function(e,t){var i=e.classNames.list,n=document.createElement("div");return N(n,i),t||n.setAttribute("aria-multiselectable","true"),n.setAttribute("role","listbox"),n},choiceGroup:function(e,t){var i=e.allowHTML,n=e.classNames,s=n.group,o=n.groupHeading,r=n.itemDisabled,a=t.id,c=t.label,l=t.disabled,h=A(c),u=document.createElement("div");N(u,s),l&&N(u,r),u.setAttribute("role","group"),u.dataset.group="",u.dataset.id=a,u.dataset.value=h,l&&u.setAttribute("aria-disabled","true");var d=document.createElement("div");return N(d,o),T(d,i,c||""),u.appendChild(d),u},choice:function(e,t,i,n){var s=e.allowHTML,o=e.classNames,r=o.item,a=o.itemChoice,c=o.itemSelectable,l=o.selectedState,h=o.itemDisabled,u=o.description,d=o.placeholder,p=t.label,m=A(t.value),f=document.createElement("div");f.id=t.elementId,N(f,r),N(f,a),n&&"string"==typeof p&&(p=O(s,p),p={trusted:p+=" (".concat(n,")")},f.dataset.groupId="".concat(t.groupId));var v=f;if(t.labelClass){var _=document.createElement("span");T(_,s,p),N(_,t.labelClass),v=_,f.appendChild(_)}else T(f,s,p);if(t.labelDescription){var g="".concat(t.elementId,"-description");v.setAttribute("aria-describedby",g);var b=document.createElement("span");T(b,s,t.labelDescription),b.id=g,N(b,u),f.appendChild(b)}return t.selected&&N(f,l),t.placeholder&&N(f,d),f.setAttribute("role",t.groupId?"treeitem":"option"),f.dataset.choice="",f.dataset.id=t.id,f.dataset.value=m,i&&(f.dataset.selectText=i),ee(f,t,!1),t.disabled?(N(f,h),f.dataset.choiceDisabled="",f.setAttribute("aria-disabled","true")):(N(f,c),f.dataset.choiceSelectable=""),f},input:function(e,t){var i=e.classNames,n=i.input,s=i.inputCloned,o=e.labelId,r=document.createElement("input");return r.type="search",N(r,n),N(r,s),r.autocomplete="off",r.autocapitalize="off",r.spellcheck=!1,r.setAttribute("role","textbox"),r.setAttribute("aria-autocomplete","list"),t?r.setAttribute("aria-label",t):o||te(this._docRoot,this.passedElement.element.id,r),r},dropdown:function(e){var t=e.classNames,i=t.list,n=t.listDropdown,s=document.createElement("div");return N(s,i),N(s,n),s.setAttribute("aria-expanded","false"),s},notice:function(e,t,i){var n=e.classNames,s=n.item,o=n.itemChoice,r=n.addChoice,a=n.noResults,c=n.noChoices,l=n.notice;void 0===i&&(i="");var h=document.createElement("div");switch(T(h,!0,t),N(h,s),N(h,o),N(h,l),i){case Z:N(h,r);break;case Y:N(h,a);break;case Q:N(h,c)}return i===Z&&(h.dataset.choiceSelectable="",h.dataset.choice=""),h},option:function(e){var t=A(e.label),i=new Option(t,e.value,!1,e.selected);return ee(i,e,!0),i.disabled=e.disabled,e.selected&&i.setAttribute("selected",""),i}},ne="-ms-scroll-limit"in document.documentElement.style&&"-ms-ime-align"in document.documentElement.style,se={},oe=function(e){if(e)return e.dataset.id?parseInt(e.dataset.id,10):void 0},re="[data-choice-selectable]";return function(){function e(t,n){void 0===t&&(t="[data-choice]"),void 0===n&&(n={});var s=this;this.initialisedOK=void 0,this._hasNonChoicePlaceholder=!1,this._lastAddedChoiceId=0,this._lastAddedGroupId=0;var o=e.defaults;this.config=i(i(i({},o.allOptions),o.options),n),v.forEach((function(e){s.config[e]=i(i(i({},o.allOptions[e]),o.options[e]),n[e])}));var r=this.config;r.silent||this._validateConfig();var a=r.shadowRoot||document.documentElement;this._docRoot=a;var c="string"==typeof t?a.querySelector(t):t;if(!c||"object"!=typeof c||"INPUT"!==c.tagName&&!G(c)){if(!c&&"string"==typeof t)throw TypeError("Selector ".concat(t," failed to find an element"));throw TypeError("Expected one of the following types text|select-one|select-multiple")}var l=c.type,h="text"===l;(h||1!==r.maxItemCount)&&(r.singleModeForMultiSelect=!1),r.singleModeForMultiSelect&&(l=g);var u=l===_,d=l===g,p=u||d;if(this._elementType=l,this._isTextElement=h,this._isSelectOneElement=u,this._isSelectMultipleElement=d,this._isSelectElement=u||d,this._canAddUserChoices=h&&r.addItems||p&&r.addChoices,"boolean"!=typeof r.renderSelectedChoices&&(r.renderSelectedChoices="always"===r.renderSelectedChoices||u),r.closeDropdownOnSelect="auto"===r.closeDropdownOnSelect?h||u||r.singleModeForMultiSelect:V(r.closeDropdownOnSelect),r.placeholder&&(r.placeholderValue?this._hasNonChoicePlaceholder=!0:c.dataset.placeholder&&(this._hasNonChoicePlaceholder=!0,r.placeholderValue=c.dataset.placeholder)),n.addItemFilter&&"function"!=typeof n.addItemFilter){var m=n.addItemFilter instanceof RegExp?n.addItemFilter:new RegExp(n.addItemFilter);r.addItemFilter=m.test.bind(m)}if(this.passedElement=this._isTextElement?new H({element:c,classNames:r.classNames}):new U({element:c,classNames:r.classNames,template:function(e){return s._templates.option(e)},extractPlaceholder:r.placeholder&&!this._hasNonChoicePlaceholder}),this.initialised=!1,this._store=new z(r),this._currentValue="",r.searchEnabled=!h&&r.searchEnabled||d,this._canSearch=r.searchEnabled,this._isScrollingOnIe=!1,this._highlightPosition=0,this._wasTap=!0,this._placeholderValue=this._generatePlaceholderValue(),this._baseId=function(e){var t=e.id||e.name&&"".concat(e.name,"-").concat(E(2))||E(4);return t=t.replace(/(:|\.|\[|\]|,)/g,""),"".concat("choices-","-").concat(t)}(c),this._direction=c.dir,!this._direction){var f=window.getComputedStyle(c).direction;f!==window.getComputedStyle(document.documentElement).direction&&(this._direction=f)}if(this._idNames={itemChoice:"item-choice"},this._templates=o.templates,this._render=this._render.bind(this),this._onFocus=this._onFocus.bind(this),this._onBlur=this._onBlur.bind(this),this._onKeyUp=this._onKeyUp.bind(this),this._onKeyDown=this._onKeyDown.bind(this),this._onInput=this._onInput.bind(this),this._onClick=this._onClick.bind(this),this._onTouchMove=this._onTouchMove.bind(this),this._onTouchEnd=this._onTouchEnd.bind(this),this._onMouseDown=this._onMouseDown.bind(this),this._onMouseOver=this._onMouseOver.bind(this),this._onFormReset=this._onFormReset.bind(this),this._onSelectKey=this._onSelectKey.bind(this),this._onEnterKey=this._onEnterKey.bind(this),this._onEscapeKey=this._onEscapeKey.bind(this),this._onDirectionKey=this._onDirectionKey.bind(this),this._onDeleteKey=this._onDeleteKey.bind(this),this.passedElement.isActive)return r.silent||console.warn("Trying to initialise Choices on element already initialised",{element:t}),this.initialised=!0,void(this.initialisedOK=!1);this.init(),this._initialItems=this._store.items.map((function(e){return e.value}))}return Object.defineProperty(e,"defaults",{get:function(){return Object.preventExtensions({get options(){return se},get allOptions(){return W},get templates(){return ie}})},enumerable:!1,configurable:!0}),e.prototype.init=function(){if(!this.initialised&&void 0===this.initialisedOK){this._searcher=new $(this.config),this._loadChoices(),this._createTemplates(),this._createElements(),this._createStructure(),this._isTextElement&&!this.config.addItems||this.passedElement.element.hasAttribute("disabled")||this.passedElement.element.closest("fieldset:disabled")?this.disable():(this.enable(),this._addEventListeners()),this._initStore(),this.initialised=!0,this.initialisedOK=!0;var e=this.config.callbackOnInit;"function"==typeof e&&e.call(this)}},e.prototype.destroy=function(){this.initialised&&(this._removeEventListeners(),this.passedElement.reveal(),this.containerOuter.unwrap(this.passedElement.element),this._store._listeners=[],this.clearStore(),this._stopSearch(),this._templates=e.defaults.templates,this.initialised=!1,this.initialisedOK=void 0)},e.prototype.enable=function(){return this.passedElement.isDisabled&&this.passedElement.enable(),this.containerOuter.isDisabled&&(this._addEventListeners(),this.input.enable(),this.containerOuter.enable()),this},e.prototype.disable=function(){return this.passedElement.isDisabled||this.passedElement.disable(),this.containerOuter.isDisabled||(this._removeEventListeners(),this.input.disable(),this.containerOuter.disable()),this},e.prototype.highlightItem=function(e,t){if(void 0===t&&(t=!0),!e||!e.id)return this;var i=this._store.items.find((function(t){return t.id===e.id}));return!i||i.highlighted||(this._store.dispatch(y(i,!0)),t&&this.passedElement.triggerEvent(f,this._getChoiceForOutput(i))),this},e.prototype.unhighlightItem=function(e,t){if(void 0===t&&(t=!0),!e||!e.id)return this;var i=this._store.items.find((function(t){return t.id===e.id}));return i&&i.highlighted?(this._store.dispatch(y(i,!1)),t&&this.passedElement.triggerEvent(f,this._getChoiceForOutput(i)),this):this},e.prototype.highlightAll=function(){var e=this;return this._store.withTxn((function(){e._store.items.forEach((function(t){t.highlighted||(e._store.dispatch(y(t,!0)),e.passedElement.triggerEvent(f,e._getChoiceForOutput(t)))}))})),this},e.prototype.unhighlightAll=function(){var e=this;return this._store.withTxn((function(){e._store.items.forEach((function(t){t.highlighted&&(e._store.dispatch(y(t,!1)),e.passedElement.triggerEvent(f,e._getChoiceForOutput(t)))}))})),this},e.prototype.removeActiveItemsByValue=function(e){var t=this;return this._store.withTxn((function(){t._store.items.filter((function(t){return t.value===e})).forEach((function(e){return t._removeItem(e)}))})),this},e.prototype.removeActiveItems=function(e){var t=this;return this._store.withTxn((function(){t._store.items.filter((function(t){return t.id!==e})).forEach((function(e){return t._removeItem(e)}))})),this},e.prototype.removeHighlightedItems=function(e){var t=this;return void 0===e&&(e=!1),this._store.withTxn((function(){t._store.highlightedActiveItems.forEach((function(i){t._removeItem(i),e&&t._triggerChange(i.value)}))})),this},e.prototype.showDropdown=function(e){var t=this;return this.dropdown.isActive||requestAnimationFrame((function(){t.dropdown.show();var i=t.dropdown.element.getBoundingClientRect();t.containerOuter.open(i.bottom,i.height),!e&&t._canSearch&&t.input.focus(),t.passedElement.triggerEvent("showDropdown")})),this},e.prototype.hideDropdown=function(e){var t=this;return this.dropdown.isActive?(requestAnimationFrame((function(){t.dropdown.hide(),t.containerOuter.close(),!e&&t._canSearch&&(t.input.removeActiveDescendant(),t.input.blur()),t.passedElement.triggerEvent("hideDropdown")})),this):this},e.prototype.getValue=function(e){var t=this;void 0===e&&(e=!1);var i=this._store.items.reduce((function(i,n){var s=e?n.value:t._getChoiceForOutput(n);return i.push(s),i}),[]);return this._isSelectOneElement||this.config.singleModeForMultiSelect?i[0]:i},e.prototype.setValue=function(e){var t=this;return this.initialisedOK?(this._store.withTxn((function(){e.forEach((function(e){e&&t._addChoice(q(e,!1))}))})),this._searcher.reset(),this):(this._warnChoicesInitFailed("setValue"),this)},e.prototype.setChoiceByValue=function(e){var t=this;return this.initialisedOK?(this._isTextElement||(this._store.withTxn((function(){(Array.isArray(e)?e:[e]).forEach((function(e){return t._findAndSelectChoiceByValue(e)})),t.unhighlightAll()})),this._searcher.reset()),this):(this._warnChoicesInitFailed("setChoiceByValue"),this)},e.prototype.setChoices=function(e,t,n,s){var o=this;if(void 0===e&&(e=[]),void 0===t&&(t="value"),void 0===n&&(n="label"),void 0===s&&(s=!1),!this.initialisedOK)return this._warnChoicesInitFailed("setChoices"),this;if(!this._isSelectElement)throw new TypeError("setChoices can't be used with INPUT based Choices");if("string"!=typeof t||!t)throw new TypeError("value parameter must be a name of 'value' field in passed objects");if(s&&this.clearChoices(),"function"==typeof e){var r=e(this);if("function"==typeof Promise&&r instanceof Promise)return new Promise((function(e){return requestAnimationFrame(e)})).then((function(){return o._handleLoadingState(!0)})).then((function(){return r})).then((function(e){return o.setChoices(e,t,n,s)})).catch((function(e){o.config.silent||console.error(e)})).then((function(){return o._handleLoadingState(!1)})).then((function(){return o}));if(!Array.isArray(r))throw new TypeError(".setChoices first argument function must return either array of choices or Promise, got: ".concat(typeof r));return this.setChoices(r,t,n,!1)}if(!Array.isArray(e))throw new TypeError(".setChoices must be called either with array of choices with a function resulting into Promise of array of choices");return this.containerOuter.removeLoadingState(),this._store.withTxn((function(){var s="value"===t,r="label"===n;e.forEach((function(e){if("choices"in e){var a=e;r||(a=i(i({},a),{label:a[n]})),o._addGroup(q(a,!0))}else{var c=e;r&&s||(c=i(i({},c),{value:c[t],label:c[n]})),o._addChoice(q(c,!1))}})),o.unhighlightAll()})),this._searcher.reset(),this},e.prototype.refresh=function(e,t,i){var n=this;return void 0===e&&(e=!1),void 0===t&&(t=!1),void 0===i&&(i=!1),this._isSelectElement?(this._store.withTxn((function(){var s=n.passedElement.optionsAsChoices(),o={};i||n._store.items.forEach((function(e){e.id&&e.active&&e.selected&&!e.disabled&&(o[e.value]=!0)})),n.clearStore(),s.forEach((function(e){if(!("choices"in e)){var t=e;i?n._store.dispatch(b(t)):o[t.value]&&(t.selected=!0)}})),n._addPredefinedChoices(s,t,e),n._isSearching&&n._searchChoices(n.input.value)})),this):(this.config.silent||console.warn("refresh method can only be used on choices backed by a element'); + } + return this; + } + this._store.withTxn(function () { + var choicesFromOptions = _this.passedElement.optionsAsChoices(); + // Build the list of items which require preserving + var existingItems = {}; + if (!deselectAll) { + _this._store.items.forEach(function (choice) { + if (choice.id && choice.active && choice.selected && !choice.disabled) { + existingItems[choice.value] = true; + } + }); + } + _this.clearStore(); + choicesFromOptions.forEach(function (groupOrChoice) { + if ('choices' in groupOrChoice) { + return; + } + var choice = groupOrChoice; + if (deselectAll) { + _this._store.dispatch(removeItem$1(choice)); + } + else if (existingItems[choice.value]) { + choice.selected = true; + } + }); + /* @todo only generate add events for the added options instead of all + if (withEvents) { + items.forEach((choice) => { + if (existingItems[choice.value]) { + this.passedElement.triggerEvent( + EventType.removeItem, + this._getChoiceForEvent(choice), + ); + } + }); + } + */ + // load new choices & items + _this._addPredefinedChoices(choicesFromOptions, selectFirstOption, withEvents); + // re-do search if required + if (_this._isSearching) { + _this._searchChoices(_this.input.value); + } + }); + return this; + }; + Choices.prototype.removeChoice = function (value) { + var choice = this._store.choices.find(function (c) { return c.value === value; }); + if (!choice) { + return this; + } + this._store.dispatch(removeChoice(choice)); + // @todo integrate with Store + this._searcher.reset(); + if (choice.selected) { + this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(choice)); + } + return this; + }; + Choices.prototype.clearChoices = function () { + this.passedElement.element.replaceChildren(''); + return this.clearStore(); + }; + Choices.prototype.clearStore = function () { + this.itemList.element.replaceChildren(''); + this.choiceList.element.replaceChildren(''); + this._clearNotice(); + this._store.reset(); + this._lastAddedChoiceId = 0; + this._lastAddedGroupId = 0; + // @todo integrate with Store + this._searcher.reset(); + return this; + }; + Choices.prototype.clearInput = function () { + var shouldSetInputWidth = !this._isSelectOneElement; + this.input.clear(shouldSetInputWidth); + this._clearNotice(); + if (this._isSearching) { + this._stopSearch(); + } + return this; + }; + Choices.prototype._validateConfig = function () { + var config = this.config; + var invalidConfigOptions = diff(config, DEFAULT_CONFIG); + if (invalidConfigOptions.length) { + console.warn('Unknown config option(s) passed', invalidConfigOptions.join(', ')); + } + if (config.allowHTML && config.allowHtmlUserInput) { + if (config.addItems) { + console.warn('Warning: allowHTML/allowHtmlUserInput/addItems all being true is strongly not recommended and may lead to XSS attacks'); + } + if (config.addChoices) { + console.warn('Warning: allowHTML/allowHtmlUserInput/addChoices all being true is strongly not recommended and may lead to XSS attacks'); + } + } + }; + Choices.prototype._render = function (changes) { + if (changes === void 0) { changes = { choices: true, groups: true, items: true }; } + if (this._store.inTxn()) { + return; + } + if (this._isSelectElement) { + if (changes.choices || changes.groups) { + this._renderChoices(); + } + } + if (changes.items) { + this._renderItems(); + } + }; + Choices.prototype._renderChoices = function () { + var _this = this; + if (!this._canAddItems()) { + return; // block rendering choices if the input limit is reached. + } + var _a = this, config = _a.config, isSearching = _a._isSearching; + var _b = this._store, activeGroups = _b.activeGroups, activeChoices = _b.activeChoices; + var renderLimit = 0; + if (isSearching && config.searchResultLimit > 0) { + renderLimit = config.searchResultLimit; + } + else if (config.renderChoiceLimit > 0) { + renderLimit = config.renderChoiceLimit; + } + if (this._isSelectElement) { + var backingOptions = activeChoices.filter(function (choice) { return !choice.element; }); + if (backingOptions.length) { + this.passedElement.addOptions(backingOptions); + } + } + var fragment = document.createDocumentFragment(); + var renderableChoices = function (choices) { + return choices.filter(function (choice) { + return !choice.placeholder && (isSearching ? !!choice.rank : config.renderSelectedChoices || !choice.selected); + }); + }; + var selectableChoices = this._isSelectOneElement; + var renderChoices = function (choices, withinGroup, groupLabel) { + if (isSearching) { + // sortByRank is used to ensure stable sorting, as scores are non-unique + // this additionally ensures fuseOptions.sortFn is not ignored + choices.sort(sortByRank); + } + else if (config.shouldSort) { + choices.sort(config.sorter); + } + var choiceLimit = choices.length; + choiceLimit = !withinGroup && renderLimit && choiceLimit > renderLimit ? renderLimit : choiceLimit; + choiceLimit--; + choices.every(function (choice, index) { + // choiceEl being empty signals the contents has probably significantly changed + var dropdownItem = choice.choiceEl || _this._templates.choice(config, choice, config.itemSelectText, groupLabel); + choice.choiceEl = dropdownItem; + fragment.appendChild(dropdownItem); + if (isSearching || !choice.selected) { + selectableChoices = true; + } + return index < choiceLimit; + }); + }; + if (activeChoices.length) { + if (config.resetScrollPosition) { + requestAnimationFrame(function () { return _this.choiceList.scrollToTop(); }); + } + if (!this._hasNonChoicePlaceholder && !isSearching && this._isSelectOneElement) { + // If we have a placeholder choice along with groups + renderChoices(activeChoices.filter(function (choice) { return choice.placeholder && !choice.groupId; }), false, undefined); + } + // If we have grouped options + if (activeGroups.length && !isSearching) { + if (config.shouldSort) { + activeGroups.sort(config.sorter); + } + activeGroups.forEach(function (group) { + var groupChoices = renderableChoices(group.choices); + if (groupChoices.length) { + if (group.label) { + var dropdownGroup = group.groupEl || _this._templates.choiceGroup(_this.config, group); + group.groupEl = dropdownGroup; + dropdownGroup.remove(); + fragment.appendChild(dropdownGroup); + } + renderChoices(groupChoices, true, config.appendGroupInSearch && isSearching ? group.label : undefined); + } + }); + } + else { + renderChoices(renderableChoices(activeChoices), false, undefined); + } + } + var notice = this._notice; + if (!selectableChoices) { + if (!notice) { + this._notice = { + text: resolveStringFunction(config.noChoicesText), + type: NoticeTypes.noChoices, + }; + } + fragment.replaceChildren(''); + } + else if (notice && notice.type === NoticeTypes.noChoices) { + this._notice = undefined; + } + this._renderNotice(fragment); + this.choiceList.element.replaceChildren(fragment); + if (selectableChoices) { + this._highlightChoice(); + } + }; + Choices.prototype._renderItems = function () { + var _this = this; + var items = this._store.items || []; + var itemList = this.itemList.element; + var config = this.config; + var fragment = document.createDocumentFragment(); + var itemFromList = function (item) { + return itemList.querySelector("[data-item][data-id=\"".concat(item.id, "\"]")); + }; + var addItemToFragment = function (item) { + var el = item.itemEl; + if (el && el.parentElement) { + return; + } + el = itemFromList(item) || _this._templates.item(config, item, config.removeItemButton); + item.itemEl = el; + fragment.appendChild(el); + }; + // new items + items.forEach(addItemToFragment); + var addItems = !!fragment.childNodes.length; + if (this._isSelectOneElement && this._hasNonChoicePlaceholder) { + var existingItems = itemList.children.length; + if (addItems || existingItems > 1) { + var placeholder = itemList.querySelector(getClassNamesSelector(config.classNames.placeholder)); + if (placeholder) { + placeholder.remove(); + } + } + else if (!existingItems) { + addItems = true; + addItemToFragment(mapInputToChoice({ + selected: true, + value: '', + label: config.placeholderValue || '', + placeholder: true, + }, false)); + } + } + if (addItems) { + itemList.append(fragment); + if (config.shouldSortItems && !this._isSelectOneElement) { + items.sort(config.sorter); + // push sorting into the DOM + items.forEach(function (item) { + var el = itemFromList(item); + if (el) { + el.remove(); + fragment.append(el); + } + }); + itemList.append(fragment); + } + } + if (this._isTextElement) { + // Update the value of the hidden input + this.passedElement.value = items.map(function (_a) { + var value = _a.value; + return value; + }).join(config.delimiter); + } + }; + Choices.prototype._displayNotice = function (text, type, openDropdown) { + if (openDropdown === void 0) { openDropdown = true; } + var oldNotice = this._notice; + if (oldNotice && + ((oldNotice.type === type && oldNotice.text === text) || + (oldNotice.type === NoticeTypes.addChoice && + (type === NoticeTypes.noResults || type === NoticeTypes.noChoices)))) { + if (openDropdown) { + this.showDropdown(true); + } + return; + } + this._clearNotice(); + this._notice = text + ? { + text: text, + type: type, + } + : undefined; + this._renderNotice(); + if (openDropdown && text) { + this.showDropdown(true); + } + }; + Choices.prototype._clearNotice = function () { + if (!this._notice) { + return; + } + var noticeElement = this.choiceList.element.querySelector(getClassNamesSelector(this.config.classNames.notice)); + if (noticeElement) { + noticeElement.remove(); + } + this._notice = undefined; + }; + Choices.prototype._renderNotice = function (fragment) { + var noticeConf = this._notice; + if (noticeConf) { + var notice = this._templates.notice(this.config, noticeConf.text, noticeConf.type); + if (fragment) { + fragment.append(notice); + } + else { + this.choiceList.prepend(notice); + } + } + }; + Choices.prototype._getChoiceForOutput = function (choice, keyCode) { + if (!choice) { + return undefined; + } + var group = choice.groupId ? this._store.getGroupById(choice.groupId) : null; + return { + id: choice.id, + highlighted: choice.highlighted, + labelClass: choice.labelClass, + labelDescription: choice.labelDescription, + customProperties: choice.customProperties, + disabled: choice.disabled, + active: choice.active, + label: choice.label, + placeholder: choice.placeholder, + value: choice.value, + groupValue: group && group.label ? group.label : undefined, + element: choice.element, + keyCode: keyCode, + }; + }; + Choices.prototype._triggerChange = function (value) { + if (value === undefined || value === null) { + return; + } + this.passedElement.triggerEvent(EventType.change, { + value: value, + }); + }; + Choices.prototype._handleButtonAction = function (element) { + var _this = this; + var items = this._store.items; + if (!items.length || !this.config.removeItems || !this.config.removeItemButton) { + return; + } + var id = element && parseDataSetId(element.parentNode); + var itemToRemove = id && items.find(function (item) { return item.id === id; }); + if (!itemToRemove) { + return; + } + this._store.withTxn(function () { + // Remove item associated with button + _this._removeItem(itemToRemove); + _this._triggerChange(itemToRemove.value); + if (_this._isSelectOneElement && !_this._hasNonChoicePlaceholder) { + var placeholderChoice = _this._store.choices + .reverse() + .find(function (choice) { return !choice.disabled && choice.placeholder; }); + if (placeholderChoice) { + _this._addItem(placeholderChoice); + _this.unhighlightAll(); + if (placeholderChoice.value) { + _this._triggerChange(placeholderChoice.value); + } + } + } + }); + }; + Choices.prototype._handleItemAction = function (element, hasShiftKey) { + var _this = this; + if (hasShiftKey === void 0) { hasShiftKey = false; } + var items = this._store.items; + if (!items.length || !this.config.removeItems || this._isSelectOneElement) { + return; + } + var id = parseDataSetId(element); + if (!id) { + return; + } + // We only want to select one item with a click + // so we deselect any items that aren't the target + // unless shift is being pressed + items.forEach(function (item) { + if (item.id === id && !item.highlighted) { + _this.highlightItem(item); + } + else if (!hasShiftKey && item.highlighted) { + _this.unhighlightItem(item); + } + }); + // Focus input as without focus, a user cannot do anything with a + // highlighted item + this.input.focus(); + }; + Choices.prototype._handleChoiceAction = function (element) { + var _this = this; + // If we are clicking on an option + var id = parseDataSetId(element); + var choice = id && this._store.getChoiceById(id); + if (!choice || choice.disabled) { + return false; + } + var hasActiveDropdown = this.dropdown.isActive; + if (!choice.selected) { + if (!this._canAddItems()) { + return true; // causes _onEnterKey to early out + } + this._store.withTxn(function () { + _this._addItem(choice, true, true); + _this.clearInput(); + _this.unhighlightAll(); + }); + this._triggerChange(choice.value); + } + // We want to close the dropdown if we are dealing with a single select box + if (hasActiveDropdown && this.config.closeDropdownOnSelect) { + this.hideDropdown(true); + this.containerOuter.element.focus(); + } + return true; + }; + Choices.prototype._handleBackspace = function (items) { + var config = this.config; + if (!config.removeItems || !items.length) { + return; + } + var lastItem = items[items.length - 1]; + var hasHighlightedItems = items.some(function (item) { return item.highlighted; }); + // If editing the last item is allowed and there are not other selected items, + // we can edit the item value. Otherwise if we can remove items, remove all selected items + if (config.editItems && !hasHighlightedItems && lastItem) { + this.input.value = lastItem.value; + this.input.setWidth(); + this._removeItem(lastItem); + this._triggerChange(lastItem.value); + } + else { + if (!hasHighlightedItems) { + // Highlight last item if none already highlighted + this.highlightItem(lastItem, false); + } + this.removeHighlightedItems(true); + } + }; + Choices.prototype._loadChoices = function () { + var _a; + var config = this.config; + if (this._isTextElement) { + // Assign preset items from passed object first + this._presetChoices = config.items.map(function (e) { return mapInputToChoice(e, false); }); + // Add any values passed from attribute + if (this.passedElement.value) { + var elementItems = this.passedElement.value + .split(config.delimiter) + .map(function (e) { return mapInputToChoice(e, false); }); + this._presetChoices = this._presetChoices.concat(elementItems); + } + this._presetChoices.forEach(function (choice) { + choice.selected = true; + }); + } + else if (this._isSelectElement) { + // Assign preset choices from passed object + this._presetChoices = config.choices.map(function (e) { return mapInputToChoice(e, true); }); + // Create array of choices from option elements + var choicesFromOptions = this.passedElement.optionsAsChoices(); + if (choicesFromOptions) { + (_a = this._presetChoices).push.apply(_a, choicesFromOptions); + } + } + }; + Choices.prototype._handleLoadingState = function (setLoading) { + if (setLoading === void 0) { setLoading = true; } + var el = this.itemList.element; + if (setLoading) { + this.disable(); + this.containerOuter.addLoadingState(); + if (this._isSelectOneElement) { + el.replaceChildren(this._templates.placeholder(this.config, this.config.loadingText)); + } + else { + this.input.placeholder = this.config.loadingText; + } + } + else { + this.enable(); + this.containerOuter.removeLoadingState(); + if (this._isSelectOneElement) { + el.replaceChildren(''); + this._render(); + } + else { + this.input.placeholder = this._placeholderValue || ''; + } + } + }; + Choices.prototype._handleSearch = function (value) { + if (!this.input.isFocussed) { + return; + } + // Check that we have a value to search and the input was an alphanumeric character + if (value !== null && typeof value !== 'undefined' && value.length >= this.config.searchFloor) { + var resultCount = this.config.searchChoices ? this._searchChoices(value) : 0; + if (resultCount !== null) { + // Trigger search event + this.passedElement.triggerEvent(EventType.search, { + value: value, + resultCount: resultCount, + }); + } + } + else if (this._store.choices.some(function (option) { return !option.active; })) { + this._stopSearch(); + } + }; + Choices.prototype._canAddItems = function () { + var config = this.config; + var maxItemCount = config.maxItemCount, maxItemText = config.maxItemText; + if (!config.singleModeForMultiSelect && maxItemCount > 0 && maxItemCount <= this._store.items.length) { + this.choiceList.element.replaceChildren(''); + this._displayNotice(typeof maxItemText === 'function' ? maxItemText(maxItemCount) : maxItemText, NoticeTypes.addChoice); + return false; + } + return true; + }; + Choices.prototype._canCreateItem = function (value) { + var config = this.config; + var canAddItem = true; + var notice = ''; + if (canAddItem && typeof config.addItemFilter === 'function' && !config.addItemFilter(value)) { + canAddItem = false; + notice = resolveNoticeFunction(config.customAddItemText, value); + } + if (canAddItem) { + var foundChoice = this._store.choices.find(function (choice) { return config.valueComparer(choice.value, value); }); + if (this._isSelectElement) { + // for exact matches, do not prompt to add it as a custom choice + if (foundChoice) { + this._displayNotice('', NoticeTypes.addChoice); + return false; + } + } + else if (this._isTextElement && !config.duplicateItemsAllowed) { + if (foundChoice) { + canAddItem = false; + notice = resolveNoticeFunction(config.uniqueItemText, value); + } + } + } + if (canAddItem) { + notice = resolveNoticeFunction(config.addItemText, value); + } + if (notice) { + this._displayNotice(notice, NoticeTypes.addChoice); + } + return canAddItem; + }; + Choices.prototype._searchChoices = function (value) { + var newValue = value.trim().replace(/\s{2,}/, ' '); + // signal input didn't change search + if (!newValue.length || newValue === this._currentValue) { + return null; + } + var searcher = this._searcher; + if (searcher.isEmptyIndex()) { + searcher.index(this._store.searchableChoices); + } + // If new value matches the desired length and is not the same as the current value with a space + var results = searcher.search(newValue); + this._currentValue = newValue; + this._highlightPosition = 0; + this._isSearching = true; + var notice = this._notice; + var noticeType = notice && notice.type; + if (noticeType !== NoticeTypes.addChoice) { + if (!results.length) { + this._displayNotice(resolveStringFunction(this.config.noResultsText), NoticeTypes.noResults); + } + else if (noticeType === NoticeTypes.noResults) { + this._clearNotice(); + } + } + this._store.dispatch(filterChoices(results)); + return results.length; + }; + Choices.prototype._stopSearch = function () { + var wasSearching = this._isSearching; + this._currentValue = ''; + this._isSearching = false; + if (wasSearching) { + this._store.dispatch(activateChoices(true)); + this.passedElement.triggerEvent(EventType.search, { + value: '', + resultCount: 0, + }); + } + }; + Choices.prototype._addEventListeners = function () { + var documentElement = this._docRoot; + var outerElement = this.containerOuter.element; + var inputElement = this.input.element; + // capture events - can cancel event processing or propagation + documentElement.addEventListener('touchend', this._onTouchEnd, true); + outerElement.addEventListener('keydown', this._onKeyDown, true); + outerElement.addEventListener('mousedown', this._onMouseDown, true); + // passive events - doesn't call `preventDefault` or `stopPropagation` + documentElement.addEventListener('click', this._onClick, { passive: true }); + documentElement.addEventListener('touchmove', this._onTouchMove, { + passive: true, + }); + this.dropdown.element.addEventListener('mouseover', this._onMouseOver, { + passive: true, + }); + if (this._isSelectOneElement) { + outerElement.addEventListener('focus', this._onFocus, { + passive: true, + }); + outerElement.addEventListener('blur', this._onBlur, { + passive: true, + }); + } + inputElement.addEventListener('keyup', this._onKeyUp, { + passive: true, + }); + inputElement.addEventListener('input', this._onInput, { + passive: true, + }); + inputElement.addEventListener('focus', this._onFocus, { + passive: true, + }); + inputElement.addEventListener('blur', this._onBlur, { + passive: true, + }); + if (inputElement.form) { + inputElement.form.addEventListener('reset', this._onFormReset, { + passive: true, + }); + } + this.input.addEventListeners(); + }; + Choices.prototype._removeEventListeners = function () { + var documentElement = this._docRoot; + var outerElement = this.containerOuter.element; + var inputElement = this.input.element; + documentElement.removeEventListener('touchend', this._onTouchEnd, true); + outerElement.removeEventListener('keydown', this._onKeyDown, true); + outerElement.removeEventListener('mousedown', this._onMouseDown, true); + documentElement.removeEventListener('click', this._onClick); + documentElement.removeEventListener('touchmove', this._onTouchMove); + this.dropdown.element.removeEventListener('mouseover', this._onMouseOver); + if (this._isSelectOneElement) { + outerElement.removeEventListener('focus', this._onFocus); + outerElement.removeEventListener('blur', this._onBlur); + } + inputElement.removeEventListener('keyup', this._onKeyUp); + inputElement.removeEventListener('input', this._onInput); + inputElement.removeEventListener('focus', this._onFocus); + inputElement.removeEventListener('blur', this._onBlur); + if (inputElement.form) { + inputElement.form.removeEventListener('reset', this._onFormReset); + } + this.input.removeEventListeners(); + }; + Choices.prototype._onKeyDown = function (event) { + var keyCode = event.keyCode; + var hasActiveDropdown = this.dropdown.isActive; + /* + See: + https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key + https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values + https://en.wikipedia.org/wiki/UTF-16#Code_points_from_U+010000_to_U+10FFFF - UTF-16 surrogate pairs + https://stackoverflow.com/a/70866532 - "Unidentified" for mobile + http://www.unicode.org/versions/Unicode5.2.0/ch16.pdf#G19635 - U+FFFF is reserved (Section 16.7) + + Logic: when a key event is sent, `event.key` represents its printable value _or_ one + of a large list of special values indicating meta keys/functionality. In addition, + key events for compose functionality contain a value of `Dead` when mid-composition. + + I can't quite verify it, but non-English IMEs may also be able to generate key codes + for code points in the surrogate-pair range, which could potentially be seen as having + key.length > 1. Since `Fn` is one of the special keys, we can't distinguish by that + alone. + + Here, key.length === 1 means we know for sure the input was printable and not a special + `key` value. When the length is greater than 1, it could be either a printable surrogate + pair or a special `key` value. We can tell the difference by checking if the _character + code_ value (not code point!) is in the "surrogate pair" range or not. + + We don't use .codePointAt because an invalid code point would return 65535, which wouldn't + pass the >= 0x10000 check we would otherwise use. + + > ...The Unicode Standard sets aside 66 noncharacter code points. The last two code points + > of each plane are noncharacters: U+FFFE and U+FFFF on the BMP... + */ + var wasPrintableChar = event.key.length === 1 || + (event.key.length === 2 && event.key.charCodeAt(0) >= 0xd800) || + event.key === 'Unidentified'; + if (!this._isTextElement && !hasActiveDropdown) { + this.showDropdown(); + if (!this.input.isFocussed && wasPrintableChar) { + /* + We update the input value with the pressed key as + the input was not focussed at the time of key press + therefore does not have the value of the key. + */ + this.input.value += event.key; + // browsers interpret a space as pagedown + if (event.key === ' ') { + event.preventDefault(); + } + } + } + switch (keyCode) { + case 65 /* KeyCodeMap.A_KEY */: + return this._onSelectKey(event, this.itemList.element.hasChildNodes()); + case 13 /* KeyCodeMap.ENTER_KEY */: + return this._onEnterKey(event, hasActiveDropdown); + case 27 /* KeyCodeMap.ESC_KEY */: + return this._onEscapeKey(event, hasActiveDropdown); + case 38 /* KeyCodeMap.UP_KEY */: + case 33 /* KeyCodeMap.PAGE_UP_KEY */: + case 40 /* KeyCodeMap.DOWN_KEY */: + case 34 /* KeyCodeMap.PAGE_DOWN_KEY */: + return this._onDirectionKey(event, hasActiveDropdown); + case 8 /* KeyCodeMap.DELETE_KEY */: + case 46 /* KeyCodeMap.BACK_KEY */: + return this._onDeleteKey(event, this._store.items, this.input.isFocussed); + } + }; + Choices.prototype._onKeyUp = function ( /* event: KeyboardEvent */) { + this._canSearch = this.config.searchEnabled; + }; + Choices.prototype._onInput = function ( /* event: InputEvent */) { + var value = this.input.value; + if (!value) { + if (this._isTextElement) { + this.hideDropdown(true); + } + else { + this._stopSearch(); + } + this._clearNotice(); + return; + } + if (!this._canAddItems()) { + return; + } + if (this._canSearch) { + // do the search even if the entered text can not be added + this._handleSearch(value); + } + if (!this._canAddUserChoices) { + return; + } + // determine if a notice needs to be displayed for why a search result can't be added + this._canCreateItem(value); + if (this._isSelectElement) { + this._highlightPosition = 0; // reset to select the notice and/or exact match + this._highlightChoice(); + } + }; + Choices.prototype._onSelectKey = function (event, hasItems) { + // If CTRL + A or CMD + A have been pressed and there are items to select + if ((event.ctrlKey || event.metaKey) && hasItems) { + this._canSearch = false; + var shouldHightlightAll = this.config.removeItems && !this.input.value && this.input.element === document.activeElement; + if (shouldHightlightAll) { + this.highlightAll(); + } + } + }; + Choices.prototype._onEnterKey = function (event, hasActiveDropdown) { + var _this = this; + var value = this.input.value; + var target = event.target; + event.preventDefault(); + if (target && target.hasAttribute('data-button')) { + this._handleButtonAction(target); + return; + } + if (!hasActiveDropdown) { + if (this._isSelectElement || this._notice) { + this.showDropdown(); + } + return; + } + var highlightedChoice = this.dropdown.element.querySelector(getClassNamesSelector(this.config.classNames.highlightedState)); + if (highlightedChoice && this._handleChoiceAction(highlightedChoice)) { + return; + } + if (!target || !value) { + this.hideDropdown(true); + return; + } + if (!this._canAddItems()) { + return; + } + var addedItem = false; + this._store.withTxn(function () { + addedItem = _this._findAndSelectChoiceByValue(value, true); + if (!addedItem) { + if (!_this._canAddUserChoices) { + return; + } + if (!_this._canCreateItem(value)) { + return; + } + var sanitisedValue = sanitise(value); + var userValue = _this.config.allowHtmlUserInput || sanitisedValue === value ? value : { escaped: sanitisedValue, raw: value }; + _this._addChoice(mapInputToChoice({ + value: userValue, + label: userValue, + selected: true, + }, false), true, true); + addedItem = true; + } + _this.clearInput(); + _this.unhighlightAll(); + }); + if (!addedItem) { + return; + } + this._triggerChange(value); + if (this.config.closeDropdownOnSelect) { + this.hideDropdown(true); + } + }; + Choices.prototype._onEscapeKey = function (event, hasActiveDropdown) { + if (hasActiveDropdown) { + event.stopPropagation(); + this.hideDropdown(true); + this.containerOuter.element.focus(); + } + }; + Choices.prototype._onDirectionKey = function (event, hasActiveDropdown) { + var keyCode = event.keyCode; + // If up or down key is pressed, traverse through options + if (hasActiveDropdown || this._isSelectOneElement) { + this.showDropdown(); + this._canSearch = false; + var directionInt = keyCode === 40 /* KeyCodeMap.DOWN_KEY */ || keyCode === 34 /* KeyCodeMap.PAGE_DOWN_KEY */ ? 1 : -1; + var skipKey = event.metaKey || keyCode === 34 /* KeyCodeMap.PAGE_DOWN_KEY */ || keyCode === 33 /* KeyCodeMap.PAGE_UP_KEY */; + var nextEl = void 0; + if (skipKey) { + if (directionInt > 0) { + nextEl = this.dropdown.element.querySelector("".concat(selectableChoiceIdentifier, ":last-of-type")); + } + else { + nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); + } + } + else { + var currentEl = this.dropdown.element.querySelector(getClassNamesSelector(this.config.classNames.highlightedState)); + if (currentEl) { + nextEl = getAdjacentEl(currentEl, selectableChoiceIdentifier, directionInt); + } + else { + nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); + } + } + if (nextEl) { + // We prevent default to stop the cursor moving + // when pressing the arrow + if (!isScrolledIntoView(nextEl, this.choiceList.element, directionInt)) { + this.choiceList.scrollToChildElement(nextEl, directionInt); + } + this._highlightChoice(nextEl); + } + // Prevent default to maintain cursor position whilst + // traversing dropdown options + event.preventDefault(); + } + }; + Choices.prototype._onDeleteKey = function (event, items, hasFocusedInput) { + // If backspace or delete key is pressed and the input has no value + if (!this._isSelectOneElement && !event.target.value && hasFocusedInput) { + this._handleBackspace(items); + event.preventDefault(); + } + }; + Choices.prototype._onTouchMove = function () { + if (this._wasTap) { + this._wasTap = false; + } + }; + Choices.prototype._onTouchEnd = function (event) { + var target = (event || event.touches[0]).target; + var touchWasWithinContainer = this._wasTap && this.containerOuter.element.contains(target); + if (touchWasWithinContainer) { + var containerWasExactTarget = target === this.containerOuter.element || target === this.containerInner.element; + if (containerWasExactTarget) { + if (this._isTextElement) { + this.input.focus(); + } + else if (this._isSelectMultipleElement) { + this.showDropdown(); + } + } + // Prevents focus event firing + event.stopPropagation(); + } + this._wasTap = true; + }; + /** + * Handles mousedown event in capture mode for containetOuter.element + */ + Choices.prototype._onMouseDown = function (event) { + var target = event.target; + if (!(target instanceof HTMLElement)) { + return; + } + // If we have our mouse down on the scrollbar and are on IE11... + if (IS_IE11 && this.choiceList.element.contains(target)) { + // check if click was on a scrollbar area + var firstChoice = this.choiceList.element.firstElementChild; + this._isScrollingOnIe = + this._direction === 'ltr' ? event.offsetX >= firstChoice.offsetWidth : event.offsetX < firstChoice.offsetLeft; + } + if (target === this.input.element) { + return; + } + var item = target.closest('[data-button],[data-item],[data-choice]'); + if (item instanceof HTMLElement) { + if ('button' in item.dataset) { + this._handleButtonAction(item); + } + else if ('item' in item.dataset) { + this._handleItemAction(item, event.shiftKey); + } + else if ('choice' in item.dataset) { + this._handleChoiceAction(item); + } + } + event.preventDefault(); + }; + /** + * Handles mouseover event over this.dropdown + * @param {MouseEvent} event + */ + Choices.prototype._onMouseOver = function (_a) { + var target = _a.target; + if (target instanceof HTMLElement && 'choice' in target.dataset) { + this._highlightChoice(target); + } + }; + Choices.prototype._onClick = function (_a) { + var target = _a.target; + var containerOuter = this.containerOuter; + var clickWasWithinContainer = containerOuter.element.contains(target); + if (clickWasWithinContainer) { + if (!this.dropdown.isActive && !containerOuter.isDisabled) { + if (this._isTextElement) { + if (document.activeElement !== this.input.element) { + this.input.focus(); + } + } + else { + this.showDropdown(); + containerOuter.element.focus(); + } + } + else if (this._isSelectOneElement && + target !== this.input.element && + !this.dropdown.element.contains(target)) { + this.hideDropdown(); + } + } + else { + containerOuter.removeFocusState(); + this.hideDropdown(true); + this.unhighlightAll(); + } + }; + Choices.prototype._onFocus = function (_a) { + var target = _a.target; + var containerOuter = this.containerOuter; + var focusWasWithinContainer = target && containerOuter.element.contains(target); + if (!focusWasWithinContainer) { + return; + } + var targetIsInput = target === this.input.element; + if (this._isTextElement) { + if (targetIsInput) { + containerOuter.addFocusState(); + } + } + else if (this._isSelectMultipleElement) { + if (targetIsInput) { + this.showDropdown(true); + // If element is a select box, the focused element is the container and the dropdown + // isn't already open, focus and show dropdown + containerOuter.addFocusState(); + } + } + else { + containerOuter.addFocusState(); + if (targetIsInput) { + this.showDropdown(true); + } + } + }; + Choices.prototype._onBlur = function (_a) { + var target = _a.target; + var containerOuter = this.containerOuter; + var blurWasWithinContainer = target && containerOuter.element.contains(target); + if (blurWasWithinContainer && !this._isScrollingOnIe) { + var targetIsInput = target === this.input.element; + if (this._isTextElement || this._isSelectMultipleElement) { + if (targetIsInput) { + containerOuter.removeFocusState(); + this.hideDropdown(true); + this.unhighlightAll(); + } + } + else { + containerOuter.removeFocusState(); + if (targetIsInput || (target === containerOuter.element && !this._canSearch)) { + this.hideDropdown(true); + } + } + } + else { + // On IE11, clicking the scollbar blurs our input and thus + // closes the dropdown. To stop this, we refocus our input + // if we know we are on IE *and* are scrolling. + this._isScrollingOnIe = false; + this.input.element.focus(); + } + }; + Choices.prototype._onFormReset = function () { + var _this = this; + this._store.withTxn(function () { + _this.clearInput(); + _this.hideDropdown(); + _this.refresh(false, false, true); + if (_this._initialItems.length) { + _this.setChoiceByValue(_this._initialItems); + } + }); + }; + Choices.prototype._highlightChoice = function (el) { + if (el === void 0) { el = null; } + var choices = Array.from(this.dropdown.element.querySelectorAll(selectableChoiceIdentifier)); + if (!choices.length) { + return; + } + var passedEl = el; + var highlightedState = this.config.classNames.highlightedState; + var highlightedChoices = Array.from(this.dropdown.element.querySelectorAll(getClassNamesSelector(highlightedState))); + // Remove any highlighted choices + highlightedChoices.forEach(function (choice) { + removeClassesFromElement(choice, highlightedState); + choice.setAttribute('aria-selected', 'false'); + }); + if (passedEl) { + this._highlightPosition = choices.indexOf(passedEl); + } + else { + // Highlight choice based on last known highlight location + if (choices.length > this._highlightPosition) { + // If we have an option to highlight + passedEl = choices[this._highlightPosition]; + } + else { + // Otherwise highlight the option before + passedEl = choices[choices.length - 1]; + } + if (!passedEl) { + passedEl = choices[0]; + } + } + addClassesToElement(passedEl, highlightedState); + passedEl.setAttribute('aria-selected', 'true'); + this.passedElement.triggerEvent(EventType.highlightChoice, { + el: passedEl, + }); + if (this.dropdown.isActive) { + // IE11 ignores aria-label and blocks virtual keyboard + // if aria-activedescendant is set without a dropdown + this.input.setActiveDescendant(passedEl.id); + this.containerOuter.setActiveDescendant(passedEl.id); + } + }; + Choices.prototype._addItem = function (item, withEvents, userTriggered) { + if (withEvents === void 0) { withEvents = true; } + if (userTriggered === void 0) { userTriggered = false; } + if (!item.id) { + throw new TypeError('item.id must be set before _addItem is called for a choice/item'); + } + if (this.config.singleModeForMultiSelect || this._isSelectOneElement) { + this.removeActiveItems(item.id); + } + this._store.dispatch(addItem(item)); + if (withEvents) { + this.passedElement.triggerEvent(EventType.addItem, this._getChoiceForOutput(item)); + if (userTriggered) { + this.passedElement.triggerEvent(EventType.choice, this._getChoiceForOutput(item)); + } + } + }; + Choices.prototype._removeItem = function (item) { + if (!item.id) { + return; + } + this._store.dispatch(removeItem$1(item)); + this.passedElement.triggerEvent(EventType.removeItem, this._getChoiceForOutput(item)); + }; + Choices.prototype._addChoice = function (choice, withEvents, userTriggered) { + if (withEvents === void 0) { withEvents = true; } + if (userTriggered === void 0) { userTriggered = false; } + if (choice.id) { + throw new TypeError('Can not re-add a choice which has already been added'); + } + // Generate unique id, in-place update is required so chaining _addItem works as expected + this._lastAddedChoiceId++; + choice.id = this._lastAddedChoiceId; + choice.elementId = "".concat(this._baseId, "-").concat(this._idNames.itemChoice, "-").concat(choice.id); + var _a = this.config, prependValue = _a.prependValue, appendValue = _a.appendValue; + if (prependValue) { + choice.value = prependValue + choice.value; + } + if (appendValue) { + choice.value += appendValue.toString(); + } + if ((prependValue || appendValue) && choice.element) { + choice.element.value = choice.value; + } + this._store.dispatch(addChoice(choice)); + if (choice.selected) { + this._addItem(choice, withEvents, userTriggered); + } + }; + Choices.prototype._addGroup = function (group, withEvents) { + var _this = this; + if (withEvents === void 0) { withEvents = true; } + if (group.id) { + throw new TypeError('Can not re-add a group which has already been added'); + } + this._store.dispatch(addGroup(group)); + if (!group.choices) { + return; + } + // add unique id for the group(s), and do not store the full list of choices in this group + this._lastAddedGroupId++; + group.id = this._lastAddedGroupId; + group.choices.forEach(function (item) { + item.groupId = group.id; + if (group.disabled) { + item.disabled = true; + } + _this._addChoice(item, withEvents); + }); + }; + Choices.prototype._createTemplates = function () { + var _this = this; + var callbackOnCreateTemplates = this.config.callbackOnCreateTemplates; + var userTemplates = {}; + if (typeof callbackOnCreateTemplates === 'function') { + userTemplates = callbackOnCreateTemplates.call(this, strToEl, escapeForTemplate); + } + var templating = {}; + Object.keys(this._templates).forEach(function (name) { + if (name in userTemplates) { + templating[name] = userTemplates[name].bind(_this); + } + else { + templating[name] = _this._templates[name].bind(_this); + } + }); + this._templates = templating; + }; + Choices.prototype._createElements = function () { + var templating = this._templates; + var _a = this, config = _a.config, isSelectOneElement = _a._isSelectOneElement; + var position = config.position, classNames = config.classNames; + var elementType = this._elementType; + this.containerOuter = new Container({ + element: templating.containerOuter(config, this._direction, this._isSelectElement, isSelectOneElement, config.searchEnabled, elementType, config.labelId), + classNames: classNames, + type: elementType, + position: position, + }); + this.containerInner = new Container({ + element: templating.containerInner(config), + classNames: classNames, + type: elementType, + position: position, + }); + this.input = new Input({ + element: templating.input(config, this._placeholderValue), + classNames: classNames, + type: elementType, + preventPaste: !config.paste, + }); + this.choiceList = new List({ + element: templating.choiceList(config, isSelectOneElement), + }); + this.itemList = new List({ + element: templating.itemList(config, isSelectOneElement), + }); + this.dropdown = new Dropdown({ + element: templating.dropdown(config), + classNames: classNames, + type: elementType, + }); + }; + Choices.prototype._createStructure = function () { + var _a = this, containerInner = _a.containerInner, containerOuter = _a.containerOuter, passedElement = _a.passedElement; + var dropdownElement = this.dropdown.element; + // Hide original element + passedElement.conceal(); + // Wrap input in container preserving DOM ordering + containerInner.wrap(passedElement.element); + // Wrapper inner container with outer container + containerOuter.wrap(containerInner.element); + if (this._isSelectOneElement) { + this.input.placeholder = this.config.searchPlaceholderValue || ''; + } + else { + if (this._placeholderValue) { + this.input.placeholder = this._placeholderValue; + } + this.input.setWidth(); + } + containerOuter.element.appendChild(containerInner.element); + containerOuter.element.appendChild(dropdownElement); + containerInner.element.appendChild(this.itemList.element); + dropdownElement.appendChild(this.choiceList.element); + if (!this._isSelectOneElement) { + containerInner.element.appendChild(this.input.element); + } + else if (this.config.searchEnabled) { + dropdownElement.insertBefore(this.input.element, dropdownElement.firstChild); + } + this._highlightPosition = 0; + this._isSearching = false; + }; + Choices.prototype._initStore = function () { + var _this = this; + this._store.subscribe(this._render); + this._store.withTxn(function () { + _this._addPredefinedChoices(_this._presetChoices, _this._isSelectOneElement && !_this._hasNonChoicePlaceholder, false); + }); + if (this._isSelectOneElement && this._hasNonChoicePlaceholder) { + this._render({ choices: false, groups: false, items: true }); + } + }; + Choices.prototype._addPredefinedChoices = function (choices, selectFirstOption, withEvents) { + var _this = this; + if (selectFirstOption === void 0) { selectFirstOption = false; } + if (withEvents === void 0) { withEvents = true; } + if (selectFirstOption) { + /** + * If there is a selected choice already or the choice is not the first in + * the array, add each choice normally. + * + * Otherwise we pre-select the first enabled choice in the array ("select-one" only) + */ + var noSelectedChoices = choices.findIndex(function (choice) { return choice.selected; }) === -1; + if (noSelectedChoices) { + choices.some(function (choice) { + if (choice.disabled || 'choices' in choice) { + return false; + } + choice.selected = true; + return true; + }); + } + } + choices.forEach(function (item) { + if ('choices' in item) { + if (_this._isSelectElement) { + _this._addGroup(item, withEvents); + } + } + else { + _this._addChoice(item, withEvents); + } + }); + }; + Choices.prototype._findAndSelectChoiceByValue = function (value, userTriggered) { + var _this = this; + if (userTriggered === void 0) { userTriggered = false; } + // Check 'value' property exists and the choice isn't already selected + var foundChoice = this._store.choices.find(function (choice) { return _this.config.valueComparer(choice.value, value); }); + if (foundChoice && !foundChoice.disabled && !foundChoice.selected) { + this._addItem(foundChoice, true, userTriggered); + return true; + } + return false; + }; + Choices.prototype._generatePlaceholderValue = function () { + var config = this.config; + if (!config.placeholder) { + return null; + } + if (this._hasNonChoicePlaceholder) { + return config.placeholderValue; + } + if (this._isSelectElement) { + var placeholderOption = this.passedElement.placeholderOption; + return placeholderOption ? placeholderOption.text : null; + } + return null; + }; + Choices.prototype._warnChoicesInitFailed = function (caller) { + if (this.config.silent) { + return; + } + if (!this.initialised) { + throw new TypeError("".concat(caller, " called on a non-initialised instance of Choices")); + } + else if (!this.initialisedOK) { + throw new TypeError("".concat(caller, " called for an element which has multiple instances of Choices initialised on it")); + } + }; + Choices.version = '11.0.1'; + return Choices; +}()); + +export { Choices as default }; diff --git a/assets/extensions/choices.js/public/assets/styles/base.css b/assets/extensions/choices.js/public/assets/styles/base.css index b64f6b95..4672d7ec 100644 --- a/assets/extensions/choices.js/public/assets/styles/base.css +++ b/assets/extensions/choices.js/public/assets/styles/base.css @@ -78,8 +78,7 @@ a:focus { border: 1px solid #ddd; border-radius: 2.5px; font-size: 14px; - -webkit-appearance: none; - appearance: none; + appearance: none; margin-bottom: 24px; } @@ -137,7 +136,7 @@ label + p { .section a, .section a:visited, .section a:focus { - color: #00bcd4; + color: #005F75; } .logo { diff --git a/assets/extensions/choices.js/public/assets/styles/base.min.css b/assets/extensions/choices.js/public/assets/styles/base.min.css index 53c15adb..ebba2030 100644 --- a/assets/extensions/choices.js/public/assets/styles/base.min.css +++ b/assets/extensions/choices.js/public/assets/styles/base.min.css @@ -1 +1 @@ -*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,::after,::before{box-sizing:border-box}body,html{position:relative;margin:0;width:100%;height:100%}body{font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;font-size:16px;line-height:1.4;color:#fff;background-color:#333;overflow-x:hidden}hr,label{display:block}label,p{margin-bottom:8px}label{font-size:14px;font-weight:500;cursor:pointer}p{margin-top:0}hr{margin:30px 0;border:0;border-bottom:1px solid #eaeaea;height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:12px;font-weight:400;line-height:1.2}a,a:focus,a:visited{color:#fff;text-decoration:none;font-weight:600}.form-control{display:block;width:100%;background-color:#f9f9f9;padding:12px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;-webkit-appearance:none;appearance:none;margin-bottom:24px}.h1,h1{font-size:32px}.h2,h2{font-size:24px}.h3,h3{font-size:20px}.h4,h4{font-size:18px}.h5,h5{font-size:16px}.h6,h6{font-size:14px}label+p{margin-top:-4px}.container{display:block;margin:auto;max-width:40em;padding:48px}@media (max-width:620px){.container{padding:0}}.section{background-color:#fff;padding:24px;color:#333}.section a,.section a:focus,.section a:visited{color:#00bcd4}.logo{display:block;margin-bottom:12px}.logo-img{width:100%;height:auto;display:inline-block;max-width:100%;vertical-align:top;padding:6px 0}.visible-ie{display:none}.push-bottom{margin-bottom:24px}.zero-bottom{margin-bottom:0}.zero-top{margin-top:0}.text-center{text-align:center}[data-test-hook]{margin-bottom:24px} \ No newline at end of file +*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,::after,::before{box-sizing:border-box}body,html{position:relative;margin:0;width:100%;height:100%}body{font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;font-size:16px;line-height:1.4;color:#fff;background-color:#333;overflow-x:hidden}hr,label{display:block}label,p{margin-bottom:8px}label{font-size:14px;font-weight:500;cursor:pointer}p{margin-top:0}hr{margin:30px 0;border:0;border-bottom:1px solid #eaeaea;height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:12px;font-weight:400;line-height:1.2}a,a:focus,a:visited{color:#fff;text-decoration:none;font-weight:600}.form-control{display:block;width:100%;background-color:#f9f9f9;padding:12px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;appearance:none;margin-bottom:24px}.h1,h1{font-size:32px}.h2,h2{font-size:24px}.h3,h3{font-size:20px}.h4,h4{font-size:18px}.h5,h5{font-size:16px}.h6,h6{font-size:14px}label+p{margin-top:-4px}.container{display:block;margin:auto;max-width:40em;padding:48px}@media (max-width:620px){.container{padding:0}}.section{background-color:#fff;padding:24px;color:#333}.section a,.section a:focus,.section a:visited{color:#005f75}.logo{display:block;margin-bottom:12px}.logo-img{width:100%;height:auto;display:inline-block;max-width:100%;vertical-align:top;padding:6px 0}.visible-ie{display:none}.push-bottom{margin-bottom:24px}.zero-bottom{margin-bottom:0}.zero-top{margin-top:0}.text-center{text-align:center}[data-test-hook]{margin-bottom:24px} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/assets/styles/choices.css b/assets/extensions/choices.js/public/assets/styles/choices.css index ed8ff340..05cd925a 100644 --- a/assets/extensions/choices.js/public/assets/styles/choices.css +++ b/assets/extensions/choices.js/public/assets/styles/choices.css @@ -62,9 +62,9 @@ opacity: 1; } .choices[data-type*=select-one] .choices__button:focus { - box-shadow: 0 0 0 2px #00bcd4; + box-shadow: 0 0 0 2px #005F75; } -.choices[data-type*=select-one] .choices__item[data-value=""] .choices__button { +.choices[data-type*=select-one] .choices__item[data-placeholder] .choices__button { display: none; } .choices[data-type*=select-one]::after { @@ -81,7 +81,7 @@ pointer-events: none; } .choices[data-type*=select-one].is-open::after { - border-color: transparent transparent #333 transparent; + border-color: transparent transparent #333; margin-top: -7.5px; } .choices[data-type*=select-one][dir=rtl]::after { @@ -108,7 +108,7 @@ margin-bottom: 0; margin-left: 8px; padding-left: 16px; - border-left: 1px solid #008fa1; + border-left: 1px solid #003642; background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg=="); background-size: 8px; width: 8px; @@ -174,8 +174,8 @@ font-weight: 500; margin-right: 3.75px; margin-bottom: 3.75px; - background-color: #00bcd4; - border: 1px solid #00a5bb; + background-color: #005F75; + border: 1px solid #004a5c; color: #fff; word-break: break-all; box-sizing: border-box; @@ -188,8 +188,8 @@ margin-left: 3.75px; } .choices__list--multiple .choices__item.is-highlighted { - background-color: #00a5bb; - border: 1px solid #008fa1; + background-color: #004a5c; + border: 1px solid #003642; } .is-disabled .choices__list--multiple .choices__item { background-color: #aaaaaa; @@ -197,7 +197,7 @@ } .choices__list--dropdown, .choices__list[aria-expanded] { - visibility: hidden; + display: none; z-index: 1; position: absolute; width: 100%; @@ -209,10 +209,9 @@ border-bottom-right-radius: 2.5px; overflow: hidden; word-break: break-all; - will-change: visibility; } .is-active.choices__list--dropdown, .is-active.choices__list[aria-expanded] { - visibility: visible; + display: block; } .is-open .choices__list--dropdown, .is-open .choices__list[aria-expanded] { border-color: #b7b7b7; @@ -240,10 +239,10 @@ text-align: right; } @media (min-width: 640px) { - .choices__list--dropdown .choices__item--selectable, .choices__list[aria-expanded] .choices__item--selectable { + .choices__list--dropdown .choices__item--selectable[data-select-text], .choices__list[aria-expanded] .choices__item--selectable[data-select-text] { padding-right: 100px; } - .choices__list--dropdown .choices__item--selectable::after, .choices__list[aria-expanded] .choices__item--selectable::after { + .choices__list--dropdown .choices__item--selectable[data-select-text]::after, .choices__list[aria-expanded] .choices__item--selectable[data-select-text]::after { content: attr(data-select-text); font-size: 12px; opacity: 0; @@ -252,12 +251,12 @@ top: 50%; transform: translateY(-50%); } - [dir=rtl] .choices__list--dropdown .choices__item--selectable, [dir=rtl] .choices__list[aria-expanded] .choices__item--selectable { + [dir=rtl] .choices__list--dropdown .choices__item--selectable[data-select-text], [dir=rtl] .choices__list[aria-expanded] .choices__item--selectable[data-select-text] { text-align: right; padding-left: 100px; padding-right: 10px; } - [dir=rtl] .choices__list--dropdown .choices__item--selectable::after, [dir=rtl] .choices__list[aria-expanded] .choices__item--selectable::after { + [dir=rtl] .choices__list--dropdown .choices__item--selectable[data-select-text]::after, [dir=rtl] .choices__list[aria-expanded] .choices__item--selectable[data-select-text]::after { right: auto; left: 10px; } @@ -294,8 +293,7 @@ .choices__button { text-indent: -9999px; - -webkit-appearance: none; - appearance: none; + appearance: none; border: 0; background-color: transparent; background-repeat: no-repeat; diff --git a/assets/extensions/choices.js/public/assets/styles/choices.css.map b/assets/extensions/choices.js/public/assets/styles/choices.css.map index b30c2773..a0c6f002 100644 --- a/assets/extensions/choices.js/public/assets/styles/choices.css.map +++ b/assets/extensions/choices.js/public/assets/styles/choices.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../../../src/styles/choices.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AA2BA;EACE;EACA;EACA,eApBkB;EAqBlB,WAxBqB;;AA0BrB;EACE;;AAGF;EACE;;AAGF;EACE;;AAIA;AAAA;EAEE,kBAlCsB;EAmCtB;EACA;;AAEF;EACE;;AAIJ;EACE;;;AAIJ;EACE;;AACA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE,kBApDyB;EAqDzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAGJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIA;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;;;AAOJ;AAAA;EACE;;AAEF;AAAA;EACE;EACA;EACA;EACA;EACA;EACA,aA5HoB;EA6HpB;EACA;EACA,kBA9HiB;EA+HjB,iBAjIuB;EAkIvB,OAlIuB;EAmIvB;EACA;EACA;;AAEA;AAAA;AAAA;EAEE;;;AAKN;EACE;EACA;EACA;EACA,kBA1JiB;EA2JjB;EACA;EACA,eA/JsB;EAgKtB,WAnKqB;EAoKrB;EACA;;AAEA;EAEE;;AAGF;EACE;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;;AAOF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;;AAIJ;EACE;;AACA;EACE;EACA;EACA,eA9MyB;EA+MzB;EACA,WAnNmB;EAoNnB;EACA;EACA;EACA,kBA9MoB;EA+MpB;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA,SApOgB;EAqOhB;EACA;EACA,kBAjP0B;EAkP1B;EACA;EACA;EACA,2BAzPsB;EA0PtB,4BA1PsB;EA2PtB;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA,WA3RmB;;AA6RnB;EACE;;AAIF;EADF;IAEI;;EAEA;IACE;IACA,WAtSe;IAuSf;IACA;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;;EAEA;IACE;IACA;;;AAKN;EACE;;AAEA;EACE;;;AAUR;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA,WAxVqB;EAyVrB;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA,kBA3WiB;EA4WjB,WAjXqB;EAkXrB;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAIE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;;;AAGF","file":"choices.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../../src/styles/choices.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AA2BA;EACE;EACA;EACA,eApBkB;EAqBlB,WAxBqB;;AA0BrB;EACE;;AAGF;EACE;;AAGF;EACE;;AAIA;AAAA;EAEE,kBAlCsB;EAmCtB;EACA;;AAEF;EACE;;AAIJ;EACE;;;AAIJ;EACE;;AACA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE,kBApDyB;EAqDzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAGJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIA;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;;;AAOJ;AAAA;EACE;;AAEF;AAAA;EACE;EACA;EACA;EACA;EACA;EACA,aA5HoB;EA6HpB;EACA;EACA,kBA9HiB;EA+HjB,iBAjIuB;EAkIvB,OAlIuB;EAmIvB;EACA;EACA;;AAEA;AAAA;AAAA;EAEE;;;AAKN;EACE;EACA;EACA;EACA,kBA1JiB;EA2JjB;EACA;EACA,eA/JsB;EAgKtB,WAnKqB;EAoKrB;EACA;;AAEA;EAEE;;AAGF;EACE;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;;AAOF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;;AAIJ;EACE;;AACA;EACE;EACA;EACA,eA9MyB;EA+MzB;EACA,WAnNmB;EAoNnB;EACA;EACA;EACA,kBA9MoB;EA+MpB;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA,SApOgB;EAqOhB;EACA;EACA,kBAjP0B;EAkP1B;EACA;EACA;EACA,2BAzPsB;EA0PtB,4BA1PsB;EA2PtB;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA,WA1RmB;;AA4RnB;EACE;;AAKA;EADF;IAEI;;EAEA;IACE;IACA,WAtSa;IAuSb;IACA;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;;EAEA;IACE;IACA;;;AAMR;EACE;;AAEA;EACE;;;AAUR;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA,WAzVqB;EA0VrB;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA,kBA5WiB;EA6WjB,WAlXqB;EAmXrB;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAIE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;;;AAGF","file":"choices.css"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/assets/styles/choices.min.css b/assets/extensions/choices.js/public/assets/styles/choices.min.css index 9260536a..cf79ea91 100644 --- a/assets/extensions/choices.js/public/assets/styles/choices.min.css +++ b/assets/extensions/choices.js/public/assets/styles/choices.min.css @@ -1 +1 @@ -.choices{position:relative;overflow:hidden;margin-bottom:24px;font-size:16px}.choices:focus{outline:0}.choices:last-child{margin-bottom:0}.choices.is-open{overflow:visible}.choices.is-disabled .choices__inner,.choices.is-disabled .choices__input{background-color:#eaeaea;cursor:not-allowed;-webkit-user-select:none;user-select:none}.choices.is-disabled .choices__item{cursor:not-allowed}.choices [hidden]{display:none!important}.choices[data-type*=select-one]{cursor:pointer}.choices[data-type*=select-one] .choices__inner{padding-bottom:7.5px}.choices[data-type*=select-one] .choices__input{display:block;width:100%;padding:10px;border-bottom:1px solid #ddd;background-color:#fff;margin:0}.choices[data-type*=select-one] .choices__button{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==);padding:0;background-size:8px;position:absolute;top:50%;right:0;margin-top:-10px;margin-right:25px;height:20px;width:20px;border-radius:10em;opacity:.25}.choices[data-type*=select-one] .choices__button:focus,.choices[data-type*=select-one] .choices__button:hover{opacity:1}.choices[data-type*=select-one] .choices__button:focus{box-shadow:0 0 0 2px #00bcd4}.choices[data-type*=select-one] .choices__item[data-value=""] .choices__button{display:none}.choices[data-type*=select-one]::after{content:"";height:0;width:0;border-style:solid;border-color:#333 transparent transparent;border-width:5px;position:absolute;right:11.5px;top:50%;margin-top:-2.5px;pointer-events:none}.choices[data-type*=select-one].is-open::after{border-color:transparent transparent #333;margin-top:-7.5px}.choices[data-type*=select-one][dir=rtl]::after{left:11.5px;right:auto}.choices[data-type*=select-one][dir=rtl] .choices__button{right:auto;left:0;margin-left:25px;margin-right:0}.choices[data-type*=select-multiple] .choices__inner,.choices[data-type*=text] .choices__inner{cursor:text}.choices[data-type*=select-multiple] .choices__button,.choices[data-type*=text] .choices__button{position:relative;display:inline-block;margin:0-4px 0 8px;padding-left:16px;border-left:1px solid #008fa1;background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==);background-size:8px;width:8px;line-height:1;opacity:.75;border-radius:0}.choices[data-type*=select-multiple] .choices__button:focus,.choices[data-type*=select-multiple] .choices__button:hover,.choices[data-type*=text] .choices__button:focus,.choices[data-type*=text] .choices__button:hover{opacity:1}.choices__inner{display:inline-block;vertical-align:top;width:100%;background-color:#f9f9f9;padding:7.5px 7.5px 3.75px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;min-height:44px;overflow:hidden}.is-focused .choices__inner,.is-open .choices__inner{border-color:#b7b7b7}.is-open .choices__inner{border-radius:2.5px 2.5px 0 0}.is-flipped.is-open .choices__inner{border-radius:0 0 2.5px 2.5px}.choices__list{margin:0;padding-left:0;list-style:none}.choices__list--single{display:inline-block;padding:4px 16px 4px 4px;width:100%}[dir=rtl] .choices__list--single{padding-right:4px;padding-left:16px}.choices__list--single .choices__item{width:100%}.choices__list--multiple{display:inline}.choices__list--multiple .choices__item{display:inline-block;vertical-align:middle;border-radius:20px;padding:4px 10px;font-size:12px;font-weight:500;margin-right:3.75px;margin-bottom:3.75px;background-color:#00bcd4;border:1px solid #00a5bb;color:#fff;word-break:break-all;box-sizing:border-box}.choices__list--multiple .choices__item[data-deletable]{padding-right:5px}[dir=rtl] .choices__list--multiple .choices__item{margin-right:0;margin-left:3.75px}.choices__list--multiple .choices__item.is-highlighted{background-color:#00a5bb;border:1px solid #008fa1}.is-disabled .choices__list--multiple .choices__item{background-color:#aaa;border:1px solid #919191}.choices__list--dropdown,.choices__list[aria-expanded]{visibility:hidden;z-index:1;position:absolute;width:100%;background-color:#fff;border:1px solid #ddd;top:100%;margin-top:-1px;border-bottom-left-radius:2.5px;border-bottom-right-radius:2.5px;overflow:hidden;word-break:break-all;will-change:visibility}.is-active.choices__list--dropdown,.is-active.choices__list[aria-expanded]{visibility:visible}.is-open .choices__list--dropdown,.is-open .choices__list[aria-expanded]{border-color:#b7b7b7}.is-flipped .choices__list--dropdown,.is-flipped .choices__list[aria-expanded]{top:auto;bottom:100%;margin-top:0;margin-bottom:-1px;border-radius:.25rem .25rem 0 0}.choices__list--dropdown .choices__list,.choices__list[aria-expanded] .choices__list{position:relative;max-height:300px;overflow:auto;-webkit-overflow-scrolling:touch;will-change:scroll-position}.choices__list--dropdown .choices__item,.choices__list[aria-expanded] .choices__item{position:relative;padding:10px;font-size:14px}[dir=rtl] .choices__list--dropdown .choices__item,[dir=rtl] .choices__list[aria-expanded] .choices__item{text-align:right}@media (min-width:640px){.choices__list--dropdown .choices__item--selectable,.choices__list[aria-expanded] .choices__item--selectable{padding-right:100px}.choices__list--dropdown .choices__item--selectable::after,.choices__list[aria-expanded] .choices__item--selectable::after{content:attr(data-select-text);font-size:12px;opacity:0;position:absolute;right:10px;top:50%;transform:translateY(-50%)}[dir=rtl] .choices__list--dropdown .choices__item--selectable,[dir=rtl] .choices__list[aria-expanded] .choices__item--selectable{text-align:right;padding-left:100px;padding-right:10px}[dir=rtl] .choices__list--dropdown .choices__item--selectable::after,[dir=rtl] .choices__list[aria-expanded] .choices__item--selectable::after{right:auto;left:10px}}.choices__list--dropdown .choices__item--selectable.is-highlighted,.choices__list[aria-expanded] .choices__item--selectable.is-highlighted{background-color:#f2f2f2}.choices__list--dropdown .choices__item--selectable.is-highlighted::after,.choices__list[aria-expanded] .choices__item--selectable.is-highlighted::after{opacity:.5}.choices__item{cursor:default}.choices__item--selectable{cursor:pointer}.choices__item--disabled{cursor:not-allowed;-webkit-user-select:none;user-select:none;opacity:.5}.choices__heading{font-weight:600;font-size:12px;padding:10px;border-bottom:1px solid #f7f7f7;color:gray}.choices__button{text-indent:-9999px;-webkit-appearance:none;appearance:none;border:0;background-color:transparent;background-repeat:no-repeat;background-position:center;cursor:pointer}.choices__button:focus,.choices__input:focus{outline:0}.choices__input{display:inline-block;vertical-align:baseline;background-color:#f9f9f9;font-size:14px;margin-bottom:5px;border:0;border-radius:0;max-width:100%;padding:4px 0 4px 2px}.choices__input::-webkit-search-cancel-button,.choices__input::-webkit-search-decoration,.choices__input::-webkit-search-results-button,.choices__input::-webkit-search-results-decoration{display:none}.choices__input::-ms-clear,.choices__input::-ms-reveal{display:none;width:0;height:0}[dir=rtl] .choices__input{padding-right:2px;padding-left:0}.choices__placeholder{opacity:.5} \ No newline at end of file +.choices{position:relative;overflow:hidden;margin-bottom:24px;font-size:16px}.choices:focus{outline:0}.choices:last-child{margin-bottom:0}.choices.is-open{overflow:visible}.choices.is-disabled .choices__inner,.choices.is-disabled .choices__input{background-color:#eaeaea;cursor:not-allowed;-webkit-user-select:none;user-select:none}.choices.is-disabled .choices__item{cursor:not-allowed}.choices [hidden]{display:none!important}.choices[data-type*=select-one]{cursor:pointer}.choices[data-type*=select-one] .choices__inner{padding-bottom:7.5px}.choices[data-type*=select-one] .choices__input{display:block;width:100%;padding:10px;border-bottom:1px solid #ddd;background-color:#fff;margin:0}.choices[data-type*=select-one] .choices__button{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==);padding:0;background-size:8px;position:absolute;top:50%;right:0;margin-top:-10px;margin-right:25px;height:20px;width:20px;border-radius:10em;opacity:.25}.choices[data-type*=select-one] .choices__button:focus,.choices[data-type*=select-one] .choices__button:hover{opacity:1}.choices[data-type*=select-one] .choices__button:focus{box-shadow:0 0 0 2px #005f75}.choices[data-type*=select-one] .choices__item[data-placeholder] .choices__button{display:none}.choices[data-type*=select-one]::after{content:"";height:0;width:0;border-style:solid;border-color:#333 transparent transparent;border-width:5px;position:absolute;right:11.5px;top:50%;margin-top:-2.5px;pointer-events:none}.choices[data-type*=select-one].is-open::after{border-color:transparent transparent #333;margin-top:-7.5px}.choices[data-type*=select-one][dir=rtl]::after{left:11.5px;right:auto}.choices[data-type*=select-one][dir=rtl] .choices__button{right:auto;left:0;margin-left:25px;margin-right:0}.choices[data-type*=select-multiple] .choices__inner,.choices[data-type*=text] .choices__inner{cursor:text}.choices[data-type*=select-multiple] .choices__button,.choices[data-type*=text] .choices__button{position:relative;display:inline-block;margin:0-4px 0 8px;padding-left:16px;border-left:1px solid #003642;background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==);background-size:8px;width:8px;line-height:1;opacity:.75;border-radius:0}.choices[data-type*=select-multiple] .choices__button:focus,.choices[data-type*=select-multiple] .choices__button:hover,.choices[data-type*=text] .choices__button:focus,.choices[data-type*=text] .choices__button:hover{opacity:1}.choices__inner{display:inline-block;vertical-align:top;width:100%;background-color:#f9f9f9;padding:7.5px 7.5px 3.75px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;min-height:44px;overflow:hidden}.is-focused .choices__inner,.is-open .choices__inner{border-color:#b7b7b7}.is-open .choices__inner{border-radius:2.5px 2.5px 0 0}.is-flipped.is-open .choices__inner{border-radius:0 0 2.5px 2.5px}.choices__list{margin:0;padding-left:0;list-style:none}.choices__list--single{display:inline-block;padding:4px 16px 4px 4px;width:100%}[dir=rtl] .choices__list--single{padding-right:4px;padding-left:16px}.choices__list--single .choices__item{width:100%}.choices__list--multiple{display:inline}.choices__list--multiple .choices__item{display:inline-block;vertical-align:middle;border-radius:20px;padding:4px 10px;font-size:12px;font-weight:500;margin-right:3.75px;margin-bottom:3.75px;background-color:#005f75;border:1px solid #004a5c;color:#fff;word-break:break-all;box-sizing:border-box}.choices__list--multiple .choices__item[data-deletable]{padding-right:5px}[dir=rtl] .choices__list--multiple .choices__item{margin-right:0;margin-left:3.75px}.choices__list--multiple .choices__item.is-highlighted{background-color:#004a5c;border:1px solid #003642}.is-disabled .choices__list--multiple .choices__item{background-color:#aaa;border:1px solid #919191}.choices__list--dropdown,.choices__list[aria-expanded]{display:none;z-index:1;position:absolute;width:100%;background-color:#fff;border:1px solid #ddd;top:100%;margin-top:-1px;border-bottom-left-radius:2.5px;border-bottom-right-radius:2.5px;overflow:hidden;word-break:break-all}.is-active.choices__list--dropdown,.is-active.choices__list[aria-expanded]{display:block}.is-open .choices__list--dropdown,.is-open .choices__list[aria-expanded]{border-color:#b7b7b7}.is-flipped .choices__list--dropdown,.is-flipped .choices__list[aria-expanded]{top:auto;bottom:100%;margin-top:0;margin-bottom:-1px;border-radius:.25rem .25rem 0 0}.choices__list--dropdown .choices__list,.choices__list[aria-expanded] .choices__list{position:relative;max-height:300px;overflow:auto;-webkit-overflow-scrolling:touch;will-change:scroll-position}.choices__list--dropdown .choices__item,.choices__list[aria-expanded] .choices__item{position:relative;padding:10px;font-size:14px}[dir=rtl] .choices__list--dropdown .choices__item,[dir=rtl] .choices__list[aria-expanded] .choices__item{text-align:right}@media (min-width:640px){.choices__list--dropdown .choices__item--selectable[data-select-text],.choices__list[aria-expanded] .choices__item--selectable[data-select-text]{padding-right:100px}.choices__list--dropdown .choices__item--selectable[data-select-text]::after,.choices__list[aria-expanded] .choices__item--selectable[data-select-text]::after{content:attr(data-select-text);font-size:12px;opacity:0;position:absolute;right:10px;top:50%;transform:translateY(-50%)}[dir=rtl] .choices__list--dropdown .choices__item--selectable[data-select-text],[dir=rtl] .choices__list[aria-expanded] .choices__item--selectable[data-select-text]{text-align:right;padding-left:100px;padding-right:10px}[dir=rtl] .choices__list--dropdown .choices__item--selectable[data-select-text]::after,[dir=rtl] .choices__list[aria-expanded] .choices__item--selectable[data-select-text]::after{right:auto;left:10px}}.choices__list--dropdown .choices__item--selectable.is-highlighted,.choices__list[aria-expanded] .choices__item--selectable.is-highlighted{background-color:#f2f2f2}.choices__list--dropdown .choices__item--selectable.is-highlighted::after,.choices__list[aria-expanded] .choices__item--selectable.is-highlighted::after{opacity:.5}.choices__item{cursor:default}.choices__item--selectable{cursor:pointer}.choices__item--disabled{cursor:not-allowed;-webkit-user-select:none;user-select:none;opacity:.5}.choices__heading{font-weight:600;font-size:12px;padding:10px;border-bottom:1px solid #f7f7f7;color:gray}.choices__button{text-indent:-9999px;appearance:none;border:0;background-color:transparent;background-repeat:no-repeat;background-position:center;cursor:pointer}.choices__button:focus,.choices__input:focus{outline:0}.choices__input{display:inline-block;vertical-align:baseline;background-color:#f9f9f9;font-size:14px;margin-bottom:5px;border:0;border-radius:0;max-width:100%;padding:4px 0 4px 2px}.choices__input::-webkit-search-cancel-button,.choices__input::-webkit-search-decoration,.choices__input::-webkit-search-results-button,.choices__input::-webkit-search-results-decoration{display:none}.choices__input::-ms-clear,.choices__input::-ms-reveal{display:none;width:0;height:0}[dir=rtl] .choices__input{padding-right:2px;padding-left:0}.choices__placeholder{opacity:.5} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/index.html b/assets/extensions/choices.js/public/index.html new file mode 100644 index 00000000..92b5efa7 --- /dev/null +++ b/assets/extensions/choices.js/public/index.html @@ -0,0 +1,968 @@ + + + + + + Choices + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +

+ Choices.js is a lightweight, configurable select box/text input + plugin. Similar to Select2 and Selectize but without the jQuery + dependency. +

+

+ For all config options, visit the + GitHub repo. +

+ +
+

+ Interested in writing your own ES6 JavaScript plugins? Check out + ES6.io for great + tutorials! 💪🏼 +

+

+ Sponsored by: +
+ + Wanderer Maps logo + +

+
+ +

Text inputs

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +

Multiple select input

+ + + + + + + + + +

+ If the following example do not load, the Discogs rate limit has + probably been reached. Try again later! +

+ + + + + + + + +

+ +
+ +

Single select input

+ + + +

+ If the following two examples do not load, the Discogs rate limit + has probably been reached. Try again later! +

+ + + + + + + + + + + + + + + + + + + + +

+ Try searching for 'fantastic', "Label 3" should display +

+ + + +

+ Try searching for 'fantastic', "Label 3" should display +

+ + + + + +
+ + +
+ +

+ Below is an example of how you could have two select inputs depend on + eachother. 'Tube stations' will only be enabled if the value of + 'Cities' is 'London' +

+ + + + + + +
+

Form interaction

+

Change the values and press reset to restore to initial state.

+
+
+ + +
+ + + + + +
+
+
+ + + + + + + + diff --git a/assets/extensions/choices.js/public/robots.txt b/assets/extensions/choices.js/public/robots.txt new file mode 100644 index 00000000..c3e00bd5 --- /dev/null +++ b/assets/extensions/choices.js/public/robots.txt @@ -0,0 +1 @@ +Disallow: /test/* \ No newline at end of file diff --git a/assets/extensions/choices.js/public/test/data.json b/assets/extensions/choices.js/public/test/data.json new file mode 100644 index 00000000..437cfd56 --- /dev/null +++ b/assets/extensions/choices.js/public/test/data.json @@ -0,0 +1,42 @@ +[ + { + "label": "Label 1", + "value": "Value 1" + }, + { + "label": "Label 2", + "value": "Value 2" + }, + { + "label": "Label 3", + "value": "Value 3" + }, + { + "label": "Label 4", + "value": "Value 4" + }, + { + "label": "Label 5", + "value": "Value 5" + }, + { + "label": "Label 6", + "value": "Value 6" + }, + { + "label": "Label 7", + "value": "Value 7" + }, + { + "label": "Label 8", + "value": "Value 8" + }, + { + "label": "Label 9", + "value": "Value 9" + }, + { + "label": "Label 10", + "value": "Value 10" + } +] \ No newline at end of file diff --git a/assets/extensions/choices.js/public/test/select-multiple/index-performance.html b/assets/extensions/choices.js/public/test/select-multiple/index-performance.html new file mode 100644 index 00000000..80f85222 --- /dev/null +++ b/assets/extensions/choices.js/public/test/select-multiple/index-performance.html @@ -0,0 +1,101 @@ + + + + + + Choices + + + + + + + + + + + + + + + + + + + + + +
+
+

Select multiple inputs

+
+ + + + + +
+
+
+ + diff --git a/assets/extensions/choices.js/public/test/select-multiple/index.html b/assets/extensions/choices.js/public/test/select-multiple/index.html new file mode 100644 index 00000000..854db4d1 --- /dev/null +++ b/assets/extensions/choices.js/public/test/select-multiple/index.html @@ -0,0 +1,951 @@ + + + + + + Choices + + + + + + + + + + + + + + + + + + + + + +
+
+

Select multiple inputs

+
+ + + + + +
+ +
+ + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
+ + +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
+ + +
+ + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + + +
+ +
+ + + + + +
+ +
+ +
+ +
+
+
+ + diff --git a/assets/extensions/choices.js/public/test/select-one/index.html b/assets/extensions/choices.js/public/test/select-one/index.html new file mode 100644 index 00000000..73f5d255 --- /dev/null +++ b/assets/extensions/choices.js/public/test/select-one/index.html @@ -0,0 +1,903 @@ + + + + + + Choices + + + + + + + + + + + + + + + + + + + + + +
+
+

Select one inputs

+
+ + + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
+ + +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + + + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
+ + +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + + + +
+ +
+ +
+ +
+
+
+ + diff --git a/assets/extensions/choices.js/public/test/text/index.html b/assets/extensions/choices.js/public/test/text/index.html new file mode 100644 index 00000000..89687aae --- /dev/null +++ b/assets/extensions/choices.js/public/test/text/index.html @@ -0,0 +1,375 @@ + + + + + + Choices + + + + + + + + + + + + + + + + + + + + + +
+
+

Text inputs

+
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+ +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
+ + +
+ +
+ +
+ + + + + +
+ +
+ +
+ +
+ +
+
+ + diff --git a/assets/extensions/choices.js/public/types/cypress/e2e/select-multiple.spec.d.ts b/assets/extensions/choices.js/public/types/cypress/e2e/select-multiple.spec.d.ts deleted file mode 100644 index 6c3e952d..00000000 --- a/assets/extensions/choices.js/public/types/cypress/e2e/select-multiple.spec.d.ts +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=select-multiple.spec.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/e2e/select-multiple.spec.d.ts.map b/assets/extensions/choices.js/public/types/cypress/e2e/select-multiple.spec.d.ts.map deleted file mode 100644 index fd77f545..00000000 --- a/assets/extensions/choices.js/public/types/cypress/e2e/select-multiple.spec.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"select-multiple.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/e2e/select-multiple.spec.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/e2e/select-one.spec.d.ts b/assets/extensions/choices.js/public/types/cypress/e2e/select-one.spec.d.ts deleted file mode 100644 index 9de7a41d..00000000 --- a/assets/extensions/choices.js/public/types/cypress/e2e/select-one.spec.d.ts +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=select-one.spec.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/e2e/select-one.spec.d.ts.map b/assets/extensions/choices.js/public/types/cypress/e2e/select-one.spec.d.ts.map deleted file mode 100644 index cb7b6e20..00000000 --- a/assets/extensions/choices.js/public/types/cypress/e2e/select-one.spec.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"select-one.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/e2e/select-one.spec.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/e2e/text.spec.d.ts b/assets/extensions/choices.js/public/types/cypress/e2e/text.spec.d.ts deleted file mode 100644 index cfb9d2df..00000000 --- a/assets/extensions/choices.js/public/types/cypress/e2e/text.spec.d.ts +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=text.spec.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/e2e/text.spec.d.ts.map b/assets/extensions/choices.js/public/types/cypress/e2e/text.spec.d.ts.map deleted file mode 100644 index 94ccbad2..00000000 --- a/assets/extensions/choices.js/public/types/cypress/e2e/text.spec.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"text.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/e2e/text.spec.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/integration/select-multiple.spec.d.ts b/assets/extensions/choices.js/public/types/cypress/integration/select-multiple.spec.d.ts deleted file mode 100644 index 6c3e952d..00000000 --- a/assets/extensions/choices.js/public/types/cypress/integration/select-multiple.spec.d.ts +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=select-multiple.spec.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/integration/select-multiple.spec.d.ts.map b/assets/extensions/choices.js/public/types/cypress/integration/select-multiple.spec.d.ts.map deleted file mode 100644 index b1fdcc1f..00000000 --- a/assets/extensions/choices.js/public/types/cypress/integration/select-multiple.spec.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"select-multiple.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/integration/select-multiple.spec.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/integration/select-one.spec.d.ts b/assets/extensions/choices.js/public/types/cypress/integration/select-one.spec.d.ts deleted file mode 100644 index 9de7a41d..00000000 --- a/assets/extensions/choices.js/public/types/cypress/integration/select-one.spec.d.ts +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=select-one.spec.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/integration/select-one.spec.d.ts.map b/assets/extensions/choices.js/public/types/cypress/integration/select-one.spec.d.ts.map deleted file mode 100644 index d2a6b77b..00000000 --- a/assets/extensions/choices.js/public/types/cypress/integration/select-one.spec.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"select-one.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/integration/select-one.spec.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/integration/text.spec.d.ts b/assets/extensions/choices.js/public/types/cypress/integration/text.spec.d.ts deleted file mode 100644 index cfb9d2df..00000000 --- a/assets/extensions/choices.js/public/types/cypress/integration/text.spec.d.ts +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=text.spec.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/integration/text.spec.d.ts.map b/assets/extensions/choices.js/public/types/cypress/integration/text.spec.d.ts.map deleted file mode 100644 index cb8c740b..00000000 --- a/assets/extensions/choices.js/public/types/cypress/integration/text.spec.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"text.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/integration/text.spec.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/plugins/index.d.ts b/assets/extensions/choices.js/public/types/cypress/plugins/index.d.ts deleted file mode 100644 index 2e1bed6c..00000000 --- a/assets/extensions/choices.js/public/types/cypress/plugins/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare function _exports(on: any, config: any): void; -export = _exports; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/plugins/index.d.ts.map b/assets/extensions/choices.js/public/types/cypress/plugins/index.d.ts.map deleted file mode 100644 index 51c72de1..00000000 --- a/assets/extensions/choices.js/public/types/cypress/plugins/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../cypress/plugins/index.js"],"names":[],"mappings":"AAaiB,sDAGhB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/support/commands.d.ts b/assets/extensions/choices.js/public/types/cypress/support/commands.d.ts deleted file mode 100644 index b7ad2b32..00000000 --- a/assets/extensions/choices.js/public/types/cypress/support/commands.d.ts +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=commands.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/support/commands.d.ts.map b/assets/extensions/choices.js/public/types/cypress/support/commands.d.ts.map deleted file mode 100644 index b4cb5324..00000000 --- a/assets/extensions/choices.js/public/types/cypress/support/commands.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../cypress/support/commands.js"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/support/e2e.d.ts b/assets/extensions/choices.js/public/types/cypress/support/e2e.d.ts deleted file mode 100644 index aafedb01..00000000 --- a/assets/extensions/choices.js/public/types/cypress/support/e2e.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=e2e.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/support/e2e.d.ts.map b/assets/extensions/choices.js/public/types/cypress/support/e2e.d.ts.map deleted file mode 100644 index 9d383030..00000000 --- a/assets/extensions/choices.js/public/types/cypress/support/e2e.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"e2e.d.ts","sourceRoot":"","sources":["../../../../cypress/support/e2e.js"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/support/index.d.ts b/assets/extensions/choices.js/public/types/cypress/support/index.d.ts deleted file mode 100644 index e26a57a8..00000000 --- a/assets/extensions/choices.js/public/types/cypress/support/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/cypress/support/index.d.ts.map b/assets/extensions/choices.js/public/types/cypress/support/index.d.ts.map deleted file mode 100644 index 02df4028..00000000 --- a/assets/extensions/choices.js/public/types/cypress/support/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../cypress/support/index.js"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/index.d.ts b/assets/extensions/choices.js/public/types/src/index.d.ts index dee565e3..8a789802 100644 --- a/assets/extensions/choices.js/public/types/src/index.d.ts +++ b/assets/extensions/choices.js/public/types/src/index.d.ts @@ -4,4 +4,3 @@ export * from './scripts/constants'; export * from './scripts/defaults'; export { default as templates } from './scripts/templates'; export default Choices; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/index.d.ts.map b/assets/extensions/choices.js/public/types/src/index.d.ts.map deleted file mode 100644 index c7f1a923..00000000 --- a/assets/extensions/choices.js/public/types/src/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,mBAAmB,CAAC;AAExC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE3D,eAAe,OAAO,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/choices.d.ts b/assets/extensions/choices.js/public/types/src/scripts/actions/choices.d.ts index 61a1b30e..73717232 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/choices.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/actions/choices.d.ts @@ -1,44 +1,30 @@ -import { ACTION_TYPES } from '../constants'; -import { Choice } from '../interfaces/choice'; -export interface AddChoiceAction { - type: typeof ACTION_TYPES.ADD_CHOICE; - id: number; - value: string; - label: string; - groupId: number; - disabled: boolean; - elementId: number; - customProperties: object; - placeholder: boolean; - keyCode: number; +import { ChoiceFull } from '../interfaces/choice-full'; +import { ActionType } from '../interfaces'; +import { SearchResult } from '../interfaces/search'; +import { AnyAction } from '../interfaces/store'; +export type ChoiceActions = AddChoiceAction | RemoveChoiceAction | FilterChoicesAction | ActivateChoicesAction | ClearChoicesAction; +export interface AddChoiceAction extends AnyAction { + choice: ChoiceFull; } -export interface Result { - item: T; - score: number; +export interface RemoveChoiceAction extends AnyAction { + choice: ChoiceFull; } -export interface FilterChoicesAction { - type: typeof ACTION_TYPES.FILTER_CHOICES; - results: Result[]; +export interface FilterChoicesAction extends AnyAction { + results: SearchResult[]; } -export interface ActivateChoicesAction { - type: typeof ACTION_TYPES.ACTIVATE_CHOICES; +export interface ActivateChoicesAction extends AnyAction { active: boolean; } -export interface ClearChoicesAction { - type: typeof ACTION_TYPES.CLEAR_CHOICES; +/** + * @deprecated use clearStore() or clearChoices() instead. + */ +export interface ClearChoicesAction extends AnyAction { } -export declare const addChoice: ({ value, label, id, groupId, disabled, elementId, customProperties, placeholder, keyCode, }: { - value: any; - label: any; - id: any; - groupId: any; - disabled: any; - elementId: any; - customProperties: any; - placeholder: any; - keyCode: any; -}) => AddChoiceAction; -export declare const filterChoices: (results: Result[]) => FilterChoicesAction; +export declare const addChoice: (choice: ChoiceFull) => AddChoiceAction; +export declare const removeChoice: (choice: ChoiceFull) => RemoveChoiceAction; +export declare const filterChoices: (results: SearchResult[]) => FilterChoicesAction; export declare const activateChoices: (active?: boolean) => ActivateChoicesAction; +/** + * @deprecated use clearStore() or clearChoices() instead. + */ export declare const clearChoices: () => ClearChoicesAction; -//# sourceMappingURL=choices.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/choices.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/actions/choices.d.ts.map deleted file mode 100644 index 2e69e60c..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/choices.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"choices.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/choices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,YAAY,CAAC,UAAU,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,YAAY,CAAC,cAAc,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,YAAY,CAAC,gBAAgB,CAAC;IAC3C,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,YAAY,CAAC,aAAa,CAAC;CACzC;AAED,eAAO,MAAM,SAAS;;;;;;;;;;MAUlB,eAWF,CAAC;AAEH,eAAO,MAAM,aAAa,YACf,OAAO,MAAM,CAAC,EAAE,KACxB,mBAGD,CAAC;AAEH,eAAO,MAAM,eAAe,wBAAoB,qBAG9C,CAAC;AAEH,eAAO,MAAM,YAAY,QAAO,kBAE9B,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/choices.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/actions/choices.test.d.ts deleted file mode 100644 index 1b34de17..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/choices.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=choices.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/choices.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/actions/choices.test.d.ts.map deleted file mode 100644 index 0f1c3a57..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/choices.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"choices.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/choices.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/groups.d.ts b/assets/extensions/choices.js/public/types/src/scripts/actions/groups.d.ts index ad7a8b7c..4f96b6d7 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/groups.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/actions/groups.d.ts @@ -1,15 +1,8 @@ -import { ACTION_TYPES } from '../constants'; -export interface AddGroupAction { - type: typeof ACTION_TYPES.ADD_GROUP; - id: number; - value: string; - active: boolean; - disabled: boolean; +import { GroupFull } from '../interfaces/group-full'; +import { ActionType } from '../interfaces'; +import { AnyAction } from '../interfaces/store'; +export type GroupActions = AddGroupAction; +export interface AddGroupAction extends AnyAction { + group: GroupFull; } -export declare const addGroup: ({ value, id, active, disabled, }: { - id: number; - value: string; - active: boolean; - disabled: boolean; -}) => AddGroupAction; -//# sourceMappingURL=groups.d.ts.map \ No newline at end of file +export declare const addGroup: (group: GroupFull) => AddGroupAction; diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/groups.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/actions/groups.d.ts.map deleted file mode 100644 index 4fd75160..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/groups.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"groups.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/groups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,YAAY,CAAC,SAAS,CAAC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,QAAQ;QAMf,MAAM;WACH,MAAM;YACL,OAAO;cACL,OAAO;MACf,cAMF,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/groups.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/actions/groups.test.d.ts deleted file mode 100644 index 8d44d56e..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/groups.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=groups.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/groups.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/actions/groups.test.d.ts.map deleted file mode 100644 index 80ca388f..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/groups.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"groups.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/groups.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/items.d.ts b/assets/extensions/choices.js/public/types/src/scripts/actions/items.d.ts index 96b0b2a8..d4af0b89 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/items.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/actions/items.d.ts @@ -1,35 +1,17 @@ -import { ACTION_TYPES } from '../constants'; -export interface AddItemAction { - type: typeof ACTION_TYPES.ADD_ITEM; - id: number; - value: string; - label: string; - choiceId: number; - groupId: number; - customProperties: object; - placeholder: boolean; - keyCode: number; +import { ChoiceFull } from '../interfaces/choice-full'; +import { ActionType } from '../interfaces'; +import { AnyAction } from '../interfaces/store'; +export type ItemActions = AddItemAction | RemoveItemAction | HighlightItemAction; +export interface AddItemAction extends AnyAction { + item: ChoiceFull; } -export interface RemoveItemAction { - type: typeof ACTION_TYPES.REMOVE_ITEM; - id: number; - choiceId: number; +export interface RemoveItemAction extends AnyAction { + item: ChoiceFull; } -export interface HighlightItemAction { - type: typeof ACTION_TYPES.HIGHLIGHT_ITEM; - id: number; +export interface HighlightItemAction extends AnyAction { + item: ChoiceFull; highlighted: boolean; } -export declare const addItem: ({ value, label, id, choiceId, groupId, customProperties, placeholder, keyCode, }: { - id: number; - value: string; - label: string; - choiceId: number; - groupId: number; - customProperties: object; - placeholder: boolean; - keyCode: number; -}) => AddItemAction; -export declare const removeItem: (id: number, choiceId: number) => RemoveItemAction; -export declare const highlightItem: (id: number, highlighted: boolean) => HighlightItemAction; -//# sourceMappingURL=items.d.ts.map \ No newline at end of file +export declare const addItem: (item: ChoiceFull) => AddItemAction; +export declare const removeItem: (item: ChoiceFull) => RemoveItemAction; +export declare const highlightItem: (item: ChoiceFull, highlighted: boolean) => HighlightItemAction; diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/items.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/actions/items.d.ts.map deleted file mode 100644 index 2ad25909..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/items.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"items.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,YAAY,CAAC,QAAQ,CAAC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,YAAY,CAAC,WAAW,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,YAAY,CAAC,cAAc,CAAC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,OAAO;QAUd,MAAM;WACH,MAAM;WACN,MAAM;cACH,MAAM;aACP,MAAM;sBACG,MAAM;iBACX,OAAO;aACX,MAAM;MACb,aAUF,CAAC;AAEH,eAAO,MAAM,UAAU,OAAQ,MAAM,YAAY,MAAM,KAAG,gBAIxD,CAAC;AAEH,eAAO,MAAM,aAAa,OACpB,MAAM,eACG,OAAO,KACnB,mBAID,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/items.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/actions/items.test.d.ts deleted file mode 100644 index e81d58b4..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/items.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=items.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/items.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/actions/items.test.d.ts.map deleted file mode 100644 index 77773c21..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/items.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"items.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/items.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/misc.d.ts b/assets/extensions/choices.js/public/types/src/scripts/actions/misc.d.ts deleted file mode 100644 index 65e1faf1..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/misc.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ACTION_TYPES } from '../constants'; -import { State } from '../interfaces/state'; -export interface ClearAllAction { - type: typeof ACTION_TYPES.CLEAR_ALL; -} -export interface ResetToAction { - type: typeof ACTION_TYPES.RESET_TO; - state: State; -} -export interface SetIsLoadingAction { - type: typeof ACTION_TYPES.SET_IS_LOADING; - isLoading: boolean; -} -export declare const clearAll: () => ClearAllAction; -export declare const resetTo: (state: State) => ResetToAction; -export declare const setIsLoading: (isLoading: boolean) => SetIsLoadingAction; -//# sourceMappingURL=misc.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/misc.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/actions/misc.d.ts.map deleted file mode 100644 index 0e77eb24..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/misc.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/misc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,YAAY,CAAC,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,YAAY,CAAC,QAAQ,CAAC;IACnC,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,YAAY,CAAC,cAAc,CAAC;IACzC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,QAAQ,QAAO,cAE1B,CAAC;AAEH,eAAO,MAAM,OAAO,UAAW,KAAK,KAAG,aAGrC,CAAC;AAEH,eAAO,MAAM,YAAY,cAAe,OAAO,KAAG,kBAGhD,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/misc.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/actions/misc.test.d.ts deleted file mode 100644 index c81b2ccc..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/misc.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=misc.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/actions/misc.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/actions/misc.test.d.ts.map deleted file mode 100644 index 912fa189..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/actions/misc.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"misc.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/misc.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/choices.d.ts b/assets/extensions/choices.js/public/types/src/scripts/choices.d.ts index accf731a..ea5172fe 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/choices.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/choices.d.ts @@ -1,22 +1,28 @@ import { Container, Dropdown, Input, List, WrappedInput, WrappedSelect } from './components'; -import { Choice } from './interfaces/choice'; -import { Group } from './interfaces/group'; -import { Item } from './interfaces/item'; -import { Notice } from './interfaces/notice'; +import { InputChoice } from './interfaces/input-choice'; +import { InputGroup } from './interfaces/input-group'; import { Options } from './interfaces/options'; -import { State } from './interfaces/state'; +import { StateChangeSet } from './interfaces/state'; import Store from './store/store'; -import templates from './templates'; +import { ChoiceFull } from './interfaces/choice-full'; +import { GroupFull } from './interfaces/group-full'; +import { PassedElementType } from './interfaces'; +import { EventChoice } from './interfaces/event-choice'; +import { NoticeType, Templates } from './interfaces/templates'; +import { Searcher } from './interfaces/search'; /** * Choices * @author Josh Johnson */ -declare class Choices implements Choices { +declare class Choices { + static version: string; static get defaults(): { options: Partial; - templates: typeof templates; + allOptions: Options; + templates: Templates; }; initialised: boolean; + initialisedOK?: boolean; config: Options; passedElement: WrappedInput | WrappedSelect; containerOuter: Container; @@ -25,15 +31,17 @@ declare class Choices implements Choices { itemList: List; input: Input; dropdown: Dropdown; + _elementType: PassedElementType; _isTextElement: boolean; _isSelectOneElement: boolean; _isSelectMultipleElement: boolean; _isSelectElement: boolean; - _store: Store; - _templates: typeof templates; - _initialState: State; - _currentState: State; - _prevState: State; + _hasNonChoicePlaceholder: boolean; + _canAddUserChoices: boolean; + _store: Store; + _templates: Templates; + _lastAddedChoiceId: number; + _lastAddedGroupId: number; _currentValue: string; _canSearch: boolean; _isScrollingOnIe: boolean; @@ -46,26 +54,30 @@ declare class Choices implements Choices { _idNames: { itemChoice: string; }; - _presetGroups: Group[] | HTMLOptGroupElement[] | Element[]; - _presetOptions: Item[] | HTMLOptionElement[]; - _presetChoices: Partial[]; - _presetItems: Item[] | string[]; + _presetChoices: (ChoiceFull | GroupFull)[]; + _initialItems: string[]; + _searcher: Searcher; + _notice?: { + type: NoticeType; + text: string; + }; + _docRoot: ShadowRoot | HTMLElement; constructor(element?: string | Element | HTMLInputElement | HTMLSelectElement, userConfig?: Partial); init(): void; destroy(): void; enable(): this; disable(): this; - highlightItem(item: Item, runEvent?: boolean): this; - unhighlightItem(item: Item): this; + highlightItem(item: InputChoice, runEvent?: boolean): this; + unhighlightItem(item: InputChoice, runEvent?: boolean): this; highlightAll(): this; unhighlightAll(): this; removeActiveItemsByValue(value: string): this; - removeActiveItems(excludedId: number): this; + removeActiveItems(excludedId?: number): this; removeHighlightedItems(runEvent?: boolean): this; showDropdown(preventInputFocus?: boolean): this; hideDropdown(preventInputBlur?: boolean): this; - getValue(valueOnly?: boolean): string[] | Item[] | Item | string; - setValue(items: string[] | Item[]): this; + getValue(valueOnly?: boolean): string[] | EventChoice[] | EventChoice | string; + setValue(items: string[] | InputChoice[]): this; setChoiceByValue(value: string | string[]): this; /** * Set choices of select input via an array of objects (or function that returns array of object or promise of it), @@ -130,37 +142,42 @@ declare class Choices implements Choices { * }], 'value', 'label', false); * ``` */ - setChoices(choicesArrayOrFetcher?: Choice[] | Group[] | ((instance: Choices) => Choice[] | Promise), value?: string, label?: string, replaceChoices?: boolean): this | Promise; + setChoices(choicesArrayOrFetcher?: (InputChoice | InputGroup)[] | ((instance: Choices) => (InputChoice | InputGroup)[] | Promise<(InputChoice | InputGroup)[]>), value?: string | null, label?: string, replaceChoices?: boolean): this | Promise; + refresh(withEvents?: boolean, selectFirstOption?: boolean, deselectAll?: boolean): this; + removeChoice(value: string): this; clearChoices(): this; clearStore(): this; clearInput(): this; - _render(): void; + _validateConfig(): void; + _render(changes?: StateChangeSet): void; _renderChoices(): void; _renderItems(): void; - _createGroupsFragment(groups: Group[], choices: Choice[], fragment?: DocumentFragment): DocumentFragment; - _createChoicesFragment(choices: Choice[], fragment?: DocumentFragment, withinGroup?: boolean): DocumentFragment; - _createItemsFragment(items: Item[], fragment?: DocumentFragment): DocumentFragment; + _displayNotice(text: string, type: NoticeType, openDropdown?: boolean): void; + _clearNotice(): void; + _renderNotice(fragment?: DocumentFragment): void; + _getChoiceForOutput(choice?: ChoiceFull, keyCode?: number): EventChoice | undefined; _triggerChange(value: any): void; - _selectPlaceholderChoice(placeholderChoice: Choice): void; - _handleButtonAction(activeItems?: Item[], element?: HTMLElement): void; - _handleItemAction(activeItems?: Item[], element?: HTMLElement, hasShiftKey?: boolean): void; - _handleChoiceAction(activeItems?: Item[], element?: HTMLElement): void; - _handleBackspace(activeItems?: Item[]): void; - _startLoading(): void; - _stopLoading(): void; + _handleButtonAction(element?: HTMLElement): void; + _handleItemAction(element?: HTMLElement, hasShiftKey?: boolean): void; + _handleChoiceAction(element?: HTMLElement): boolean; + _handleBackspace(items: ChoiceFull[]): void; + _loadChoices(): void; _handleLoadingState(setLoading?: boolean): void; - _handleSearch(value: string): void; - _canAddItem(activeItems: Item[], value: string): Notice; - _searchChoices(value: string): number; + _handleSearch(value?: string): void; + _canAddItems(): boolean; + _canCreateItem(value: string): boolean; + _searchChoices(value: string): number | null; + _stopSearch(): void; _addEventListeners(): void; _removeEventListeners(): void; _onKeyDown(event: KeyboardEvent): void; - _onKeyUp({ target, keyCode, }: Pick): void; + _onKeyUp(): void; + _onInput(): void; _onSelectKey(event: KeyboardEvent, hasItems: boolean): void; - _onEnterKey(event: KeyboardEvent, activeItems: Item[], hasActiveDropdown: boolean): void; - _onEscapeKey(hasActiveDropdown: boolean): void; + _onEnterKey(event: KeyboardEvent, hasActiveDropdown: boolean): void; + _onEscapeKey(event: KeyboardEvent, hasActiveDropdown: boolean): void; _onDirectionKey(event: KeyboardEvent, hasActiveDropdown: boolean): void; - _onDeleteKey(event: KeyboardEvent, activeItems: Item[], hasFocusedInput: boolean): void; + _onDeleteKey(event: KeyboardEvent, items: ChoiceFull[], hasFocusedInput: boolean): void; _onTouchMove(): void; _onTouchEnd(event: TouchEvent): void; /** @@ -177,42 +194,17 @@ declare class Choices implements Choices { _onBlur({ target }: Pick): void; _onFormReset(): void; _highlightChoice(el?: HTMLElement | null): void; - _addItem({ value, label, choiceId, groupId, customProperties, placeholder, keyCode, }: { - value: string; - label?: string | null; - choiceId?: number; - groupId?: number; - customProperties?: object; - placeholder?: boolean; - keyCode?: number; - }): void; - _removeItem(item: Item): void; - _addChoice({ value, label, isSelected, isDisabled, groupId, customProperties, placeholder, keyCode, }: { - value: string; - label?: string | null; - isSelected?: boolean; - isDisabled?: boolean; - groupId?: number; - customProperties?: Record; - placeholder?: boolean; - keyCode?: number; - }): void; - _addGroup({ group, id, valueKey, labelKey }: { - group: any; - id: any; - valueKey?: string | undefined; - labelKey?: string | undefined; - }): void; - _getTemplate(template: string, ...args: any): any; + _addItem(item: ChoiceFull, withEvents?: boolean, userTriggered?: boolean): void; + _removeItem(item: ChoiceFull): void; + _addChoice(choice: ChoiceFull, withEvents?: boolean, userTriggered?: boolean): void; + _addGroup(group: GroupFull, withEvents?: boolean): void; _createTemplates(): void; _createElements(): void; _createStructure(): void; - _addPredefinedGroups(groups: Group[] | HTMLOptGroupElement[] | Element[]): void; - _addPredefinedChoices(choices: Partial[]): void; - _addPredefinedItems(items: Item[] | string[]): void; - _setChoiceOrItem(item: any): void; - _findAndSelectChoiceByValue(value: string): void; + _initStore(): void; + _addPredefinedChoices(choices: (ChoiceFull | GroupFull)[], selectFirstOption?: boolean, withEvents?: boolean): void; + _findAndSelectChoiceByValue(value: string, userTriggered?: boolean): boolean; _generatePlaceholderValue(): string | null; + _warnChoicesInitFailed(caller: string): void; } export default Choices; -//# sourceMappingURL=choices.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/choices.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/choices.d.ts.map deleted file mode 100644 index 32cb7a2e..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/choices.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"choices.d.ts","sourceRoot":"","sources":["../../../../src/scripts/choices.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,SAAS,EACT,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,aAAa,EACd,MAAM,cAAc,CAAC;AAStB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAe3C,OAAO,KAAK,MAAM,eAAe,CAAC;AAClC,OAAO,SAAS,MAAM,aAAa,CAAC;AASpC;;;GAGG;AACH,cAAM,OAAQ,YAAW,OAAO;IAC9B,MAAM,KAAK,QAAQ,IAAI;QACrB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1B,SAAS,EAAE,OAAO,SAAS,CAAC;KAC7B,CASA;IAED,WAAW,EAAE,OAAO,CAAC;IAErB,MAAM,EAAE,OAAO,CAAC;IAEhB,aAAa,EAAE,YAAY,GAAG,aAAa,CAAC;IAE5C,cAAc,EAAE,SAAS,CAAC;IAE1B,cAAc,EAAE,SAAS,CAAC;IAE1B,UAAU,EAAE,IAAI,CAAC;IAEjB,QAAQ,EAAE,IAAI,CAAC;IAEf,KAAK,EAAE,KAAK,CAAC;IAEb,QAAQ,EAAE,QAAQ,CAAC;IAEnB,cAAc,EAAE,OAAO,CAAC;IAExB,mBAAmB,EAAE,OAAO,CAAC;IAE7B,wBAAwB,EAAE,OAAO,CAAC;IAElC,gBAAgB,EAAE,OAAO,CAAC;IAE1B,MAAM,EAAE,KAAK,CAAC;IAEd,UAAU,EAAE,OAAO,SAAS,CAAC;IAE7B,aAAa,EAAE,KAAK,CAAC;IAErB,aAAa,EAAE,KAAK,CAAC;IAErB,UAAU,EAAE,KAAK,CAAC;IAElB,aAAa,EAAE,MAAM,CAAC;IAEtB,UAAU,EAAE,OAAO,CAAC;IAEpB,gBAAgB,EAAE,OAAO,CAAC;IAE1B,kBAAkB,EAAE,MAAM,CAAC;IAE3B,OAAO,EAAE,OAAO,CAAC;IAEjB,YAAY,EAAE,OAAO,CAAC;IAEtB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC,OAAO,EAAE,MAAM,CAAC;IAEhB,UAAU,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;IAE/B,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF,aAAa,EAAE,KAAK,EAAE,GAAG,mBAAmB,EAAE,GAAG,OAAO,EAAE,CAAC;IAE3D,cAAc,EAAE,IAAI,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAE7C,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IAElC,YAAY,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;gBAG9B,OAAO,GACH,MAAM,GACN,OAAO,GACP,gBAAgB,GAChB,iBAAmC,EACvC,UAAU,GAAE,OAAO,CAAC,OAAO,CAAM;IAuLnC,IAAI,IAAI,IAAI;IA+BZ,OAAO,IAAI,IAAI;IAmBf,MAAM,IAAI,IAAI;IAcd,OAAO,IAAI,IAAI;IAcf,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,UAAO,GAAG,IAAI;IAsBhD,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAmBjC,YAAY,IAAI,IAAI;IAMpB,cAAc,IAAI,IAAI;IAMtB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ7C,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAQ3C,sBAAsB,CAAC,QAAQ,UAAQ,GAAG,IAAI;IAa9C,YAAY,CAAC,iBAAiB,CAAC,EAAE,OAAO,GAAG,IAAI;IAmB/C,YAAY,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,IAAI;IAoB9C,QAAQ,CAAC,SAAS,UAAQ,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,GAAG,MAAM;IAc9D,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI;IAUxC,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAchD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8DG;IACH,UAAU,CACR,qBAAqB,GACjB,MAAM,EAAE,GACR,KAAK,EAAE,GACP,CAAC,CAAC,QAAQ,EAAE,OAAO,KAAK,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAM,EAC9D,KAAK,SAAU,EACf,KAAK,SAAU,EACf,cAAc,UAAQ,GACrB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA+FvB,YAAY,IAAI,IAAI;IAMpB,UAAU,IAAI,IAAI;IAMlB,UAAU,IAAI,IAAI;IAYlB,OAAO,IAAI,IAAI;IA8Bf,cAAc,IAAI,IAAI;IA6EtB,YAAY,IAAI,IAAI;IAcpB,qBAAqB,CACnB,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,GAAE,gBAAoD,GAC7D,gBAAgB;IA8BnB,sBAAsB,CACpB,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,GAAE,gBAAoD,EAC9D,WAAW,UAAQ,GAClB,gBAAgB;IAyEnB,oBAAoB,CAClB,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,GAAE,gBAAoD,GAC7D,gBAAgB;IAgCnB,cAAc,CAAC,KAAK,KAAA,GAAG,IAAI;IAU3B,wBAAwB,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI;IAYzD,mBAAmB,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI;IA4BtE,iBAAiB,CACf,WAAW,CAAC,EAAE,IAAI,EAAE,EACpB,OAAO,CAAC,EAAE,WAAW,EACrB,WAAW,UAAQ,GAClB,IAAI;IA4BP,mBAAmB,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI;IAoDtE,gBAAgB,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI;IAwB5C,aAAa,IAAI,IAAI;IAIrB,YAAY,IAAI,IAAI;IAIpB,mBAAmB,CAAC,UAAU,UAAO,GAAG,IAAI;IAuC5C,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IA4BlC,WAAW,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAwDvD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IA6BrC,kBAAkB,IAAI,IAAI;IAsD1B,qBAAqB,IAAI,IAAI;IAmC7B,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAsDtC,QAAQ,CAAC,EACP,MAAM,EACN,OAAO,GACR,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC,GAAG,IAAI;IAoCnD,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAmB3D,WAAW,CACT,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,IAAI,EAAE,EACnB,iBAAiB,EAAE,OAAO,GACzB,IAAI;IA2CP,YAAY,CAAC,iBAAiB,EAAE,OAAO,GAAG,IAAI;IAO9C,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,OAAO,GAAG,IAAI;IAgEvE,YAAY,CACV,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,IAAI,EAAE,EACnB,eAAe,EAAE,OAAO,GACvB,IAAI;IAaP,YAAY,IAAI,IAAI;IAMpB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAyBpC;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAyCrC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,IAAI;IAM1D,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,IAAI;IAkCtD,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,IAAI;IAiCtD,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,IAAI;IA+CrD,YAAY,IAAI,IAAI;IAIpB,gBAAgB,CAAC,EAAE,GAAE,WAAW,GAAG,IAAW,GAAG,IAAI;IAmDrD,QAAQ,CAAC,EACP,KAAK,EACL,KAAY,EACZ,QAAa,EACb,OAAY,EACZ,gBAAqB,EACrB,WAAmB,EACnB,OAAY,GACb,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI;IA+CR,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAmB7B,UAAU,CAAC,EACT,KAAK,EACL,KAAY,EACZ,UAAkB,EAClB,UAAkB,EAClB,OAAY,EACZ,gBAAqB,EACrB,WAAmB,EACnB,OAAY,GACb,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACvC,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI;IAqCR,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,QAAkB,EAAE,QAAkB,EAAE;;;;;KAAA,GAAG,IAAI;IA6CtE,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,GAAG;IAIjD,gBAAgB,IAAI,IAAI;IAcxB,eAAe,IAAI,IAAI;IA6CvB,gBAAgB,IAAI,IAAI;IAmDxB,oBAAoB,CAClB,MAAM,EAAE,KAAK,EAAE,GAAG,mBAAmB,EAAE,GAAG,OAAO,EAAE,GAClD,IAAI;IA2BP,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI;IA0DvD,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI;IAoBnD,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAgDjC,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAoBhD,yBAAyB,IAAI,MAAM,GAAG,IAAI;CA2B3C;AAED,eAAe,OAAO,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/choices.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/choices.test.d.ts deleted file mode 100644 index 1b34de17..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/choices.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=choices.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/choices.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/choices.test.d.ts.map deleted file mode 100644 index 13f8b43e..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/choices.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"choices.test.d.ts","sourceRoot":"","sources":["../../../../src/scripts/choices.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/container.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/container.d.ts index ad8ac4e6..a0a67bba 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/components/container.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/components/container.d.ts @@ -8,7 +8,6 @@ export default class Container { position: PositionOptionsType; isOpen: boolean; isFlipped: boolean; - isFocussed: boolean; isDisabled: boolean; isLoading: boolean; constructor({ element, type, classNames, position, }: { @@ -17,27 +16,21 @@ export default class Container { classNames: ClassNames; position: PositionOptionsType; }); - addEventListeners(): void; - removeEventListeners(): void; /** * Determine whether container should be flipped based on passed * dropdown position */ - shouldFlip(dropdownPos: number): boolean; + shouldFlip(dropdownPos: number, dropdownHeight: number): boolean; setActiveDescendant(activeDescendantID: string): void; removeActiveDescendant(): void; - open(dropdownPos: number): void; + open(dropdownPos: number, dropdownHeight: number): void; close(): void; - focus(): void; addFocusState(): void; removeFocusState(): void; enable(): void; disable(): void; - wrap(element: HTMLSelectElement | HTMLInputElement | HTMLElement): void; + wrap(element: HTMLElement): void; unwrap(element: HTMLElement): void; addLoadingState(): void; removeLoadingState(): void; - _onFocus(): void; - _onBlur(): void; } -//# sourceMappingURL=container.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/container.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/container.d.ts.map deleted file mode 100644 index e253b2fb..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/container.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/container.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,MAAM,CAAC,OAAO,OAAO,SAAS;IAC5B,OAAO,EAAE,WAAW,CAAC;IAErB,IAAI,EAAE,iBAAiB,CAAC;IAExB,UAAU,EAAE,UAAU,CAAC;IAEvB,QAAQ,EAAE,mBAAmB,CAAC;IAE9B,MAAM,EAAE,OAAO,CAAC;IAEhB,SAAS,EAAE,OAAO,CAAC;IAEnB,UAAU,EAAE,OAAO,CAAC;IAEpB,UAAU,EAAE,OAAO,CAAC;IAEpB,SAAS,EAAE,OAAO,CAAC;gBAEP,EACV,OAAO,EACP,IAAI,EACJ,UAAU,EACV,QAAQ,GACT,EAAE;QACD,OAAO,EAAE,WAAW,CAAC;QACrB,IAAI,EAAE,iBAAiB,CAAC;QACxB,UAAU,EAAE,UAAU,CAAC;QACvB,QAAQ,EAAE,mBAAmB,CAAC;KAC/B;IAcD,iBAAiB,IAAI,IAAI;IAKzB,oBAAoB,IAAI,IAAI;IAK5B;;;OAGG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAkBxC,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI;IAIrD,sBAAsB,IAAI,IAAI;IAI9B,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAW/B,KAAK,IAAI,IAAI;IAab,KAAK,IAAI,IAAI;IAMb,aAAa,IAAI,IAAI;IAIrB,gBAAgB,IAAI,IAAI;IAIxB,MAAM,IAAI,IAAI;IASd,OAAO,IAAI,IAAI;IASf,IAAI,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,WAAW,GAAG,IAAI;IAIvE,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IASlC,eAAe,IAAI,IAAI;IAMvB,kBAAkB,IAAI,IAAI;IAM1B,QAAQ,IAAI,IAAI;IAIhB,OAAO,IAAI,IAAI;CAGhB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/container.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/container.test.d.ts deleted file mode 100644 index 1628d9d7..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/container.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=container.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/container.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/container.test.d.ts.map deleted file mode 100644 index 85b9faa6..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/container.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"container.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/container.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.d.ts index a6f57425..64a4a9d2 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.d.ts @@ -10,11 +10,6 @@ export default class Dropdown { type: PassedElementType; classNames: ClassNames; }); - /** - * Bottom position of dropdown in viewport coordinates - */ - get distanceFromTopWindow(): number; - getChild(selector: string): HTMLElement | null; /** * Show dropdown to user by adding active state class */ @@ -24,4 +19,3 @@ export default class Dropdown { */ hide(): this; } -//# sourceMappingURL=dropdown.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.d.ts.map deleted file mode 100644 index 129ec116..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"dropdown.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/dropdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC3B,OAAO,EAAE,WAAW,CAAC;IAErB,IAAI,EAAE,iBAAiB,CAAC;IAExB,UAAU,EAAE,UAAU,CAAC;IAEvB,QAAQ,EAAE,OAAO,CAAC;gBAEN,EACV,OAAO,EACP,IAAI,EACJ,UAAU,GACX,EAAE;QACD,OAAO,EAAE,WAAW,CAAC;QACrB,IAAI,EAAE,iBAAiB,CAAC;QACxB,UAAU,EAAE,UAAU,CAAC;KACxB;IAOD;;OAEG;IACH,IAAI,qBAAqB,IAAI,MAAM,CAElC;IAED,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI9C;;OAEG;IACH,IAAI,IAAI,IAAI;IAQZ;;OAEG;IACH,IAAI,IAAI,IAAI;CAOb"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.test.d.ts deleted file mode 100644 index 2dff0fae..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=dropdown.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.test.d.ts.map deleted file mode 100644 index 4c26ccd8..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/dropdown.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"dropdown.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/dropdown.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/index.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/index.d.ts index b37addf9..fe965926 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/components/index.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/components/index.d.ts @@ -5,4 +5,3 @@ import List from './list'; import WrappedInput from './wrapped-input'; import WrappedSelect from './wrapped-select'; export { Dropdown, Container, Input, List, WrappedInput, WrappedSelect }; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/index.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/index.d.ts.map deleted file mode 100644 index 4e478ab4..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,IAAI,MAAM,QAAQ,CAAC;AAC1B,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAC3C,OAAO,aAAa,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/input.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/input.d.ts index 3b36571d..f1d5aaa9 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/components/input.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/components/input.d.ts @@ -16,7 +16,6 @@ export default class Input { set placeholder(placeholder: string); get value(): string; set value(value: string); - get rawValue(): string; addEventListeners(): void; removeEventListeners(): void; enable(): void; @@ -36,4 +35,3 @@ export default class Input { _onFocus(): void; _onBlur(): void; } -//# sourceMappingURL=input.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/input.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/input.d.ts.map deleted file mode 100644 index 8828eb16..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/input.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/input.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,MAAM,CAAC,OAAO,OAAO,KAAK;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAE1B,IAAI,EAAE,iBAAiB,CAAC;IAExB,UAAU,EAAE,UAAU,CAAC;IAEvB,YAAY,EAAE,OAAO,CAAC;IAEtB,UAAU,EAAE,OAAO,CAAC;IAEpB,UAAU,EAAE,OAAO,CAAC;gBAER,EACV,OAAO,EACP,IAAI,EACJ,UAAU,EACV,YAAY,GACb,EAAE;QACD,OAAO,EAAE,gBAAgB,CAAC;QAC1B,IAAI,EAAE,iBAAiB,CAAC;QACxB,UAAU,EAAE,UAAU,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;KACvB;IAcD,IAAI,WAAW,CAAC,WAAW,EAAE,MAAM,EAElC;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,iBAAiB,IAAI,IAAI;IAazB,oBAAoB,IAAI,IAAI;IAO5B,MAAM,IAAI,IAAI;IAKd,OAAO,IAAI,IAAI;IAKf,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAMZ,KAAK,CAAC,QAAQ,UAAO,GAAG,IAAI;IAY5B;;;OAGG;IACH,QAAQ,IAAI,IAAI;IAOhB,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI;IAIrD,sBAAsB,IAAI,IAAI;IAI9B,QAAQ,IAAI,IAAI;IAMhB,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAMrC,QAAQ,IAAI,IAAI;IAIhB,OAAO,IAAI,IAAI;CAGhB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/input.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/input.test.d.ts deleted file mode 100644 index f6118e42..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/input.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=input.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/input.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/input.test.d.ts.map deleted file mode 100644 index be433685..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/input.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"input.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/input.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/list.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/list.d.ts index 51a08685..f202a854 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/components/list.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/components/list.d.ts @@ -5,14 +5,10 @@ export default class List { constructor({ element }: { element: HTMLElement; }); - clear(): void; - append(node: Element | DocumentFragment): void; - getChild(selector: string): HTMLElement | null; - hasChildren(): boolean; + prepend(node: Element | DocumentFragment): void; scrollToTop(): void; scrollToChildElement(element: HTMLElement, direction: 1 | -1): void; _scrollDown(scrollPos: number, strength: number, destination: number): void; _scrollUp(scrollPos: number, strength: number, destination: number): void; _animateScroll(destination: number, direction: number): void; } -//# sourceMappingURL=list.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/list.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/list.d.ts.map deleted file mode 100644 index 8b9068f4..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/list.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/list.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB,OAAO,EAAE,WAAW,CAAC;IAErB,SAAS,EAAE,MAAM,CAAC;IAElB,MAAM,EAAE,MAAM,CAAC;gBAEH,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE;IAMjD,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI;IAI9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI9C,WAAW,IAAI,OAAO;IAItB,WAAW,IAAI,IAAI;IAInB,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI;IAwBnE,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAO3E,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAOzE,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CAyB7D"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/list.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/list.test.d.ts deleted file mode 100644 index ce43e8d4..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/list.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=list.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/list.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/list.test.d.ts.map deleted file mode 100644 index ad131680..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/list.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"list.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/list.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.d.ts index ae18b82e..3397556d 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.d.ts @@ -1,7 +1,8 @@ import { ClassNames } from '../interfaces/class-names'; -import { EventType } from '../interfaces/event-type'; -export default class WrappedElement { - element: HTMLInputElement | HTMLSelectElement; +import { EventTypes } from '../interfaces/event-type'; +import { EventMap } from '../interfaces'; +export default class WrappedElement { + element: T; classNames: ClassNames; isDisabled: boolean; constructor({ element, classNames }: { @@ -16,6 +17,5 @@ export default class WrappedElement { reveal(): void; enable(): void; disable(): void; - triggerEvent(eventType: EventType, data?: object): void; + triggerEvent(eventType: EventTypes, data?: EventMap[K]['detail']): void; } -//# sourceMappingURL=wrapped-element.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.d.ts.map deleted file mode 100644 index 2df95bf8..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"wrapped-element.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/wrapped-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGrD,MAAM,CAAC,OAAO,OAAO,cAAc;IACjC,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;IAE9C,UAAU,EAAE,UAAU,CAAC;IAEvB,UAAU,EAAE,OAAO,CAAC;gBAER,EAAE,OAAO,EAAE,UAAU,EAAE;;;KAAA;IAcnC,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAGtB;IAED,OAAO,IAAI,IAAI;IAkBf,MAAM,IAAI,IAAI;IAsBd,MAAM,IAAI,IAAI;IAMd,OAAO,IAAI,IAAI;IAMf,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;CAGxD"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.test.d.ts deleted file mode 100644 index a9838b85..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=wrapped-element.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.test.d.ts.map deleted file mode 100644 index fb26915d..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-element.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"wrapped-element.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/wrapped-element.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.d.ts index c4c35240..6b44b580 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.d.ts @@ -1,14 +1,3 @@ -import { ClassNames } from '../interfaces/class-names'; import WrappedElement from './wrapped-element'; -export default class WrappedInput extends WrappedElement { - element: HTMLInputElement; - delimiter: string; - constructor({ element, classNames, delimiter, }: { - element: HTMLInputElement; - classNames: ClassNames; - delimiter: string; - }); - get value(): string; - set value(value: string); +export default class WrappedInput extends WrappedElement { } -//# sourceMappingURL=wrapped-input.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.d.ts.map deleted file mode 100644 index 224197b8..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"wrapped-input.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/wrapped-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,cAAc;IACtD,OAAO,EAAE,gBAAgB,CAAC;IAE1B,SAAS,EAAE,MAAM,CAAC;gBAEN,EACV,OAAO,EACP,UAAU,EACV,SAAS,GACV,EAAE;QACD,OAAO,EAAE,gBAAgB,CAAC;QAC1B,UAAU,EAAE,UAAU,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB;IAKD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAGtB;CACF"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.test.d.ts deleted file mode 100644 index 5b233465..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=wrapped-input.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.test.d.ts.map deleted file mode 100644 index 28ba6ce0..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-input.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"wrapped-input.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/wrapped-input.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.d.ts index 5b4f647b..559018fa 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.d.ts @@ -1,19 +1,20 @@ import { ClassNames } from '../interfaces/class-names'; -import { Item } from '../interfaces/item'; import WrappedElement from './wrapped-element'; -export default class WrappedSelect extends WrappedElement { - element: HTMLSelectElement; +import { GroupFull } from '../interfaces/group-full'; +import { ChoiceFull } from '../interfaces/choice-full'; +export default class WrappedSelect extends WrappedElement { classNames: ClassNames; template: (data: object) => HTMLOptionElement; - constructor({ element, classNames, template, }: { + extractPlaceholder: boolean; + constructor({ element, classNames, template, extractPlaceholder, }: { element: HTMLSelectElement; classNames: ClassNames; template: (data: object) => HTMLOptionElement; + extractPlaceholder: boolean; }); get placeholderOption(): HTMLOptionElement | null; - get optionGroups(): Element[]; - get options(): Item[] | HTMLOptionElement[]; - set options(options: Item[] | HTMLOptionElement[]); - appendDocFragment(fragment: DocumentFragment): void; + addOptions(choices: ChoiceFull[]): void; + optionsAsChoices(): (ChoiceFull | GroupFull)[]; + _optionToChoice(option: HTMLOptionElement): ChoiceFull; + _optgroupToChoice(optgroup: HTMLOptGroupElement): GroupFull; } -//# sourceMappingURL=wrapped-select.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.d.ts.map deleted file mode 100644 index 47ebbf79..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"wrapped-select.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/wrapped-select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,cAAc;IACvD,OAAO,EAAE,iBAAiB,CAAC;IAE3B,UAAU,EAAE,UAAU,CAAC;IAEvB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,CAAC;gBAElC,EACV,OAAO,EACP,UAAU,EACV,QAAQ,GACT,EAAE;QACD,OAAO,EAAE,iBAAiB,CAAC;QAC3B,UAAU,EAAE,UAAU,CAAC;QACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,CAAC;KAC/C;IAKD,IAAI,iBAAiB,IAAI,iBAAiB,GAAG,IAAI,CAMhD;IAED,IAAI,YAAY,IAAI,OAAO,EAAE,CAE5B;IAED,IAAI,OAAO,IAAI,IAAI,EAAE,GAAG,iBAAiB,EAAE,CAE1C;IAED,IAAI,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,iBAAiB,EAAE,EAahD;IAED,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;CAIpD"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.test.d.ts deleted file mode 100644 index 414d6156..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=wrapped-select.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.test.d.ts.map deleted file mode 100644 index e9740956..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/components/wrapped-select.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"wrapped-select.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/components/wrapped-select.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/constants.d.ts b/assets/extensions/choices.js/public/types/src/scripts/constants.d.ts index 1891ccca..99194be4 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/constants.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/constants.d.ts @@ -1,11 +1 @@ -import { ActionType } from './interfaces/action-type'; -import { EventType } from './interfaces/event-type'; -import { KeyCodeMap } from './interfaces/keycode-map'; -export declare const EVENTS: Record; -export declare const ACTION_TYPES: Record; -export declare const KEY_CODES: KeyCodeMap; -export declare const TEXT_TYPE: HTMLInputElement['type']; -export declare const SELECT_ONE_TYPE: HTMLSelectElement['type']; -export declare const SELECT_MULTIPLE_TYPE: HTMLSelectElement['type']; -export declare const SCROLLING_SPEED = 4; -//# sourceMappingURL=constants.d.ts.map \ No newline at end of file +export declare const SCROLLING_SPEED: number; diff --git a/assets/extensions/choices.js/public/types/src/scripts/constants.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/constants.d.ts.map deleted file mode 100644 index 1a564df7..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/constants.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/scripts/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,CAW/C,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,UAAU,EAAE,UAAU,CAYvD,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,UAUvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAU,CAAC;AAC1D,eAAO,MAAM,eAAe,EAAE,iBAAiB,CAAC,MAAM,CAAgB,CAAC;AACvE,eAAO,MAAM,oBAAoB,EAAE,iBAAiB,CAAC,MAAM,CACxC,CAAC;AAEpB,eAAO,MAAM,eAAe,IAAI,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/constants.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/constants.test.d.ts deleted file mode 100644 index bc2a88b9..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/constants.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=constants.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/constants.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/constants.test.d.ts.map deleted file mode 100644 index 20f77997..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/constants.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"constants.test.d.ts","sourceRoot":"","sources":["../../../../src/scripts/constants.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/defaults.d.ts b/assets/extensions/choices.js/public/types/src/scripts/defaults.d.ts index db8a9a92..e9cdce08 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/defaults.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/defaults.d.ts @@ -2,4 +2,3 @@ import { ClassNames } from './interfaces/class-names'; import { Options } from './interfaces/options'; export declare const DEFAULT_CLASSNAMES: ClassNames; export declare const DEFAULT_CONFIG: Options; -//# sourceMappingURL=defaults.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/defaults.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/defaults.d.ts.map deleted file mode 100644 index dffe8a88..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/defaults.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../../src/scripts/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG/C,eAAO,MAAM,kBAAkB,EAAE,UA2BhC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,OA+C5B,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/action-type.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/action-type.d.ts index d7d694f5..443038e4 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/action-type.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/action-type.d.ts @@ -1,2 +1,13 @@ -export type ActionType = 'ADD_CHOICE' | 'FILTER_CHOICES' | 'ACTIVATE_CHOICES' | 'CLEAR_CHOICES' | 'ADD_GROUP' | 'ADD_ITEM' | 'REMOVE_ITEM' | 'HIGHLIGHT_ITEM' | 'CLEAR_ALL' | 'RESET_TO' | 'SET_IS_LOADING'; -//# sourceMappingURL=action-type.d.ts.map \ No newline at end of file +import { Types } from './types'; +export declare const ActionType: { + readonly ADD_CHOICE: "ADD_CHOICE"; + readonly REMOVE_CHOICE: "REMOVE_CHOICE"; + readonly FILTER_CHOICES: "FILTER_CHOICES"; + readonly ACTIVATE_CHOICES: "ACTIVATE_CHOICES"; + readonly CLEAR_CHOICES: "CLEAR_CHOICES"; + readonly ADD_GROUP: "ADD_GROUP"; + readonly ADD_ITEM: "ADD_ITEM"; + readonly REMOVE_ITEM: "REMOVE_ITEM"; + readonly HIGHLIGHT_ITEM: "HIGHLIGHT_ITEM"; +}; +export type ActionTypes = Types.ValueOf; diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/action-type.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/action-type.d.ts.map deleted file mode 100644 index 9721610a..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/action-type.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"action-type.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/action-type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,YAAY,GACZ,gBAAgB,GAChB,kBAAkB,GAClB,eAAe,GACf,WAAW,GACX,UAAU,GACV,aAAa,GACb,gBAAgB,GAChB,WAAW,GACX,UAAU,GACV,gBAAgB,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/build-flags.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/build-flags.d.ts new file mode 100644 index 00000000..c803580a --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/build-flags.d.ts @@ -0,0 +1,9 @@ +export declare const canUseDom: boolean; +export declare const searchFuse: string | undefined; +/** + * These are not directly used, as an exported object (even as const) will prevent tree-shake away code paths + */ +export declare const BuildFlags: { + readonly searchFuse: string | undefined; + readonly canUseDom: boolean; +}; diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/choice-full.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/choice-full.d.ts new file mode 100644 index 00000000..ea946058 --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/choice-full.d.ts @@ -0,0 +1,22 @@ +import { StringUntrusted } from './string-untrusted'; +export type CustomProperties = Record | string; +export interface ChoiceFull { + id: number; + highlighted: boolean; + element?: HTMLOptionElement | HTMLOptGroupElement; + itemEl?: HTMLElement; + choiceEl?: HTMLElement; + labelClass?: Array; + labelDescription?: string; + customProperties?: CustomProperties; + disabled: boolean; + active: boolean; + elementId?: string; + groupId: number; + label: StringUntrusted | string; + placeholder: boolean; + selected: boolean; + value: string; + score: number; + rank: number; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/choice.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/choice.d.ts deleted file mode 100644 index db222d05..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/choice.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -export interface Choice { - id?: number; - customProperties?: Record; - disabled?: boolean; - active?: boolean; - elementId?: number; - groupId?: number; - keyCode?: number; - label: string; - placeholder?: boolean; - selected?: boolean; - value: any; - score?: number; - choices?: Choice[]; -} -//# sourceMappingURL=choice.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/choice.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/choice.d.ts.map deleted file mode 100644 index b692cb7a..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/choice.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"choice.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/choice.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,MAAM;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/choices.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/choices.d.ts deleted file mode 100644 index 613a2ab0..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/choices.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Options } from 'deepmerge'; -import { Store } from 'redux'; -import { WrappedInput, WrappedSelect, Container, List, Input, Dropdown } from '../components'; -import { Choice } from './choice'; -import { Group } from './group'; -import { Item } from './item'; -import { State } from './state'; -import templates from '../templates'; -export interface Choices { - initialised: boolean; - config: Options; - passedElement: WrappedInput | WrappedSelect; - containerOuter: Container; - containerInner: Container; - choiceList: List; - itemList: List; - input: Input; - dropdown: Dropdown; - _isTextElement: boolean; - _isSelectOneElement: boolean; - _isSelectMultipleElement: boolean; - _isSelectElement: boolean; - _store: Store; - _templates: typeof templates; - _initialState: State; - _currentState: State; - _prevState: State; - _currentValue: string; - _canSearch: boolean; - _isScrollingOnIe: boolean; - _highlightPosition: number; - _wasTap: boolean; - _isSearching: boolean; - _placeholderValue: string | null; - _baseId: string; - _direction: HTMLElement['dir']; - _idNames: { - itemChoice: string; - }; - _presetGroups: Group[] | HTMLOptGroupElement[] | Element[]; - _presetOptions: Item[] | HTMLOptionElement[]; - _presetChoices: Partial[]; - _presetItems: Item[] | string[]; - new (element: string | Element | HTMLInputElement | HTMLSelectElement, userConfig: Partial): any; -} -//# sourceMappingURL=choices.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/choices.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/choices.d.ts.map deleted file mode 100644 index acb6e085..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/choices.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"choices.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/choices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EACL,YAAY,EACZ,aAAa,EACb,SAAS,EACT,IAAI,EACJ,KAAK,EACL,QAAQ,EACT,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,SAAS,MAAM,cAAc,CAAC;AAErC,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAEhB,aAAa,EAAE,YAAY,GAAG,aAAa,CAAC;IAE5C,cAAc,EAAE,SAAS,CAAC;IAE1B,cAAc,EAAE,SAAS,CAAC;IAE1B,UAAU,EAAE,IAAI,CAAC;IAEjB,QAAQ,EAAE,IAAI,CAAC;IAEf,KAAK,EAAE,KAAK,CAAC;IAEb,QAAQ,EAAE,QAAQ,CAAC;IAEnB,cAAc,EAAE,OAAO,CAAC;IAExB,mBAAmB,EAAE,OAAO,CAAC;IAE7B,wBAAwB,EAAE,OAAO,CAAC;IAElC,gBAAgB,EAAE,OAAO,CAAC;IAE1B,MAAM,EAAE,KAAK,CAAC;IAEd,UAAU,EAAE,OAAO,SAAS,CAAC;IAE7B,aAAa,EAAE,KAAK,CAAC;IAErB,aAAa,EAAE,KAAK,CAAC;IAErB,UAAU,EAAE,KAAK,CAAC;IAElB,aAAa,EAAE,MAAM,CAAC;IAEtB,UAAU,EAAE,OAAO,CAAC;IAEpB,gBAAgB,EAAE,OAAO,CAAC;IAE1B,kBAAkB,EAAE,MAAM,CAAC;IAE3B,OAAO,EAAE,OAAO,CAAC;IAEjB,YAAY,EAAE,OAAO,CAAC;IAEtB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC,OAAO,EAAE,MAAM,CAAC;IAEhB,UAAU,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;IAE/B,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF,aAAa,EAAE,KAAK,EAAE,GAAG,mBAAmB,EAAE,GAAG,OAAO,EAAE,CAAC;IAE3D,cAAc,EAAE,IAAI,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAE7C,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IAElC,YAAY,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;IAEhC,KACE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,gBAAgB,GAAG,iBAAiB,EAChE,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,OAC5B;CACH"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/class-names.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/class-names.d.ts index 09818ef6..b6283385 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/class-names.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/class-names.d.ts @@ -1,56 +1,61 @@ /** Classes added to HTML generated by By default classnames follow the BEM notation. */ export interface ClassNames { - /** @default 'choices' */ - containerOuter: string; - /** @default 'choices__inner' */ - containerInner: string; - /** @default 'choices__input' */ - input: string; - /** @default 'choices__input--cloned' */ - inputCloned: string; - /** @default 'choices__list' */ - list: string; - /** @default 'choices__list--multiple' */ - listItems: string; - /** @default 'choices__list--single' */ - listSingle: string; - /** @default 'choices__list--dropdown' */ - listDropdown: string; - /** @default 'choices__item' */ - item: string; - /** @default 'choices__item--selectable' */ - itemSelectable: string; - /** @default 'choices__item--disabled' */ - itemDisabled: string; - /** @default 'choices__item--choice' */ - itemChoice: string; - /** @default 'choices__placeholder' */ - placeholder: string; - /** @default 'choices__group' */ - group: string; - /** @default 'choices__heading' */ - groupHeading: string; - /** @default 'choices__button' */ - button: string; - /** @default 'is-active' */ - activeState: string; - /** @default 'is-focused' */ - focusState: string; - /** @default 'is-open' */ - openState: string; - /** @default 'is-disabled' */ - disabledState: string; - /** @default 'is-highlighted' */ - highlightedState: string; - /** @default 'is-selected' */ - selectedState: string; - /** @default 'is-flipped' */ - flippedState: string; - /** @default 'is-loading' */ - loadingState: string; - /** @default 'has-no-results' */ - noResults: string; - /** @default 'has-no-choices' */ - noChoices: string; + /** @default ['choices'] */ + containerOuter: string | Array; + /** @default ['choices__inner'] */ + containerInner: string | Array; + /** @default ['choices__input'] */ + input: string | Array; + /** @default ['choices__input--cloned'] */ + inputCloned: string | Array; + /** @default ['choices__list'] */ + list: string | Array; + /** @default ['choices__list--multiple'] */ + listItems: string | Array; + /** @default ['choices__list--single'] */ + listSingle: string | Array; + /** @default ['choices__list--dropdown'] */ + listDropdown: string | Array; + /** @default ['choices__item'] */ + item: string | Array; + /** @default ['choices__item--selectable'] */ + itemSelectable: string | Array; + /** @default ['choices__item--disabled'] */ + itemDisabled: string | Array; + /** @default ['choices__item--choice'] */ + itemChoice: string | Array; + /** @default ['choices__description'] */ + description: string | Array; + /** @default ['choices__placeholder'] */ + placeholder: string | Array; + /** @default ['choices__group'] */ + group: string | Array; + /** @default ['choices__heading'] */ + groupHeading: string | Array; + /** @default ['choices__button'] */ + button: string | Array; + /** @default ['is-active'] */ + activeState: string | Array; + /** @default ['is-focused'] */ + focusState: string | Array; + /** @default ['is-open'] */ + openState: string | Array; + /** @default ['is-disabled'] */ + disabledState: string | Array; + /** @default ['is-highlighted'] */ + highlightedState: string | Array; + /** @default ['is-selected'] */ + selectedState: string | Array; + /** @default ['is-flipped'] */ + flippedState: string | Array; + /** @default ['is-loading'] */ + loadingState: string | Array; + /** @default ['choices__notice'] */ + notice: string | Array; + /** @default ['choices__item--selectable', 'add-choice'] */ + addChoice: string | Array; + /** @default ['has-no-results'] */ + noResults: string | Array; + /** @default ['has-no-choices'] */ + noChoices: string | Array; } -//# sourceMappingURL=class-names.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/class-names.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/class-names.d.ts.map deleted file mode 100644 index b5c60687..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/class-names.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"class-names.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/class-names.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,MAAM,WAAW,UAAU;IACzB,yBAAyB;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-choice.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-choice.d.ts new file mode 100644 index 00000000..5fbc45c2 --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-choice.d.ts @@ -0,0 +1,6 @@ +import { InputChoice } from './input-choice'; +export interface EventChoice extends InputChoice { + element?: HTMLOptionElement | HTMLOptGroupElement; + groupValue?: string; + keyCode?: number; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-type.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-type.d.ts index b2d97ac9..2562c9d6 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-type.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-type.d.ts @@ -1,2 +1,14 @@ -export type EventType = 'addItem' | 'removeItem' | 'highlightItem' | 'unhighlightItem' | 'choice' | 'change' | 'search' | 'showDropdown' | 'hideDropdown' | 'highlightChoice'; -//# sourceMappingURL=event-type.d.ts.map \ No newline at end of file +import { Types } from './types'; +export declare const EventType: { + readonly showDropdown: "showDropdown"; + readonly hideDropdown: "hideDropdown"; + readonly change: "change"; + readonly choice: "choice"; + readonly search: "search"; + readonly addItem: "addItem"; + readonly removeItem: "removeItem"; + readonly highlightItem: "highlightItem"; + readonly highlightChoice: "highlightChoice"; + readonly unhighlightItem: "unhighlightItem"; +}; +export type EventTypes = Types.ValueOf; diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-type.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-type.d.ts.map deleted file mode 100644 index 4ce8a6fc..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/event-type.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"event-type.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/event-type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,YAAY,GACZ,eAAe,GACf,iBAAiB,GACjB,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,cAAc,GACd,cAAc,GACd,iBAAiB,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/group-full.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/group-full.d.ts new file mode 100644 index 00000000..359dcdbf --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/group-full.d.ts @@ -0,0 +1,10 @@ +import { ChoiceFull } from './choice-full'; +export interface GroupFull { + id: number; + active: boolean; + disabled: boolean; + label?: string; + element?: HTMLOptGroupElement; + groupEl?: HTMLElement; + choices: ChoiceFull[]; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/group.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/group.d.ts deleted file mode 100644 index 3fa395aa..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/group.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface Group { - id?: number; - active?: boolean; - disabled?: boolean; - value: any; -} -//# sourceMappingURL=group.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/group.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/group.d.ts.map deleted file mode 100644 index bff19fb8..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/group.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/group.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,KAAK;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,GAAG,CAAC;CACZ"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/index.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/index.d.ts index 66ecddcf..267e573e 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/index.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/index.d.ts @@ -1,16 +1,14 @@ export * from './action-type'; -export * from './choice'; -export * from './choices'; +export * from './input-choice'; +export * from './input-group'; +export * from './event-choice'; export * from './class-names'; export * from './event-type'; -export * from './group'; export * from './item'; export * from './keycode-map'; -export * from './notice'; export * from './options'; export * from './passed-element'; export * from './passed-element-type'; export * from './position-options-type'; export * from './state'; export * from './types'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/index.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/index.d.ts.map deleted file mode 100644 index d28ff02d..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/input-choice.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/input-choice.d.ts new file mode 100644 index 00000000..71482657 --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/input-choice.d.ts @@ -0,0 +1,14 @@ +import { StringUntrusted } from './string-untrusted'; +export interface InputChoice { + id?: number; + highlighted?: boolean; + labelClass?: string | Array; + labelDescription?: string; + customProperties?: Record | string; + disabled?: boolean; + active?: boolean; + label: StringUntrusted | string; + placeholder?: boolean; + selected?: boolean; + value: any; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/input-group.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/input-group.d.ts new file mode 100644 index 00000000..fae9be6b --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/input-group.d.ts @@ -0,0 +1,10 @@ +import { InputChoice } from './input-choice'; +import { StringUntrusted } from './string-untrusted'; +export interface InputGroup { + id?: number; + active?: boolean; + disabled?: boolean; + label?: StringUntrusted | string; + value: string; + choices: InputChoice[]; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/item.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/item.d.ts index 1d58b80a..b164f265 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/item.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/item.d.ts @@ -1,6 +1,17 @@ -import { Choice } from './choice'; -export interface Item extends Choice { - choiceId?: number; - highlighted?: boolean; +import { InputChoice } from './input-choice'; +import { InputGroup } from './input-group'; +/** + * @deprecated Use InputChoice instead + */ +export interface Item extends InputChoice { +} +/** + * @deprecated Use InputChoice instead + */ +export interface Choice extends InputChoice { +} +/** + * @deprecated Use InputGroup instead + */ +export interface Group extends InputGroup { } -//# sourceMappingURL=item.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/item.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/item.d.ts.map deleted file mode 100644 index 15f89f15..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/item.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,WAAW,IAAK,SAAQ,MAAM;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts index f7ece2bc..62a59a23 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts @@ -1,12 +1,11 @@ -export interface KeyCodeMap { - BACK_KEY: 46; - DELETE_KEY: 8; - ENTER_KEY: 13; - A_KEY: 65; - ESC_KEY: 27; - UP_KEY: 38; - DOWN_KEY: 40; - PAGE_UP_KEY: 33; - PAGE_DOWN_KEY: 34; +export declare const enum KeyCodeMap { + BACK_KEY = 46, + DELETE_KEY = 8, + ENTER_KEY = 13, + A_KEY = 65, + ESC_KEY = 27, + UP_KEY = 38, + DOWN_KEY = 40, + PAGE_UP_KEY = 33, + PAGE_DOWN_KEY = 34 } -//# sourceMappingURL=keycode-map.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts.map deleted file mode 100644 index 04580068..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/keycode-map.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"keycode-map.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/keycode-map.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,EAAE,CAAC;IACb,UAAU,EAAE,CAAC,CAAC;IACd,SAAS,EAAE,EAAE,CAAC;IACd,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,EAAE,CAAC;IACZ,MAAM,EAAE,EAAE,CAAC;IACX,QAAQ,EAAE,EAAE,CAAC;IACb,WAAW,EAAE,EAAE,CAAC;IAChB,aAAa,EAAE,EAAE,CAAC;CACnB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/notice.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/notice.d.ts deleted file mode 100644 index 071f8d43..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/notice.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface Notice { - response: boolean; - notice: string; -} -//# sourceMappingURL=notice.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/notice.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/notice.d.ts.map deleted file mode 100644 index f2983f3a..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/notice.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"notice.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/notice.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/options.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/options.d.ts index 0952366a..10e9eb97 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/options.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/options.d.ts @@ -1,9 +1,9 @@ -import Fuse from 'fuse.js'; -import { Choices } from './choices'; -import { Choice } from './choice'; +import { IFuseOptions } from 'fuse.js'; +import { InputChoice } from './input-choice'; import { ClassNames } from './class-names'; import { PositionOptionsType } from './position-options-type'; import { Types } from './types'; +export declare const ObjectsInConfig: string[]; /** * Choices options interface * @@ -51,7 +51,7 @@ export interface Options { * * @default [] */ - items: string[] | Choice[]; + items: string[] | InputChoice[]; /** * Add choices (see terminology) to select input. * @@ -74,12 +74,31 @@ export interface Options { * description: 'Custom description about Option 2', * random: 'Another random custom property' * }, + * }, + * { + * label: 'Group 1', + * choices: [{ + * value: 'Option 3', + * label: 'Option 4', + * selected: true, + * disabled: false, + * }, + * { + * value: 'Option 2', + * label: 'Option 2', + * selected: false, + * disabled: true, + * customProperties: { + * description: 'Custom description about Option 2', + * random: 'Another random custom property' + * } + * }] * }] * ``` * * @default [] */ - choices: Choice[]; + choices: InputChoice[]; /** * The amount of choices to be rendered within the dropdown list `("-1" indicates no limit)`. This is useful if you have a lot of choices where it is easier for a user to use the search area to find a choice. * @@ -96,6 +115,36 @@ export interface Options { * @default -1 */ maxItemCount: number; + /** + * Control how the dropdown closes after making a selection for select-one or select-multiple + * + * 'auto' defaults based on backing-element type: + * select-one: true + * select-multiple: false + * + * **Input types affected:** select-one, select-multiple + * + * @default 'auto' + */ + closeDropdownOnSelect: boolean | 'auto'; + /** + * Make select-multiple with a max item count of 1 work similar to select-one does. + * Selecting an item will auto-close the dropdown and swap any existing item for the just selected choice. + * If applied to a select-one, it functions as above and not the standard select-one. + * + * **Input types affected:** select-one, select-multiple + * + * @default false + */ + singleModeForMultiSelect: boolean; + /** + * Whether a user can add choices dynamically. + * + * **Input types affected:** select-one, select-multiple + * + * @default false + */ + addChoices: boolean; /** * Whether a user can add items. * @@ -107,22 +156,53 @@ export interface Options { /** * A filter that will need to pass for a user to successfully add an item. * - * **Input types affected:** text + * **Input types affected:** text, select-one, select-multiple * - * @default null + * @default (value) => !!value && value !== '' */ addItemFilter: string | RegExp | Types.FilterFunction | null; /** * The text that is shown when a user has inputted a new item but has not pressed the enter key. To access the current input value, pass a function with a `value` argument (see the **default config** [https://github.com/jshjohnson/Choices#setup] for an example), otherwise pass a string. + * The raw non-sanitised value is passed as a 2nd argument. * - * **Input types affected:** text + * Return type must be safe to insert into HTML (ie use the 1st argument which is sanitised) + * + * **Input types affected:** text, one-select, select-one, select-multiple * * @default * ``` - * (value) => `Press Enter to add "${value}"`; + * (value, valueRaw) => `Press Enter to add "${value}"`; * ``` */ addItemText: string | Types.NoticeStringFunction; + /** + * The text/icon for the remove button. To access the item's value, pass a function with a `value` argument (see the **default config** [https://github.com/jshjohnson/Choices#setup] for an example), otherwise pass a string. + * The raw non-sanitised value is passed as a 2nd argument. + * + * Return type must be safe to insert into HTML (ie use the 1st argument which is sanitised) + * + * **Input types affected:** text, select-one, select-multiple + * + * @default + * ``` + * (value, valueRaw) => `Remove item`; + * ``` + */ + removeItemIconText: string | Types.NoticeStringFunction; + /** + * The text for the remove button's aria label. To access the item's value, pass a function with a `value` argument (see the **default config** [https://github.com/jshjohnson/Choices#setup] for an example), otherwise pass a string. + * The raw non-sanitised value is passed as a 2nd argument. + * + * Return type must be safe to insert into HTML (ie use the 1st argument which is sanitised) + * + * **Input types affected:** text, select-one, select-multiple + * + * @default + * ``` + * (value, valueRaw) => `Remove item: ${value}`; + * ``` + */ + removeItemLabelText: string | Types.NoticeStringFunction; /** * Whether a user can remove items. * @@ -139,6 +219,14 @@ export interface Options { * @default false */ removeItemButton: boolean; + /** + * Align item remove button left vs right. + * + * **Input types affected:** text, select-one, select-multiple + * + * @default false + */ + removeItemButtonAlignLeft: boolean; /** * Whether a user can edit items. An item's value can be edited by pressing the backspace. * @@ -152,17 +240,25 @@ export interface Options { * If `false`, all elements (placeholder, items, etc.) will be treated as plain text. * If `true`, this can be used to perform XSS scripting attacks if you load choices from a remote source. * - * **Deprecation Warning:** This will default to `false` in a future release. - * * **Input types affected:** text, select-one, select-multiple * - * @default true + * @default false */ allowHTML: boolean; + /** + * Whether HTML should be escaped on input when `addItems` or `addChoices` is true. + * If `false`, user input will be treated as plain text. + * If `true`, this can be used to perform XSS scripting attacks if you load previously submitted choices from a remote source. + * + * **Input types affected:** text, select-one, select-multiple + * + * @default false + */ + allowHtmlUserInput: boolean; /** * Whether each inputted/chosen item should be unique. * - * **Input types affected:** text, select-multiple + * **Input types affected:** text * * @default true */ @@ -186,9 +282,7 @@ export interface Options { /** * Whether a search area should be shown. * - * @note Multiple select boxes will always show search areas. - * - * **Input types affected:** select-one + * **Input types affected:** select-one, select-multiple * * @default true */ @@ -210,7 +304,7 @@ export interface Options { */ searchFloor: number; /** - * The maximum amount of search results to show. + * The maximum amount of search results to show. `("-1" indicates no limit)` * * **Input types affected:** select-one, select-multiple * @@ -241,6 +335,10 @@ export interface Options { * @default true */ resetScrollPosition: boolean; + /** + * The shadow root for use within ShadowDom + */ + shadowRoot: ShadowRoot | null; /** * Whether choices and groups should be sorted. If false, choices/groups will appear in the order they were given. * @@ -274,7 +372,7 @@ export interface Options { * * @default sortByAlpha */ - sorter: (current: Choice, next: Choice) => number; + sorter: (current: Types.RecordToCompare, next: Types.RecordToCompare) => number; /** * Whether the input should show a placeholder. Used in conjunction with `placeholderValue`. If `placeholder` is set to true and no value is passed to `placeholderValue`, the passed input's placeholder attribute will be used as the placeholder value. * @@ -282,8 +380,7 @@ export interface Options { * * @note For single select boxes, the recommended way of adding a placeholder is as follows: * ``` - * * * * @@ -332,7 +429,7 @@ export interface Options { * * @default 'auto'; */ - renderSelectedChoices: 'auto' | 'always'; + renderSelectedChoices: 'auto' | 'always' | boolean; /** * The text that is shown whilst choices are being populated via AJAX. * @@ -358,7 +455,7 @@ export interface Options { */ noChoicesText: string | Types.StringFunction; /** - * The text that is shown when a user hovers over a selectable choice. + * The text that is shown when a user hovers over a selectable choice. Set to empty to not reserve space for this text. * * **Input types affected:** select-multiple, select-one * @@ -379,12 +476,16 @@ export interface Options { /** * If no duplicates are allowed, and the value already exists in the array. * + * Return type must be safe to insert into HTML (ie use the 1st argument which is sanitised) + * * @default 'Only unique values can be added' */ uniqueItemText: string | Types.NoticeStringFunction; /** * The text that is shown when addItemFilter is passed and it returns false * + * Return type must be safe to insert into HTML (ie use the 1st argument which is sanitised) + * * **Input types affected:** text * * @default 'Only values matching specific conditions can be added' @@ -410,7 +511,7 @@ export interface Options { /** * Choices uses the great Fuse library for searching. You can find more options here: https://fusejs.io/api/options.html */ - fuseOptions: Fuse.IFuseOptions; + fuseOptions: IFuseOptions; /** * ID of the connected label to improve a11y. If set, aria-labelledby will be added. */ @@ -424,30 +525,30 @@ export interface Options { * * @default null */ - callbackOnInit: ((this: Choices) => void) | null; + callbackOnInit: (() => void) | null; /** * Function to run on template creation. Through this callback it is possible to provide custom templates for the various components of Choices (see terminology). For Choices to work with custom templates, it is important you maintain the various data attributes defined here [https://github.com/jshjohnson/Choices/blob/67f29c286aa21d88847adfcd6304dc7d068dc01f/assets/scripts/src/choices.js#L1993-L2067]. * * **Input types affected:** text, select-one, select-multiple * - * @note For each callback, this refers to the current instance of This can be useful if you need access to methods `(this.disable())` or the config object `(this.config)`. + * @note For each callback, `this` refers to the current instance of Choices. This can be useful if you need access to methods `(this.disable())`. * * @example * ``` * const example = new Choices(element, { - * callbackOnCreateTemplates: function (template) { + * callbackOnCreateTemplates: function (template, originalTemplates) { * var classNames = this.config.classNames; * return { * item: (data) => { * return template(` - *
+ *
* ${data.label} *
* `); * }, * choice: (data) => { * return template(` - *
0 ? 'role="treeitem"' : 'role="option"'}> + *
* ${data.label} *
* `); @@ -459,6 +560,6 @@ export interface Options { * * @default null */ - callbackOnCreateTemplates: ((template: Types.StrToEl) => void) | null; + callbackOnCreateTemplates: ((template: Types.StrToEl, escapeForTemplate: Types.EscapeForTemplateFn) => void) | null; + appendGroupInSearch: false; } -//# sourceMappingURL=options.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/options.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/options.d.ts.map deleted file mode 100644 index 7d1f58d5..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/options.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/options.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB;;;;;;OAMG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAE3B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;;;;OAMG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;IAE7D;;;;;;;;;OASG;IACH,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC,oBAAoB,CAAC;IAEjD;;;;;;OAMG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;;;;;OAMG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAE1B;;;;;;OAMG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;;;;;;;;;OAUG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;;;;;OAMG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAE/B;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;;;;;;;OAQG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB;;;;;;OAMG;IACH,QAAQ,EAAE,mBAAmB,CAAC;IAE9B;;;;;;OAMG;IACH,mBAAmB,EAAE,OAAO,CAAC;IAE7B;;;;;;OAMG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;;;;;OAMG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAElD;;;;;;;;;;;;;;;;OAgBG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;;;;;OAMG;IACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;;;;;OAMG;IACH,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtC;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B;;;;;;OAMG;IACH,qBAAqB,EAAE,MAAM,GAAG,QAAQ,CAAC;IAEzC;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC;IAE7C;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC;IAE7C;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;;;;;;;OASG;IACH,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC,mBAAmB,CAAC;IAEhD;;;;OAIG;IACH,cAAc,EAAE,MAAM,GAAG,KAAK,CAAC,oBAAoB,CAAC;IAEpD;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,GAAG,KAAK,CAAC,oBAAoB,CAAC;IAEvD;;;;;;;;;OASG;IACH,aAAa,EAAE,KAAK,CAAC,oBAAoB,CAAC;IAE1C;;;;OAIG;IACH,UAAU,EAAE,UAAU,CAAC;IAEvB;;OAEG;IACH,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAExC;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;;;;OAQG;IACH,cAAc,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,yBAAyB,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CACvE"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts index 19ca5068..9748c088 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts @@ -1,2 +1,7 @@ -export type PassedElementType = 'text' | 'select-one' | 'select-multiple'; -//# sourceMappingURL=passed-element-type.d.ts.map \ No newline at end of file +import { Types } from './types'; +export declare const PassedElementTypes: { + readonly Text: "text"; + readonly SelectOne: "select-one"; + readonly SelectMultiple: "select-multiple"; +}; +export type PassedElementType = Types.ValueOf; diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts.map deleted file mode 100644 index e4901736..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element-type.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"passed-element-type.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/passed-element-type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,YAAY,GAAG,iBAAiB,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts index 54172d70..29e21498 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts @@ -1,17 +1,5 @@ -import { Choices } from './choices'; -import { Choice } from './choice'; -import { ClassNames } from './class-names'; -import { EventType } from './event-type'; -import { PassedElementType } from './passed-element-type'; -export interface PassedElement extends HTMLElement { - classNames: ClassNames; - element: (HTMLInputElement | HTMLSelectElement) & { - addEventListener(type: K, listener: (this: HTMLInputElement | HTMLSelectElement, ev: EventMap[K]) => void, options?: boolean | AddEventListenerOptions): void; - }; - type: PassedElementType; - isDisabled: boolean; - parentInstance: Choices; -} +import { InputChoice } from './input-choice'; +import { EventChoice } from './event-choice'; /** * Events fired by Choices behave the same as standard events. Each event is triggered on the element passed to Choices (accessible via `this.passedElement`. Arguments are accessible within the `event.detail` object. */ @@ -21,15 +9,9 @@ export interface EventMap { * * **Input types affected:** text, select-one, select-multiple * - * Arguments: id, value, label, groupValue, keyCode + * Arguments: id, value, label, groupValue */ - addItem: CustomEvent<{ - id: number; - value: string; - label: string; - groupValue: string; - keyCode: number; - }>; + addItem: CustomEvent; /** * Triggered each time an item is removed (programmatically or by the user). * @@ -37,12 +19,7 @@ export interface EventMap { * * Arguments: id, value, label, groupValue */ - removeItem: CustomEvent<{ - id: number; - value: string; - label: string; - groupValue: string; - }>; + removeItem: CustomEvent; /** * Triggered each time an item is highlighted. * @@ -50,12 +27,7 @@ export interface EventMap { * * Arguments: id, value, label, groupValue */ - highlightItem: CustomEvent<{ - id: number; - value: string; - label: string; - groupValue: string; - }>; + highlightItem: CustomEvent; /** * Triggered each time an item is unhighlighted. * @@ -63,12 +35,7 @@ export interface EventMap { * * Arguments: id, value, label, groupValue */ - unhighlightItem: CustomEvent<{ - id: number; - value: string; - label: string; - groupValue: string; - }>; + unhighlightItem: CustomEvent; /** * Triggered each time a choice is selected **by a user**, regardless if it changes the value of the input. * @@ -77,7 +44,7 @@ export interface EventMap { * Arguments: choice: Choice */ choice: CustomEvent<{ - choice: Choice; + choice: InputChoice; }>; /** * Triggered each time an item is added/removed **by a user**. @@ -90,7 +57,7 @@ export interface EventMap { value: string; }>; /** - * Triggered when a user types into an input to search choices. + * Triggered when a user types into an input to search choices. When a search is ended, a search event with an empty value with no resultCount is triggered. * * **Input types affected:** select-one, select-multiple * @@ -123,7 +90,6 @@ export interface EventMap { * Arguments: el is the choice.passedElement that was affected. */ highlightChoice: CustomEvent<{ - el: PassedElement; + el: HTMLElement; }>; } -//# sourceMappingURL=passed-element.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts.map deleted file mode 100644 index 4798e53f..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/passed-element.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"passed-element.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/passed-element.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,CAAC,gBAAgB,GAAG,iBAAiB,CAAC,GAAG;QAEhD,gBAAgB,CAAC,CAAC,SAAS,SAAS,EAClC,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CACR,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,EAC1C,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,KACZ,IAAI,EACT,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC;KACT,CAAC;IACF,IAAI,EAAE,iBAAiB,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;;OAMG;IACH,OAAO,EAAE,WAAW,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IAEH;;;;;;OAMG;IACH,UAAU,EAAE,WAAW,CAAC;QACtB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IAEH;;;;;;OAMG;IACH,aAAa,EAAE,WAAW,CAAC;QACzB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IAEH;;;;;;OAMG;IACH,eAAe,EAAE,WAAW,CAAC;QAC3B,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IAEH;;;;;;OAMG;IACH,MAAM,EAAE,WAAW,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAExC;;;;;;OAMG;IACH,MAAM,EAAE,WAAW,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEvC;;;;;;OAMG;IACH,MAAM,EAAE,WAAW,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE5D;;;;;;OAMG;IACH,YAAY,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAErC;;;;;;OAMG;IACH,YAAY,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAErC;;;;;OAKG;IACH,eAAe,EAAE,WAAW,CAAC;QAAE,EAAE,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;CACrD"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts index 694e3d26..d23b4e6e 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts @@ -1,2 +1 @@ export type PositionOptionsType = 'auto' | 'top' | 'bottom'; -//# sourceMappingURL=position-options-type.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts.map deleted file mode 100644 index f89c2121..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/position-options-type.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"position-options-type.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/position-options-type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/search.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/search.d.ts new file mode 100644 index 00000000..4788b986 --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/search.d.ts @@ -0,0 +1,11 @@ +export interface SearchResult { + item: T; + score: number; + rank: number; +} +export interface Searcher { + reset(): void; + isEmptyIndex(): boolean; + index(data: T[]): void; + search(needle: string): SearchResult[]; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/state.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/state.d.ts index a713d050..31320e95 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/state.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/state.d.ts @@ -1,10 +1,10 @@ -import { Choice } from './choice'; -import { Group } from './group'; -import { Item } from './item'; +import { ChoiceFull } from './choice-full'; +import { GroupFull } from './group-full'; export interface State { - choices: Choice[]; - groups: Group[]; - items: Item[]; - loading: boolean; + choices: ChoiceFull[]; + groups: GroupFull[]; + items: ChoiceFull[]; } -//# sourceMappingURL=state.d.ts.map \ No newline at end of file +export type StateChangeSet = { + [K in keyof State]: boolean; +}; diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/state.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/state.d.ts.map deleted file mode 100644 index 0907396d..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/state.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/store.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/store.d.ts new file mode 100644 index 00000000..83256c22 --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/store.d.ts @@ -0,0 +1,64 @@ +import { StateChangeSet, State } from './state'; +import { ChoiceFull } from './choice-full'; +import { GroupFull } from './group-full'; +import { ActionTypes } from './action-type'; +export interface AnyAction { + type: A; +} +export interface StateUpdate { + update: boolean; + state: T; +} +export type Reducer = (state: T, action: AnyAction, context?: unknown) => StateUpdate; +export type StoreListener = (changes: StateChangeSet) => void; +export interface Store { + dispatch(action: AnyAction): void; + subscribe(onChange: StoreListener): void; + withTxn(func: () => void): void; + reset(): void; + get defaultState(): State; + /** + * Get store object + */ + get state(): State; + /** + * Get items from store + */ + get items(): ChoiceFull[]; + /** + * Get highlighted items from store + */ + get highlightedActiveItems(): ChoiceFull[]; + /** + * Get choices from store + */ + get choices(): ChoiceFull[]; + /** + * Get active choices from store + */ + get activeChoices(): ChoiceFull[]; + /** + * Get choices that can be searched (excluding placeholders) + */ + get searchableChoices(): ChoiceFull[]; + /** + * Get groups from store + */ + get groups(): GroupFull[]; + /** + * Get active groups from store + */ + get activeGroups(): GroupFull[]; + /** + * Get loading state from store + */ + inTxn(): boolean; + /** + * Get single choice by it's ID + */ + getChoiceById(id: number): ChoiceFull | undefined; + /** + * Get group by group id + */ + getGroupById(id: number): GroupFull | undefined; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/string-pre-escaped.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/string-pre-escaped.d.ts new file mode 100644 index 00000000..2f8ed2c9 --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/string-pre-escaped.d.ts @@ -0,0 +1,3 @@ +export interface StringPreEscaped { + readonly trusted: string; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/string-untrusted.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/string-untrusted.d.ts new file mode 100644 index 00000000..983c91ee --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/string-untrusted.d.ts @@ -0,0 +1,4 @@ +export interface StringUntrusted { + readonly escaped: string; + readonly raw: string; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/templates.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/templates.d.ts new file mode 100644 index 00000000..8de4217f --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/templates.d.ts @@ -0,0 +1,28 @@ +import { PassedElementType } from './passed-element-type'; +import { StringPreEscaped } from './string-pre-escaped'; +import { ChoiceFull } from './choice-full'; +import { GroupFull } from './group-full'; +import { Options } from './options'; +import { Types } from './types'; +export type TemplateOptions = Pick; +export declare const NoticeTypes: { + readonly noChoices: "no-choices"; + readonly noResults: "no-results"; + readonly addChoice: "add-choice"; + readonly generic: ""; +}; +export type NoticeType = Types.ValueOf; +export interface Templates { + containerOuter(options: TemplateOptions, dir: HTMLElement['dir'], isSelectElement: boolean, isSelectOneElement: boolean, searchEnabled: boolean, passedElementType: PassedElementType, labelId: string): HTMLDivElement; + containerInner({ classNames: { containerInner } }: TemplateOptions): HTMLDivElement; + itemList(options: TemplateOptions, isSelectOneElement: boolean): HTMLDivElement; + placeholder(options: TemplateOptions, value: StringPreEscaped | string): HTMLDivElement; + item(options: TemplateOptions, choice: ChoiceFull, removeItemButton: boolean): HTMLDivElement; + choiceList(options: TemplateOptions, isSelectOneElement: boolean): HTMLDivElement; + choiceGroup(options: TemplateOptions, group: GroupFull): HTMLDivElement; + choice(options: TemplateOptions, choice: ChoiceFull, selectText: string, groupText?: string): HTMLDivElement; + input(options: TemplateOptions, placeholderValue: string | null): HTMLInputElement; + dropdown(options: TemplateOptions): HTMLDivElement; + notice(options: TemplateOptions, innerText: string, type: NoticeType): HTMLDivElement; + option(choice: ChoiceFull): HTMLOptionElement; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/types.d.ts b/assets/extensions/choices.js/public/types/src/scripts/interfaces/types.d.ts index 5a2cf64f..b76f39a1 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/types.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/interfaces/types.d.ts @@ -1,9 +1,16 @@ +import { StringUntrusted } from './string-untrusted'; +import { StringPreEscaped } from './string-pre-escaped'; export declare namespace Types { type StrToEl = (str: string) => HTMLElement | HTMLInputElement | HTMLOptionElement; + type EscapeForTemplateFn = (allowHTML: boolean, s: StringUntrusted | StringPreEscaped | string) => string; type StringFunction = () => string; - type NoticeStringFunction = (value: string) => string; + type NoticeStringFunction = (value: string, valueRaw: string) => string; type NoticeLimitFunction = (maxItemCount: number) => string; type FilterFunction = (value: string) => boolean; type ValueCompareFunction = (value1: string, value2: string) => boolean; + interface RecordToCompare { + value?: StringUntrusted | string; + label?: StringUntrusted | string; + } + type ValueOf = T[keyof T]; } -//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/interfaces/types.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/interfaces/types.d.ts.map deleted file mode 100644 index 4c44c1d1..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/interfaces/types.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/interfaces/types.ts"],"names":[],"mappings":"AAAA,yBAAiB,KAAK,CAAC;IACrB,KAAY,OAAO,GAAG,CACpB,GAAG,EAAE,MAAM,KACR,WAAW,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;IACxD,KAAY,cAAc,GAAG,MAAM,MAAM,CAAC;IAC1C,KAAY,oBAAoB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7D,KAAY,mBAAmB,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IACnE,KAAY,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACxD,KAAY,oBAAoB,GAAG,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,KACX,OAAO,CAAC;CACd"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/lib/choice-input.d.ts b/assets/extensions/choices.js/public/types/src/scripts/lib/choice-input.d.ts new file mode 100644 index 00000000..6953e374 --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/lib/choice-input.d.ts @@ -0,0 +1,9 @@ +import { InputChoice } from '../interfaces/input-choice'; +import { InputGroup } from '../interfaces/input-group'; +import { GroupFull } from '../interfaces/group-full'; +import { ChoiceFull } from '../interfaces/choice-full'; +type MappedInputTypeToChoiceType = T extends InputGroup ? GroupFull : ChoiceFull; +export declare const coerceBool: (arg: unknown, defaultValue?: boolean) => boolean; +export declare const stringToHtmlClass: (input: string | string[] | undefined) => string[] | undefined; +export declare const mapInputToChoice: (value: T, allowGroup: boolean) => MappedInputTypeToChoiceType; +export {}; diff --git a/assets/extensions/choices.js/public/types/src/scripts/lib/html-guard-statements.d.ts b/assets/extensions/choices.js/public/types/src/scripts/lib/html-guard-statements.d.ts new file mode 100644 index 00000000..5eeadf4f --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/lib/html-guard-statements.d.ts @@ -0,0 +1,4 @@ +export declare const isHtmlInputElement: (e: Element) => e is HTMLInputElement; +export declare const isHtmlSelectElement: (e: Element) => e is HTMLSelectElement; +export declare const isHtmlOption: (e: Element) => e is HTMLOptionElement; +export declare const isHtmlOptgroup: (e: Element) => e is HTMLOptGroupElement; diff --git a/assets/extensions/choices.js/public/types/src/scripts/lib/utils.d.ts b/assets/extensions/choices.js/public/types/src/scripts/lib/utils.d.ts index 3eff9ed8..2c2c0797 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/lib/utils.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/lib/utils.d.ts @@ -1,28 +1,31 @@ -import { Choice } from '../interfaces/choice'; -import { EventType } from '../interfaces/event-type'; -export declare const getRandomNumber: (min: number, max: number) => number; -export declare const generateChars: (length: number) => string; +import { EventTypes } from '../interfaces/event-type'; +import { StringUntrusted } from '../interfaces/string-untrusted'; +import { StringPreEscaped } from '../interfaces/string-pre-escaped'; +import { ChoiceFull } from '../interfaces/choice-full'; +import { Types } from '../interfaces/types'; export declare const generateId: (element: HTMLInputElement | HTMLSelectElement, prefix: string) => string; -export declare const getType: (obj: any) => string; -export declare const isType: (type: string, obj: any) => boolean; -export declare const wrap: (element: HTMLElement, wrapper?: HTMLElement) => HTMLElement; -export declare const getAdjacentEl: (startEl: Element, selector: string, direction?: number) => Element; +export declare const getAdjacentEl: (startEl: HTMLElement, selector: string, direction?: number) => HTMLElement | null; export declare const isScrolledIntoView: (element: HTMLElement, parent: HTMLElement, direction?: number) => boolean; -export declare const sanitise: (value: string | T) => string | T; +export declare const sanitise: (value: T | StringUntrusted | StringPreEscaped | string) => T | string; export declare const strToEl: (str: string) => Element; -interface RecordToCompare { - value: string; - label?: string; -} -export declare const sortByAlpha: ({ value, label }: RecordToCompare, { value: value2, label: label2 }: RecordToCompare) => number; -export declare const sortByScore: (a: Pick, b: Pick) => number; -export declare const dispatchEvent: (element: HTMLElement, type: EventType, customArgs?: object | null) => boolean; -export declare const existsInArray: (array: any[], value: string, key?: string) => boolean; -export declare const cloneObject: (obj: object) => object; +export declare const resolveNoticeFunction: (fn: Types.NoticeStringFunction | string, value: string) => string; +export declare const resolveStringFunction: (fn: Types.StringFunction | string) => string; +export declare const unwrapStringForRaw: (s?: StringUntrusted | StringPreEscaped | string) => string; +export declare const unwrapStringForEscaped: (s?: StringUntrusted | StringPreEscaped | string) => string; +export declare const escapeForTemplate: (allowHTML: boolean, s: StringUntrusted | StringPreEscaped | string) => string; +export declare const setElementHtml: (el: HTMLElement, allowHtml: boolean, html: StringUntrusted | StringPreEscaped | string) => void; +export declare const sortByAlpha: ({ value, label }: Types.RecordToCompare, { value: value2, label: label2 }: Types.RecordToCompare) => number; +export declare const sortByScore: (a: Pick, b: Pick) => number; +export declare const sortByRank: (a: Pick, b: Pick) => number; +export declare const dispatchEvent: (element: HTMLElement, type: EventTypes, customArgs?: object | null) => boolean; +export declare const cloneObject: (obj: T) => T; /** * Returns an array of keys present on the first but missing on the second object */ export declare const diff: (a: Record, b: Record) => string[]; -export declare const parseCustomProperties: (customProperties: any) => any; -export {}; -//# sourceMappingURL=utils.d.ts.map \ No newline at end of file +export declare const getClassNames: (ClassNames: Array | string) => Array; +export declare const getClassNamesSelector: (option: string | Array | null) => string; +export declare const addClassesToElement: (element: HTMLElement, className: Array | string) => void; +export declare const removeClassesFromElement: (element: HTMLElement, className: Array | string) => void; +export declare const parseCustomProperties: (customProperties?: string) => object | string; +export declare const updateClassList: (item: ChoiceFull, add: string | string[], remove: string | string[]) => void; diff --git a/assets/extensions/choices.js/public/types/src/scripts/lib/utils.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/lib/utils.d.ts.map deleted file mode 100644 index 7c1131e2..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/lib/utils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/lib/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,eAAO,MAAM,eAAe,QAAS,MAAM,OAAO,MAAM,KAAG,MACZ,CAAC;AAEhD,eAAO,MAAM,aAAa,WAAY,MAAM,KAAG,MAC6B,CAAC;AAE7E,eAAO,MAAM,UAAU,YACZ,gBAAgB,GAAG,iBAAiB,UACrC,MAAM,KACb,MASF,CAAC;AAEF,eAAO,MAAM,OAAO,QAAS,GAAG,KAAG,MACe,CAAC;AAEnD,eAAO,MAAM,MAAM,SAAU,MAAM,OAAO,GAAG,KAAG,OACY,CAAC;AAE7D,eAAO,MAAM,IAAI,YACN,WAAW,YACX,WAAW,KACnB,WAUF,CAAC;AAEF,eAAO,MAAM,aAAa,YACf,OAAO,YACN,MAAM,yBAEf,OAYF,CAAC;AAEF,eAAO,MAAM,kBAAkB,YACpB,WAAW,UACZ,WAAW,yBAElB,OAkBF,CAAC;AAEF,eAAO,MAAM,QAAQ,sCAUpB,CAAC;AAEF,eAAO,MAAM,OAAO,QAAe,MAAM,KAAK,OAc1C,CAAC;AAEL,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,eAAO,MAAM,WAAW,qBACI,eAAe,oCACE,eAAe,KACzD,MAKC,CAAC;AAEL,eAAO,MAAM,WAAW,MACnB,KAAK,MAAM,EAAE,OAAO,CAAC,KACrB,KAAK,MAAM,EAAE,OAAO,CAAC,KACvB,MAKF,CAAC;AAEF,eAAO,MAAM,aAAa,YACf,WAAW,QACd,SAAS,eACH,MAAM,GAAG,IAAI,KACxB,OAQF,CAAC;AAEF,eAAO,MAAM,aAAa,UACjB,GAAG,EAAE,SACL,MAAM,mBAEZ,OAOC,CAAC;AAEL,eAAO,MAAM,WAAW,QAAS,MAAM,KAAG,MACT,CAAC;AAElC;;GAEG;AACH,eAAO,MAAM,IAAI,MACZ,OAAO,MAAM,EAAE,GAAG,CAAC,KACnB,OAAO,MAAM,EAAE,GAAG,CAAC,KACrB,MAAM,EAKR,CAAC;AAEF,eAAO,MAAM,qBAAqB,6BAAuB,GAUxD,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/lib/utils.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/lib/utils.test.d.ts deleted file mode 100644 index c727c85c..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/lib/utils.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=utils.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/lib/utils.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/lib/utils.test.d.ts.map deleted file mode 100644 index 58a4177e..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/lib/utils.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/lib/utils.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.d.ts index bf907900..34edb202 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.d.ts @@ -1,8 +1,8 @@ -import { AddChoiceAction, FilterChoicesAction, ActivateChoicesAction, ClearChoicesAction } from '../actions/choices'; -import { AddItemAction, RemoveItemAction } from '../actions/items'; -import { Choice } from '../interfaces/choice'; -export declare const defaultState: never[]; -type ActionTypes = AddChoiceAction | FilterChoicesAction | ActivateChoicesAction | ClearChoicesAction | AddItemAction | RemoveItemAction | Record; -export default function choices(state?: Choice[], action?: ActionTypes): Choice[]; +import { Options, State } from '../interfaces'; +import { StateUpdate } from '../interfaces/store'; +import { ChoiceActions } from '../actions/choices'; +import { ItemActions } from '../actions/items'; +type ActionTypes = ChoiceActions | ItemActions; +type StateType = State['choices']; +export default function choices(s: StateType, action: ActionTypes, context?: Options): StateUpdate; export {}; -//# sourceMappingURL=choices.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.d.ts.map deleted file mode 100644 index efdac490..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"choices.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/choices.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,eAAO,MAAM,YAAY,SAAK,CAAC;AAE/B,KAAK,WAAW,GACZ,eAAe,GACf,mBAAmB,GACnB,qBAAqB,GACrB,kBAAkB,GAClB,aAAa,GACb,gBAAgB,GAChB,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE1B,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,KAAK,GAAE,MAAM,EAAiB,EAC9B,MAAM,GAAE,WAAgB,GACvB,MAAM,EAAE,CAwGV"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.test.d.ts deleted file mode 100644 index 1b34de17..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=choices.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.test.d.ts.map deleted file mode 100644 index abcc18fa..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/choices.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"choices.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/choices.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.d.ts index c60ba238..d91bf7f7 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.d.ts @@ -1,9 +1,8 @@ -import { AddGroupAction } from '../actions/groups'; -import { ClearChoicesAction } from '../actions/choices'; -import { Group } from '../interfaces/group'; +import { GroupActions } from '../actions/groups'; import { State } from '../interfaces/state'; -export declare const defaultState: never[]; -type ActionTypes = AddGroupAction | ClearChoicesAction | Record; -export default function groups(state?: Group[], action?: ActionTypes): State['groups']; +import { StateUpdate } from '../interfaces/store'; +import { ChoiceActions } from '../actions/choices'; +type ActionTypes = ChoiceActions | GroupActions; +type StateType = State['groups']; +export default function groups(s: StateType, action: ActionTypes): StateUpdate; export {}; -//# sourceMappingURL=groups.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.d.ts.map deleted file mode 100644 index df2d6b5c..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"groups.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/groups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE5C,eAAO,MAAM,YAAY,SAAK,CAAC;AAE/B,KAAK,WAAW,GAAG,cAAc,GAAG,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/E,MAAM,CAAC,OAAO,UAAU,MAAM,CAC5B,KAAK,GAAE,KAAK,EAAiB,EAC7B,MAAM,GAAE,WAAgB,GACvB,KAAK,CAAC,QAAQ,CAAC,CAwBjB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.test.d.ts deleted file mode 100644 index 8d44d56e..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=groups.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.test.d.ts.map deleted file mode 100644 index ea6a989c..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/groups.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"groups.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/groups.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/index.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/index.d.ts deleted file mode 100644 index 212bcc13..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export declare const defaultState: { - groups: never[]; - items: never[]; - choices: never[]; - loading: boolean; -}; -declare const rootReducer: (passedState: any, action: any) => object; -export default rootReducer; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/index.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/index.d.ts.map deleted file mode 100644 index d95e352b..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/index.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,YAAY;;;;;CAKxB,CAAC;AASF,QAAA,MAAM,WAAW,qCAA0B,MAa1C,CAAC;AAEF,eAAe,WAAW,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/index.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/index.test.d.ts deleted file mode 100644 index 121d59b3..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/index.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=index.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/index.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/index.test.d.ts.map deleted file mode 100644 index c182b406..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/index.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/index.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/items.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/items.d.ts index 4b825f9d..d9b75477 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/items.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/reducers/items.d.ts @@ -1,8 +1,9 @@ -import { AddItemAction, RemoveItemAction, HighlightItemAction } from '../actions/items'; -import { Item } from '../interfaces/item'; +import { ItemActions } from '../actions/items'; import { State } from '../interfaces/state'; -export declare const defaultState: never[]; -type ActionTypes = AddItemAction | RemoveItemAction | HighlightItemAction | Record; -export default function items(state?: Item[], action?: ActionTypes): State['items']; +import { ChoiceActions } from '../actions/choices'; +import { Options } from '../interfaces'; +import { StateUpdate } from '../interfaces/store'; +type ActionTypes = ChoiceActions | ItemActions; +type StateType = State['items']; +export default function items(s: StateType, action: ActionTypes, context?: Options): StateUpdate; export {}; -//# sourceMappingURL=items.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/items.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/items.d.ts.map deleted file mode 100644 index 517343b9..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/items.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"items.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/items.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE5C,eAAO,MAAM,YAAY,SAAK,CAAC;AAE/B,KAAK,WAAW,GACZ,aAAa,GACb,gBAAgB,GAChB,mBAAmB,GACnB,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE1B,MAAM,CAAC,OAAO,UAAU,KAAK,CAC3B,KAAK,GAAE,IAAI,EAAiB,EAC5B,MAAM,GAAE,WAAgB,GACvB,KAAK,CAAC,OAAO,CAAC,CA0DhB"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/items.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/items.test.d.ts deleted file mode 100644 index e81d58b4..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/items.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=items.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/items.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/items.test.d.ts.map deleted file mode 100644 index 64192571..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/items.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"items.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/items.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.d.ts deleted file mode 100644 index b5518f0e..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { SetIsLoadingAction } from '../actions/misc'; -import { State } from '../interfaces/state'; -export declare const defaultState = false; -type ActionTypes = SetIsLoadingAction | Record; -declare const general: (state?: boolean, action?: ActionTypes) => State['loading']; -export default general; -//# sourceMappingURL=loading.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.d.ts.map deleted file mode 100644 index 34945a60..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"loading.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/loading.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE5C,eAAO,MAAM,YAAY,QAAQ,CAAC;AAElC,KAAK,WAAW,GAAG,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE9D,QAAA,MAAM,OAAO,6BAEH,WAAW,KAClB,KAAK,CAAC,SAAS,CAUjB,CAAC;AAEF,eAAe,OAAO,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.test.d.ts deleted file mode 100644 index b1d0de1d..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=loading.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.test.d.ts.map deleted file mode 100644 index 1f2efe5c..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/reducers/loading.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"loading.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/reducers/loading.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/search/fuse.d.ts b/assets/extensions/choices.js/public/types/src/scripts/search/fuse.d.ts new file mode 100644 index 00000000..53134d21 --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/search/fuse.d.ts @@ -0,0 +1,14 @@ +import { default as FuseFull, IFuseOptions } from 'fuse.js'; +import { default as FuseBasic } from 'fuse.js/basic'; +import { Options } from '../interfaces/options'; +import { Searcher, SearchResult } from '../interfaces/search'; +export declare class SearchByFuse implements Searcher { + _fuseOptions: IFuseOptions; + _haystack: T[]; + _fuse: FuseFull | FuseBasic | undefined; + constructor(config: Options); + index(data: T[]): void; + reset(): void; + isEmptyIndex(): boolean; + search(needle: string): SearchResult[]; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/search/index.d.ts b/assets/extensions/choices.js/public/types/src/scripts/search/index.d.ts new file mode 100644 index 00000000..ebc42d6f --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/search/index.d.ts @@ -0,0 +1,3 @@ +import { Options } from '../interfaces'; +import { Searcher } from '../interfaces/search'; +export declare function getSearcher(config: Options): Searcher; diff --git a/assets/extensions/choices.js/public/types/src/scripts/search/prefix-filter.d.ts b/assets/extensions/choices.js/public/types/src/scripts/search/prefix-filter.d.ts new file mode 100644 index 00000000..e0868f38 --- /dev/null +++ b/assets/extensions/choices.js/public/types/src/scripts/search/prefix-filter.d.ts @@ -0,0 +1,11 @@ +import { Options } from '../interfaces'; +import { Searcher, SearchResult } from '../interfaces/search'; +export declare class SearchByPrefixFilter implements Searcher { + _fields: string[]; + _haystack: T[]; + constructor(config: Options); + index(data: T[]): void; + reset(): void; + isEmptyIndex(): boolean; + search(_needle: string): SearchResult[]; +} diff --git a/assets/extensions/choices.js/public/types/src/scripts/store/store.d.ts b/assets/extensions/choices.js/public/types/src/scripts/store/store.d.ts index b6ff4120..35d2f282 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/store/store.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/store/store.d.ts @@ -1,74 +1,59 @@ -import { Store as IStore, AnyAction } from 'redux'; -import { Choice } from '../interfaces/choice'; -import { Group } from '../interfaces/group'; -import { Item } from '../interfaces/item'; -import { State } from '../interfaces/state'; -export default class Store { - _store: IStore; - constructor(); - /** - * Subscribe store to function call (wrapped Redux method) - */ - subscribe(onChange: () => void): void; - /** - * Dispatch event to store (wrapped Redux method) - */ +import { AnyAction, Store as IStore, StoreListener } from '../interfaces/store'; +import { StateChangeSet, State } from '../interfaces/state'; +import { ChoiceFull } from '../interfaces/choice-full'; +import { GroupFull } from '../interfaces/group-full'; +export default class Store implements IStore { + _state: State; + _listeners: StoreListener[]; + _txn: number; + _changeSet?: StateChangeSet; + _context: T; + constructor(context: T); + get defaultState(): State; + changeSet(init: boolean): StateChangeSet; + reset(): void; + subscribe(onChange: StoreListener): void; dispatch(action: AnyAction): void; + withTxn(func: () => void): void; /** - * Get store object (wrapping Redux method) + * Get store object */ get state(): State; /** * Get items from store */ - get items(): Item[]; - /** - * Get active items from store - */ - get activeItems(): Item[]; + get items(): ChoiceFull[]; /** * Get highlighted items from store */ - get highlightedActiveItems(): Item[]; + get highlightedActiveItems(): ChoiceFull[]; /** * Get choices from store */ - get choices(): Choice[]; + get choices(): ChoiceFull[]; /** * Get active choices from store */ - get activeChoices(): Choice[]; - /** - * Get selectable choices from store - */ - get selectableChoices(): Choice[]; + get activeChoices(): ChoiceFull[]; /** * Get choices that can be searched (excluding placeholders) */ - get searchableChoices(): Choice[]; - /** - * Get placeholder choice from store - */ - get placeholderChoice(): Choice | undefined; + get searchableChoices(): ChoiceFull[]; /** * Get groups from store */ - get groups(): Group[]; + get groups(): GroupFull[]; /** * Get active groups from store */ - get activeGroups(): Group[]; - /** - * Get loading state from store - */ - isLoading(): boolean; + get activeGroups(): GroupFull[]; + inTxn(): boolean; /** * Get single choice by it's ID */ - getChoiceById(id: string): Choice | undefined; + getChoiceById(id: number): ChoiceFull | undefined; /** * Get group by group id */ - getGroupById(id: number): Group | undefined; + getGroupById(id: number): GroupFull | undefined; } -//# sourceMappingURL=store.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/store/store.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/store/store.d.ts.map deleted file mode 100644 index 32a519e7..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/store/store.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/store/store.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,IAAI,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAG5C,MAAM,CAAC,OAAO,OAAO,KAAK;IACxB,MAAM,EAAE,MAAM,CAAC;;IAUf;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAIrC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAIjC;;OAEG;IACH,IAAI,KAAK,IAAI,KAAK,CAEjB;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,IAAI,EAAE,CAElB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,IAAI,EAAE,CAExB;IAED;;OAEG;IACH,IAAI,sBAAsB,IAAI,IAAI,EAAE,CAEnC;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,EAAE,CAEtB;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IAED;;OAEG;IACH,IAAI,iBAAiB,IAAI,MAAM,EAAE,CAEhC;IAED;;OAEG;IACH,IAAI,iBAAiB,IAAI,MAAM,EAAE,CAIhC;IAED;;OAEG;IACH,IAAI,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAI1C;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,KAAK,EAAE,CAEpB;IAED;;OAEG;IACH,IAAI,YAAY,IAAI,KAAK,EAAE,CAW1B;IAED;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7C;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;CAG5C"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/store/store.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/store/store.test.d.ts deleted file mode 100644 index 6ffd6f9e..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/store/store.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=store.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/store/store.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/store/store.test.d.ts.map deleted file mode 100644 index fa49f4c7..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/store/store.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"store.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/store/store.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/templates.d.ts b/assets/extensions/choices.js/public/types/src/scripts/templates.d.ts index 03a5ebfe..6bdc114f 100644 --- a/assets/extensions/choices.js/public/types/src/scripts/templates.d.ts +++ b/assets/extensions/choices.js/public/types/src/scripts/templates.d.ts @@ -1,25 +1,8 @@ /** * Helpers to create HTML elements used by Choices - * Can be overridden by providing `callbackOnCreateTemplates` option + * Can be overridden by providing `callbackOnCreateTemplates` option. + * `Choices.defaults.templates` allows access to the default template methods from `callbackOnCreateTemplates` */ -import { Choice } from './interfaces/choice'; -import { Group } from './interfaces/group'; -import { Item } from './interfaces/item'; -import { PassedElementType } from './interfaces/passed-element-type'; -type TemplateOptions = Record<'classNames' | 'allowHTML', any>; -declare const templates: { - containerOuter({ classNames: { containerOuter } }: TemplateOptions, dir: HTMLElement['dir'], isSelectElement: boolean, isSelectOneElement: boolean, searchEnabled: boolean, passedElementType: PassedElementType, labelId: string): HTMLDivElement; - containerInner({ classNames: { containerInner }, }: TemplateOptions): HTMLDivElement; - itemList({ classNames: { list, listSingle, listItems } }: TemplateOptions, isSelectOneElement: boolean): HTMLDivElement; - placeholder({ allowHTML, classNames: { placeholder } }: TemplateOptions, value: string): HTMLDivElement; - item({ allowHTML, classNames: { item, button, highlightedState, itemSelectable, placeholder, }, }: TemplateOptions, { id, value, label, customProperties, active, disabled, highlighted, placeholder: isPlaceholder, }: Item, removeItemButton: boolean): HTMLDivElement; - choiceList({ classNames: { list } }: TemplateOptions, isSelectOneElement: boolean): HTMLDivElement; - choiceGroup({ allowHTML, classNames: { group, groupHeading, itemDisabled }, }: TemplateOptions, { id, value, disabled }: Group): HTMLDivElement; - choice({ allowHTML, classNames: { item, itemChoice, itemSelectable, selectedState, itemDisabled, placeholder, }, }: TemplateOptions, { id, value, label, groupId, elementId, disabled: isDisabled, selected: isSelected, placeholder: isPlaceholder, }: Choice, selectText: string): HTMLDivElement; - input({ classNames: { input, inputCloned } }: TemplateOptions, placeholderValue: string): HTMLInputElement; - dropdown({ classNames: { list, listDropdown }, }: TemplateOptions): HTMLDivElement; - notice({ allowHTML, classNames: { item, itemChoice, noResults, noChoices }, }: TemplateOptions, innerText: string, type?: 'no-choices' | 'no-results' | ''): HTMLDivElement; - option({ label, value, customProperties, active, disabled, }: Item): HTMLOptionElement; -}; +import { Templates as TemplatesInterface } from './interfaces/templates'; +declare const templates: TemplatesInterface; export default templates; -//# sourceMappingURL=templates.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/templates.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/templates.d.ts.map deleted file mode 100644 index ac8b7018..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/templates.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../../src/scripts/templates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,KAAK,eAAe,GAAG,MAAM,CAAC,YAAY,GAAG,WAAW,EAAE,GAAG,CAAC,CAAC;AAE/D,QAAA,MAAM,SAAS;uDAEyB,eAAe,OAC9C,WAAW,CAAC,KAAK,CAAC,mBACN,OAAO,sBACJ,OAAO,iBACZ,OAAO,qBACH,iBAAiB,WAC3B,MAAM,GACd,cAAc;wDAiCd,eAAe,GAAG,cAAc;8DAOgB,eAAe,sBAC5C,OAAO,GAC1B,cAAc;4DAO6B,eAAe,SACpD,MAAM,GACZ,cAAc;uGAiBZ,eAAe,sGAUf,IAAI,oBACW,OAAO,GACxB,cAAc;yCAmDW,eAAe,sBACrB,OAAO,GAC1B,cAAc;mFAiBZ,eAAe,2BACO,KAAK,GAC7B,cAAc;wHAsCZ,eAAe,qHAUf,MAAM,cACG,MAAM,GACjB,cAAc;kDAqCyB,eAAe,oBACrC,MAAM,GACvB,gBAAgB;sDAmBhB,eAAe,GAAG,cAAc;mFAa9B,eAAe,aACP,MAAM,SACX,YAAY,GAAG,YAAY,GAAG,EAAE,GACrC,cAAc;kEAqBd,IAAI,GAAG,iBAAiB;CAW5B,CAAC;AAEF,eAAe,SAAS,CAAC"} \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/templates.test.d.ts b/assets/extensions/choices.js/public/types/src/scripts/templates.test.d.ts deleted file mode 100644 index ba2e643a..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/templates.test.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {}; -//# sourceMappingURL=templates.test.d.ts.map \ No newline at end of file diff --git a/assets/extensions/choices.js/public/types/src/scripts/templates.test.d.ts.map b/assets/extensions/choices.js/public/types/src/scripts/templates.test.d.ts.map deleted file mode 100644 index d7d77ed3..00000000 --- a/assets/extensions/choices.js/public/types/src/scripts/templates.test.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"templates.test.d.ts","sourceRoot":"","sources":["../../../../src/scripts/templates.test.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/assets/extensions/choices.js/src/entry.js b/assets/extensions/choices.js/src/entry.js new file mode 100644 index 00000000..d7840877 --- /dev/null +++ b/assets/extensions/choices.js/src/entry.js @@ -0,0 +1,3 @@ +import Choices from './scripts/choices'; + +export default Choices; diff --git a/assets/extensions/choices.js/src/scripts/actions/choices.test.ts b/assets/extensions/choices.js/src/scripts/actions/choices.test.ts deleted file mode 100644 index d023b255..00000000 --- a/assets/extensions/choices.js/src/scripts/actions/choices.test.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { expect } from 'chai'; -import * as actions from './choices'; - -describe('actions/choices', () => { - describe('addChoice action', () => { - it('returns ADD_CHOICE action', () => { - const value = 'test'; - const label = 'test'; - const id = 1; - const groupId = 1; - const disabled = false; - const elementId = 1; - const customProperties = { test: true }; - const placeholder = true; - const keyCode = 10; - - const expectedAction: actions.AddChoiceAction = { - type: 'ADD_CHOICE', - value, - label, - id, - groupId, - disabled, - elementId, - customProperties, - placeholder, - keyCode, - }; - - expect( - actions.addChoice({ - value, - label, - id, - groupId, - disabled, - elementId, - customProperties, - placeholder, - keyCode, - }), - ).to.eql(expectedAction); - }); - }); - - describe('filterChoices action', () => { - it('returns FILTER_CHOICES action', () => { - const results = Array(10); - const expectedAction: actions.FilterChoicesAction = { - type: 'FILTER_CHOICES', - results, - }; - - expect(actions.filterChoices(results)).to.eql(expectedAction); - }); - }); - - describe('activateChoices action', () => { - describe('not passing active parameter', () => { - it('returns ACTIVATE_CHOICES action', () => { - const expectedAction: actions.ActivateChoicesAction = { - type: 'ACTIVATE_CHOICES', - active: true, - }; - - expect(actions.activateChoices()).to.eql(expectedAction); - }); - }); - - describe('passing active parameter', () => { - it('returns ACTIVATE_CHOICES action', () => { - const active = true; - const expectedAction: actions.ActivateChoicesAction = { - type: 'ACTIVATE_CHOICES', - active, - }; - - expect(actions.activateChoices(active)).to.eql(expectedAction); - }); - }); - }); - - describe('clearChoices action', () => { - it('returns CLEAR_CHOICES action', () => { - const expectedAction: actions.ClearChoicesAction = { - type: 'CLEAR_CHOICES', - }; - - expect(actions.clearChoices()).to.eql(expectedAction); - }); - }); -}); diff --git a/assets/extensions/choices.js/src/scripts/actions/choices.ts b/assets/extensions/choices.js/src/scripts/actions/choices.ts index db95c99a..f8594e73 100644 --- a/assets/extensions/choices.js/src/scripts/actions/choices.ts +++ b/assets/extensions/choices.js/src/scripts/actions/choices.ts @@ -1,73 +1,59 @@ -import { ACTION_TYPES } from '../constants'; -import { Choice } from '../interfaces/choice'; - -export interface AddChoiceAction { - type: typeof ACTION_TYPES.ADD_CHOICE; - id: number; - value: string; - label: string; - groupId: number; - disabled: boolean; - elementId: number; - customProperties: object; - placeholder: boolean; - keyCode: number; +import { ChoiceFull } from '../interfaces/choice-full'; +import { ActionType } from '../interfaces'; +import { SearchResult } from '../interfaces/search'; +import { AnyAction } from '../interfaces/store'; + +export type ChoiceActions = + | AddChoiceAction + | RemoveChoiceAction + | FilterChoicesAction + | ActivateChoicesAction + | ClearChoicesAction; + +export interface AddChoiceAction extends AnyAction { + choice: ChoiceFull; } -export interface Result { - item: T; - score: number; +export interface RemoveChoiceAction extends AnyAction { + choice: ChoiceFull; } -export interface FilterChoicesAction { - type: typeof ACTION_TYPES.FILTER_CHOICES; - results: Result[]; +export interface FilterChoicesAction extends AnyAction { + results: SearchResult[]; } -export interface ActivateChoicesAction { - type: typeof ACTION_TYPES.ACTIVATE_CHOICES; +export interface ActivateChoicesAction extends AnyAction { active: boolean; } -export interface ClearChoicesAction { - type: typeof ACTION_TYPES.CLEAR_CHOICES; -} +/** + * @deprecated use clearStore() or clearChoices() instead. + */ +export interface ClearChoicesAction extends AnyAction {} + +export const addChoice = (choice: ChoiceFull): AddChoiceAction => ({ + type: ActionType.ADD_CHOICE, + choice, +}); -export const addChoice = ({ - value, - label, - id, - groupId, - disabled, - elementId, - customProperties, - placeholder, - keyCode, -}): AddChoiceAction => ({ - type: ACTION_TYPES.ADD_CHOICE, - value, - label, - id, - groupId, - disabled, - elementId, - customProperties, - placeholder, - keyCode, +export const removeChoice = (choice: ChoiceFull): RemoveChoiceAction => ({ + type: ActionType.REMOVE_CHOICE, + choice, }); -export const filterChoices = ( - results: Result[], -): FilterChoicesAction => ({ - type: ACTION_TYPES.FILTER_CHOICES, +export const filterChoices = (results: SearchResult[]): FilterChoicesAction => ({ + type: ActionType.FILTER_CHOICES, results, }); export const activateChoices = (active = true): ActivateChoicesAction => ({ - type: ACTION_TYPES.ACTIVATE_CHOICES, + type: ActionType.ACTIVATE_CHOICES, active, }); +/** + * @deprecated use clearStore() or clearChoices() instead. + */ export const clearChoices = (): ClearChoicesAction => ({ - type: ACTION_TYPES.CLEAR_CHOICES, + type: ActionType.CLEAR_CHOICES, }); diff --git a/assets/extensions/choices.js/src/scripts/actions/groups.test.ts b/assets/extensions/choices.js/src/scripts/actions/groups.test.ts deleted file mode 100644 index f56e29c2..00000000 --- a/assets/extensions/choices.js/src/scripts/actions/groups.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { expect } from 'chai'; -import * as actions from './groups'; - -describe('actions/groups', () => { - describe('addGroup action', () => { - it('returns ADD_GROUP action', () => { - const value = 'test'; - const id = 1; - const active = true; - const disabled = false; - - const expectedAction: actions.AddGroupAction = { - type: 'ADD_GROUP', - value, - id, - active, - disabled, - }; - - expect(actions.addGroup({ value, id, active, disabled })).to.eql( - expectedAction, - ); - }); - }); -}); diff --git a/assets/extensions/choices.js/src/scripts/actions/groups.ts b/assets/extensions/choices.js/src/scripts/actions/groups.ts index 9c4a24e6..f9828424 100644 --- a/assets/extensions/choices.js/src/scripts/actions/groups.ts +++ b/assets/extensions/choices.js/src/scripts/actions/groups.ts @@ -1,27 +1,14 @@ -import { ACTION_TYPES } from '../constants'; +import { GroupFull } from '../interfaces/group-full'; +import { ActionType } from '../interfaces'; +import { AnyAction } from '../interfaces/store'; -export interface AddGroupAction { - type: typeof ACTION_TYPES.ADD_GROUP; - id: number; - value: string; - active: boolean; - disabled: boolean; +export type GroupActions = AddGroupAction; + +export interface AddGroupAction extends AnyAction { + group: GroupFull; } -export const addGroup = ({ - value, - id, - active, - disabled, -}: { - id: number; - value: string; - active: boolean; - disabled: boolean; -}): AddGroupAction => ({ - type: ACTION_TYPES.ADD_GROUP, - value, - id, - active, - disabled, +export const addGroup = (group: GroupFull): AddGroupAction => ({ + type: ActionType.ADD_GROUP, + group, }); diff --git a/assets/extensions/choices.js/src/scripts/actions/items.test.ts b/assets/extensions/choices.js/src/scripts/actions/items.test.ts deleted file mode 100644 index 28b9ba03..00000000 --- a/assets/extensions/choices.js/src/scripts/actions/items.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { expect } from 'chai'; -import * as actions from './items'; - -describe('actions/items', () => { - describe('addItem action', () => { - it('returns ADD_ITEM action', () => { - const value = 'test'; - const label = 'test'; - const id = 1; - const choiceId = 1; - const groupId = 1; - const customProperties = { test: true }; - const placeholder = true; - const keyCode = 10; - - const expectedAction: actions.AddItemAction = { - type: 'ADD_ITEM', - value, - label, - id, - choiceId, - groupId, - customProperties, - placeholder, - keyCode, - }; - - expect( - actions.addItem({ - value, - label, - id, - choiceId, - groupId, - customProperties, - placeholder, - keyCode, - }), - ).to.eql(expectedAction); - }); - }); - - describe('removeItem action', () => { - it('returns REMOVE_ITEM action', () => { - const id = 1; - const choiceId = 1; - - const expectedAction: actions.RemoveItemAction = { - type: 'REMOVE_ITEM', - id, - choiceId, - }; - - expect(actions.removeItem(id, choiceId)).to.eql(expectedAction); - }); - }); - - describe('highlightItem action', () => { - it('returns HIGHLIGHT_ITEM action', () => { - const id = 1; - const highlighted = true; - - const expectedAction: actions.HighlightItemAction = { - type: 'HIGHLIGHT_ITEM', - id, - highlighted, - }; - - expect(actions.highlightItem(id, highlighted)).to.eql(expectedAction); - }); - }); -}); diff --git a/assets/extensions/choices.js/src/scripts/actions/items.ts b/assets/extensions/choices.js/src/scripts/actions/items.ts index e7ec8a49..5cd78d37 100644 --- a/assets/extensions/choices.js/src/scripts/actions/items.ts +++ b/assets/extensions/choices.js/src/scripts/actions/items.ts @@ -1,70 +1,34 @@ -import { ACTION_TYPES } from '../constants'; +import { ChoiceFull } from '../interfaces/choice-full'; +import { ActionType } from '../interfaces'; +import { AnyAction } from '../interfaces/store'; -export interface AddItemAction { - type: typeof ACTION_TYPES.ADD_ITEM; - id: number; - value: string; - label: string; - choiceId: number; - groupId: number; - customProperties: object; - placeholder: boolean; - keyCode: number; +export type ItemActions = AddItemAction | RemoveItemAction | HighlightItemAction; + +export interface AddItemAction extends AnyAction { + item: ChoiceFull; } -export interface RemoveItemAction { - type: typeof ACTION_TYPES.REMOVE_ITEM; - id: number; - choiceId: number; +export interface RemoveItemAction extends AnyAction { + item: ChoiceFull; } -export interface HighlightItemAction { - type: typeof ACTION_TYPES.HIGHLIGHT_ITEM; - id: number; +export interface HighlightItemAction extends AnyAction { + item: ChoiceFull; highlighted: boolean; } -export const addItem = ({ - value, - label, - id, - choiceId, - groupId, - customProperties, - placeholder, - keyCode, -}: { - id: number; - value: string; - label: string; - choiceId: number; - groupId: number; - customProperties: object; - placeholder: boolean; - keyCode: number; -}): AddItemAction => ({ - type: ACTION_TYPES.ADD_ITEM, - value, - label, - id, - choiceId, - groupId, - customProperties, - placeholder, - keyCode, +export const addItem = (item: ChoiceFull): AddItemAction => ({ + type: ActionType.ADD_ITEM, + item, }); -export const removeItem = (id: number, choiceId: number): RemoveItemAction => ({ - type: ACTION_TYPES.REMOVE_ITEM, - id, - choiceId, +export const removeItem = (item: ChoiceFull): RemoveItemAction => ({ + type: ActionType.REMOVE_ITEM, + item, }); -export const highlightItem = ( - id: number, - highlighted: boolean, -): HighlightItemAction => ({ - type: ACTION_TYPES.HIGHLIGHT_ITEM, - id, +export const highlightItem = (item: ChoiceFull, highlighted: boolean): HighlightItemAction => ({ + type: ActionType.HIGHLIGHT_ITEM, + item, highlighted, }); diff --git a/assets/extensions/choices.js/src/scripts/actions/misc.test.ts b/assets/extensions/choices.js/src/scripts/actions/misc.test.ts deleted file mode 100644 index b9b0d9f2..00000000 --- a/assets/extensions/choices.js/src/scripts/actions/misc.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { expect } from 'chai'; -import { State } from '../interfaces/state'; -import * as actions from './misc'; - -describe('actions/misc', () => { - describe('clearAll action', () => { - it('returns CLEAR_ALL action', () => { - const expectedAction: actions.ClearAllAction = { - type: 'CLEAR_ALL', - }; - - expect(actions.clearAll()).to.eql(expectedAction); - }); - }); - - describe('resetTo action', () => { - it('returns RESET_TO action', () => { - const state: State = { - choices: [], - items: [], - groups: [], - loading: false, - }; - const expectedAction: actions.ResetToAction = { - type: 'RESET_TO', - state, - }; - - expect(actions.resetTo(state)).to.eql(expectedAction); - }); - }); - - describe('setIsLoading action', () => { - describe('setting loading state to true', () => { - it('returns expected action', () => { - const expectedAction: actions.SetIsLoadingAction = { - type: 'SET_IS_LOADING', - isLoading: true, - }; - - expect(actions.setIsLoading(true)).to.eql(expectedAction); - }); - }); - - describe('setting loading state to false', () => { - it('returns expected action', () => { - const expectedAction: actions.SetIsLoadingAction = { - type: 'SET_IS_LOADING', - isLoading: false, - }; - - expect(actions.setIsLoading(false)).to.eql(expectedAction); - }); - }); - }); -}); diff --git a/assets/extensions/choices.js/src/scripts/actions/misc.ts b/assets/extensions/choices.js/src/scripts/actions/misc.ts deleted file mode 100644 index c667b77b..00000000 --- a/assets/extensions/choices.js/src/scripts/actions/misc.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ACTION_TYPES } from '../constants'; -import { State } from '../interfaces/state'; - -export interface ClearAllAction { - type: typeof ACTION_TYPES.CLEAR_ALL; -} - -export interface ResetToAction { - type: typeof ACTION_TYPES.RESET_TO; - state: State; -} - -export interface SetIsLoadingAction { - type: typeof ACTION_TYPES.SET_IS_LOADING; - isLoading: boolean; -} - -export const clearAll = (): ClearAllAction => ({ - type: ACTION_TYPES.CLEAR_ALL, -}); - -export const resetTo = (state: State): ResetToAction => ({ - type: ACTION_TYPES.RESET_TO, - state, -}); - -export const setIsLoading = (isLoading: boolean): SetIsLoadingAction => ({ - type: ACTION_TYPES.SET_IS_LOADING, - isLoading, -}); diff --git a/assets/extensions/choices.js/src/scripts/choices.test.ts b/assets/extensions/choices.js/src/scripts/choices.test.ts deleted file mode 100644 index 20629fbe..00000000 --- a/assets/extensions/choices.js/src/scripts/choices.test.ts +++ /dev/null @@ -1,2361 +0,0 @@ -import chai, { expect } from 'chai'; -import { spy, stub } from 'sinon'; -import sinonChai from 'sinon-chai'; - -import Choices from './choices'; - -import { EVENTS, ACTION_TYPES, KEY_CODES } from './constants'; -import { WrappedSelect, WrappedInput } from './components/index'; -import { removeItem } from './actions/items'; -import templates from './templates'; -import { Choice } from './interfaces/choice'; -import { Group } from './interfaces/group'; -import { Item } from './interfaces/item'; -import { DEFAULT_CONFIG } from './defaults'; - -chai.use(sinonChai); - -describe('choices', () => { - let instance; - let output; - let passedElement; - - beforeEach(() => { - passedElement = document.createElement('input'); - passedElement.type = 'text'; - passedElement.className = 'js-choices'; - document.body.appendChild(passedElement); - - instance = new Choices(passedElement, { allowHTML: true }); - }); - - afterEach(() => { - output = null; - instance = null; - }); - - describe('constructor', () => { - describe('config', () => { - describe('not passing config options', () => { - it('uses the default config', () => { - document.body.innerHTML = ` - - `; - - instance = new Choices(); - - expect(instance.config).to.eql(DEFAULT_CONFIG); - }); - }); - - describe('passing config options', () => { - it('merges the passed config with the default config', () => { - document.body.innerHTML = ` - - `; - - const config = { - allowHTML: true, - renderChoiceLimit: 5, - }; - instance = new Choices('[data-choice]', config); - - expect(instance.config).to.eql({ - ...DEFAULT_CONFIG, - ...config, - }); - }); - - describe('passing the searchEnabled config option with a value of false', () => { - describe('passing a select-multiple element', () => { - it('sets searchEnabled to true', () => { - document.body.innerHTML = ` - - `; - - instance = new Choices('[data-choice]', { - allowHTML: true, - searchEnabled: false, - }); - - expect(instance.config.searchEnabled).to.equal(true); - }); - }); - }); - - describe('passing the renderSelectedChoices config option with an unexpected value', () => { - it('sets renderSelectedChoices to "auto"', () => { - document.body.innerHTML = ` - - `; - - instance = new Choices('[data-choice]', { - allowHTML: true, - renderSelectedChoices: 'test' as any, - }); - - expect(instance.config.renderSelectedChoices).to.equal('auto'); - }); - }); - }); - }); - - describe('not passing an element', () => { - it('returns a Choices instance for the first element with a "data-choice" attribute', () => { - document.body.innerHTML = ` - - - - `; - - const inputs = document.querySelectorAll('[data-choice]'); - expect(inputs.length).to.equal(3); - - instance = new Choices(undefined, { allowHTML: true }); - - expect(instance.passedElement.element.id).to.equal(inputs[0].id); - }); - - describe('when an element cannot be found in the DOM', () => { - it('throws an error', () => { - document.body.innerHTML = ``; - expect(() => new Choices(undefined, { allowHTML: true })).to.throw( - TypeError, - 'Expected one of the following types text|select-one|select-multiple', - ); - }); - }); - }); - - describe('passing an element', () => { - describe('passing an element that has not been initialised with Choices', () => { - beforeEach(() => { - document.body.innerHTML = ` - - `; - }); - - it('sets the initialised flag to true', () => { - instance = new Choices('#input-1', { allowHTML: true }); - expect(instance.initialised).to.equal(true); - }); - - it('intialises', () => { - const initSpy = spy(); - // initialise with the same element - instance = new Choices('#input-1', { - allowHTML: true, - silent: true, - callbackOnInit: initSpy, - }); - - expect(initSpy.called).to.equal(true); - }); - }); - - describe('passing an element that has already be initialised with Choices', () => { - beforeEach(() => { - document.body.innerHTML = ` - - `; - - // initialise once - new Choices('#input-1', { allowHTML: true, silent: true }); - }); - - it('sets the initialised flag to true', () => { - // initialise with the same element - instance = new Choices('#input-1', { allowHTML: true, silent: true }); - - expect(instance.initialised).to.equal(true); - }); - - it('does not reinitialise', () => { - const initSpy = spy(); - // initialise with the same element - instance = new Choices('#input-1', { - allowHTML: true, - silent: true, - callbackOnInit: initSpy, - }); - - expect(initSpy.called).to.equal(false); - }); - }); - - describe(`passing an element as a DOMString`, () => { - describe('passing a input element type', () => { - it('sets the "passedElement" instance property as an instance of WrappedInput', () => { - document.body.innerHTML = ` - - `; - - instance = new Choices('[data-choice]', { allowHTML: true }); - - expect(instance.passedElement).to.be.an.instanceOf(WrappedInput); - }); - }); - - describe('passing a select element type', () => { - it('sets the "passedElement" instance property as an instance of WrappedSelect', () => { - document.body.innerHTML = ` - - `; - - instance = new Choices('[data-choice]', { allowHTML: true }); - - expect(instance.passedElement).to.be.an.instanceOf(WrappedSelect); - }); - }); - }); - - describe(`passing an element as a HTMLElement`, () => { - describe('passing a input element type', () => { - it('sets the "passedElement" instance property as an instance of WrappedInput', () => { - document.body.innerHTML = ` - - `; - - instance = new Choices('[data-choice]', { allowHTML: true }); - - expect(instance.passedElement).to.be.an.instanceOf(WrappedInput); - }); - }); - - describe('passing a select element type', () => { - it('sets the "passedElement" instance property as an instance of WrappedSelect', () => { - document.body.innerHTML = ` - - `; - - instance = new Choices('[data-choice]', { allowHTML: true }); - - expect(instance.passedElement).to.be.an.instanceOf(WrappedSelect); - }); - }); - }); - - describe('passing an invalid element type', () => { - it('throws an TypeError', () => { - document.body.innerHTML = ` -
- `; - expect( - () => new Choices('[data-choice]', { allowHTML: true }), - ).to.throw( - TypeError, - 'Expected one of the following types text|select-one|select-multiple', - ); - }); - }); - }); - }); - - describe('public methods', () => { - describe('init', () => { - const callbackOnInitSpy = spy(); - - beforeEach(() => { - instance = new Choices(passedElement, { - allowHTML: true, - callbackOnInit: callbackOnInitSpy, - silent: true, - }); - }); - - describe('when already initialised', () => { - beforeEach(() => { - instance.initialised = true; - instance.init(); - }); - - it("doesn't set initialise flag", () => { - expect(instance.initialised).to.not.equal(false); - }); - }); - - describe('not already initialised', () => { - let createTemplatesSpy; - let createInputSpy; - let storeSubscribeSpy; - let renderSpy; - let addEventListenersSpy; - - beforeEach(() => { - createTemplatesSpy = spy(instance, '_createTemplates'); - createInputSpy = spy(instance, '_createStructure'); - storeSubscribeSpy = spy(instance._store, 'subscribe'); - renderSpy = spy(instance, '_render'); - addEventListenersSpy = spy(instance, '_addEventListeners'); - - instance.initialised = false; - instance.init(); - }); - - afterEach(() => { - createTemplatesSpy.restore(); - createInputSpy.restore(); - storeSubscribeSpy.restore(); - renderSpy.restore(); - addEventListenersSpy.restore(); - }); - - it('sets initialise flag', () => { - expect(instance.initialised).to.equal(true); - }); - - it('creates templates', () => { - expect(createTemplatesSpy.called).to.equal(true); - }); - - it('creates input', () => { - expect(createInputSpy.called).to.equal(true); - }); - - it('subscribes to store with render method', () => { - expect(storeSubscribeSpy.called).to.equal(true); - expect(storeSubscribeSpy.lastCall.args[0]).to.equal(instance._render); - }); - - it('fires initial render', () => { - expect(renderSpy.called).to.equal(true); - }); - - it('adds event listeners', () => { - expect(addEventListenersSpy.called).to.equal(true); - }); - - it('fires callback', () => { - expect(callbackOnInitSpy.called).to.equal(true); - }); - }); - }); - - describe('destroy', () => { - beforeEach(() => { - passedElement = document.createElement('input'); - passedElement.type = 'text'; - passedElement.className = 'js-choices'; - document.body.appendChild(passedElement); - - instance = new Choices(passedElement, { allowHTML: true }); - }); - - describe('not already initialised', () => { - beforeEach(() => { - instance.initialised = false; - instance.destroy(); - }); - - it("doesn't set initialise flag", () => { - expect(instance.initialised).to.not.equal(true); - }); - }); - - describe('when already initialised', () => { - let removeEventListenersSpy; - let passedElementRevealSpy; - let containerOuterUnwrapSpy; - let clearStoreSpy; - - beforeEach(() => { - removeEventListenersSpy = spy(instance, '_removeEventListeners'); - passedElementRevealSpy = spy(instance.passedElement, 'reveal'); - containerOuterUnwrapSpy = spy(instance.containerOuter, 'unwrap'); - clearStoreSpy = spy(instance, 'clearStore'); - - instance.initialised = true; - instance.destroy(); - }); - - afterEach(() => { - removeEventListenersSpy.restore(); - passedElementRevealSpy.restore(); - containerOuterUnwrapSpy.restore(); - clearStoreSpy.restore(); - }); - - it('removes event listeners', () => { - expect(removeEventListenersSpy.called).to.equal(true); - }); - - it('reveals passed element', () => { - expect(passedElementRevealSpy.called).to.equal(true); - }); - - it('reverts outer container', () => { - expect(containerOuterUnwrapSpy.called).to.equal(true); - expect(containerOuterUnwrapSpy.lastCall.args[0]).to.equal( - instance.passedElement.element, - ); - }); - - it('clears store', () => { - expect(clearStoreSpy.called).to.equal(true); - }); - - it('restes templates config', () => { - expect(instance._templates).to.deep.equal(templates); - }); - - it('resets initialise flag', () => { - expect(instance.initialised).to.equal(false); - }); - }); - }); - - describe('enable', () => { - let passedElementEnableSpy; - let addEventListenersSpy; - let containerOuterEnableSpy; - let inputEnableSpy; - - beforeEach(() => { - addEventListenersSpy = spy(instance, '_addEventListeners'); - passedElementEnableSpy = spy(instance.passedElement, 'enable'); - containerOuterEnableSpy = spy(instance.containerOuter, 'enable'); - inputEnableSpy = spy(instance.input, 'enable'); - }); - - afterEach(() => { - addEventListenersSpy.restore(); - passedElementEnableSpy.restore(); - containerOuterEnableSpy.restore(); - inputEnableSpy.restore(); - }); - - describe('when already enabled', () => { - beforeEach(() => { - instance.passedElement.isDisabled = false; - instance.containerOuter.isDisabled = false; - output = instance.enable(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('returns early', () => { - expect(passedElementEnableSpy.called).to.equal(false); - expect(addEventListenersSpy.called).to.equal(false); - expect(inputEnableSpy.called).to.equal(false); - expect(containerOuterEnableSpy.called).to.equal(false); - }); - }); - - describe('when not already enabled', () => { - beforeEach(() => { - instance.passedElement.isDisabled = true; - instance.containerOuter.isDisabled = true; - instance.enable(); - }); - - it('adds event listeners', () => { - expect(addEventListenersSpy.called).to.equal(true); - }); - - it('enables input', () => { - expect(inputEnableSpy.called).to.equal(true); - }); - - it('enables containerOuter', () => { - expect(containerOuterEnableSpy.called).to.equal(true); - }); - }); - }); - - describe('disable', () => { - let removeEventListenersSpy; - let passedElementDisableSpy; - let containerOuterDisableSpy; - let inputDisableSpy; - - beforeEach(() => { - removeEventListenersSpy = spy(instance, '_removeEventListeners'); - passedElementDisableSpy = spy(instance.passedElement, 'disable'); - containerOuterDisableSpy = spy(instance.containerOuter, 'disable'); - inputDisableSpy = spy(instance.input, 'disable'); - }); - - afterEach(() => { - removeEventListenersSpy.restore(); - passedElementDisableSpy.restore(); - containerOuterDisableSpy.restore(); - inputDisableSpy.restore(); - }); - - describe('when already disabled', () => { - beforeEach(() => { - instance.passedElement.isDisabled = true; - instance.containerOuter.isDisabled = true; - output = instance.disable(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('returns early', () => { - expect(removeEventListenersSpy.called).to.equal(false); - expect(passedElementDisableSpy.called).to.equal(false); - expect(containerOuterDisableSpy.called).to.equal(false); - expect(inputDisableSpy.called).to.equal(false); - }); - }); - - describe('when not already disabled', () => { - beforeEach(() => { - instance.passedElement.isDisabled = false; - instance.containerOuter.isDisabled = false; - output = instance.disable(); - }); - - it('removes event listeners', () => { - expect(removeEventListenersSpy.called).to.equal(true); - }); - - it('disables input', () => { - expect(inputDisableSpy.called).to.equal(true); - }); - - it('enables containerOuter', () => { - expect(containerOuterDisableSpy.called).to.equal(true); - }); - }); - }); - - describe('showDropdown', () => { - let containerOuterOpenSpy; - let dropdownShowSpy; - let inputFocusSpy; - let passedElementTriggerEventStub; - - beforeEach(() => { - containerOuterOpenSpy = spy(instance.containerOuter, 'open'); - dropdownShowSpy = spy(instance.dropdown, 'show'); - inputFocusSpy = spy(instance.input, 'focus'); - passedElementTriggerEventStub = stub(); - - instance.passedElement.triggerEvent = passedElementTriggerEventStub; - }); - - afterEach(() => { - containerOuterOpenSpy.restore(); - dropdownShowSpy.restore(); - inputFocusSpy.restore(); - instance.passedElement.triggerEvent.reset(); - }); - - describe('dropdown active', () => { - beforeEach(() => { - instance.dropdown.isActive = true; - output = instance.showDropdown(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('returns early', () => { - expect(containerOuterOpenSpy.called).to.equal(false); - expect(dropdownShowSpy.called).to.equal(false); - expect(inputFocusSpy.called).to.equal(false); - expect(passedElementTriggerEventStub.called).to.equal(false); - }); - }); - - describe('dropdown inactive', () => { - beforeEach(() => { - instance.dropdown.isActive = false; - output = instance.showDropdown(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('opens containerOuter', (done) => { - requestAnimationFrame(() => { - expect(containerOuterOpenSpy.called).to.equal(true); - done(); - }); - }); - - it('shows dropdown with blurInput flag', (done) => { - requestAnimationFrame(() => { - expect(dropdownShowSpy.called).to.equal(true); - done(); - }); - }); - - it('triggers event on passedElement', (done) => { - requestAnimationFrame(() => { - expect(passedElementTriggerEventStub.called).to.equal(true); - expect(passedElementTriggerEventStub.lastCall.args[0]).to.eql( - EVENTS.showDropdown, - ); - expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({}); - done(); - }); - }); - - describe('passing true focusInput flag with canSearch set to true', () => { - beforeEach(() => { - instance.dropdown.isActive = false; - instance._canSearch = true; - output = instance.showDropdown(true); - }); - - it('focuses input', (done) => { - requestAnimationFrame(() => { - expect(inputFocusSpy.called).to.equal(true); - done(); - }); - }); - }); - }); - }); - - describe('hideDropdown', () => { - let containerOuterCloseSpy; - let dropdownHideSpy; - let inputBlurSpy; - let inputRemoveActiveDescendantSpy; - let passedElementTriggerEventStub; - - beforeEach(() => { - containerOuterCloseSpy = spy(instance.containerOuter, 'close'); - dropdownHideSpy = spy(instance.dropdown, 'hide'); - inputBlurSpy = spy(instance.input, 'blur'); - inputRemoveActiveDescendantSpy = spy( - instance.input, - 'removeActiveDescendant', - ); - passedElementTriggerEventStub = stub(); - - instance.passedElement.triggerEvent = passedElementTriggerEventStub; - }); - - afterEach(() => { - containerOuterCloseSpy.restore(); - dropdownHideSpy.restore(); - inputBlurSpy.restore(); - inputRemoveActiveDescendantSpy.restore(); - instance.passedElement.triggerEvent.reset(); - }); - - describe('dropdown inactive', () => { - beforeEach(() => { - instance.dropdown.isActive = false; - output = instance.hideDropdown(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('returns early', () => { - expect(containerOuterCloseSpy.called).to.equal(false); - expect(dropdownHideSpy.called).to.equal(false); - expect(inputBlurSpy.called).to.equal(false); - expect(passedElementTriggerEventStub.called).to.equal(false); - }); - }); - - describe('dropdown active', () => { - beforeEach(() => { - instance.dropdown.isActive = true; - output = instance.hideDropdown(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('closes containerOuter', (done) => { - requestAnimationFrame(() => { - expect(containerOuterCloseSpy.called).to.equal(true); - done(); - }); - }); - - it('hides dropdown with blurInput flag', (done) => { - requestAnimationFrame(() => { - expect(dropdownHideSpy.called).to.equal(true); - done(); - }); - }); - - it('triggers event on passedElement', (done) => { - requestAnimationFrame(() => { - expect(passedElementTriggerEventStub.called).to.equal(true); - expect(passedElementTriggerEventStub.lastCall.args[0]).to.eql( - EVENTS.hideDropdown, - ); - expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({}); - done(); - }); - }); - - describe('passing true blurInput flag with canSearch set to true', () => { - beforeEach(() => { - instance.dropdown.isActive = true; - instance._canSearch = true; - output = instance.hideDropdown(true); - }); - - it('removes active descendants', (done) => { - requestAnimationFrame(() => { - expect(inputRemoveActiveDescendantSpy.called).to.equal(true); - done(); - }); - }); - - it('blurs input', (done) => { - requestAnimationFrame(() => { - expect(inputBlurSpy.called).to.equal(true); - done(); - }); - }); - }); - }); - }); - - describe('highlightItem', () => { - let passedElementTriggerEventStub; - let storeDispatchSpy; - let storeGetGroupByIdStub; - const groupIdValue = 'Test'; - - beforeEach(() => { - passedElementTriggerEventStub = stub(); - storeGetGroupByIdStub = stub().returns({ - value: groupIdValue, - }); - storeDispatchSpy = spy(instance._store, 'dispatch'); - - instance._store.getGroupById = storeGetGroupByIdStub; - instance.passedElement.triggerEvent = passedElementTriggerEventStub; - }); - - afterEach(() => { - storeDispatchSpy.restore(); - instance._store.getGroupById.reset(); - instance.passedElement.triggerEvent.reset(); - }); - - describe('no item passed', () => { - beforeEach(() => { - output = instance.highlightItem(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('returns early', () => { - expect(passedElementTriggerEventStub.called).to.equal(false); - expect(storeDispatchSpy.called).to.equal(false); - expect(storeGetGroupByIdStub.called).to.equal(false); - }); - }); - - describe('item passed', () => { - const item: Item = { - id: 1234, - value: 'Test', - label: 'Test', - }; - - describe('passing truthy second paremeter', () => { - beforeEach(() => { - output = instance.highlightItem(item, true); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('dispatches highlightItem action with correct arguments', () => { - expect(storeDispatchSpy.called).to.equal(true); - expect(storeDispatchSpy.lastCall.args[0]).to.eql({ - type: ACTION_TYPES.HIGHLIGHT_ITEM, - id: item.id, - highlighted: true, - }); - }); - - describe('item with negative groupId', () => { - beforeEach(() => { - item.groupId = -1; - output = instance.highlightItem(item); - }); - - it('triggers event with null groupValue', () => { - expect(passedElementTriggerEventStub.called).to.equal(true); - expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal( - EVENTS.highlightItem, - ); - expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({ - id: item.id, - value: item.value, - label: item.label, - groupValue: null, - }); - }); - }); - - describe('item without groupId', () => { - beforeEach(() => { - item.groupId = 1; - output = instance.highlightItem(item); - }); - - it('triggers event with groupValue', () => { - expect(passedElementTriggerEventStub.called).to.equal(true); - expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal( - EVENTS.highlightItem, - ); - expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({ - id: item.id, - value: item.value, - label: item.label, - groupValue: groupIdValue, - }); - }); - }); - }); - - describe('passing falsey second paremeter', () => { - beforeEach(() => { - output = instance.highlightItem(item, false); - }); - - it("doesn't trigger event", () => { - expect(passedElementTriggerEventStub.called).to.equal(false); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - }); - }); - }); - - describe('unhighlightItem', () => { - let passedElementTriggerEventStub; - let storeDispatchSpy; - let storeGetGroupByIdStub; - const groupIdValue = 'Test'; - - beforeEach(() => { - passedElementTriggerEventStub = stub(); - storeGetGroupByIdStub = stub().returns({ - value: groupIdValue, - }); - storeDispatchSpy = spy(instance._store, 'dispatch'); - - instance._store.getGroupById = storeGetGroupByIdStub; - instance.passedElement.triggerEvent = passedElementTriggerEventStub; - }); - - afterEach(() => { - storeDispatchSpy.restore(); - instance._store.getGroupById.reset(); - instance.passedElement.triggerEvent.reset(); - }); - - describe('no item passed', () => { - beforeEach(() => { - output = instance.unhighlightItem(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('returns early', () => { - expect(passedElementTriggerEventStub.called).to.equal(false); - expect(storeDispatchSpy.called).to.equal(false); - expect(storeGetGroupByIdStub.called).to.equal(false); - }); - }); - - describe('item passed', () => { - const item: Item = { - id: 1234, - value: 'Test', - label: 'Test', - }; - - describe('passing truthy second paremeter', () => { - beforeEach(() => { - output = instance.unhighlightItem(item, true); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('dispatches highlightItem action with correct arguments', () => { - expect(storeDispatchSpy.called).to.equal(true); - expect(storeDispatchSpy.lastCall.args[0]).to.eql({ - type: ACTION_TYPES.HIGHLIGHT_ITEM, - id: item.id, - highlighted: false, - }); - }); - - describe('item with negative groupId', () => { - beforeEach(() => { - item.groupId = -1; - output = instance.unhighlightItem(item); - }); - - it('triggers event with null groupValue', () => { - expect(passedElementTriggerEventStub.called).to.equal(true); - expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal( - EVENTS.highlightItem, - ); - expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({ - id: item.id, - value: item.value, - label: item.label, - groupValue: null, - }); - }); - }); - - describe('item without groupId', () => { - beforeEach(() => { - item.groupId = 1; - output = instance.highlightItem(item); - }); - - it('triggers event with groupValue', () => { - expect(passedElementTriggerEventStub.called).to.equal(true); - expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal( - EVENTS.highlightItem, - ); - expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({ - id: item.id, - value: item.value, - label: item.label, - groupValue: groupIdValue, - }); - }); - }); - }); - - describe('passing falsey second paremeter', () => { - beforeEach(() => { - output = instance.highlightItem(item, false); - }); - - it("doesn't trigger event", () => { - expect(passedElementTriggerEventStub.called).to.equal(false); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - }); - }); - }); - - describe('highlightAll', () => { - let storeGetItemsStub; - let highlightItemStub; - - const items = [ - { - id: 1, - value: 'Test 1', - }, - { - id: 2, - value: 'Test 2', - }, - ]; - - beforeEach(() => { - storeGetItemsStub = stub(instance._store, 'items').get(() => items); - highlightItemStub = stub(); - - instance.highlightItem = highlightItemStub; - - output = instance.highlightAll(); - }); - - afterEach(() => { - highlightItemStub.reset(); - storeGetItemsStub.reset(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('highlights each item in store', () => { - expect(highlightItemStub.callCount).to.equal(items.length); - expect(highlightItemStub.firstCall.args[0]).to.equal(items[0]); - expect(highlightItemStub.lastCall.args[0]).to.equal(items[1]); - }); - }); - - describe('unhighlightAll', () => { - let storeGetItemsStub; - let unhighlightItemStub; - - const items = [ - { - id: 1, - value: 'Test 1', - }, - { - id: 2, - value: 'Test 2', - }, - ]; - - beforeEach(() => { - storeGetItemsStub = stub(instance._store, 'items').get(() => items); - unhighlightItemStub = stub(); - - instance.unhighlightItem = unhighlightItemStub; - - output = instance.unhighlightAll(); - }); - - afterEach(() => { - instance.unhighlightItem.reset(); - storeGetItemsStub.reset(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('unhighlights each item in store', () => { - expect(unhighlightItemStub.callCount).to.equal(items.length); - expect(unhighlightItemStub.firstCall.args[0]).to.equal(items[0]); - expect(unhighlightItemStub.lastCall.args[0]).to.equal(items[1]); - }); - }); - - describe('clearChoices', () => { - let storeDispatchStub; - - beforeEach(() => { - storeDispatchStub = stub(); - instance._store.dispatch = storeDispatchStub; - - output = instance.clearChoices(); - }); - - afterEach(() => { - instance._store.dispatch.reset(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('dispatches clearChoices action', () => { - expect(storeDispatchStub.lastCall.args[0]).to.eql({ - type: ACTION_TYPES.CLEAR_CHOICES, - }); - }); - }); - - describe('clearStore', () => { - let storeDispatchStub; - - beforeEach(() => { - storeDispatchStub = stub(); - instance._store.dispatch = storeDispatchStub; - - output = instance.clearStore(); - }); - - afterEach(() => { - instance._store.dispatch.reset(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - it('dispatches clearAll action', () => { - expect(storeDispatchStub.lastCall.args[0]).to.eql({ - type: ACTION_TYPES.CLEAR_ALL, - }); - }); - }); - - describe('clearInput', () => { - let inputClearSpy; - let storeDispatchStub; - - beforeEach(() => { - inputClearSpy = spy(instance.input, 'clear'); - storeDispatchStub = stub(); - instance._store.dispatch = storeDispatchStub; - output = instance.clearInput(); - }); - - afterEach(() => { - inputClearSpy.restore(); - instance._store.dispatch.reset(); - }); - - it('returns this', () => { - expect(output).to.eql(instance); - }); - - describe('text element', () => { - beforeEach(() => { - instance._isSelectOneElement = false; - instance._isTextElement = false; - - output = instance.clearInput(); - }); - - it('clears input with correct arguments', () => { - expect(inputClearSpy.called).to.equal(true); - expect(inputClearSpy.lastCall.args[0]).to.equal(true); - }); - }); - - describe('select element with search enabled', () => { - beforeEach(() => { - instance._isSelectOneElement = true; - instance._isTextElement = false; - instance.config.searchEnabled = true; - - output = instance.clearInput(); - }); - - it('clears input with correct arguments', () => { - expect(inputClearSpy.called).to.equal(true); - expect(inputClearSpy.lastCall.args[0]).to.equal(false); - }); - - it('resets search flag', () => { - expect(instance._isSearching).to.equal(false); - }); - - it('dispatches activateChoices action', () => { - expect(storeDispatchStub.called).to.equal(true); - expect(storeDispatchStub.lastCall.args[0]).to.eql({ - type: ACTION_TYPES.ACTIVATE_CHOICES, - active: true, - }); - }); - }); - }); - - describe('setChoices with callback/Promise', () => { - describe('not initialised', () => { - beforeEach(() => { - instance.initialised = false; - }); - - it('should throw', () => { - expect(() => instance.setChoices(null)).Throw(ReferenceError); - }); - }); - - describe('text element', () => { - beforeEach(() => { - instance._isSelectElement = false; - }); - - it('should throw', () => { - expect(() => instance.setChoices(null)).Throw(TypeError); - }); - }); - - describe('passing invalid function', () => { - beforeEach(() => { - instance._isSelectElement = true; - }); - - it('should throw on non function', () => { - expect(() => instance.setChoices(null)).Throw(TypeError, /Promise/i); - }); - - it(`should throw on function that doesn't return promise`, () => { - expect(() => instance.setChoices(() => 'boo')).to.throw( - TypeError, - /promise/i, - ); - }); - }); - - describe('select element', () => { - it('fetches and sets choices', async () => { - document.body.innerHTML = ' - `; - - instance = new Choices('[data-choice]', { - choices, - allowHTML: false, - searchEnabled: true, - }); - }); - - it('details are passed', (done) => { - const query = - 'This is a query & a "test" with characters that should not be sanitised.'; - - instance.input.value = query; - instance.input.focus(); - instance.passedElement.element.addEventListener( - 'search', - (event) => { - expect(event.detail).to.eql({ - value: query, - resultCount: 0, - }); - done(); - }, - { once: true }, - ); - - instance._onKeyUp({ target: null, keyCode: null }); - }); - - it('uses Fuse options', (done) => { - instance.input.value = 'test'; - instance.input.focus(); - instance.passedElement.element.addEventListener( - 'search', - (event) => { - expect(event.detail.resultCount).to.eql(2); - - instance.config.fuseOptions.isCaseSensitive = true; - instance.config.fuseOptions.minMatchCharLength = 4; - instance.passedElement.element.addEventListener( - 'search', - (eventCaseSensitive) => { - expect(eventCaseSensitive.detail.resultCount).to.eql(0); - done(); - }, - { once: true }, - ); - - instance._onKeyUp({ target: null, keyCode: null }); - }, - { once: true }, - ); - - instance._onKeyUp({ target: null, keyCode: null }); - }); - - it('is fired with a searchFloor of 0', (done) => { - instance.config.searchFloor = 0; - instance.input.value = ''; - instance.input.focus(); - instance.passedElement.element.addEventListener('search', (event) => { - expect(event.detail).to.eql({ - value: instance.input.value, - resultCount: 0, - }); - done(); - }); - - instance._onKeyUp({ target: null, keyCode: null }); - }); - }); - }); - - describe('private methods', () => { - describe('_createGroupsFragment', () => { - let _createChoicesFragmentStub; - const choices: Choice[] = [ - { - id: 1, - selected: true, - groupId: 1, - value: 'Choice 1', - label: 'Choice 1', - }, - { - id: 2, - selected: false, - groupId: 2, - value: 'Choice 2', - label: 'Choice 2', - }, - { - id: 3, - selected: false, - groupId: 1, - value: 'Choice 3', - label: 'Choice 3', - }, - ]; - - const groups: Group[] = [ - { - id: 2, - value: 'Group 2', - active: true, - disabled: false, - }, - { - id: 1, - value: 'Group 1', - active: true, - disabled: false, - }, - ]; - - beforeEach(() => { - _createChoicesFragmentStub = stub(); - instance._createChoicesFragment = _createChoicesFragmentStub; - }); - - afterEach(() => { - instance._createChoicesFragment.reset(); - }); - - describe('returning a fragment of groups', () => { - describe('passing fragment argument', () => { - it('updates fragment with groups', () => { - const fragment = document.createDocumentFragment(); - const childElement = document.createElement('div'); - fragment.appendChild(childElement); - - output = instance._createGroupsFragment(groups, choices, fragment); - const elementToWrapFragment = document.createElement('div'); - elementToWrapFragment.appendChild(output); - - expect(output).to.be.instanceOf(DocumentFragment); - expect(elementToWrapFragment.children[0]).to.eql(childElement); - expect( - elementToWrapFragment.querySelectorAll('[data-group]').length, - ).to.equal(2); - }); - }); - - describe('not passing fragment argument', () => { - it('returns new groups fragment', () => { - output = instance._createGroupsFragment(groups, choices); - const elementToWrapFragment = document.createElement('div'); - elementToWrapFragment.appendChild(output); - - expect(output).to.be.instanceOf(DocumentFragment); - expect( - elementToWrapFragment.querySelectorAll('[data-group]').length, - ).to.equal(2); - }); - }); - - describe('sorting groups', () => { - let sortFnStub; - - beforeEach(() => { - sortFnStub = stub(); - instance.config.sorter = sortFnStub; - instance.config.shouldSort = true; - }); - - afterEach(() => { - instance.config.sorter.reset(); - }); - - it('sorts groups by config.sorter', () => { - expect(sortFnStub.called).to.equal(false); - instance._createGroupsFragment(groups, choices); - expect(sortFnStub.called).to.equal(true); - }); - }); - - describe('not sorting groups', () => { - let sortFnStub; - - beforeEach(() => { - sortFnStub = stub(); - instance.config.sorter = sortFnStub; - instance.config.shouldSort = false; - }); - - afterEach(() => { - instance.config.sorter.reset(); - }); - - it('does not sort groups', () => { - instance._createGroupsFragment(groups, choices); - expect(sortFnStub.called).to.equal(false); - }); - }); - - describe('select-one element', () => { - beforeEach(() => { - instance._isSelectOneElement = true; - }); - - it('calls _createChoicesFragment with choices that belong to each group', () => { - expect(_createChoicesFragmentStub.called).to.equal(false); - instance._createGroupsFragment(groups, choices); - expect(_createChoicesFragmentStub.called).to.equal(true); - expect(_createChoicesFragmentStub.firstCall.args[0]).to.eql([ - { - id: 1, - selected: true, - groupId: 1, - value: 'Choice 1', - label: 'Choice 1', - }, - { - id: 3, - selected: false, - groupId: 1, - value: 'Choice 3', - label: 'Choice 3', - }, - ]); - expect(_createChoicesFragmentStub.secondCall.args[0]).to.eql([ - { - id: 2, - selected: false, - groupId: 2, - value: 'Choice 2', - label: 'Choice 2', - }, - ]); - }); - }); - - describe('text/select-multiple element', () => { - describe('renderSelectedChoices set to "always"', () => { - beforeEach(() => { - instance._isSelectOneElement = false; - instance.config.renderSelectedChoices = 'always'; - }); - - it('calls _createChoicesFragment with choices that belong to each group', () => { - expect(_createChoicesFragmentStub.called).to.equal(false); - instance._createGroupsFragment(groups, choices); - expect(_createChoicesFragmentStub.called).to.equal(true); - expect(_createChoicesFragmentStub.firstCall.args[0]).to.eql([ - { - id: 1, - selected: true, - groupId: 1, - value: 'Choice 1', - label: 'Choice 1', - }, - { - id: 3, - selected: false, - groupId: 1, - value: 'Choice 3', - label: 'Choice 3', - }, - ]); - expect(_createChoicesFragmentStub.secondCall.args[0]).to.eql([ - { - id: 2, - selected: false, - groupId: 2, - value: 'Choice 2', - label: 'Choice 2', - }, - ]); - }); - }); - - describe('renderSelectedChoices not set to "always"', () => { - beforeEach(() => { - instance._isSelectOneElement = false; - instance.config.renderSelectedChoices = false; - }); - - it('calls _createChoicesFragment with choices that belong to each group that are not already selected', () => { - expect(_createChoicesFragmentStub.called).to.equal(false); - instance._createGroupsFragment(groups, choices); - expect(_createChoicesFragmentStub.called).to.equal(true); - expect(_createChoicesFragmentStub.firstCall.args[0]).to.eql([ - { - id: 3, - selected: false, - groupId: 1, - value: 'Choice 3', - label: 'Choice 3', - }, - ]); - expect(_createChoicesFragmentStub.secondCall.args[0]).to.eql([ - { - id: 2, - selected: false, - groupId: 2, - value: 'Choice 2', - label: 'Choice 2', - }, - ]); - }); - }); - }); - }); - }); - - describe('_generatePlaceholderValue', () => { - describe('select element', () => { - describe('when a placeholder option is defined', () => { - it('returns the text value of the placeholder option', () => { - const placeholderValue = 'I am a placeholder'; - - instance._isSelectElement = true; - instance.passedElement.placeholderOption = { - text: placeholderValue, - }; - - const value = instance._generatePlaceholderValue(); - expect(value).to.equal(placeholderValue); - }); - }); - - describe('when a placeholder option is not defined', () => { - it('returns null', () => { - instance._isSelectElement = true; - instance.passedElement.placeholderOption = undefined; - - const value = instance._generatePlaceholderValue(); - expect(value).to.equal(null); - }); - }); - }); - - describe('text input', () => { - describe('when the placeholder config option is set to true', () => { - describe('when the placeholderValue config option is defined', () => { - it('returns placeholderValue', () => { - const placeholderValue = 'I am a placeholder'; - - instance._isSelectElement = false; - instance.config.placeholder = true; - instance.config.placeholderValue = placeholderValue; - - const value = instance._generatePlaceholderValue(); - expect(value).to.equal(placeholderValue); - }); - }); - - describe('when the placeholderValue config option is not defined', () => { - describe('when the placeholder attribute is defined on the passed element', () => { - it('returns the value of the placeholder attribute', () => { - const placeholderValue = 'I am a placeholder'; - - instance._isSelectElement = false; - instance.config.placeholder = true; - instance.config.placeholderValue = undefined; - instance.passedElement.element = { - dataset: { - placeholder: placeholderValue, - }, - }; - - const value = instance._generatePlaceholderValue(); - expect(value).to.equal(placeholderValue); - }); - }); - - describe('when the placeholder attribute is not defined on the passed element', () => { - it('returns null', () => { - instance._isSelectElement = false; - instance.config.placeholder = true; - instance.config.placeholderValue = undefined; - instance.passedElement.element = { - dataset: { - placeholder: undefined, - }, - }; - - const value = instance._generatePlaceholderValue(); - expect(value).to.equal(null); - }); - }); - }); - }); - - describe('when the placeholder config option is set to false', () => { - it('returns null', () => { - instance._isSelectElement = false; - instance.config.placeholder = false; - - const value = instance._generatePlaceholderValue(); - expect(value).to.equal(null); - }); - }); - }); - }); - - describe('_getTemplate', () => { - describe('when passing a template key', () => { - it('returns the generated template for the given template key', () => { - const templateKey = 'test'; - const element = document.createElement('div'); - const customArg = { test: true }; - - instance._templates = { - [templateKey]: stub().returns(element), - }; - - output = instance._getTemplate(templateKey, customArg); - expect(output).to.deep.equal(element); - expect(instance._templates[templateKey]).to.have.been.calledOnceWith( - instance.config, - customArg, - ); - }); - }); - }); - - describe('_onKeyDown', () => { - let activeItems; - let hasItems; - let hasActiveDropdown; - let hasFocussedInput; - - beforeEach(() => { - instance.showDropdown = stub(); - instance._onSelectKey = stub(); - instance._onEnterKey = stub(); - instance._onEscapeKey = stub(); - instance._onDirectionKey = stub(); - instance._onDeleteKey = stub(); - - ({ activeItems } = instance._store); - hasItems = instance.itemList.hasChildren(); - hasActiveDropdown = instance.dropdown.isActive; - hasFocussedInput = instance.input.isFocussed; - }); - - describe('direction key', () => { - const keyCodes = [ - KEY_CODES.UP_KEY, - KEY_CODES.DOWN_KEY, - KEY_CODES.PAGE_UP_KEY, - KEY_CODES.PAGE_DOWN_KEY, - ]; - - keyCodes.forEach((keyCode) => { - it(`calls _onDirectionKey with the expected arguments`, () => { - const event = { - keyCode, - }; - - instance._onKeyDown(event); - - expect(instance._onDirectionKey).to.have.been.calledWith( - event, - hasActiveDropdown, - ); - }); - }); - }); - - describe('select key', () => { - it(`calls _onSelectKey with the expected arguments`, () => { - const event = { - keyCode: KEY_CODES.A_KEY, - }; - - instance._onKeyDown(event); - - expect(instance._onSelectKey).to.have.been.calledWith( - event, - hasItems, - ); - }); - }); - - describe('enter key', () => { - it(`calls _onEnterKey with the expected arguments`, () => { - const event = { - keyCode: KEY_CODES.ENTER_KEY, - }; - - instance._onKeyDown(event); - - expect(instance._onEnterKey).to.have.been.calledWith( - event, - activeItems, - hasActiveDropdown, - ); - }); - }); - - describe('delete key', () => { - const keyCodes = [KEY_CODES.DELETE_KEY, KEY_CODES.BACK_KEY]; - - keyCodes.forEach((keyCode) => { - it(`calls _onDeleteKey with the expected arguments`, () => { - const event = { - keyCode, - }; - - instance._onKeyDown(event); - - expect(instance._onDeleteKey).to.have.been.calledWith( - event, - activeItems, - hasFocussedInput, - ); - }); - }); - }); - }); - - describe('_removeItem', () => { - beforeEach(() => { - instance._store.dispatch = stub(); - }); - - afterEach(() => { - instance._store.dispatch.reset(); - }); - - describe('when given an item to remove', () => { - const item = { - id: 1111, - value: 'test value', - label: 'test label', - choiceId: 2222, - groupId: 3333, - customProperties: {}, - }; - - it('dispatches a REMOVE_ITEM action to the store', () => { - instance._removeItem(item); - - expect(instance._store.dispatch).to.have.been.calledWith( - removeItem(item.id, item.choiceId), - ); - }); - - it('triggers a REMOVE_ITEM event on the passed element', (done) => { - passedElement.addEventListener( - 'removeItem', - (event) => { - expect(event.detail).to.eql({ - id: item.id, - value: item.value, - label: item.label, - customProperties: item.customProperties, - groupValue: null, - }); - done(); - }, - false, - ); - - instance._removeItem(item); - }); - - describe('when the item belongs to a group', () => { - const group = { - id: 1, - value: 'testing', - }; - const itemWithGroup = { - ...item, - groupId: group.id, - }; - - beforeEach(() => { - instance._store.getGroupById = stub(); - instance._store.getGroupById.returns(group); - }); - - afterEach(() => { - instance._store.getGroupById.reset(); - }); - - it("includes the group's value in the triggered event", (done) => { - passedElement.addEventListener( - 'removeItem', - (event) => { - expect(event.detail).to.eql({ - id: itemWithGroup.id, - value: itemWithGroup.value, - label: itemWithGroup.label, - customProperties: itemWithGroup.customProperties, - groupValue: group.value, - }); - - done(); - }, - false, - ); - - instance._removeItem(itemWithGroup); - }); - }); - }); - }); - }); -}); diff --git a/assets/extensions/choices.js/src/scripts/choices.ts b/assets/extensions/choices.js/src/scripts/choices.ts index 36a51da4..07cfbe83 100644 --- a/assets/extensions/choices.js/src/scripts/choices.ts +++ b/assets/extensions/choices.js/src/scripts/choices.ts @@ -1,85 +1,89 @@ -import merge from 'deepmerge'; /* eslint-disable @typescript-eslint/no-explicit-any */ -import Fuse from 'fuse.js'; - -import { - activateChoices, - addChoice, - clearChoices, - filterChoices, - Result, -} from './actions/choices'; +import { activateChoices, addChoice, removeChoice, filterChoices } from './actions/choices'; import { addGroup } from './actions/groups'; import { addItem, highlightItem, removeItem } from './actions/items'; -import { clearAll, resetTo, setIsLoading } from './actions/misc'; -import { - Container, - Dropdown, - Input, - List, - WrappedInput, - WrappedSelect, -} from './components'; -import { - EVENTS, - KEY_CODES, - SELECT_MULTIPLE_TYPE, - SELECT_ONE_TYPE, - TEXT_TYPE, -} from './constants'; +import { Container, Dropdown, Input, List, WrappedInput, WrappedSelect } from './components'; import { DEFAULT_CONFIG } from './defaults'; -import { Choice } from './interfaces/choice'; -import { Group } from './interfaces/group'; -import { Item } from './interfaces/item'; -import { Notice } from './interfaces/notice'; -import { Options } from './interfaces/options'; -import { PassedElement } from './interfaces/passed-element'; -import { State } from './interfaces/state'; - +import { InputChoice } from './interfaces/input-choice'; +import { InputGroup } from './interfaces/input-group'; +import { Options, ObjectsInConfig } from './interfaces/options'; +import { StateChangeSet } from './interfaces/state'; import { + addClassesToElement, diff, - existsInArray, + escapeForTemplate, generateId, getAdjacentEl, - getType, + getClassNamesSelector, isScrolledIntoView, - isType, - sortByScore, + removeClassesFromElement, + resolveNoticeFunction, + resolveStringFunction, + sanitise, + sortByRank, strToEl, - parseCustomProperties, } from './lib/utils'; -import { defaultState } from './reducers'; import Store from './store/store'; -import templates from './templates'; +import { coerceBool, mapInputToChoice } from './lib/choice-input'; +import { ChoiceFull } from './interfaces/choice-full'; +import { GroupFull } from './interfaces/group-full'; +import { EventType, KeyCodeMap, PassedElementType, PassedElementTypes } from './interfaces'; +import { EventChoice } from './interfaces/event-choice'; +import { NoticeType, NoticeTypes, Templates } from './interfaces/templates'; +import { isHtmlInputElement, isHtmlSelectElement } from './lib/html-guard-statements'; +import { Searcher } from './interfaces/search'; +import { getSearcher } from './search'; +// eslint-disable-next-line import/no-named-default +import { default as defaultTemplates } from './templates'; +import { canUseDom } from './interfaces/build-flags'; /** @see {@link http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c} */ const IS_IE11 = + canUseDom && '-ms-scroll-limit' in document.documentElement.style && '-ms-ime-align' in document.documentElement.style; const USER_DEFAULTS: Partial = {}; +const parseDataSetId = (element?: HTMLElement): number | undefined => { + if (!element) { + return undefined; + } + + return element.dataset.id ? parseInt(element.dataset.id, 10) : undefined; +}; + +const selectableChoiceIdentifier = '[data-choice-selectable]'; + /** * Choices * @author Josh Johnson */ -class Choices implements Choices { +class Choices { + static version: string = '__VERSION__'; + static get defaults(): { options: Partial; - templates: typeof templates; + allOptions: Options; + templates: Templates; } { return Object.preventExtensions({ get options(): Partial { return USER_DEFAULTS; }, - get templates(): typeof templates { - return templates; + get allOptions(): Options { + return DEFAULT_CONFIG; + }, + get templates(): Templates { + return defaultTemplates; }, }); } initialised: boolean; + initialisedOK?: boolean = undefined; + config: Options; passedElement: WrappedInput | WrappedSelect; @@ -96,6 +100,8 @@ class Choices implements Choices { dropdown: Dropdown; + _elementType: PassedElementType; + _isTextElement: boolean; _isSelectOneElement: boolean; @@ -104,15 +110,17 @@ class Choices implements Choices { _isSelectElement: boolean; - _store: Store; + _hasNonChoicePlaceholder: boolean = false; + + _canAddUserChoices: boolean; - _templates: typeof templates; + _store: Store; - _initialState: State; + _templates: Templates; - _currentState: State; + _lastAddedChoiceId: number = 0; - _prevState: State; + _lastAddedGroupId: number = 0; _currentValue: string; @@ -136,124 +144,138 @@ class Choices implements Choices { itemChoice: string; }; - _presetGroups: Group[] | HTMLOptGroupElement[] | Element[]; + _presetChoices: (ChoiceFull | GroupFull)[]; - _presetOptions: Item[] | HTMLOptionElement[]; + _initialItems: string[]; - _presetChoices: Partial[]; + _searcher: Searcher; + + _notice?: { + type: NoticeType; + text: string; + }; - _presetItems: Item[] | string[]; + _docRoot: ShadowRoot | HTMLElement; constructor( - element: - | string - | Element - | HTMLInputElement - | HTMLSelectElement = '[data-choice]', + element: string | Element | HTMLInputElement | HTMLSelectElement = '[data-choice]', userConfig: Partial = {}, ) { - if (userConfig.allowHTML === undefined) { - console.warn( - 'Deprecation warning: allowHTML will default to false in a future release. To render HTML in Choices, you will need to set it to true. Setting allowHTML will suppress this message.', - ); - } - - this.config = merge.all( - [DEFAULT_CONFIG, Choices.defaults.options, userConfig], - // When merging array configs, replace with a copy of the userConfig array, - // instead of concatenating with the default array - { arrayMerge: (_, sourceArray) => [...sourceArray] }, - ); + const { defaults } = Choices; + this.config = { + ...defaults.allOptions, + ...defaults.options, + ...userConfig, + } as Options; + ObjectsInConfig.forEach((key) => { + this.config[key] = { + ...defaults.allOptions[key], + ...defaults.options[key], + ...userConfig[key], + }; + }); - const invalidConfigOptions = diff(this.config, DEFAULT_CONFIG); - if (invalidConfigOptions.length) { - console.warn( - 'Unknown config option(s) passed', - invalidConfigOptions.join(', '), - ); + const { config } = this; + if (!config.silent) { + this._validateConfig(); } - const passedElement = - typeof element === 'string' ? document.querySelector(element) : element; + const docRoot = config.shadowRoot || document.documentElement; + this._docRoot = docRoot; + const passedElement = typeof element === 'string' ? docRoot.querySelector(element) : element; if ( - !( - passedElement instanceof HTMLInputElement || - passedElement instanceof HTMLSelectElement - ) + !passedElement || + typeof passedElement !== 'object' || + !(isHtmlInputElement(passedElement) || isHtmlSelectElement(passedElement)) ) { - throw TypeError( - 'Expected one of the following types text|select-one|select-multiple', - ); + if (!passedElement && typeof element === 'string') { + throw TypeError(`Selector ${element} failed to find an element`); + } + throw TypeError(`Expected one of the following types text|select-one|select-multiple`); } - this._isTextElement = passedElement.type === TEXT_TYPE; - this._isSelectOneElement = passedElement.type === SELECT_ONE_TYPE; - this._isSelectMultipleElement = passedElement.type === SELECT_MULTIPLE_TYPE; - this._isSelectElement = - this._isSelectOneElement || this._isSelectMultipleElement; + let elementType = passedElement.type as PassedElementType; + const isText = elementType === PassedElementTypes.Text; + if (isText || config.maxItemCount !== 1) { + config.singleModeForMultiSelect = false; + } + if (config.singleModeForMultiSelect) { + elementType = PassedElementTypes.SelectMultiple; + } + const isSelectOne = elementType === PassedElementTypes.SelectOne; + const isSelectMultiple = elementType === PassedElementTypes.SelectMultiple; + const isSelect = isSelectOne || isSelectMultiple; - this.config.searchEnabled = - this._isSelectMultipleElement || this.config.searchEnabled; + this._elementType = elementType; + this._isTextElement = isText; + this._isSelectOneElement = isSelectOne; + this._isSelectMultipleElement = isSelectMultiple; + this._isSelectElement = isSelectOne || isSelectMultiple; + this._canAddUserChoices = (isText && config.addItems) || (isSelect && config.addChoices); - if (!['auto', 'always'].includes(`${this.config.renderSelectedChoices}`)) { - this.config.renderSelectedChoices = 'auto'; + if (typeof config.renderSelectedChoices !== 'boolean') { + config.renderSelectedChoices = config.renderSelectedChoices === 'always' || isSelectOne; } - if ( - userConfig.addItemFilter && - typeof userConfig.addItemFilter !== 'function' - ) { + if (config.closeDropdownOnSelect === 'auto') { + config.closeDropdownOnSelect = isText || isSelectOne || config.singleModeForMultiSelect; + } else { + config.closeDropdownOnSelect = coerceBool(config.closeDropdownOnSelect); + } + + if (config.placeholder) { + if (config.placeholderValue) { + this._hasNonChoicePlaceholder = true; + } else if (passedElement.dataset.placeholder) { + this._hasNonChoicePlaceholder = true; + config.placeholderValue = passedElement.dataset.placeholder; + } + } + + if (userConfig.addItemFilter && typeof userConfig.addItemFilter !== 'function') { const re = - userConfig.addItemFilter instanceof RegExp - ? userConfig.addItemFilter - : new RegExp(userConfig.addItemFilter); + userConfig.addItemFilter instanceof RegExp ? userConfig.addItemFilter : new RegExp(userConfig.addItemFilter); - this.config.addItemFilter = re.test.bind(re); + config.addItemFilter = re.test.bind(re); } if (this._isTextElement) { this.passedElement = new WrappedInput({ element: passedElement as HTMLInputElement, - classNames: this.config.classNames, - delimiter: this.config.delimiter, + classNames: config.classNames, }); } else { + const selectEl = passedElement as HTMLSelectElement; this.passedElement = new WrappedSelect({ - element: passedElement as HTMLSelectElement, - classNames: this.config.classNames, - template: (data: Item): HTMLOptionElement => - this._templates.option(data), + element: selectEl, + classNames: config.classNames, + template: (data: ChoiceFull): HTMLOptionElement => this._templates.option(data), + extractPlaceholder: config.placeholder && !this._hasNonChoicePlaceholder, }); } this.initialised = false; - this._store = new Store(); - this._initialState = defaultState; - this._currentState = defaultState; - this._prevState = defaultState; + this._store = new Store(config); this._currentValue = ''; - this._canSearch = !!this.config.searchEnabled; + config.searchEnabled = (!isText && config.searchEnabled) || isSelectMultiple; + this._canSearch = config.searchEnabled; this._isScrollingOnIe = false; this._highlightPosition = 0; this._wasTap = true; this._placeholderValue = this._generatePlaceholderValue(); - this._baseId = generateId(this.passedElement.element, 'choices-'); + this._baseId = generateId(passedElement, 'choices-'); /** * setting direction in cases where it's explicitly set on passedElement * or when calculated direction is different from the document */ - this._direction = this.passedElement.dir; + this._direction = passedElement.dir; - if (!this._direction) { - const { direction: elementDirection } = window.getComputedStyle( - this.passedElement.element, - ); - const { direction: documentDirection } = window.getComputedStyle( - document.documentElement, - ); + if (canUseDom && !this._direction) { + const { direction: elementDirection } = window.getComputedStyle(passedElement); + const { direction: documentDirection } = window.getComputedStyle(document.documentElement); if (elementDirection !== documentDirection) { this._direction = elementDirection; } @@ -263,46 +285,13 @@ class Choices implements Choices { itemChoice: 'item-choice', }; - if (this._isSelectElement) { - // Assign preset groups from passed element - this._presetGroups = (this.passedElement as WrappedSelect).optionGroups; - // Assign preset options from passed element - this._presetOptions = (this.passedElement as WrappedSelect).options; - } - - // Assign preset choices from passed object - this._presetChoices = this.config.choices; - // Assign preset items from passed object first - this._presetItems = this.config.items; - // Add any values passed from attribute - if (this.passedElement.value && this._isTextElement) { - const splitValues: string[] = this.passedElement.value.split( - this.config.delimiter, - ); - this._presetItems = (this._presetItems as string[]).concat(splitValues); - } - // Create array of choices from option elements - if ((this.passedElement as WrappedSelect).options) { - (this.passedElement as WrappedSelect).options.forEach((option) => { - this._presetChoices.push({ - value: option.value, - label: option.innerHTML, - selected: !!option.selected, - disabled: option.disabled || option.parentNode.disabled, - placeholder: - option.value === '' || option.hasAttribute('placeholder'), - customProperties: parseCustomProperties( - option.dataset.customProperties, - ), - }); - }); - } - + this._templates = defaults.templates; this._render = this._render.bind(this); this._onFocus = this._onFocus.bind(this); this._onBlur = this._onBlur.bind(this); this._onKeyUp = this._onKeyUp.bind(this); this._onKeyDown = this._onKeyDown.bind(this); + this._onInput = this._onInput.bind(this); this._onClick = this._onClick.bind(this); this._onTouchMove = this._onTouchMove.bind(this); this._onTouchEnd = this._onTouchEnd.bind(this); @@ -317,49 +306,53 @@ class Choices implements Choices { // If element has already been initialised with Choices, fail silently if (this.passedElement.isActive) { - if (!this.config.silent) { - console.warn( - 'Trying to initialise Choices on element already initialised', - { element }, - ); + if (!config.silent) { + console.warn('Trying to initialise Choices on element already initialised', { element }); } this.initialised = true; + this.initialisedOK = false; return; } // Let's go this.init(); + // preserve the selected item list after setup for form reset + this._initialItems = this._store.items.map((choice) => choice.value); } init(): void { - if (this.initialised) { + if (this.initialised || this.initialisedOK !== undefined) { return; } + this._searcher = getSearcher(this.config); + this._loadChoices(); this._createTemplates(); this._createElements(); this._createStructure(); - this._store.subscribe(this._render); - - this._render(); - this._addEventListeners(); - - const shouldDisable = - !this.config.addItems || - this.passedElement.element.hasAttribute('disabled'); - - if (shouldDisable) { + if ( + (this._isTextElement && !this.config.addItems) || + this.passedElement.element.hasAttribute('disabled') || + !!this.passedElement.element.closest('fieldset:disabled') + ) { this.disable(); + } else { + this.enable(); + this._addEventListeners(); } + // should be triggered **after** disabled state to avoid additional re-draws + this._initStore(); + this.initialised = true; + this.initialisedOK = true; const { callbackOnInit } = this.config; // Run callback if it is a function - if (callbackOnInit && typeof callbackOnInit === 'function') { + if (typeof callbackOnInit === 'function') { callbackOnInit.call(this); } } @@ -373,14 +366,13 @@ class Choices implements Choices { this.passedElement.reveal(); this.containerOuter.unwrap(this.passedElement.element); + this._store._listeners = []; // prevents select/input value being wiped this.clearStore(); + this._stopSearch(); - if (this._isSelectElement) { - (this.passedElement as WrappedSelect).options = this._presetOptions; - } - - this._templates = templates; + this._templates = Choices.defaults.templates; this.initialised = false; + this.initialisedOK = undefined; } enable(): this { @@ -411,83 +403,96 @@ class Choices implements Choices { return this; } - highlightItem(item: Item, runEvent = true): this { + highlightItem(item: InputChoice, runEvent = true): this { if (!item || !item.id) { return this; } + const choice = this._store.items.find((c) => c.id === item.id); + if (!choice || choice.highlighted) { + return this; + } - const { id, groupId = -1, value = '', label = '' } = item; - const group = groupId >= 0 ? this._store.getGroupById(groupId) : null; - - this._store.dispatch(highlightItem(id, true)); + this._store.dispatch(highlightItem(choice, true)); if (runEvent) { - this.passedElement.triggerEvent(EVENTS.highlightItem, { - id, - value, - label, - groupValue: group && group.value ? group.value : null, - }); + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice)); } return this; } - unhighlightItem(item: Item): this { + unhighlightItem(item: InputChoice, runEvent = true): this { if (!item || !item.id) { return this; } + const choice = this._store.items.find((c) => c.id === item.id); + if (!choice || !choice.highlighted) { + return this; + } - const { id, groupId = -1, value = '', label = '' } = item; - const group = groupId >= 0 ? this._store.getGroupById(groupId) : null; + this._store.dispatch(highlightItem(choice, false)); - this._store.dispatch(highlightItem(id, false)); - this.passedElement.triggerEvent(EVENTS.highlightItem, { - id, - value, - label, - groupValue: group && group.value ? group.value : null, - }); + if (runEvent) { + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(choice)); + } return this; } highlightAll(): this { - this._store.items.forEach((item) => this.highlightItem(item)); + this._store.withTxn(() => { + this._store.items.forEach((item) => { + if (!item.highlighted) { + this._store.dispatch(highlightItem(item, true)); + + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(item)); + } + }); + }); return this; } unhighlightAll(): this { - this._store.items.forEach((item) => this.unhighlightItem(item)); + this._store.withTxn(() => { + this._store.items.forEach((item) => { + if (item.highlighted) { + this._store.dispatch(highlightItem(item, false)); + + this.passedElement.triggerEvent(EventType.highlightItem, this._getChoiceForOutput(item)); + } + }); + }); return this; } removeActiveItemsByValue(value: string): this { - this._store.activeItems - .filter((item) => item.value === value) - .forEach((item) => this._removeItem(item)); + this._store.withTxn(() => { + this._store.items.filter((item) => item.value === value).forEach((item) => this._removeItem(item)); + }); return this; } - removeActiveItems(excludedId: number): this { - this._store.activeItems - .filter(({ id }) => id !== excludedId) - .forEach((item) => this._removeItem(item)); + removeActiveItems(excludedId?: number): this { + this._store.withTxn(() => { + this._store.items.filter(({ id }) => id !== excludedId).forEach((item) => this._removeItem(item)); + }); return this; } removeHighlightedItems(runEvent = false): this { - this._store.highlightedActiveItems.forEach((item) => { - this._removeItem(item); - // If this action was performed by the user - // trigger the event - if (runEvent) { - this._triggerChange(item.value); - } + this._store.withTxn(() => { + this._store.highlightedActiveItems.forEach((item) => { + this._removeItem(item); + // If this action was performed by the user + // trigger the event + if (runEvent) { + this._triggerChange(item.value); + } + }); }); return this; @@ -500,13 +505,14 @@ class Choices implements Choices { requestAnimationFrame(() => { this.dropdown.show(); - this.containerOuter.open(this.dropdown.distanceFromTopWindow); + const rect = this.dropdown.element.getBoundingClientRect(); + this.containerOuter.open(rect.bottom, rect.height); if (!preventInputFocus && this._canSearch) { this.input.focus(); } - this.passedElement.triggerEvent(EVENTS.showDropdown, {}); + this.passedElement.triggerEvent(EventType.showDropdown); }); return this; @@ -526,46 +532,64 @@ class Choices implements Choices { this.input.blur(); } - this.passedElement.triggerEvent(EVENTS.hideDropdown, {}); + this.passedElement.triggerEvent(EventType.hideDropdown); }); return this; } - getValue(valueOnly = false): string[] | Item[] | Item | string { - const values = this._store.activeItems.reduce( - (selectedItems, item) => { - const itemValue = valueOnly ? item.value : item; - selectedItems.push(itemValue); + getValue(valueOnly = false): string[] | EventChoice[] | EventChoice | string { + const values = this._store.items.reduce((selectedItems, item) => { + const itemValue = valueOnly ? item.value : this._getChoiceForOutput(item); + selectedItems.push(itemValue); - return selectedItems; - }, - [], - ); + return selectedItems; + }, []); - return this._isSelectOneElement ? values[0] : values; + return this._isSelectOneElement || this.config.singleModeForMultiSelect ? values[0] : values; } - setValue(items: string[] | Item[]): this { - if (!this.initialised) { + setValue(items: string[] | InputChoice[]): this { + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setValue'); + return this; } - items.forEach((value) => this._setChoiceOrItem(value)); + this._store.withTxn(() => { + items.forEach((value: string | InputChoice) => { + if (value) { + this._addChoice(mapInputToChoice(value, false)); + } + }); + }); + + // @todo integrate with Store + this._searcher.reset(); return this; } setChoiceByValue(value: string | string[]): this { - if (!this.initialised || this._isTextElement) { + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setChoiceByValue'); + + return this; + } + if (this._isTextElement) { return this; } + this._store.withTxn(() => { + // If only one value has been passed, convert to array + const choiceValue = Array.isArray(value) ? value : [value]; - // If only one value has been passed, convert to array - const choiceValue = Array.isArray(value) ? value : [value]; + // Loop through each value and + choiceValue.forEach((val) => this._findAndSelectChoiceByValue(val)); + this.unhighlightAll(); + }); - // Loop through each value and - choiceValue.forEach((val) => this._findAndSelectChoiceByValue(val)); + // @todo integrate with Store + this._searcher.reset(); return this; } @@ -635,26 +659,23 @@ class Choices implements Choices { */ setChoices( choicesArrayOrFetcher: - | Choice[] - | Group[] - | ((instance: Choices) => Choice[] | Promise) = [], - value = 'value', + | (InputChoice | InputGroup)[] + | ((instance: Choices) => (InputChoice | InputGroup)[] | Promise<(InputChoice | InputGroup)[]>) = [], + value: string | null = 'value', label = 'label', replaceChoices = false, ): this | Promise { - if (!this.initialised) { - throw new ReferenceError( - `setChoices was called on a non-initialized instance of Choices`, - ); + if (!this.initialisedOK) { + this._warnChoicesInitFailed('setChoices'); + + return this; } if (!this._isSelectElement) { throw new TypeError(`setChoices can't be used with INPUT based Choices`); } if (typeof value !== 'string' || !value) { - throw new TypeError( - `value parameter must be a name of 'value' field in passed objects`, - ); + throw new TypeError(`value parameter must be a name of 'value' field in passed objects`); } // Clear choices if needed @@ -672,9 +693,7 @@ class Choices implements Choices { return new Promise((resolve) => requestAnimationFrame(resolve)) .then(() => this._handleLoadingState(true)) .then(() => fetcher) - .then((data: Choice[]) => - this.setChoices(data, value, label, replaceChoices), - ) + .then((data: InputChoice[]) => this.setChoices(data, value, label, replaceChoices)) .catch((err) => { if (!this.config.silent) { console.error(err); @@ -703,47 +722,135 @@ class Choices implements Choices { this.containerOuter.removeLoadingState(); - this._startLoading(); + this._store.withTxn(() => { + const isDefaultValue = value === 'value'; + const isDefaultLabel = label === 'label'; + + choicesArrayOrFetcher.forEach((groupOrChoice: InputGroup | InputChoice) => { + if ('choices' in groupOrChoice) { + let group = groupOrChoice; + if (!isDefaultLabel) { + group = { + ...group, + label: group[label], + } as InputGroup; + } + + this._addGroup(mapInputToChoice(group, true)); + } else { + let choice = groupOrChoice; + if (!isDefaultLabel || !isDefaultValue) { + choice = { + ...choice, + value: choice[value], + label: choice[label], + } as InputChoice; + } + this._addChoice(mapInputToChoice(choice, false)); + } + }); + + this.unhighlightAll(); + }); - type ChoiceGroup = { - id: string; - choices: Choice[]; - }; + // @todo integrate with Store + this._searcher.reset(); - choicesArrayOrFetcher.forEach((groupOrChoice: ChoiceGroup | Choice) => { - if ((groupOrChoice as ChoiceGroup).choices) { - this._addGroup({ - id: groupOrChoice.id ? parseInt(`${groupOrChoice.id}`, 10) : null, - group: groupOrChoice, - valueKey: value, - labelKey: label, + return this; + } + + refresh(withEvents: boolean = false, selectFirstOption: boolean = false, deselectAll: boolean = false): this { + if (!this._isSelectElement) { + if (!this.config.silent) { + console.warn('refresh method can only be used on choices backed by a - * + * - `); - const actualOutput = templates.input(inputOptions, 'test placeholder'); - - expectEqualElements(actualOutput, expectedOutput); - }); - }); - - describe('dropdown', () => { - const dropdownOptions = createOptionsWithPartialClasses({ - list: 'class-1', - listDropdown: 'class-2', - }); - - it('returns expected html', () => { - const expectedOutput = strToEl( - ``, - ); - const actualOutput = templates.dropdown(dropdownOptions); - - expectEqualElements(actualOutput, expectedOutput); - }); - }); - - describe('notice', () => { - const noticeOptions = createOptionsWithPartialClasses({ - item: 'class-1', - itemChoice: 'class-2', - noResults: 'class-3', - noChoices: 'class-4', - }); - - const label = 'test'; - - it('returns expected html', () => { - const expectedOutput = strToEl(` -
- ${label} -
- `); - const actualOutput = templates.notice(noticeOptions, label); - - expectEqualElements(actualOutput, expectedOutput); - }); - - describe('passing a notice type', () => { - describe('no results', () => { - it('adds no results classname', () => { - const expectedOutput = strToEl(` -
- ${label} -
- `); - const actualOutput = templates.notice( - noticeOptions, - label, - 'no-results', - ); - - expectEqualElements(actualOutput, expectedOutput); - }); - }); - - describe('no choices', () => { - it('adds no choices classname', () => { - const expectedOutput = strToEl(` -
- ${label} -
- `); - const actualOutput = templates.notice( - noticeOptions, - label, - 'no-choices', - ); - - expectEqualElements(actualOutput, expectedOutput); - }); - }); - }); - }); - - describe('option', () => { - let data; - - beforeEach(() => { - data = { - disabled: false, - selected: false, - value: 'test value', - label: 'test label', - }; - }); - - it('returns expected html', () => { - const expectedOutput = strToEl( - ``, - ); - const actualOutput = templates.option(data); - - expectEqualElements(actualOutput, expectedOutput); - }); - - describe('when selected', () => { - beforeEach(() => { - data = { - ...data, - active: true, - }; - }); - - it('sets selected attr to true', () => { - const output = templates.option(data); - expect(output.selected).to.equal(true); - }); - }); - - describe('when disabled', () => { - beforeEach(() => { - data = { - ...data, - disabled: true, - }; - }); - - it('sets disabled attr to true', () => { - const output = templates.option(data); - expect(output.disabled).to.equal(true); - }); - }); - }); -}); diff --git a/assets/extensions/choices.js/src/scripts/templates.ts b/assets/extensions/choices.js/src/scripts/templates.ts index ee4eafd6..e5d82b40 100644 --- a/assets/extensions/choices.js/src/scripts/templates.ts +++ b/assets/extensions/choices.js/src/scripts/templates.ts @@ -1,17 +1,66 @@ /** * Helpers to create HTML elements used by Choices - * Can be overridden by providing `callbackOnCreateTemplates` option + * Can be overridden by providing `callbackOnCreateTemplates` option. + * `Choices.defaults.templates` allows access to the default template methods from `callbackOnCreateTemplates` */ -import { Choice } from './interfaces/choice'; -import { Group } from './interfaces/group'; -import { Item } from './interfaces/item'; +import { ChoiceFull } from './interfaces/choice-full'; +import { GroupFull } from './interfaces/group-full'; import { PassedElementType } from './interfaces/passed-element-type'; +import { StringPreEscaped } from './interfaces/string-pre-escaped'; +import { + getClassNames, + unwrapStringForRaw, + resolveNoticeFunction, + setElementHtml, + escapeForTemplate, + addClassesToElement, + removeClassesFromElement, +} from './lib/utils'; +import { NoticeType, NoticeTypes, TemplateOptions, Templates as TemplatesInterface } from './interfaces/templates'; +import { StringUntrusted } from './interfaces/string-untrusted'; + +const isEmptyObject = (obj: object): boolean => { + // eslint-disable-next-line no-restricted-syntax + for (const prop in obj) { + if (Object.prototype.hasOwnProperty.call(obj, prop)) { + return false; + } + } + + return true; +}; + +const assignCustomProperties = (el: HTMLElement, choice: ChoiceFull, withCustomProperties: boolean): void => { + const { dataset } = el; + const { customProperties, labelClass, labelDescription } = choice; + + if (labelClass) { + dataset.labelClass = getClassNames(labelClass).join(' '); + } -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type TemplateOptions = Record<'classNames' | 'allowHTML', any>; + if (labelDescription) { + dataset.labelDescription = labelDescription; + } -const templates = { + if (withCustomProperties && customProperties) { + if (typeof customProperties === 'string') { + dataset.customProperties = customProperties; + } else if (typeof customProperties === 'object' && !isEmptyObject(customProperties)) { + dataset.customProperties = JSON.stringify(customProperties); + } + } +}; + +const addAriaLabel = (docRoot: HTMLElement | ShadowRoot, id: string | undefined, element: HTMLElement): void => { + const label = id && docRoot.querySelector(`label[for='${id}']`); + const text = label && (label as HTMLElement).innerText; + if (text) { + element.setAttribute('aria-label', text); + } +}; + +const templates: TemplatesInterface = { containerOuter( { classNames: { containerOuter } }: TemplateOptions, dir: HTMLElement['dir'], @@ -21,9 +70,8 @@ const templates = { passedElementType: PassedElementType, labelId: string, ): HTMLDivElement { - const div = Object.assign(document.createElement('div'), { - className: containerOuter, - }); + const div = document.createElement('div'); + addClassesToElement(div, containerOuter); div.dataset.type = passedElementType; @@ -39,11 +87,14 @@ const templates = { div.setAttribute('role', searchEnabled ? 'combobox' : 'listbox'); if (searchEnabled) { div.setAttribute('aria-autocomplete', 'list'); + } else if (!labelId) { + addAriaLabel(this._docRoot, this.passedElement.element.id, div); } + + div.setAttribute('aria-haspopup', 'true'); + div.setAttribute('aria-expanded', 'false'); } - div.setAttribute('aria-haspopup', 'true'); - div.setAttribute('aria-expanded', 'false'); if (labelId) { div.setAttribute('aria-labelledby', labelId); } @@ -51,112 +102,113 @@ const templates = { return div; }, - containerInner({ - classNames: { containerInner }, - }: TemplateOptions): HTMLDivElement { - return Object.assign(document.createElement('div'), { - className: containerInner, - }); + containerInner({ classNames: { containerInner } }: TemplateOptions): HTMLDivElement { + const div = document.createElement('div'); + addClassesToElement(div, containerInner); + + return div; }, itemList( - { classNames: { list, listSingle, listItems } }: TemplateOptions, + { searchEnabled, classNames: { list, listSingle, listItems } }: TemplateOptions, isSelectOneElement: boolean, ): HTMLDivElement { - return Object.assign(document.createElement('div'), { - className: `${list} ${isSelectOneElement ? listSingle : listItems}`, - }); + const div = document.createElement('div'); + addClassesToElement(div, list); + addClassesToElement(div, isSelectOneElement ? listSingle : listItems); + + if (this._isSelectElement && searchEnabled) { + div.setAttribute('role', 'listbox'); + } + + return div; }, placeholder( { allowHTML, classNames: { placeholder } }: TemplateOptions, - value: string, + value: StringPreEscaped | string, ): HTMLDivElement { - return Object.assign(document.createElement('div'), { - className: placeholder, - [allowHTML ? 'innerHTML' : 'innerText']: value, - }); + const div = document.createElement('div'); + addClassesToElement(div, placeholder); + setElementHtml(div, allowHTML, value); + + return div; }, item( { allowHTML, - classNames: { - item, - button, - highlightedState, - itemSelectable, - placeholder, - }, + removeItemButtonAlignLeft, + removeItemIconText, + removeItemLabelText, + classNames: { item, button, highlightedState, itemSelectable, placeholder }, }: TemplateOptions, - { - id, - value, - label, - customProperties, - active, - disabled, - highlighted, - placeholder: isPlaceholder, - }: Item, + choice: ChoiceFull, removeItemButton: boolean, ): HTMLDivElement { - const div = Object.assign(document.createElement('div'), { - className: item, - [allowHTML ? 'innerHTML' : 'innerText']: label, - }); - - Object.assign(div.dataset, { - item: '', - id, - value, - customProperties, - }); - - if (active) { - div.setAttribute('aria-selected', 'true'); + const rawValue = unwrapStringForRaw(choice.value); + const div = document.createElement('div'); + addClassesToElement(div, item); + + if (choice.labelClass) { + const spanLabel = document.createElement('span'); + setElementHtml(spanLabel, allowHTML, choice.label); + addClassesToElement(spanLabel, choice.labelClass); + div.appendChild(spanLabel); + } else { + setElementHtml(div, allowHTML, choice.label); } - if (disabled) { + div.dataset.item = ''; + div.dataset.id = choice.id as unknown as string; + div.dataset.value = rawValue; + + assignCustomProperties(div, choice, true); + + if (choice.disabled || this.containerOuter.isDisabled) { div.setAttribute('aria-disabled', 'true'); } + if (this._isSelectElement) { + div.setAttribute('aria-selected', 'true'); + div.setAttribute('role', 'option'); + } - if (isPlaceholder) { - div.classList.add(placeholder); + if (choice.placeholder) { + addClassesToElement(div, placeholder); + div.dataset.placeholder = ''; } - div.classList.add(highlighted ? highlightedState : itemSelectable); + addClassesToElement(div, choice.highlighted ? highlightedState : itemSelectable); if (removeItemButton) { - if (disabled) { - div.classList.remove(itemSelectable); + if (choice.disabled) { + removeClassesFromElement(div, itemSelectable); } div.dataset.deletable = ''; - /** @todo This MUST be localizable, not hardcoded! */ - const REMOVE_ITEM_TEXT = 'Remove item'; - const removeButton = Object.assign(document.createElement('button'), { - type: 'button', - className: button, - [allowHTML ? 'innerHTML' : 'innerText']: REMOVE_ITEM_TEXT, - }); - removeButton.setAttribute( - 'aria-label', - `${REMOVE_ITEM_TEXT}: '${value}'`, - ); + + const removeButton = document.createElement('button'); + removeButton.type = 'button'; + addClassesToElement(removeButton, button); + setElementHtml(removeButton, true, resolveNoticeFunction(removeItemIconText, choice.value)); + + const REMOVE_ITEM_LABEL = resolveNoticeFunction(removeItemLabelText, choice.value); + if (REMOVE_ITEM_LABEL) { + removeButton.setAttribute('aria-label', REMOVE_ITEM_LABEL); + } removeButton.dataset.button = ''; - div.appendChild(removeButton); + if (removeItemButtonAlignLeft) { + div.insertAdjacentElement('afterbegin', removeButton); + } else { + div.appendChild(removeButton); + } } return div; }, - choiceList( - { classNames: { list } }: TemplateOptions, - isSelectOneElement: boolean, - ): HTMLDivElement { - const div = Object.assign(document.createElement('div'), { - className: list, - }); + choiceList({ classNames: { list } }: TemplateOptions, isSelectOneElement: boolean): HTMLDivElement { + const div = document.createElement('div'); + addClassesToElement(div, list); if (!isSelectOneElement) { div.setAttribute('aria-multiselectable', 'true'); @@ -167,34 +219,30 @@ const templates = { }, choiceGroup( - { - allowHTML, - classNames: { group, groupHeading, itemDisabled }, - }: TemplateOptions, - { id, value, disabled }: Group, + { allowHTML, classNames: { group, groupHeading, itemDisabled } }: TemplateOptions, + { id, label, disabled }: GroupFull, ): HTMLDivElement { - const div = Object.assign(document.createElement('div'), { - className: `${group} ${disabled ? itemDisabled : ''}`, - }); + const rawLabel = unwrapStringForRaw(label); + const div = document.createElement('div'); + addClassesToElement(div, group); + if (disabled) { + addClassesToElement(div, itemDisabled); + } div.setAttribute('role', 'group'); - Object.assign(div.dataset, { - group: '', - id, - value, - }); + div.dataset.group = ''; + div.dataset.id = id as unknown as string; + div.dataset.value = rawLabel; if (disabled) { div.setAttribute('aria-disabled', 'true'); } - div.appendChild( - Object.assign(document.createElement('div'), { - className: groupHeading, - [allowHTML ? 'innerHTML' : 'innerText']: value, - }), - ); + const heading = document.createElement('div'); + addClassesToElement(heading, groupHeading); + setElementHtml(heading, allowHTML, label || ''); + div.appendChild(heading); return div; }, @@ -202,56 +250,73 @@ const templates = { choice( { allowHTML, - classNames: { - item, - itemChoice, - itemSelectable, - selectedState, - itemDisabled, - placeholder, - }, + classNames: { item, itemChoice, itemSelectable, selectedState, itemDisabled, description, placeholder }, }: TemplateOptions, - { - id, - value, - label, - groupId, - elementId, - disabled: isDisabled, - selected: isSelected, - placeholder: isPlaceholder, - }: Choice, + choice: ChoiceFull, selectText: string, + groupName?: string, ): HTMLDivElement { - const div = Object.assign(document.createElement('div'), { - id: elementId, - [allowHTML ? 'innerHTML' : 'innerText']: label, - className: `${item} ${itemChoice}`, - }); - - if (isSelected) { - div.classList.add(selectedState); + // eslint-disable-next-line prefer-destructuring + let label: string | StringUntrusted | StringPreEscaped = choice.label; + const rawValue = unwrapStringForRaw(choice.value); + const div = document.createElement('div'); + div.id = choice.elementId as string; + addClassesToElement(div, item); + addClassesToElement(div, itemChoice); + + if (groupName && typeof label === 'string') { + label = escapeForTemplate(allowHTML, label); + label += ` (${groupName})`; + label = { trusted: label }; + div.dataset.groupId = `${choice.groupId}`; } - if (isPlaceholder) { - div.classList.add(placeholder); + let describedBy: HTMLElement = div; + if (choice.labelClass) { + const spanLabel = document.createElement('span'); + setElementHtml(spanLabel, allowHTML, label); + addClassesToElement(spanLabel, choice.labelClass); + describedBy = spanLabel; + div.appendChild(spanLabel); + } else { + setElementHtml(div, allowHTML, label); } - div.setAttribute('role', groupId && groupId > 0 ? 'treeitem' : 'option'); + if (choice.labelDescription) { + const descId = `${choice.elementId}-description`; + describedBy.setAttribute('aria-describedby', descId); + const spanDesc = document.createElement('span'); + setElementHtml(spanDesc, allowHTML, choice.labelDescription); + spanDesc.id = descId; + addClassesToElement(spanDesc, description); + div.appendChild(spanDesc); + } + + if (choice.selected) { + addClassesToElement(div, selectedState); + } + + if (choice.placeholder) { + addClassesToElement(div, placeholder); + } + + div.setAttribute('role', choice.groupId ? 'treeitem' : 'option'); + + div.dataset.choice = ''; + div.dataset.id = choice.id as unknown as string; + div.dataset.value = rawValue; + if (selectText) { + div.dataset.selectText = selectText; + } - Object.assign(div.dataset, { - choice: '', - id, - value, - selectText, - }); + assignCustomProperties(div, choice, false); - if (isDisabled) { - div.classList.add(itemDisabled); + if (choice.disabled) { + addClassesToElement(div, itemDisabled); div.dataset.choiceDisabled = ''; div.setAttribute('aria-disabled', 'true'); } else { - div.classList.add(itemSelectable); + addClassesToElement(div, itemSelectable); div.dataset.choiceSelectable = ''; } @@ -259,72 +324,82 @@ const templates = { }, input( - { classNames: { input, inputCloned } }: TemplateOptions, - placeholderValue: string, + { classNames: { input, inputCloned }, labelId }: TemplateOptions, + placeholderValue: string | null, ): HTMLInputElement { - const inp = Object.assign(document.createElement('input'), { - type: 'search', - name: 'search_terms', - className: `${input} ${inputCloned}`, - autocomplete: 'off', - autocapitalize: 'off', - spellcheck: false, - }); + const inp = document.createElement('input'); + inp.type = 'search'; + addClassesToElement(inp, input); + addClassesToElement(inp, inputCloned); + inp.autocomplete = 'off'; + inp.autocapitalize = 'off'; + inp.spellcheck = false; inp.setAttribute('role', 'textbox'); inp.setAttribute('aria-autocomplete', 'list'); - inp.setAttribute('aria-label', placeholderValue); + if (placeholderValue) { + inp.setAttribute('aria-label', placeholderValue); + } else if (!labelId) { + addAriaLabel(this._docRoot, this.passedElement.element.id, inp); + } return inp; }, - dropdown({ - classNames: { list, listDropdown }, - }: TemplateOptions): HTMLDivElement { + dropdown({ classNames: { list, listDropdown } }: TemplateOptions): HTMLDivElement { const div = document.createElement('div'); - div.classList.add(list, listDropdown); + addClassesToElement(div, list); + addClassesToElement(div, listDropdown); div.setAttribute('aria-expanded', 'false'); return div; }, notice( - { - allowHTML, - classNames: { item, itemChoice, noResults, noChoices }, - }: TemplateOptions, - innerText: string, - type: 'no-choices' | 'no-results' | '' = '', + { classNames: { item, itemChoice, addChoice, noResults, noChoices, notice: noticeItem } }: TemplateOptions, + innerHTML: string, + type: NoticeType = NoticeTypes.generic, ): HTMLDivElement { - const classes = [item, itemChoice]; + const notice = document.createElement('div'); + setElementHtml(notice, true, innerHTML); + + addClassesToElement(notice, item); + addClassesToElement(notice, itemChoice); + addClassesToElement(notice, noticeItem); + + // eslint-disable-next-line default-case + switch (type) { + case NoticeTypes.addChoice: + addClassesToElement(notice, addChoice); + break; + case NoticeTypes.noResults: + addClassesToElement(notice, noResults); + break; + case NoticeTypes.noChoices: + addClassesToElement(notice, noChoices); + break; + } - if (type === 'no-choices') { - classes.push(noChoices); - } else if (type === 'no-results') { - classes.push(noResults); + if (type === NoticeTypes.addChoice) { + notice.dataset.choiceSelectable = ''; + notice.dataset.choice = ''; } - return Object.assign(document.createElement('div'), { - [allowHTML ? 'innerHTML' : 'innerText']: innerText, - className: classes.join(' '), - }); + return notice; }, - option({ - label, - value, - customProperties, - active, - disabled, - }: Item): HTMLOptionElement { - const opt = new Option(label, value, false, active); - - if (customProperties) { - opt.dataset.customProperties = `${customProperties}`; - } + option(choice: ChoiceFull): HTMLOptionElement { + // HtmlOptionElement's label value does not support HTML, so the avoid double escaping unwrap the untrusted string. + const labelValue = unwrapStringForRaw(choice.label); - opt.disabled = !!disabled; + const opt = new Option(labelValue, choice.value, false, choice.selected); + assignCustomProperties(opt, choice, true); + + opt.disabled = choice.disabled; + if (choice.selected) { + opt.setAttribute('selected', ''); + } return opt; }, diff --git a/assets/extensions/choices.js/src/styles/base.scss b/assets/extensions/choices.js/src/styles/base.scss index 00c2d477..2a471618 100644 --- a/assets/extensions/choices.js/src/styles/base.scss +++ b/assets/extensions/choices.js/src/styles/base.scss @@ -144,7 +144,7 @@ label + p { a, a:visited, a:focus { - color: #00bcd4; + color: #005F75; } } diff --git a/assets/extensions/choices.js/src/styles/choices.scss b/assets/extensions/choices.js/src/styles/choices.scss index d9fc4346..9d2c62a4 100644 --- a/assets/extensions/choices.js/src/styles/choices.scss +++ b/assets/extensions/choices.js/src/styles/choices.scss @@ -16,7 +16,7 @@ $choices-bg-color-disabled: #eaeaea !default; $choices-bg-color-dropdown: #fff !default; $choices-text-color: #333 !default; $choices-keyline-color: #ddd !default; -$choices-primary-color: #00bcd4 !default; +$choices-primary-color: #005F75 !default; $choices-disabled-color: #eaeaea !default; $choices-highlight-color: $choices-primary-color !default; $choices-button-dimension: 8px !default; @@ -96,7 +96,7 @@ $choices-z-index: 1 !default; box-shadow: 0 0 0 2px $choices-highlight-color; } } - .#{$choices-selector}__item[data-value=''] .#{$choices-selector}__button { + .#{$choices-selector}__item[data-placeholder] .#{$choices-selector}__button { display: none; } @@ -115,7 +115,7 @@ $choices-z-index: 1 !default; } &.is-open::after { - border-color: transparent transparent $choices-text-color transparent; + border-color: transparent transparent $choices-text-color; margin-top: -7.5px; } @@ -250,7 +250,7 @@ $choices-z-index: 1 !default; } %choices-dropdown { - visibility: hidden; + display: none; z-index: $choices-z-index; position: absolute; width: 100%; @@ -262,10 +262,9 @@ $choices-z-index: 1 !default; border-bottom-right-radius: $choices-border-radius; overflow: hidden; word-break: break-all; - will-change: visibility; &.is-active { - visibility: visible; + display: block; } .is-open & { @@ -296,27 +295,29 @@ $choices-z-index: 1 !default; } } .#{$choices-selector}__item--selectable { - @media (min-width: 640px) { - padding-right: 100px; + &[data-select-text] { + @media (min-width: 640px) { + padding-right: 100px; - &::after { - content: attr(data-select-text); - font-size: $choices-font-size-sm; - opacity: 0; - position: absolute; - right: 10px; - top: 50%; - transform: translateY(-50%); - } + &::after { + content: attr(data-select-text); + font-size: $choices-font-size-sm; + opacity: 0; + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + } - [dir="rtl"] & { - text-align: right; - padding-left: 100px; - padding-right: 10px; + [dir="rtl"] & { + text-align: right; + padding-left: 100px; + padding-right: 10px; - &::after { - right: auto; - left: 10px; + &::after { + right: auto; + left: 10px; + } } } } diff --git a/assets/extensions/choices.js/src/tsconfig.json b/assets/extensions/choices.js/src/tsconfig.json new file mode 100644 index 00000000..fe8cd710 --- /dev/null +++ b/assets/extensions/choices.js/src/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "es6", + "lib": ["es2017", "dom"], + "target": "es5", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "strict": false, + "noImplicitAny": false, + "allowJs": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "strictNullChecks": true, + "newLine": "lf", + "declaration": false, + "declarationMap": false + }, + "include": ["."], + "exclude": ["**/node_modules", "**/public"] +} \ No newline at end of file