Remove deprecated scripts for adding head-matter to wt_config.xml, including Python and Bash implementations, to streamline configuration management.
This commit is contained in:
21
client/node_modules/@vueform/multiselect/.github/ISSUE_TEMPLATE/1_bugs.md
generated
vendored
Normal file
21
client/node_modules/@vueform/multiselect/.github/ISSUE_TEMPLATE/1_bugs.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
name: "Bug report"
|
||||
about: "If you've found a bug."
|
||||
---
|
||||
|
||||
<!--
|
||||
PLEASE READ: HELP US SO WE CAN HELP YOU, BY FILLING OUT THIS TEMPLATE
|
||||
Issues that do not include enough information might not be picked up and closed.
|
||||
-->
|
||||
|
||||
### Version
|
||||
|
||||
* Vue version: <!-- 2 or 3 -->
|
||||
|
||||
### Description
|
||||
|
||||
<!-- Describe the issue -->
|
||||
|
||||
### Demo
|
||||
|
||||
Please use our [JSFiddle template](https://jsfiddle.net/5yxpmw4v/) to reproduce the bug. Issues without working reproduction might be ignored.
|
||||
4
client/node_modules/@vueform/multiselect/.github/ISSUE_TEMPLATE/2_other.md
generated
vendored
Normal file
4
client/node_modules/@vueform/multiselect/.github/ISSUE_TEMPLATE/2_other.md
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
name: "Other"
|
||||
about: "Open an issue about anything else than a bug."
|
||||
---
|
||||
16
client/node_modules/@vueform/multiselect/.github/stale.yml
generated
vendored
Normal file
16
client/node_modules/@vueform/multiselect/.github/stale.yml
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 360
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 15
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
- upcoming
|
||||
- enhancement
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: Hi 👋 this issue has been automatically marked as `stale` 📌 because it has not had recent activity 😴. It will be closed if no further activity occurs.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: Hi again 👋 we would like to inform you that this issue has been automatically closed 🔒 because it had not recent activity during the stale period.
|
||||
571
client/node_modules/@vueform/multiselect/CHANGELOG.md
generated
vendored
Normal file
571
client/node_modules/@vueform/multiselect/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,571 @@
|
||||
## v2.6.11
|
||||
|
||||
> `2024-11-23`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Don't throw error when endpoint type `options` is undefined
|
||||
|
||||
## v2.6.10
|
||||
|
||||
> `2024-09-16`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Option should display as selected even when value is an object
|
||||
|
||||
## v2.6.9
|
||||
|
||||
> `2024-07-29`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Removed optional chaining, fixes #420
|
||||
|
||||
## v2.6.8
|
||||
|
||||
> `2024-06-14`
|
||||
|
||||
### 🎉 Feature
|
||||
- export `resolvedOptions`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Typing fixes (Thanks to @nurbek0298 🙏)
|
||||
- Always scroll to selected option on open #406
|
||||
- Use `click` instead of `mousedown` event #387
|
||||
|
||||
### 🧹 Chore
|
||||
- Performance optimization (Thanks to @negezor 🙏)
|
||||
|
||||
## v2.6.7
|
||||
|
||||
> `2024-03-20`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Clicking on scroll bar closes the dropdown fix #383
|
||||
- Types for scoped slots #391
|
||||
- Missing method types and typo fixes #376 #392
|
||||
- Don't show dropdown id when id is not defined
|
||||
- Avoid error when multiselect does not exist #394
|
||||
|
||||
## v2.6.6
|
||||
|
||||
> `2023-10-18`
|
||||
|
||||
### 🎉 Feature
|
||||
- Added `appendTo` option.
|
||||
- Added `${id}-dropdown` to dropdown DOM.
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Included `@popperjs/core` for `appendToBody` / `appendTo` position fixes.
|
||||
|
||||
## v2.6.5
|
||||
|
||||
> `2023-10-16`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Type fixes.
|
||||
|
||||
## v2.6.4
|
||||
|
||||
> `2023-10-14`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Type fixes.
|
||||
|
||||
## v2.6.3
|
||||
|
||||
> `2023-10-07`
|
||||
|
||||
### 🎉 Feature
|
||||
- Added `appendToBody` **experimental** feature for **Vue.js 3 only**. #133 #341
|
||||
- `trackBy` can now accept array. #314
|
||||
- Auto truncate long tags. Added `breakTags` prop. #346
|
||||
- Added `handleCaretClick` and `isOpen` to `caret` slot. #320
|
||||
- The externalValue (from `v-model`) is now reactive. #356
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- `limit` prop was not reactive. #342
|
||||
- Trigger `deselect` on tags backspace. #335
|
||||
- Keyboard nav on group select fix. #354
|
||||
- TypeScript fixes. Thanks @antpngl92 @Adeiko @mathildaax 🙏 #287 #282 #260 #230
|
||||
- `searchFilter` did not receive proper args. #338 #337
|
||||
- Open dropdown when it has search, it's focued and dropdown is closed. #333
|
||||
- Options are cleared before `clear` event is emitted. #332
|
||||
|
||||
## v2.6.2
|
||||
|
||||
> `2023-04-17`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Removed `sideEffects: false` from `package.json`.
|
||||
|
||||
## v2.6.1
|
||||
|
||||
> `2023-03-14`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Use `.mjs` for `import`.
|
||||
|
||||
## v2.6.0
|
||||
|
||||
> `2023-03-11`
|
||||
|
||||
### 🎉 Feature
|
||||
- All texts including, option & group labels can now be provided in multiple languages. Added `locale` and `fallbackLocale` props.
|
||||
- Added `searchFilter` prop that allow to provide a custom search algorithm #313.
|
||||
- Added `allowAbsent` option to allow adding values that are not among the options.
|
||||
- Added `closeOnDeselect` prop.
|
||||
- Deprecated `option` event, added `create` instead (`option` still works).
|
||||
- Tags that added can also be disabled, which will prevent their removal.
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Fix for new option display when using `groups`, `createOption` and `tags` #254 #291.
|
||||
- String pointer equality #316.
|
||||
- Disabled tags will not be removed on backspace #318.
|
||||
- Added `.mjs` extension build and referenced `module` to that #290 #258.
|
||||
- The `selectAll()` now does not select disabled options and does not duplicate already selected options.
|
||||
|
||||
## v2.5.8
|
||||
|
||||
> `2022-12-21`
|
||||
|
||||
### 🎉 Feature
|
||||
- Added `--ms-border-width-active` and `--ms-border-color-active` CSS vars #213.
|
||||
- Added `@max` event #269.
|
||||
- Added `clearOnBlur` option #251.
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Removed `max-height` duplicate from default theme #240.
|
||||
- Norwegian chars fix #243.
|
||||
- Trigger `@change` event on updating external value #259.
|
||||
- Docs fix for 2.7 installation instructions #294.
|
||||
- Docs fix fiddle url.
|
||||
- Tags dropdown focus fix #286 #300.
|
||||
- Stop propagation on tag remove click #295.
|
||||
|
||||
## v2.5.7
|
||||
|
||||
> `2022-11-21`
|
||||
|
||||
### 🎉 Feature
|
||||
- **BREAKING**: added a wrapper `div` and related classes inside the main container next to the dropdown container.
|
||||
- Accessibility improvements.
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Don't select new tag on IME enter #226.
|
||||
- Removed `v-html` from option & single label for XSS security #278.
|
||||
- Arrow left should not throw error when not using tags #271.
|
||||
|
||||
## v2.5.6
|
||||
|
||||
> `2022-09-28`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Async options resolve fix [#266](https://github.com/vueform/multiselect/issues/266).
|
||||
|
||||
## v2.5.5
|
||||
|
||||
> `2022-09-26`
|
||||
|
||||
### 🎉 Feature
|
||||
- Unnecessary ES6 feature removed.
|
||||
|
||||
## v2.5.4
|
||||
|
||||
> `2022-09-26`
|
||||
|
||||
### 🎉 Feature
|
||||
- A11y improvements.
|
||||
|
||||
## v2.5.3
|
||||
|
||||
> `2022-09-22`
|
||||
|
||||
### 🎉 Feature
|
||||
- A11y improvements.
|
||||
|
||||
## v2.5.2
|
||||
|
||||
> `2022-07-22`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Fix for `tailwind.css`.
|
||||
|
||||
## v2.5.1
|
||||
|
||||
> `2022-07-11`
|
||||
|
||||
### 🎉 Feature
|
||||
- Vue `2.7` compatibility.
|
||||
|
||||
## v2.5.0
|
||||
|
||||
> `2022-07-11`
|
||||
|
||||
### 🎉 Feature
|
||||
- Vue `2.7` compatibility.
|
||||
|
||||
## v2.4.2
|
||||
|
||||
> `2022-05-31`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Hotfix for ES6 [#235](https://github.com/vueform/multiselect/issues/235)
|
||||
-
|
||||
## v2.4.1
|
||||
|
||||
> `2022-05-31`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Hotfix for SSR [#235](https://github.com/vueform/multiselect/issues/235)
|
||||
|
||||
## v2.4.0
|
||||
|
||||
> `2022-05-30`
|
||||
|
||||
### 🎉 Feature
|
||||
- 🎉 Added accessibility (a11y) support [#22](https://github.com/vueform/multiselect/issues/22), [#179](https://github.com/vueform/multiselect/issues/179).
|
||||
- 🎉 Added infinite scroll [#76](https://github.com/vueform/multiselect/issues/76), [#165](https://github.com/vueform/multiselect/issues/165), [#198](https://github.com/vueform/multiselect/issues/198).
|
||||
- 🎉 Added RTL support [#206](https://github.com/vueform/multiselect/issues/206).
|
||||
- 🎉 Close on click if opened [#162](https://github.com/vueform/multiselect/issues/162).
|
||||
- Added `id` to input when searchable.
|
||||
- Re-open input on arrows & search type if closed.
|
||||
- Close dropdown instead of blur on select.
|
||||
- Added `regex` option [#138](https://github.com/vueform/multiselect/issues/138).
|
||||
- Scroll to first selected on open [#168](https://github.com/vueform/multiselect/issues/168).
|
||||
- Options are not reversed when `openPosition: true`.
|
||||
- Added `reverse` option.
|
||||
- Added `searchStart` option [#169](https://github.com/vueform/multiselect/issues/169).
|
||||
- Added `disabledProp` option [#202](https://github.com/vueform/multiselect/issues/202).
|
||||
- Added `onCreate` option [#204](https://github.com/vueform/multiselect/issues/204).
|
||||
- Added `select$` as second param to events and async options.
|
||||
- Added `isSelected` & `isPointed` to `option` slot scope [#195](https://github.com/vueform/multiselect/issues/195).
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Headless UI conflict resolved [#182](https://github.com/vueform/multiselect/issues/182).
|
||||
- Keep selected options when async [#228](https://github.com/vueform/multiselect/issues/228).
|
||||
- Show spinner even when not active [#223](https://github.com/vueform/multiselect/issues/223).
|
||||
- Allow `false` value [#222](https://github.com/vueform/multiselect/issues/222).
|
||||
- Resolve options on `minChars: 0` too [#230](https://github.com/vueform/multiselect/issues/230).
|
||||
- Added `keyup`, `keydown` events.
|
||||
- Resolved number tag creation duplicate bug.
|
||||
- Input height fix when `searchable` for FF.
|
||||
- CSS: moved max height to dropdown container from wrapper.
|
||||
- Vite & Nuxt 3 build warn fixes.).
|
||||
|
||||
## v2.3.4
|
||||
|
||||
> `2022-05-11`
|
||||
|
||||
### 🎉 Feature
|
||||
- Async options change detectiion.
|
||||
- Label prop change detection.
|
||||
- Option & label texts can contain HTML.
|
||||
|
||||
## v2.3.3
|
||||
|
||||
> `2022-02-26`
|
||||
|
||||
### 🎉 Feature
|
||||
- Added `attrs` prop.
|
||||
|
||||
## v2.3.2
|
||||
|
||||
> `2022-02-06`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Removed `@apply` from default theme.
|
||||
|
||||
## v2.3.1
|
||||
|
||||
> `2021-12-16`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Removed `exports` from `package.json` [#178](https://github.com/vueform/multiselect/issues/178).
|
||||
|
||||
## v2.3.0
|
||||
|
||||
> `2021-12-16`
|
||||
|
||||
### 🎉 Feature
|
||||
- **Deprecated:** `appendNewTag`, `createTag`, `addTagOn` props and `@tag` event.
|
||||
- Added `appendNewOption`, `createOption`, `addOptionOn` props and `@option` event [#150](https://github.com/vueform/multiselect/issues/150).
|
||||
- Added `selectAll` method [#172](https://github.com/vueform/multiselect/issues/172).
|
||||
- The `trackBy` prop now defaults to `label` [#175](https://github.com/vueform/multiselect/issues/175).
|
||||
- Replaces focus on search when an option is selected [#163](https://github.com/vueform/multiselect/issues/163).
|
||||
- Added `<span>` wrapper for single label with `singleLabelText` class key [#157](https://github.com/vueform/multiselect/issues/157).
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Don't show spinner when not active [#156](https://github.com/vueform/multiselect/issues/156).
|
||||
- Tailwind CSS 3 compatibility issue fix [#176](https://github.com/vueform/multiselect/issues/176).
|
||||
- Don't show caret when `showOptions` are disabled [#173](https://github.com/vueform/multiselect/issues/173).
|
||||
- Resolved headless UI modal click issue [#148](https://github.com/vueform/multiselect/issues/148).
|
||||
- Resolved Tailwind CSS/form ring issue [#135](https://github.com/vueform/multiselect/issues/135).
|
||||
- Made classes reactive [#126](https://github.com/vueform/multiselect/issues/126).
|
||||
- The `addTagOn` prop uses `key` instead of `keyCode` internally [#125](https://github.com/vueform/multiselect/issues/125).
|
||||
|
||||
## v2.2.1
|
||||
|
||||
> `2021-11-23`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Added missing CSS vars.
|
||||
|
||||
## v2.2.0
|
||||
|
||||
> `2021-09-09`
|
||||
|
||||
### 🎉 Feature
|
||||
- 🎉🎉 Added `groups` and related props which allow groupping options. 🎉🎉
|
||||
- Added `tailwind.scss` theme to use instead of `classes` if needed.
|
||||
- Added support for case sensitive tags when `createTag` is `true` [#119](https://github.com/vueform/multiselect/issues/119).
|
||||
- Added `inputType` prop [#108](https://github.com/vueform/multiselect/issues/116), [#116](https://github.com/vueform/multiselect/issues/116).
|
||||
- Added `@paste` event [#105](https://github.com/vueform/multiselect/issues/105).
|
||||
- Added `tab` as option for `addTagOn` [#117](https://github.com/vueform/multiselect/issues/117).
|
||||
- Updated default `max-height` for dropdown (to `15rem`).
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- When `closeOnSelect` is `true` in `searchable` `tags` and `multiple` mode the input now blurs upon selecting an option.
|
||||
- Fix for empty dropdown when async options are loading [#115](https://github.com/vueform/multiselect/issues/115).
|
||||
- Fixed dropdown auto-scrolling when using arrows.
|
||||
|
||||
## v2.1.2
|
||||
|
||||
> `2021-08-09`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Removed async/await.
|
||||
|
||||
## v2.1.1
|
||||
|
||||
> `2021-08-09`
|
||||
|
||||
### 🎉 Feature
|
||||
- Added `closeOnSelect` prop.
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Clear search on single option select [#99](https://github.com/vueform/multiselect/issues/99) and [#106](https://github.com/vueform/multiselect/issues/106).
|
||||
- No blur when tags are being removed.
|
||||
|
||||
|
||||
## v2.1.0
|
||||
|
||||
> `2021-07-26`
|
||||
|
||||
### 🎉 Feature
|
||||
- **BREAKING**: `dropdown` class now has `dropdownHidden` when it is closed instead of using `v-show` (requires using 2.1.0's `themes/default.css`)
|
||||
- **BREAKING**: removed `:maxHeight` prop. Use `var(--ms-max-height)` instead.
|
||||
- **BREAKING**: tags search layout has changed -> added a wrapper div and an extra span to calculate input width.
|
||||
- Dropddown can be closed on caret click [#88](https://github.com/vueform/multiselect/issues/88).
|
||||
- Added `:strict` prop to achieve accent-free search [#82](https://github.com/vueform/multiselect/issues/82).
|
||||
- Removed inline styles, CSP compilance [#84](https://github.com/vueform/multiselect/issues/84).
|
||||
- Background images are now customizable via `background-color` [#85](https://github.com/vueform/multiselect/issues/85).
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Free typed tags fix [#96](https://github.com/vueform/multiselect/issues/96).
|
||||
- Tabindex becomes `-1` when `:disabled`.
|
||||
|
||||
## v2.0.1
|
||||
|
||||
> `2021-06-27`
|
||||
|
||||
### 🎉 Feature
|
||||
- Classname fixes.
|
||||
- Readme update.
|
||||
|
||||
## v2.0.0
|
||||
|
||||
> `2021-06-20`
|
||||
|
||||
### 🎉 Feature
|
||||
- **BREAKING**: Completely rewritten `<template>` and `default.css`.
|
||||
- Caret is now always displayed when `caret: true` regardless if the multiselect has selected option(s).
|
||||
- Added `canDeselect` and `classes` prop.
|
||||
- Added `;` and `,` options to `addTagOn` prop.
|
||||
|
||||
## v1.5.0
|
||||
|
||||
> `2021-05-17`
|
||||
|
||||
### 🎉 Feature
|
||||
- Added native input support [#48](https://github.com/vueform/multiselect/issues/48).
|
||||
- Added `openDirection` prop [#52](https://github.com/vueform/multiselect/issues/52).
|
||||
- Added `option` as second param for `select` and `deselect` events.
|
||||
- Added `@clear` event [#68](https://github.com/vueform/multiselect/issues/68).
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Clear icon CSS fix.
|
||||
- Fixed unintendeed clear button showing up when `canDeselect` is `false` [#61](https://github.com/vueform/multiselect/issues/61).
|
||||
|
||||
## v1.4.0
|
||||
|
||||
> `2021-04-06`
|
||||
|
||||
### 🎉 Feature
|
||||
- **BREAKING**: array `options` are no longer treated as objects, but both option value and label will equal to array item value. Eg. `option: ['v1','v2']` used to be equal to `{0: 'v1', 1: 'v2'}`, now they're equal to `{v1: 'v1', v2: 'v2'}`.
|
||||
- Optimized variable names for lower package size.
|
||||
|
||||
## v1.3.7
|
||||
|
||||
> `2021-04-06`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Async options fix for [#39](https://github.com/vueform/multiselect/issues/39). Refreshing non-async options now will only be reflected after a tick.
|
||||
|
||||
### 🎉 Feature
|
||||
- Added caret, remove and spinner slots.
|
||||
|
||||
## v1.3.6
|
||||
|
||||
> `2021-03-30`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Remove extra space when creating a tag with space ([#46](https://github.com/vueform/multiselect/issues/46)).
|
||||
- Fixed issues around refreshing async options ([#45](https://github.com/vueform/multiselect/issues/45)).
|
||||
- Android keyboard fix ([#49](https://github.com/vueform/multiselect/issues/49) & [#50](https://github.com/vueform/multiselect/issues/50)).
|
||||
|
||||
### 🎉 Feature
|
||||
- Added installation guide for Nuxt.js.
|
||||
|
||||
## v1.3.5
|
||||
|
||||
> `2021-03-20`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Fix for unintended side effect on space when using single mode ([#42](https://github.com/vueform/multiselect/issues/42)).
|
||||
|
||||
## v1.3.4
|
||||
|
||||
> `2021-03-13`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Recursion error when accessing `value` inside computed `options` ([#39](https://github.com/vueform/multiselect/issues/39)).
|
||||
- Set initial value when options are loaded later ([#40](https://github.com/vueform/multiselect/issues/40)).
|
||||
|
||||
## v1.3.3
|
||||
|
||||
> `2021-03-12`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Selected items' label update when options label change ([#39](https://github.com/vueform/multiselect/issues/39)).
|
||||
- Horizontal scroll fix ([#31](https://github.com/vueform/multiselect/issues/31)).
|
||||
|
||||
### 🎉 Feature
|
||||
- Added `addTagOn` that can enable `enter` and/or `space` key to create a tag.
|
||||
- Added `required` prop that renders a HTML5 required attribute on a fake input next to multiselect.
|
||||
- Added `showOptions` prop that hide options list if somebody wants to have only a free-type tag list.
|
||||
|
||||
## v1.3.2
|
||||
|
||||
> `2021-02-05`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Tags slots scope updated with `handleTagRemove` instead of `remove`.
|
||||
|
||||
## v1.3.1
|
||||
|
||||
> `2021-02-05`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Readme API fix.
|
||||
|
||||
## v1.3.0
|
||||
|
||||
> `2021-02-05`
|
||||
|
||||
### 🎉 Feature
|
||||
- Added Typescript definitions based on [#20](https://github.com/vueform/multiselect/pull/20).
|
||||
- Added Clear button for `multiple` and `tags` mode.
|
||||
- Added `placeholder` slot.
|
||||
- Added proper `open` and `close` methods.
|
||||
- Hide options when resolving with `clearOnSearch` `true`.
|
||||
- Added `refreshOptions` method to refresh async options.
|
||||
- Added API docs.
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Added fix for #26. The value now can be set the same time that `options` change.
|
||||
- Added fix for #28. Right mouse click no longer removes tag.
|
||||
- Added fix for #29. Focus is no longer trapped to option list when using search.
|
||||
|
||||
## v1.2.5
|
||||
|
||||
> `2021-01-17`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Close open dropdown on input click
|
||||
- Select first option after async search fix #18
|
||||
- Update options when `:options` property changes #16 #17
|
||||
|
||||
## v1.2.4
|
||||
|
||||
> `2021-01-12`
|
||||
|
||||
### 🎉 Feature
|
||||
- Added `:max` property
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Backspace issue fix #9
|
||||
- Custom label issue fix #13
|
||||
|
||||
## v1.2.3
|
||||
|
||||
> `2020-12-29`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- `v-model` deep sync
|
||||
|
||||
## v1.2.2
|
||||
|
||||
> `2020-12-28`
|
||||
|
||||
### 🎉 Feature
|
||||
- Added `canDeselect` option
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Set internalValue on init when using async options with `:object` `true` and `resolveOnLoad` `false`
|
||||
|
||||
## v1.2.1
|
||||
|
||||
> `2020-12-23`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- Changes in `v-model` will sync with multiselect value
|
||||
|
||||
## v1.2.0
|
||||
|
||||
> `2020-12-23`
|
||||
|
||||
### 🎉 Feature
|
||||
- Options now can be disabled using an array of objects as options, with `disabled` property being set to `true`
|
||||
- The `value` property of an object option now can be customized with `:valueProp`
|
||||
|
||||
## v1.1.3
|
||||
|
||||
> `2020-12-19`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- **Breaking**: Renamed slots to lowercase instead of camel case because of [DOM issue](https://github.com/vuejs/vue/issues/9449#issuecomment-461170017)
|
||||
|
||||
### 🎉 Feature
|
||||
- Added `change` event
|
||||
- **Breaking**: renamed `hideSelectedTag` to `hideSelected`
|
||||
|
||||
## v1.1.2
|
||||
|
||||
> `2020-12-19`
|
||||
|
||||
### 🎉 Feature
|
||||
- Async/await eliminated from code thus reducing bundle size without runtimeRegenerator
|
||||
- UMD bundle replaced with global
|
||||
|
||||
## v1.1.1
|
||||
|
||||
> `2020-12-19`
|
||||
|
||||
### 🐞 Bug Fixes
|
||||
- RuntimeRegenerator added to esm builds
|
||||
|
||||
## v1.1.0
|
||||
|
||||
> `2020-12-18`
|
||||
|
||||
### 🎉 Feature
|
||||
- Options now can be defined as a sync or async function. This opens up the capabilities to load options from remote data source and/or to implement autocomplete behaviour.
|
||||
21
client/node_modules/@vueform/multiselect/LICENSE.md
generated
vendored
Normal file
21
client/node_modules/@vueform/multiselect/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2020-2021 Adam Berecz <adam@vueform.com>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
1165
client/node_modules/@vueform/multiselect/README.md
generated
vendored
Normal file
1165
client/node_modules/@vueform/multiselect/README.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
client/node_modules/@vueform/multiselect/dist/multiselect.global.js
generated
vendored
Normal file
1
client/node_modules/@vueform/multiselect/dist/multiselect.global.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4794
client/node_modules/@vueform/multiselect/dist/multiselect.js
generated
vendored
Normal file
4794
client/node_modules/@vueform/multiselect/dist/multiselect.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
client/node_modules/@vueform/multiselect/dist/multiselect.min.js
generated
vendored
Normal file
1
client/node_modules/@vueform/multiselect/dist/multiselect.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4794
client/node_modules/@vueform/multiselect/dist/multiselect.mjs
generated
vendored
Normal file
4794
client/node_modules/@vueform/multiselect/dist/multiselect.mjs
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
client/node_modules/@vueform/multiselect/dist/multiselect.vue2.global.js
generated
vendored
Normal file
1
client/node_modules/@vueform/multiselect/dist/multiselect.vue2.global.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
5169
client/node_modules/@vueform/multiselect/dist/multiselect.vue2.js
generated
vendored
Normal file
5169
client/node_modules/@vueform/multiselect/dist/multiselect.vue2.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
client/node_modules/@vueform/multiselect/dist/multiselect.vue2.min.js
generated
vendored
Normal file
1
client/node_modules/@vueform/multiselect/dist/multiselect.vue2.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
92
client/node_modules/@vueform/multiselect/package.json
generated
vendored
Normal file
92
client/node_modules/@vueform/multiselect/package.json
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"name": "@vueform/multiselect",
|
||||
"version": "2.6.11",
|
||||
"private": false,
|
||||
"description": "Vue 3 multiselect component with single select, multiselect and tagging options.",
|
||||
"license": "MIT",
|
||||
"author": "Adam Berecz <adam@vueform.com>",
|
||||
"main": "./dist/multiselect.js",
|
||||
"types": "./src/index.d.ts",
|
||||
"module": "./dist/multiselect.mjs",
|
||||
"unpkg": "./dist/multiselect.global.js",
|
||||
"jsdelivr": "./dist/multiselect.global.js",
|
||||
"style": "./themes/default.css",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.d.ts",
|
||||
"node": {
|
||||
"import": {
|
||||
"production": "./dist/multiselect.mjs",
|
||||
"development": "./dist/multiselect.mjs",
|
||||
"default": "./dist/multiselect.mjs"
|
||||
},
|
||||
"require": {
|
||||
"production": "./dist/multiselect.js",
|
||||
"development": "./dist/multiselect.js",
|
||||
"default": "./dist/multiselect.js"
|
||||
}
|
||||
},
|
||||
"import": "./dist/multiselect.mjs",
|
||||
"require": "./dist/multiselect.js"
|
||||
},
|
||||
"./src/*": "./src/*",
|
||||
"./dist/*": "./dist/*",
|
||||
"./themes/*": "./themes/*",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vueform/multiselect.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/vueform/multiselect/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build:vue2; npm run build:vue3; npm run build:themes",
|
||||
"build:vue2": "rollup --config build/vue2.rollup.config.js",
|
||||
"build:vue3": "rollup --config build/vue3.rollup.config.js",
|
||||
"build:themes": "rollup --config build/themes.rollup.config.js",
|
||||
"test": "jest --config=jest/jest.config.vue3.js; jest --config=jest/jest.config.vue2.js;",
|
||||
"test:vue2": "jest --verbose --config=jest/jest.config.vue2.js",
|
||||
"test:vue3": "jest --verbose --config=jest/jest.config.vue3.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.10",
|
||||
"@babel/plugin-transform-modules-umd": "^7.12.1",
|
||||
"@babel/preset-env": "^7.12.10",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@rollup/plugin-alias": "^3.1.1",
|
||||
"@rollup/plugin-babel": "^5.2.2",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@testing-library/jest-dom": "^5.11.5",
|
||||
"@vue/compiler-sfc": "^3.0.4",
|
||||
"autoprefixer": "^10.3.1",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
"babel-jest": "^27.3.1",
|
||||
"babel-plugin-rename-umd-globals": "^1.0.0",
|
||||
"flush-promises": "^1.0.2",
|
||||
"fraction.js": "^4.1.1",
|
||||
"jest": "^27.3.1",
|
||||
"jest-environment-jsdom-sixteen": "^1.0.3",
|
||||
"node-sass": "^7.0.0",
|
||||
"postcss": "^8.4.31",
|
||||
"rollup": "^2.34.2",
|
||||
"rollup-plugin-postcss": "^4.0.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"typescript": "^4.1.2",
|
||||
"vue-next": "npm:vue@^3.2.20",
|
||||
"vue-next-jest": "npm:@vue/vue3-jest@^27.0.0-alpha.1",
|
||||
"vue-next-rollup-plugin-vue": "npm:rollup-plugin-vue@^6.0.0",
|
||||
"vue-next-test-utils": "npm:@vue/test-utils@2.0.0-rc.16",
|
||||
"vue-prev": "npm:vue@^2.7.8",
|
||||
"vue-prev-jest": "npm:@vue/vue2-jest@^27.0.0-alpha.2",
|
||||
"vue-prev-rollup-plugin-vue": "npm:rollup-plugin-vue@^5.1.9",
|
||||
"vue-prev-test-utils": "npm:@vue/test-utils@1.2.2",
|
||||
"vue-template-compiler": "^2.7.8"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead"
|
||||
]
|
||||
}
|
||||
1
client/node_modules/@vueform/multiselect/postcss.config.js
generated
vendored
Normal file
1
client/node_modules/@vueform/multiselect/postcss.config.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = {}
|
||||
297
client/node_modules/@vueform/multiselect/src/Multiselect.d.ts
generated
vendored
Normal file
297
client/node_modules/@vueform/multiselect/src/Multiselect.d.ts
generated
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
import { VNode, defineComponent } from 'vue';
|
||||
|
||||
interface ClassList {
|
||||
assist: string;
|
||||
caret: Array<string>;
|
||||
clear: string;
|
||||
clearIcon: string;
|
||||
container: Array<string>;
|
||||
dropdown: Array<string>;
|
||||
fakeInput: string;
|
||||
group: string;
|
||||
groupLabel: (g: any) => any;
|
||||
groupOptions: string;
|
||||
inifinite: string;
|
||||
inifiniteSpinner: string;
|
||||
multipleLabel: string;
|
||||
noOptions: string;
|
||||
noResults: string;
|
||||
option: (o:any, g:any) => any;
|
||||
options: Array<string>;
|
||||
placeholder: string;
|
||||
search: string;
|
||||
singleLabel: string;
|
||||
singleLabelText: string;
|
||||
spacer: string;
|
||||
spinner: string;
|
||||
tag: Array<string>
|
||||
tagDisabled: string;
|
||||
tagRemove: string;
|
||||
tagRemoveIcon: string;
|
||||
tags: string;
|
||||
tagsSearch: string;
|
||||
tagsSearchCopy: string;
|
||||
tagsSearchWrapper: string;
|
||||
wrapper: string;
|
||||
}
|
||||
|
||||
interface MultiselectProps {
|
||||
modelValue?: any;
|
||||
value?: any;
|
||||
mode?: 'single' | 'multiple' | 'tags';
|
||||
options?: any[] | object | Function;
|
||||
searchable?: boolean;
|
||||
valueProp?: string;
|
||||
trackBy?: string | string[];
|
||||
label?: string;
|
||||
placeholder?: string | null;
|
||||
multipleLabel?: any; // Function
|
||||
disabled?: boolean;
|
||||
max?: number;
|
||||
limit?: number;
|
||||
loading?: boolean;
|
||||
id?: string;
|
||||
caret?: boolean;
|
||||
maxHeight?: string | number;
|
||||
noOptionsText?: string | object;
|
||||
noResultsText?: string | object;
|
||||
canDeselect?: boolean;
|
||||
canClear?: boolean;
|
||||
clearOnSearch?: boolean;
|
||||
clearOnSelect?: boolean;
|
||||
delay?: number;
|
||||
filterResults?: boolean;
|
||||
minChars?: number;
|
||||
resolveOnLoad?: boolean;
|
||||
appendNewTag?: boolean;
|
||||
appendNewOption?: boolean;
|
||||
createTag?: boolean;
|
||||
createOption?: boolean;
|
||||
addTagOn?: string[];
|
||||
addOptionOn?: string[];
|
||||
hideSelected?: boolean;
|
||||
showOptions?: boolean;
|
||||
object?: boolean;
|
||||
required?: boolean;
|
||||
openDirection?: 'top' | 'bottom';
|
||||
nativeSupport?: boolean;
|
||||
classes?: object;
|
||||
strict?: boolean;
|
||||
closeOnSelect?: boolean;
|
||||
closeOnDeselect?: boolean;
|
||||
autocomplete?: string;
|
||||
groups?: boolean;
|
||||
groupLabel?: string;
|
||||
groupOptions?: string;
|
||||
groupHideEmpty?: boolean;
|
||||
groupSelect?: boolean;
|
||||
inputType?: string;
|
||||
attrs?: object;
|
||||
onCreate?: Function;
|
||||
searchStart?: boolean;
|
||||
reverse?: boolean;
|
||||
regex?: string | object;
|
||||
rtl?: boolean;
|
||||
infinite?: boolean;
|
||||
aria?: object;
|
||||
clearOnBlur?: boolean;
|
||||
locale?: string;
|
||||
fallbackLocale?: string;
|
||||
searchFilter?: Function;
|
||||
allowAbsent?: boolean;
|
||||
appendToBody?: boolean;
|
||||
closeOnScroll?: boolean;
|
||||
breakTags?: boolean;
|
||||
appendTo?: string;
|
||||
}
|
||||
|
||||
declare class Multiselect implements ReturnType<typeof defineComponent> {
|
||||
modelValue: MultiselectProps['modelValue'];
|
||||
value: MultiselectProps['value'];
|
||||
mode: MultiselectProps['mode'];
|
||||
options: MultiselectProps['options'];
|
||||
searchable: MultiselectProps['searchable'];
|
||||
valueProp: MultiselectProps['valueProp'];
|
||||
trackBy: MultiselectProps['trackBy'];
|
||||
label: MultiselectProps['label'];
|
||||
placeholder: MultiselectProps['placeholder'];
|
||||
multipleLabel: MultiselectProps['multipleLabel'];
|
||||
disabled: MultiselectProps['disabled'];
|
||||
max: MultiselectProps['max'];
|
||||
limit: MultiselectProps['limit'];
|
||||
loading: MultiselectProps['loading'];
|
||||
id: MultiselectProps['id'];
|
||||
caret: MultiselectProps['caret'];
|
||||
maxHeight: MultiselectProps['maxHeight'];
|
||||
noOptionsText: MultiselectProps['noOptionsText'];
|
||||
noResultsText: MultiselectProps['noResultsText'];
|
||||
canDeselect: MultiselectProps['canDeselect'];
|
||||
canClear: MultiselectProps['canClear'];
|
||||
clearOnSearch: MultiselectProps['clearOnSearch'];
|
||||
clearOnSelect: MultiselectProps['clearOnSelect'];
|
||||
delay: MultiselectProps['delay'];
|
||||
filterResults: MultiselectProps['filterResults'];
|
||||
minChars: MultiselectProps['minChars'];
|
||||
resolveOnLoad: MultiselectProps['resolveOnLoad'];
|
||||
appendNewTag: MultiselectProps['appendNewTag'];
|
||||
appendNewOption: MultiselectProps['appendNewOption'];
|
||||
createTag: MultiselectProps['createTag'];
|
||||
createOption: MultiselectProps['createOption'];
|
||||
addTagOn: MultiselectProps['addTagOn'];
|
||||
addOptionOn: MultiselectProps['addOptionOn'];
|
||||
hideSelected: MultiselectProps['hideSelected'];
|
||||
showOptions: MultiselectProps['showOptions'];
|
||||
object: MultiselectProps['object'];
|
||||
required: MultiselectProps['required'];
|
||||
openDirection: MultiselectProps['openDirection'];
|
||||
nativeSupport: MultiselectProps['nativeSupport'];
|
||||
classes: MultiselectProps['classes'];
|
||||
strict: MultiselectProps['strict'];
|
||||
closeOnSelect: MultiselectProps['closeOnSelect'];
|
||||
closeOnDeselect: MultiselectProps['closeOnDeselect'];
|
||||
autocomplete: MultiselectProps['autocomplete'];
|
||||
groups: MultiselectProps['groups'];
|
||||
groupLabel: MultiselectProps['groupLabel'];
|
||||
groupOptions: MultiselectProps['groupOptions'];
|
||||
groupHideEmpty: MultiselectProps['groupHideEmpty'];
|
||||
groupSelect: MultiselectProps['groupSelect'];
|
||||
inputType: MultiselectProps['inputType'];
|
||||
attrs: MultiselectProps['attrs'];
|
||||
onCreate: MultiselectProps['onCreate'];
|
||||
searchStart: MultiselectProps['searchStart'];
|
||||
reverse: MultiselectProps['reverse'];
|
||||
regex: MultiselectProps['regex'];
|
||||
rtl: MultiselectProps['rtl'];
|
||||
infinite: MultiselectProps['infinite'];
|
||||
aria: MultiselectProps['aria'];
|
||||
clearOnBlur: MultiselectProps['clearOnBlur'];
|
||||
locale: MultiselectProps['locale'];
|
||||
fallbackLocale: MultiselectProps['fallbackLocale'];
|
||||
searchFilter: MultiselectProps['searchFilter'];
|
||||
allowAbsent: MultiselectProps['allowAbsent'];
|
||||
appendToBody: MultiselectProps['appendToBody'];
|
||||
closeOnScroll: MultiselectProps['closeOnScroll'];
|
||||
breakTags: MultiselectProps['breakTags'];
|
||||
appendTo: MultiselectProps['appendTo'];
|
||||
|
||||
$props: MultiselectProps;
|
||||
|
||||
$emit(eventName: 'change', value: any, instance: this): this | void;
|
||||
$emit(eventName: 'select', value: any, option: any, instance:this): this | void;
|
||||
$emit(eventName: 'deselect', value: any, option: any, instance:this): this | void;
|
||||
$emit(eventName: 'search-change', query: string, instance: this): this | void;
|
||||
$emit(eventName: 'tag', option: any, instance: this): this | void;
|
||||
$emit(eventName: 'option', option: any, instance: this): this | void;
|
||||
$emit(eventName: 'create', option: any, instance: this): this | void;
|
||||
$emit(eventName: 'paste', e: Event, instance: this): this | void;
|
||||
$emit(eventName: 'keydown', e: Event, instance: this): this | void;
|
||||
$emit(eventName: 'keyup', e: Event, instance: this): this | void;
|
||||
$emit(eventName: 'open', instance: this): this | void;
|
||||
$emit(eventName: 'close', instance: this): this | void;
|
||||
$emit(eventName: 'clear', instance: this): this | void;
|
||||
$emit(eventName: 'max', instance: this): this | void;
|
||||
|
||||
$slots: {
|
||||
placeholder: VNode[];
|
||||
afterlist: (props: { options: any[] }) => VNode[];
|
||||
beforelist: (props: { options: any[] }) => VNode[];
|
||||
multiplelabel: (props: { values: any[] | object }) => VNode[];
|
||||
singlelabel: (props: { value: any }) => VNode[];
|
||||
option: (props: { option: any, isSelected: (option: any) => boolean, isPointed: (option: any) => boolean, search: null | string }) => VNode[];
|
||||
grouplabel: (props: { group: any, isSelected: (option: any) => boolean, isPointed: (option: any) => boolean }) => VNode[];
|
||||
tag: (props: { option: any, handleTagRemove: (option: any, e: Event) => void, disabled: boolean, }) => VNode[];
|
||||
infinite: VNode[];
|
||||
nooptions: VNode[];
|
||||
noresults: VNode[];
|
||||
caret: (props: { handleCaretClick: () => void, isOpen: boolean, }) => VNode[];
|
||||
clear: (props: { clear: () => void }) => VNode[];
|
||||
spinner: VNode[];
|
||||
};
|
||||
|
||||
activate: (shouldOpen?: boolean) => void;
|
||||
ariaActiveDescendant: string | undefined;
|
||||
ariaAssist: string;
|
||||
ariaControls: string;
|
||||
ariaGroupId: (option : any) => string;
|
||||
ariaGroupLabel: (label: any) => string;
|
||||
ariaLabel: string;
|
||||
ariaMultiselectable: boolean;
|
||||
ariaOptionId: (option: any) => string;
|
||||
ariaOptionLabel: (label: any) => string;
|
||||
ariaPlaceholder: any;
|
||||
ariaTagLabel: (label: any) => string;
|
||||
arias: object;
|
||||
backwardPointer: any;
|
||||
blur: () => void;
|
||||
busy: boolean;
|
||||
canPointGroups: boolean;
|
||||
classList: ClassList;
|
||||
clear: () => void;
|
||||
clearPointer: () => void;
|
||||
clearSearch: () => void;
|
||||
close: () => void;
|
||||
deactivate: () => void;
|
||||
deselect: (option: any) => void;
|
||||
disabledProp?: string;
|
||||
extendedGroups: Array<any>
|
||||
extendedOptions: Array<any>
|
||||
externalValue: any;
|
||||
filteredGroups: Array<any>
|
||||
filteredOptions: any;
|
||||
focus: () => void;
|
||||
forwardPointer: () => void;
|
||||
getOption: (val: any) => any
|
||||
handleCaretClick: () => void;
|
||||
handleFocusIn: (e: any) => void;
|
||||
handleFocusOut: () => void;
|
||||
handleGroupClick: (group: any) => void;
|
||||
handleKeydown: (e: Event) => void;
|
||||
handleKeypress: (e: Event) => void;
|
||||
handleKeyup: (e: Event) => void;
|
||||
handleMousedown: (e: Event) => void;
|
||||
handleOptionClic: (option: any) => void;
|
||||
handlePaste: (e: Event) => void;
|
||||
handleSearchInput: (e: Event) => void;
|
||||
handleTagRemove: (option: any, e: Event) => void;
|
||||
hasMore: boolean;
|
||||
hasSelected: boolean;
|
||||
infiniteLoader: any;
|
||||
input: HTMLInputElement;
|
||||
internalValue: any;
|
||||
isActive: boolean;
|
||||
isDisabled: boolean;
|
||||
isMax: () => boolean;
|
||||
isOpen: boolean;
|
||||
isPointed: (option: any) => boolean | undefined;
|
||||
isSelected: (option: any) => boolean;
|
||||
localize: (target: any) => any;
|
||||
mouseClicked: boolean;
|
||||
multipleLabelText: string;
|
||||
multiselect: any;
|
||||
offset: number;
|
||||
open: () => void;
|
||||
plainValue: any;
|
||||
pointer: any;
|
||||
placement: string;
|
||||
popper: object;
|
||||
preparePointer: () => void;
|
||||
refreshLabels: () => void;
|
||||
refreshOptions: (callback: any) => void;
|
||||
remove: (option: any) => void;
|
||||
resolveOptions: (callback: any) => void;
|
||||
resolving: boolean;
|
||||
search: any;
|
||||
select: (option: any) => void;
|
||||
selectAll: () => void;
|
||||
selectPointer: () => void;
|
||||
setPointer: (option: any) => void;
|
||||
setPointerFirst: () => void;
|
||||
showDropdown: boolean;
|
||||
tabindex: number;
|
||||
tags: any;
|
||||
textValue: any;
|
||||
update: (val: any, triggerInput?: boolean) => void;
|
||||
updatePopper: () => void;
|
||||
}
|
||||
|
||||
export default Multiselect;
|
||||
691
client/node_modules/@vueform/multiselect/src/Multiselect.vue
generated
vendored
Normal file
691
client/node_modules/@vueform/multiselect/src/Multiselect.vue
generated
vendored
Normal file
@@ -0,0 +1,691 @@
|
||||
<template>
|
||||
<div
|
||||
ref="multiselect"
|
||||
:class="classList.container"
|
||||
:id="searchable ? undefined : id"
|
||||
:dir="rtl ? 'rtl' : undefined"
|
||||
@focusin="handleFocusIn"
|
||||
@focusout="handleFocusOut"
|
||||
@keyup="handleKeyup"
|
||||
@keydown="handleKeydown"
|
||||
>
|
||||
<div
|
||||
:class="classList.wrapper"
|
||||
@mousedown="handleMousedown"
|
||||
ref="wrapper"
|
||||
|
||||
:tabindex="tabindex"
|
||||
:aria-controls="!searchable ? ariaControls : undefined"
|
||||
:aria-placeholder="!searchable ? ariaPlaceholder : undefined"
|
||||
:aria-expanded="!searchable ? isOpen : undefined"
|
||||
:aria-activedescendant="!searchable ? ariaActiveDescendant : undefined"
|
||||
:aria-multiselectable="!searchable ? ariaMultiselectable : undefined"
|
||||
:role="!searchable ? 'combobox' : undefined"
|
||||
v-bind="!searchable ? arias : {}"
|
||||
>
|
||||
<!-- Search -->
|
||||
<template v-if="mode !== 'tags' && searchable && !disabled">
|
||||
<input
|
||||
:type="inputType"
|
||||
:modelValue="search"
|
||||
:value="search"
|
||||
:class="classList.search"
|
||||
:autocomplete="autocomplete"
|
||||
:id="searchable ? id : undefined"
|
||||
@input="handleSearchInput"
|
||||
@keypress="handleKeypress"
|
||||
@paste.stop="handlePaste"
|
||||
ref="input"
|
||||
|
||||
:aria-controls="ariaControls"
|
||||
:aria-placeholder="ariaPlaceholder"
|
||||
:aria-expanded="isOpen"
|
||||
:aria-activedescendant="ariaActiveDescendant"
|
||||
:aria-multiselectable="ariaMultiselectable"
|
||||
role="combobox"
|
||||
|
||||
v-bind="{
|
||||
...attrs,
|
||||
...arias,
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- Tags (with search) -->
|
||||
<template v-if="mode == 'tags'">
|
||||
<div :class="classList.tags" data-tags>
|
||||
<slot
|
||||
v-for="(option, i, key) in iv"
|
||||
name="tag"
|
||||
:option="option"
|
||||
:handleTagRemove="handleTagRemove"
|
||||
:disabled="disabled"
|
||||
>
|
||||
<span
|
||||
:class="[
|
||||
classList.tag,
|
||||
option.disabled ? classList.tagDisabled : null,
|
||||
]"
|
||||
tabindex="-1"
|
||||
@keyup.enter="handleTagRemove(option, $event)"
|
||||
:key="key"
|
||||
|
||||
:aria-label="ariaTagLabel(localize(option[label]))"
|
||||
>
|
||||
<span :class="classList.tagWrapper">{{ localize(option[label]) }}</span>
|
||||
<span
|
||||
v-if="!disabled && !option.disabled"
|
||||
:class="classList.tagRemove"
|
||||
@click.stop="handleTagRemove(option, $event)"
|
||||
>
|
||||
<span :class="classList.tagRemoveIcon"></span>
|
||||
</span>
|
||||
</span>
|
||||
</slot>
|
||||
|
||||
<div :class="classList.tagsSearchWrapper" ref="tags">
|
||||
<!-- Used for measuring search width -->
|
||||
<span :class="classList.tagsSearchCopy">{{ search }}</span>
|
||||
|
||||
<!-- Actual search input -->
|
||||
<input
|
||||
v-if="searchable && !disabled"
|
||||
:type="inputType"
|
||||
:modelValue="search"
|
||||
:value="search"
|
||||
:class="classList.tagsSearch"
|
||||
:id="searchable ? id : undefined"
|
||||
:autocomplete="autocomplete"
|
||||
@input="handleSearchInput"
|
||||
@keypress="handleKeypress"
|
||||
@paste.stop="handlePaste"
|
||||
ref="input"
|
||||
|
||||
:aria-controls="ariaControls"
|
||||
:aria-placeholder="ariaPlaceholder"
|
||||
:aria-expanded="isOpen"
|
||||
:aria-activedescendant="ariaActiveDescendant"
|
||||
:aria-multiselectable="ariaMultiselectable"
|
||||
role="combobox"
|
||||
|
||||
v-bind="{
|
||||
...attrs,
|
||||
...arias,
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Single label -->
|
||||
<template v-if="mode == 'single' && hasSelected && !search && iv">
|
||||
<slot name="singlelabel" :value="iv">
|
||||
<div :class="classList.singleLabel">
|
||||
<span :class="classList.singleLabelText">{{ localize(iv[label]) }}</span>
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<!-- Multiple label -->
|
||||
<template v-if="mode == 'multiple' && hasSelected && !search">
|
||||
<slot name="multiplelabel" :values="iv">
|
||||
<div :class="classList.multipleLabel" v-html="multipleLabelText"></div>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<!-- Placeholder -->
|
||||
<template v-if="placeholder && !hasSelected && !search">
|
||||
<slot name="placeholder">
|
||||
<div :class="classList.placeholder" aria-hidden="true">
|
||||
{{ placeholder }}
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<!-- Spinner -->
|
||||
<slot v-if="loading || resolving" name="spinner">
|
||||
<span :class="classList.spinner" aria-hidden="true"></span>
|
||||
</slot>
|
||||
|
||||
<!-- Clear -->
|
||||
<slot v-if="hasSelected && !disabled && canClear && !busy" name="clear" :clear="clear">
|
||||
<span
|
||||
aria-hidden="true"
|
||||
tabindex="0"
|
||||
role="button"
|
||||
data-clear
|
||||
aria-roledescription="❎"
|
||||
:class="classList.clear"
|
||||
@click="clear"
|
||||
@keyup.enter="clear"
|
||||
><span :class="classList.clearIcon"></span></span>
|
||||
</slot>
|
||||
|
||||
<!-- Caret -->
|
||||
<slot v-if="caret && showOptions" name="caret" :handle-caret-click="handleCaretClick" :is-open="isOpen">
|
||||
<span :class="classList.caret" @click="handleCaretClick" aria-hidden="true"></span>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<!-- Options -->
|
||||
<Teleport :to="appendTo || 'body'" :disabled="!appendToBody && !appendTo">
|
||||
<div
|
||||
:id="id ? `${id}-dropdown` : undefined"
|
||||
:class="classList.dropdown"
|
||||
tabindex="-1"
|
||||
ref="dropdown"
|
||||
@focusin="handleFocusIn"
|
||||
@focusout="handleFocusOut"
|
||||
>
|
||||
<slot name="beforelist" :options="fo"></slot>
|
||||
|
||||
<ul :class="classList.options" :id="ariaControls" role="listbox">
|
||||
<template v-if="groups">
|
||||
<li
|
||||
v-for="(group, i, key) in fg"
|
||||
:class="classList.group"
|
||||
:key="key"
|
||||
|
||||
:id="ariaGroupId(group)"
|
||||
:aria-label="ariaGroupLabel(localize(group[groupLabel]))"
|
||||
:aria-selected="isSelected(group)"
|
||||
role="option"
|
||||
>
|
||||
<div
|
||||
v-if="!group.__CREATE__"
|
||||
:class="classList.groupLabel(group)"
|
||||
:data-pointed="isPointed(group)"
|
||||
@mouseenter="setPointer(group, i)"
|
||||
@click="handleGroupClick(group)"
|
||||
>
|
||||
<slot name="grouplabel" :group="group" :is-selected="isSelected" :is-pointed="isPointed">
|
||||
<span v-html="localize(group[groupLabel])"></span>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<ul
|
||||
:class="classList.groupOptions"
|
||||
|
||||
:aria-label="ariaGroupLabel(localize(group[groupLabel]))"
|
||||
role="group"
|
||||
>
|
||||
<li
|
||||
v-for="(option, i, key) in group.__VISIBLE__"
|
||||
:class="classList.option(option, group)"
|
||||
:data-pointed="isPointed(option)"
|
||||
:data-selected="isSelected(option) || undefined"
|
||||
:key="key"
|
||||
@mouseenter="setPointer(option)"
|
||||
@click="handleOptionClick(option)"
|
||||
|
||||
:id="ariaOptionId(option)"
|
||||
:aria-selected="isSelected(option)"
|
||||
:aria-label="ariaOptionLabel(localize(option[label]))"
|
||||
role="option"
|
||||
>
|
||||
<slot name="option" :option="option" :is-selected="isSelected" :is-pointed="isPointed" :search="search">
|
||||
<span>{{ localize(option[label]) }}</span>
|
||||
</slot>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</template>
|
||||
<template v-else>
|
||||
<li
|
||||
v-for="(option, i, key) in fo"
|
||||
:class="classList.option(option)"
|
||||
:data-pointed="isPointed(option)"
|
||||
:data-selected="isSelected(option) || undefined"
|
||||
:key="key"
|
||||
@mouseenter="setPointer(option)"
|
||||
@click="handleOptionClick(option)"
|
||||
|
||||
:id="ariaOptionId(option)"
|
||||
:aria-selected="isSelected(option)"
|
||||
:aria-label="ariaOptionLabel(localize(option[label]))"
|
||||
role="option"
|
||||
>
|
||||
<slot name="option" :option="option" :isSelected="isSelected" :is-pointed="isPointed" :search="search">
|
||||
<span>{{ localize(option[label]) }}</span>
|
||||
</slot>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
|
||||
<slot v-if="noOptions" name="nooptions">
|
||||
<div :class="classList.noOptions" v-html="localize(noOptionsText)"></div>
|
||||
</slot>
|
||||
|
||||
<slot v-if="noResults" name="noresults">
|
||||
<div :class="classList.noResults" v-html="localize(noResultsText)"></div>
|
||||
</slot>
|
||||
|
||||
<div v-if="infinite && hasMore" :class="classList.inifinite" ref="infiniteLoader">
|
||||
<slot name="infinite">
|
||||
<span :class="classList.inifiniteSpinner"></span>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<slot name="afterlist" :options="fo"></slot>
|
||||
</div>
|
||||
</Teleport>
|
||||
|
||||
<!-- Hacky input element to show HTML5 required warning -->
|
||||
<input v-if="required" :class="classList.fakeInput" tabindex="-1" :value="textValue" required/>
|
||||
|
||||
<!-- Native input support -->
|
||||
<template v-if="nativeSupport">
|
||||
<input v-if="mode == 'single'" type="hidden" :name="name" :value="plainValue !== undefined ? plainValue : ''" />
|
||||
<template v-else>
|
||||
<input v-for="(v, i) in plainValue" type="hidden" :name="`${name}[]`" :value="v" :key="i" />
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- Screen reader assistive text -->
|
||||
<div v-if="searchable && hasSelected" :class="classList.assist" :id="ariaAssist" aria-hidden="true">
|
||||
{{ ariaLabel }}
|
||||
</div>
|
||||
|
||||
<!-- Create height for empty input -->
|
||||
<div :class="classList.spacer"></div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* istanbul ignore file */
|
||||
|
||||
import useData from './composables/useData'
|
||||
import useValue from './composables/useValue'
|
||||
import useSearch from './composables/useSearch'
|
||||
import usePointer from './composables/usePointer'
|
||||
import useOptions from './composables/useOptions'
|
||||
import usePointerAction from './composables/usePointerAction'
|
||||
import useDropdown from './composables/useDropdown'
|
||||
import useMultiselect from './composables/useMultiselect'
|
||||
import useKeyboard from './composables/useKeyboard'
|
||||
import useClasses from './composables/useClasses'
|
||||
import useScroll from './composables/useScroll'
|
||||
import useA11y from './composables/useA11y'
|
||||
import useI18n from './composables/useI18n'
|
||||
import useRefs from './composables/useRefs'
|
||||
|
||||
import resolveDeps from './utils/resolveDeps'
|
||||
|
||||
export default {
|
||||
name: 'Multiselect',
|
||||
emits: [
|
||||
'paste', 'open', 'close', 'select', 'deselect',
|
||||
'input', 'search-change', 'tag', 'option', 'update:modelValue',
|
||||
'change', 'clear', 'keydown', 'keyup', 'max', 'create',
|
||||
],
|
||||
props: {
|
||||
value: {
|
||||
required: false,
|
||||
},
|
||||
modelValue: {
|
||||
required: false,
|
||||
},
|
||||
options: {
|
||||
type: [Array, Object, Function],
|
||||
required: false,
|
||||
default: () => ([])
|
||||
},
|
||||
id: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
name: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: 'multiselect',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'label',
|
||||
},
|
||||
trackBy: {
|
||||
type: [String, Array],
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
valueProp: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'value',
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'single', // single|multiple|tags
|
||||
},
|
||||
searchable: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: -1,
|
||||
},
|
||||
hideSelected: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
createTag: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
createOption: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
appendNewTag: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
appendNewOption: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
addTagOn: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
addOptionOn: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
caret: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
noOptionsText: {
|
||||
type: [String, Object],
|
||||
required: false,
|
||||
default: 'The list is empty',
|
||||
},
|
||||
noResultsText: {
|
||||
type: [String, Object],
|
||||
required: false,
|
||||
default: 'No results found',
|
||||
},
|
||||
multipleLabel: {
|
||||
type: Function,
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
object: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
delay: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: -1,
|
||||
},
|
||||
minChars: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0,
|
||||
},
|
||||
resolveOnLoad: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
filterResults: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
clearOnSearch: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
clearOnSelect: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
canDeselect: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
canClear: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: -1,
|
||||
},
|
||||
showOptions: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
openDirection: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'bottom',
|
||||
},
|
||||
nativeSupport: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
classes: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({})
|
||||
},
|
||||
strict: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
closeOnSelect: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
closeOnDeselect: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
autocomplete: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
groups: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
groupLabel: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'label',
|
||||
},
|
||||
groupOptions: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'options',
|
||||
},
|
||||
groupHideEmpty: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
groupSelect: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
inputType: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'text',
|
||||
},
|
||||
attrs: {
|
||||
required: false,
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
onCreate: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: undefined,
|
||||
},
|
||||
disabledProp: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'disabled',
|
||||
},
|
||||
searchStart: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
reverse: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
regex: {
|
||||
type: [Object, String, RegExp],
|
||||
required: false,
|
||||
default: undefined,
|
||||
},
|
||||
rtl: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
infinite: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
aria: {
|
||||
required: false,
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
clearOnBlur: {
|
||||
required: false,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
locale: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
fallbackLocale: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: 'en',
|
||||
},
|
||||
searchFilter: {
|
||||
required: false,
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
allowAbsent: {
|
||||
required: false,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
appendToBody: {
|
||||
required: false,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
closeOnScroll: {
|
||||
required: false,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
breakTags: {
|
||||
required: false,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
appendTo: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
setup(props, context)
|
||||
{
|
||||
return resolveDeps(props, context, [
|
||||
useRefs,
|
||||
useI18n,
|
||||
useValue,
|
||||
usePointer,
|
||||
useDropdown,
|
||||
useSearch,
|
||||
useData,
|
||||
useMultiselect,
|
||||
useOptions,
|
||||
useScroll,
|
||||
usePointerAction,
|
||||
useKeyboard,
|
||||
useClasses,
|
||||
useA11y,
|
||||
])
|
||||
},
|
||||
beforeMount() {
|
||||
if ((this.$root.constructor && this.$root.constructor.version && this.$root.constructor.version.match(/^2\./)) || this.vueVersionMs === 2) {
|
||||
if (!this.$options.components.Teleport) {
|
||||
this.$options.components.Teleport = {
|
||||
render() {
|
||||
return this.$slots.default ? this.$slots.default[0] : null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
127
client/node_modules/@vueform/multiselect/src/composables/useA11y.js
generated
vendored
Normal file
127
client/node_modules/@vueform/multiselect/src/composables/useA11y.js
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
import { toRefs, onMounted, ref, computed } from 'vue'
|
||||
import toRef from './../utils/toRef'
|
||||
|
||||
export default function useA11y (props, context, dep)
|
||||
{
|
||||
const {
|
||||
placeholder, id, valueProp, label: labelProp, mode, groupLabel, aria, searchable ,
|
||||
} = toRefs(props)
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const pointer = dep.pointer
|
||||
const iv = dep.iv
|
||||
const hasSelected = dep.hasSelected
|
||||
const multipleLabelText = dep.multipleLabelText
|
||||
|
||||
// ================ DATA ================
|
||||
|
||||
const label = ref(null)
|
||||
|
||||
// ============== COMPUTED ==============
|
||||
|
||||
const ariaAssist = toRef(() => (
|
||||
`${id.value ? id.value + '-' : ''}assist`
|
||||
))
|
||||
|
||||
const ariaControls = toRef(() => (
|
||||
`${id.value ? id.value + '-' : ''}multiselect-options`
|
||||
))
|
||||
|
||||
const ariaActiveDescendant = toRef(() => {
|
||||
if (pointer.value) {
|
||||
let texts = id.value
|
||||
? `${id.value}-`
|
||||
: '';
|
||||
|
||||
texts += `${pointer.value.group ? 'multiselect-group' : 'multiselect-option'}-`
|
||||
|
||||
texts += pointer.value.group ? pointer.value.index : pointer.value[valueProp.value]
|
||||
|
||||
return texts
|
||||
}
|
||||
})
|
||||
|
||||
const ariaPlaceholder = toRef(() => {
|
||||
return placeholder.value
|
||||
})
|
||||
|
||||
const ariaMultiselectable = toRef(() => {
|
||||
return mode.value !== 'single'
|
||||
})
|
||||
|
||||
const ariaLabel = computed(() => {
|
||||
if (mode.value === 'single' && hasSelected.value) {
|
||||
return iv.value[labelProp.value]
|
||||
}
|
||||
|
||||
if (mode.value === 'multiple' && hasSelected.value) {
|
||||
return multipleLabelText.value
|
||||
}
|
||||
|
||||
if (mode.value === 'tags' && hasSelected.value) {
|
||||
return iv.value.map(v => v[labelProp.value]).join(', ')
|
||||
}
|
||||
|
||||
return ''
|
||||
})
|
||||
|
||||
const arias = computed(() => {
|
||||
let arias = { ...aria.value }
|
||||
|
||||
// Need to add manually because focusing
|
||||
// the input won't read the selected value
|
||||
if (searchable.value) {
|
||||
arias['aria-labelledby'] = arias['aria-labelledby']
|
||||
? `${ariaAssist.value} ${arias['aria-labelledby']}`
|
||||
: ariaAssist.value
|
||||
|
||||
if (ariaLabel.value && arias['aria-label']) {
|
||||
arias['aria-label'] = `${ariaLabel.value}, ${arias['aria-label']}`
|
||||
}
|
||||
}
|
||||
|
||||
return arias
|
||||
})
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
const ariaOptionId = (option) => (
|
||||
`${id.value ? id.value + '-' : ''}multiselect-option-${option[valueProp.value]}`
|
||||
)
|
||||
|
||||
const ariaGroupId = (option) => (
|
||||
`${id.value ? id.value + '-' : ''}multiselect-group-${option.index}`
|
||||
)
|
||||
|
||||
const ariaOptionLabel = (label) => `${label}`
|
||||
|
||||
const ariaGroupLabel = (label) => `${label}`
|
||||
|
||||
const ariaTagLabel = (label) => `${label} ❎`
|
||||
|
||||
// =============== HOOKS ================
|
||||
|
||||
onMounted(() => {
|
||||
/* istanbul ignore next */
|
||||
if (id.value && document && document.querySelector) {
|
||||
let forTag = document.querySelector(`[for="${id.value}"]`)
|
||||
label.value = forTag ? forTag.innerText : null
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
arias,
|
||||
ariaLabel,
|
||||
ariaAssist,
|
||||
ariaControls,
|
||||
ariaPlaceholder,
|
||||
ariaMultiselectable,
|
||||
ariaActiveDescendant,
|
||||
ariaOptionId,
|
||||
ariaOptionLabel,
|
||||
ariaGroupId,
|
||||
ariaGroupLabel,
|
||||
ariaTagLabel,
|
||||
}
|
||||
}
|
||||
165
client/node_modules/@vueform/multiselect/src/composables/useClasses.js
generated
vendored
Normal file
165
client/node_modules/@vueform/multiselect/src/composables/useClasses.js
generated
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
import { computed, toRefs } from 'vue'
|
||||
import toRef from './../utils/toRef'
|
||||
|
||||
export default function useClasses (props, context, dependencies)
|
||||
{const {
|
||||
classes: classes_, disabled, showOptions, breakTags
|
||||
} = toRefs(props)
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const isOpen = dependencies.isOpen
|
||||
const isPointed = dependencies.isPointed
|
||||
const isSelected = dependencies.isSelected
|
||||
const isDisabled = dependencies.isDisabled
|
||||
const isActive = dependencies.isActive
|
||||
const canPointGroups = dependencies.canPointGroups
|
||||
const resolving = dependencies.resolving
|
||||
const fo = dependencies.fo
|
||||
const placement = dependencies.placement
|
||||
|
||||
// ============== COMPUTED ==============
|
||||
|
||||
const classes = toRef(() => ({
|
||||
container: 'multiselect',
|
||||
containerDisabled: 'is-disabled',
|
||||
containerOpen: 'is-open',
|
||||
containerOpenTop: 'is-open-top',
|
||||
containerActive: 'is-active',
|
||||
wrapper: 'multiselect-wrapper',
|
||||
singleLabel: 'multiselect-single-label',
|
||||
singleLabelText: 'multiselect-single-label-text',
|
||||
multipleLabel: 'multiselect-multiple-label',
|
||||
search: 'multiselect-search',
|
||||
tags: 'multiselect-tags',
|
||||
tag: 'multiselect-tag',
|
||||
tagWrapper: 'multiselect-tag-wrapper',
|
||||
tagWrapperBreak: 'multiselect-tag-wrapper-break',
|
||||
tagDisabled: 'is-disabled',
|
||||
tagRemove: 'multiselect-tag-remove',
|
||||
tagRemoveIcon: 'multiselect-tag-remove-icon',
|
||||
tagsSearchWrapper: 'multiselect-tags-search-wrapper',
|
||||
tagsSearch: 'multiselect-tags-search',
|
||||
tagsSearchCopy: 'multiselect-tags-search-copy',
|
||||
placeholder: 'multiselect-placeholder',
|
||||
caret: 'multiselect-caret',
|
||||
caretOpen: 'is-open',
|
||||
clear: 'multiselect-clear',
|
||||
clearIcon: 'multiselect-clear-icon',
|
||||
spinner: 'multiselect-spinner',
|
||||
inifinite: 'multiselect-inifite',
|
||||
inifiniteSpinner: 'multiselect-inifite-spinner',
|
||||
dropdown: 'multiselect-dropdown',
|
||||
dropdownTop: 'is-top',
|
||||
dropdownHidden: 'is-hidden',
|
||||
options: 'multiselect-options',
|
||||
optionsTop: 'is-top',
|
||||
group: 'multiselect-group',
|
||||
groupLabel: 'multiselect-group-label',
|
||||
groupLabelPointable: 'is-pointable',
|
||||
groupLabelPointed: 'is-pointed',
|
||||
groupLabelSelected: 'is-selected',
|
||||
groupLabelDisabled: 'is-disabled',
|
||||
groupLabelSelectedPointed: 'is-selected is-pointed',
|
||||
groupLabelSelectedDisabled: 'is-selected is-disabled',
|
||||
groupOptions: 'multiselect-group-options',
|
||||
option: 'multiselect-option',
|
||||
optionPointed: 'is-pointed',
|
||||
optionSelected: 'is-selected',
|
||||
optionDisabled: 'is-disabled',
|
||||
optionSelectedPointed: 'is-selected is-pointed',
|
||||
optionSelectedDisabled: 'is-selected is-disabled',
|
||||
noOptions: 'multiselect-no-options',
|
||||
noResults: 'multiselect-no-results',
|
||||
fakeInput: 'multiselect-fake-input',
|
||||
assist: 'multiselect-assistive-text',
|
||||
spacer: 'multiselect-spacer',
|
||||
...classes_.value,
|
||||
}))
|
||||
|
||||
const showDropdown = toRef(() => {
|
||||
return !!(isOpen.value && showOptions.value && (!resolving.value || (resolving.value && fo.value.length)))
|
||||
})
|
||||
|
||||
const classList = computed(() => {
|
||||
const c = classes.value
|
||||
|
||||
return {
|
||||
container: [c.container]
|
||||
.concat(disabled.value ? c.containerDisabled : [])
|
||||
.concat(showDropdown.value && placement.value === 'top' ? c.containerOpenTop : [])
|
||||
.concat(showDropdown.value && placement.value !== 'top' ? c.containerOpen : [])
|
||||
.concat(isActive.value ? c.containerActive : []),
|
||||
wrapper: c.wrapper,
|
||||
spacer: c.spacer,
|
||||
singleLabel: c.singleLabel,
|
||||
singleLabelText: c.singleLabelText,
|
||||
multipleLabel: c.multipleLabel,
|
||||
search: c.search,
|
||||
tags: c.tags,
|
||||
tag: [c.tag]
|
||||
.concat(disabled.value ? c.tagDisabled : []),
|
||||
tagWrapper: [c.tagWrapper, breakTags.value ? c.tagWrapperBreak : null],
|
||||
tagDisabled: c.tagDisabled,
|
||||
tagRemove: c.tagRemove,
|
||||
tagRemoveIcon: c.tagRemoveIcon,
|
||||
tagsSearchWrapper: c.tagsSearchWrapper,
|
||||
tagsSearch: c.tagsSearch,
|
||||
tagsSearchCopy: c.tagsSearchCopy,
|
||||
placeholder: c.placeholder,
|
||||
caret: [c.caret]
|
||||
.concat(isOpen.value ? c.caretOpen : []),
|
||||
clear: c.clear,
|
||||
clearIcon: c.clearIcon,
|
||||
spinner: c.spinner,
|
||||
inifinite: c.inifinite,
|
||||
inifiniteSpinner: c.inifiniteSpinner,
|
||||
dropdown: [c.dropdown]
|
||||
.concat(placement.value === 'top' ? c.dropdownTop : [])
|
||||
.concat(!isOpen.value || !showOptions.value || !showDropdown.value ? c.dropdownHidden : []),
|
||||
options: [c.options]
|
||||
.concat(placement.value === 'top' ? c.optionsTop : []),
|
||||
group: c.group,
|
||||
groupLabel: (g) => {
|
||||
let groupLabel = [c.groupLabel]
|
||||
|
||||
if (isPointed(g)) {
|
||||
groupLabel.push(isSelected(g) ? c.groupLabelSelectedPointed : c.groupLabelPointed)
|
||||
} else if (isSelected(g) && canPointGroups.value) {
|
||||
groupLabel.push(isDisabled(g) ? c.groupLabelSelectedDisabled : c.groupLabelSelected)
|
||||
} else if (isDisabled(g)) {
|
||||
groupLabel.push(c.groupLabelDisabled)
|
||||
}
|
||||
|
||||
if (canPointGroups.value) {
|
||||
groupLabel.push(c.groupLabelPointable)
|
||||
}
|
||||
|
||||
return groupLabel
|
||||
},
|
||||
groupOptions: c.groupOptions,
|
||||
option: (o, g) => {
|
||||
let option = [c.option]
|
||||
|
||||
if (isPointed(o)) {
|
||||
option.push(isSelected(o) ? c.optionSelectedPointed : c.optionPointed)
|
||||
} else if (isSelected(o)) {
|
||||
option.push(isDisabled(o) ? c.optionSelectedDisabled : c.optionSelected)
|
||||
} else if (isDisabled(o) || (g && isDisabled(g))) {
|
||||
option.push(c.optionDisabled)
|
||||
}
|
||||
|
||||
return option
|
||||
},
|
||||
noOptions: c.noOptions,
|
||||
noResults: c.noResults,
|
||||
assist: c.assist,
|
||||
fakeInput: c.fakeInput,
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
classList,
|
||||
showDropdown,
|
||||
}
|
||||
}
|
||||
62
client/node_modules/@vueform/multiselect/src/composables/useData.js
generated
vendored
Normal file
62
client/node_modules/@vueform/multiselect/src/composables/useData.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
import { toRefs, getCurrentInstance } from 'vue'
|
||||
import isNullish from './../utils/isNullish'
|
||||
|
||||
export default function useData (props, context, dep)
|
||||
{
|
||||
const { object, valueProp, mode } = toRefs(props)
|
||||
|
||||
const $this = getCurrentInstance().proxy
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const iv = dep.iv
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
const update = (val, triggerInput = true) => {
|
||||
// Setting object(s) as internal value
|
||||
iv.value = makeInternal(val)
|
||||
|
||||
// Setting object(s) or plain value as external
|
||||
// value based on `option` setting
|
||||
const externalVal = makeExternal(val)
|
||||
|
||||
context.emit('change', externalVal, $this)
|
||||
|
||||
if (triggerInput) {
|
||||
context.emit('input', externalVal)
|
||||
context.emit('update:modelValue', externalVal)
|
||||
}
|
||||
}
|
||||
|
||||
// no export
|
||||
const makeExternal = (val) => {
|
||||
// If external value should be object
|
||||
// no transformation is required
|
||||
if (object.value) {
|
||||
return val
|
||||
}
|
||||
|
||||
// No need to transform if empty value
|
||||
if (isNullish(val)) {
|
||||
return val
|
||||
}
|
||||
|
||||
// If external should be plain transform
|
||||
// value object to plain values
|
||||
return !Array.isArray(val) ? val[valueProp.value] : val.map(v => v[valueProp.value])
|
||||
}
|
||||
|
||||
// no export
|
||||
const makeInternal = (val) => {
|
||||
if (isNullish(val)) {
|
||||
return mode.value === 'single' ? {} : []
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
return {
|
||||
update,
|
||||
}
|
||||
}
|
||||
158
client/node_modules/@vueform/multiselect/src/composables/useDropdown.js
generated
vendored
Normal file
158
client/node_modules/@vueform/multiselect/src/composables/useDropdown.js
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
import { ref, toRefs, getCurrentInstance, onMounted, onBeforeUnmount, nextTick } from 'vue'
|
||||
import { createPopper } from '@popperjs/core/lib/popper-lite'
|
||||
import preventOverflow from '@popperjs/core/lib/modifiers/preventOverflow'
|
||||
import flip from '@popperjs/core/lib/modifiers/flip'
|
||||
import toRef from './../utils/toRef'
|
||||
|
||||
export default function useDropdown (props, context, dep)
|
||||
{
|
||||
const { disabled, appendTo, appendToBody, openDirection } = toRefs(props)
|
||||
|
||||
const $this = getCurrentInstance().proxy
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const multiselect = dep.multiselect
|
||||
const dropdown = dep.dropdown
|
||||
|
||||
// ================ DATA ================
|
||||
|
||||
const isOpen = ref(false)
|
||||
const popper = ref(null)
|
||||
const forcedPlacement = ref(null)
|
||||
|
||||
// ============== COMPUTED ==============
|
||||
|
||||
const appended = toRef(() => {
|
||||
return appendTo.value || appendToBody.value
|
||||
})
|
||||
|
||||
const placement = toRef(() => {
|
||||
return (openDirection.value === 'top' && forcedPlacement.value === 'bottom') ||
|
||||
(openDirection.value === 'bottom' && forcedPlacement.value !== 'top')
|
||||
? 'bottom'
|
||||
: 'top'
|
||||
})
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
const open = () => {
|
||||
if (isOpen.value || disabled.value) {
|
||||
return
|
||||
}
|
||||
|
||||
isOpen.value = true
|
||||
context.emit('open', $this)
|
||||
|
||||
|
||||
if (appended.value) {
|
||||
nextTick(() => {
|
||||
updatePopper()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
if (!isOpen.value) {
|
||||
return
|
||||
}
|
||||
|
||||
isOpen.value = false
|
||||
context.emit('close', $this)
|
||||
}
|
||||
|
||||
const updatePopper = () => {
|
||||
if (!popper.value) {
|
||||
return
|
||||
}
|
||||
|
||||
let borderTopWidth = parseInt(window.getComputedStyle(dropdown.value).borderTopWidth.replace('px', ''))
|
||||
let borderBottomWidth = parseInt(window.getComputedStyle(dropdown.value).borderBottomWidth.replace('px', ''))
|
||||
|
||||
popper.value.setOptions((options) => ({
|
||||
...options,
|
||||
modifiers: [
|
||||
...options.modifiers,
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: [0, (placement.value === 'top' ? borderTopWidth : borderBottomWidth) * -1],
|
||||
},
|
||||
},
|
||||
]
|
||||
}))
|
||||
|
||||
popper.value.update()
|
||||
}
|
||||
|
||||
/* istanbul ignore next: UI feature */
|
||||
const hasFixedParent = (element) => {
|
||||
while (element && element !== document.body) {
|
||||
const style = getComputedStyle(element)
|
||||
|
||||
if (style.position === 'fixed') {
|
||||
return true
|
||||
}
|
||||
|
||||
element = element.parentElement
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!appended.value) {
|
||||
return
|
||||
}
|
||||
|
||||
/* istanbul ignore next: popper mock */
|
||||
popper.value = createPopper(multiselect.value, dropdown.value, {
|
||||
strategy: hasFixedParent(multiselect.value) ? /* istanbul ignore next: UI feature */ 'fixed' : undefined,
|
||||
placement: openDirection.value,
|
||||
modifiers: [
|
||||
preventOverflow,
|
||||
flip,
|
||||
{
|
||||
name: 'sameWidth',
|
||||
enabled: true,
|
||||
phase: 'beforeWrite',
|
||||
requires: ['computeStyles'],
|
||||
fn: ({ state }) => {
|
||||
state.styles.popper.width = `${state.rects.reference.width}px`
|
||||
},
|
||||
effect: ({ state }) => {
|
||||
state.elements.popper.style.width = `${
|
||||
state.elements.reference.offsetWidth
|
||||
}px`
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'toggleClass',
|
||||
enabled: true,
|
||||
phase: 'write',
|
||||
fn({ state }) {
|
||||
forcedPlacement.value = state.placement
|
||||
},
|
||||
},
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (!appended.value || !popper.value) {
|
||||
return
|
||||
}
|
||||
|
||||
popper.value.destroy()
|
||||
popper.value = null
|
||||
})
|
||||
|
||||
return {
|
||||
popper,
|
||||
isOpen,
|
||||
open,
|
||||
close,
|
||||
placement,
|
||||
updatePopper,
|
||||
}
|
||||
}
|
||||
34
client/node_modules/@vueform/multiselect/src/composables/useI18n.js
generated
vendored
Normal file
34
client/node_modules/@vueform/multiselect/src/composables/useI18n.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
export default function useI18n (props, context, dep)
|
||||
{
|
||||
const {
|
||||
locale, fallbackLocale,
|
||||
} = toRefs(props)
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
const localize = (target) => {
|
||||
if (!target || typeof target !== 'object') {
|
||||
return target
|
||||
}
|
||||
|
||||
if (target && target[locale.value]) {
|
||||
return target[locale.value]
|
||||
} else if (target && locale.value && target[locale.value.toUpperCase()]) {
|
||||
return target[locale.value.toUpperCase()]
|
||||
} else if (target && target[fallbackLocale.value]) {
|
||||
return target[fallbackLocale.value]
|
||||
} else if (target && fallbackLocale.value && target[fallbackLocale.value.toUpperCase()]) {
|
||||
return target[fallbackLocale.value.toUpperCase()]
|
||||
} else if (target && Object.keys(target)[0]) {
|
||||
return target[Object.keys(target)[0]]
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
localize,
|
||||
}
|
||||
}
|
||||
247
client/node_modules/@vueform/multiselect/src/composables/useKeyboard.js
generated
vendored
Normal file
247
client/node_modules/@vueform/multiselect/src/composables/useKeyboard.js
generated
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
import { toRefs, getCurrentInstance } from 'vue'
|
||||
import toRef from './../utils/toRef'
|
||||
|
||||
export default function useKeyboard (props, context, dep)
|
||||
{
|
||||
const {
|
||||
mode, addTagOn, openDirection, searchable,
|
||||
showOptions, valueProp, groups: groupped,
|
||||
addOptionOn: addOptionOn_, createTag, createOption: createOption_,
|
||||
reverse,
|
||||
} = toRefs(props)
|
||||
|
||||
const $this = getCurrentInstance().proxy
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const iv = dep.iv
|
||||
const update = dep.update
|
||||
const deselect = dep.deselect
|
||||
const search = dep.search
|
||||
const setPointer = dep.setPointer
|
||||
const selectPointer = dep.selectPointer
|
||||
const backwardPointer = dep.backwardPointer
|
||||
const forwardPointer = dep.forwardPointer
|
||||
const multiselect = dep.multiselect
|
||||
const wrapper = dep.wrapper
|
||||
const tags = dep.tags
|
||||
const isOpen = dep.isOpen
|
||||
const open = dep.open
|
||||
const blur = dep.blur
|
||||
const fo = dep.fo
|
||||
|
||||
// ============== COMPUTED ==============
|
||||
|
||||
// no export
|
||||
const createOption = toRef(() => {
|
||||
return createTag.value || createOption_.value || false
|
||||
})
|
||||
|
||||
// no export
|
||||
const addOptionOn = toRef(() => {
|
||||
if (addTagOn.value !== undefined) {
|
||||
return addTagOn.value
|
||||
}
|
||||
else if (addOptionOn_.value !== undefined) {
|
||||
return addOptionOn_.value
|
||||
}
|
||||
|
||||
return ['enter']
|
||||
})
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
// no export
|
||||
const preparePointer = () => {
|
||||
// When options are hidden and creating tags is allowed
|
||||
// no pointer will be set (because options are hidden).
|
||||
// In such case we need to set the pointer manually to the
|
||||
// first option, which equals to the option created from
|
||||
// the search value.
|
||||
if (mode.value === 'tags' && !showOptions.value && createOption.value && searchable.value && !groupped.value) {
|
||||
setPointer(fo.value[fo.value.map(o => o[valueProp.value]).indexOf(search.value)])
|
||||
}
|
||||
}
|
||||
|
||||
const handleKeydown = (e) => {
|
||||
context.emit('keydown', e, $this)
|
||||
|
||||
let tagList
|
||||
let activeIndex
|
||||
|
||||
if (['ArrowLeft', 'ArrowRight', 'Enter'].indexOf(e.key) !== -1 && mode.value === 'tags') {
|
||||
tagList = [...(multiselect.value.querySelectorAll(`[data-tags] > *`))].filter(e => e !== tags.value)
|
||||
activeIndex = tagList.findIndex(e => e === document.activeElement)
|
||||
}
|
||||
|
||||
switch (e.key) {
|
||||
case 'Backspace':
|
||||
if (mode.value === 'single') {
|
||||
return
|
||||
}
|
||||
|
||||
if (searchable.value && [null, ''].indexOf(search.value) === -1) {
|
||||
return
|
||||
}
|
||||
|
||||
if (iv.value.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
let deselectables = iv.value.filter(v=>!v.disabled && v.remove !== false)
|
||||
|
||||
if (deselectables.length) {
|
||||
deselect(deselectables[deselectables.length - 1])
|
||||
}
|
||||
break
|
||||
|
||||
case 'Enter':
|
||||
e.preventDefault()
|
||||
|
||||
if (e.keyCode === 229) {
|
||||
// ignore IME confirmation
|
||||
return
|
||||
}
|
||||
|
||||
if (activeIndex !== -1 && activeIndex !== undefined) {
|
||||
update([...iv.value].filter((v, k) => k !== activeIndex))
|
||||
|
||||
if (activeIndex === tagList.length - 1) {
|
||||
if (tagList.length - 1) {
|
||||
tagList[tagList.length - 2].focus()
|
||||
} else if (searchable.value) {
|
||||
tags.value.querySelector('input').focus()
|
||||
} else {
|
||||
wrapper.value.focus()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (addOptionOn.value.indexOf('enter') === -1 && createOption.value) {
|
||||
return
|
||||
}
|
||||
|
||||
preparePointer()
|
||||
selectPointer()
|
||||
break
|
||||
|
||||
case ' ':
|
||||
if (!createOption.value && !searchable.value) {
|
||||
e.preventDefault()
|
||||
|
||||
preparePointer()
|
||||
selectPointer()
|
||||
return
|
||||
}
|
||||
|
||||
if (!createOption.value) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (addOptionOn.value.indexOf('space') === -1 && createOption.value) {
|
||||
return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
preparePointer()
|
||||
selectPointer()
|
||||
break
|
||||
|
||||
case 'Tab':
|
||||
case ';':
|
||||
case ',':
|
||||
if (addOptionOn.value.indexOf(e.key.toLowerCase()) === -1 || !createOption.value) {
|
||||
return
|
||||
}
|
||||
|
||||
preparePointer()
|
||||
selectPointer()
|
||||
e.preventDefault()
|
||||
break
|
||||
|
||||
case 'Escape':
|
||||
blur()
|
||||
break
|
||||
|
||||
case 'ArrowUp':
|
||||
e.preventDefault()
|
||||
|
||||
if (!showOptions.value) {
|
||||
return
|
||||
}
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (!isOpen.value) {
|
||||
open()
|
||||
}
|
||||
|
||||
backwardPointer()
|
||||
break
|
||||
|
||||
case 'ArrowDown':
|
||||
e.preventDefault()
|
||||
|
||||
if (!showOptions.value) {
|
||||
return
|
||||
}
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (!isOpen.value) {
|
||||
open()
|
||||
}
|
||||
|
||||
forwardPointer()
|
||||
break
|
||||
|
||||
case 'ArrowLeft':
|
||||
if (
|
||||
(searchable.value && tags.value && tags.value.querySelector('input').selectionStart)
|
||||
|| e.shiftKey || mode.value !== 'tags' || !iv.value || !iv.value.length
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
if (activeIndex === -1) {
|
||||
tagList[tagList.length-1].focus()
|
||||
}
|
||||
else if (activeIndex > 0) {
|
||||
tagList[activeIndex-1].focus()
|
||||
}
|
||||
break
|
||||
|
||||
case 'ArrowRight':
|
||||
if (activeIndex === -1 || e.shiftKey || mode.value !== 'tags' || !iv.value || !iv.value.length) {
|
||||
return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (tagList.length > activeIndex + 1) {
|
||||
tagList[activeIndex+1].focus()
|
||||
}
|
||||
else if (searchable.value) {
|
||||
tags.value.querySelector('input').focus()
|
||||
}
|
||||
else if (!searchable.value) {
|
||||
wrapper.value.focus()
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const handleKeyup = (e) => {
|
||||
context.emit('keyup', e, $this)
|
||||
}
|
||||
|
||||
return {
|
||||
handleKeydown,
|
||||
handleKeyup,
|
||||
preparePointer,
|
||||
}
|
||||
}
|
||||
121
client/node_modules/@vueform/multiselect/src/composables/useMultiselect.js
generated
vendored
Normal file
121
client/node_modules/@vueform/multiselect/src/composables/useMultiselect.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
import { ref, toRefs } from 'vue'
|
||||
import toRef from './../utils/toRef'
|
||||
|
||||
export default function useMultiselect (props, context, dep)
|
||||
{
|
||||
const { searchable, disabled, clearOnBlur } = toRefs(props)
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const input = dep.input
|
||||
const open = dep.open
|
||||
const close = dep.close
|
||||
const clearSearch = dep.clearSearch
|
||||
const isOpen = dep.isOpen
|
||||
const wrapper = dep.wrapper
|
||||
const tags = dep.tags
|
||||
|
||||
// ================ DATA ================
|
||||
|
||||
const isActive = ref(false)
|
||||
|
||||
const mouseClicked = ref(false)
|
||||
|
||||
// ============== COMPUTED ==============
|
||||
|
||||
const tabindex = toRef(() => {
|
||||
return searchable.value || disabled.value ? -1 : 0
|
||||
})
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
const blur = () => {
|
||||
if (searchable.value) {
|
||||
input.value.blur()
|
||||
}
|
||||
|
||||
wrapper.value.blur()
|
||||
}
|
||||
|
||||
const focus = () => {
|
||||
if (searchable.value && !disabled.value) {
|
||||
input.value.focus()
|
||||
}
|
||||
}
|
||||
|
||||
const activate = (shouldOpen = true) => {
|
||||
if (disabled.value) {
|
||||
return
|
||||
}
|
||||
|
||||
isActive.value = true
|
||||
|
||||
if (shouldOpen) {
|
||||
open()
|
||||
}
|
||||
}
|
||||
|
||||
const deactivate = () => {
|
||||
isActive.value = false
|
||||
|
||||
setTimeout(() => {
|
||||
if (!isActive.value) {
|
||||
close()
|
||||
|
||||
if (clearOnBlur.value) {
|
||||
clearSearch()
|
||||
}
|
||||
}
|
||||
}, 1)
|
||||
}
|
||||
|
||||
const handleFocusIn = (e) => {
|
||||
if ((e.target.closest('[data-tags]') && e.target.nodeName !== 'INPUT') || e.target.closest('[data-clear]')) {
|
||||
return
|
||||
}
|
||||
|
||||
activate(mouseClicked.value)
|
||||
}
|
||||
|
||||
const handleFocusOut = () => {
|
||||
deactivate()
|
||||
}
|
||||
|
||||
const handleCaretClick = () => {
|
||||
deactivate()
|
||||
blur()
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
const handleMousedown = (e) => {
|
||||
mouseClicked.value = true
|
||||
|
||||
if (isOpen.value && (e.target.isEqualNode(wrapper.value) || e.target.isEqualNode(tags.value))) {
|
||||
setTimeout(() => {
|
||||
deactivate()
|
||||
}, 0)
|
||||
} else if (!isOpen.value
|
||||
&& (document.activeElement.isEqualNode(wrapper.value)
|
||||
|| document.activeElement.isEqualNode(input.value))) {
|
||||
activate()
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
mouseClicked.value = false
|
||||
}, 0)
|
||||
}
|
||||
|
||||
return {
|
||||
tabindex,
|
||||
isActive,
|
||||
mouseClicked,
|
||||
blur,
|
||||
focus,
|
||||
activate,
|
||||
deactivate,
|
||||
handleFocusIn,
|
||||
handleFocusOut,
|
||||
handleCaretClick,
|
||||
handleMousedown,
|
||||
}
|
||||
}
|
||||
888
client/node_modules/@vueform/multiselect/src/composables/useOptions.js
generated
vendored
Normal file
888
client/node_modules/@vueform/multiselect/src/composables/useOptions.js
generated
vendored
Normal file
@@ -0,0 +1,888 @@
|
||||
import { ref, toRefs, computed, watch, getCurrentInstance } from 'vue'
|
||||
import normalize from './../utils/normalize'
|
||||
import isObject from './../utils/isObject'
|
||||
import isNullish from './../utils/isNullish'
|
||||
import arraysEqual from './../utils/arraysEqual'
|
||||
import objectsEqual from './../utils/objectsEqual'
|
||||
import toRef from './../utils/toRef'
|
||||
|
||||
export default function useOptions (props, context, dep)
|
||||
{
|
||||
const {
|
||||
options, mode, trackBy: trackBy_, limit, hideSelected, createTag, createOption: createOption_, label,
|
||||
appendNewTag, appendNewOption: appendNewOption_, multipleLabel, object, loading, delay, resolveOnLoad,
|
||||
minChars, filterResults, clearOnSearch, clearOnSelect, valueProp, allowAbsent, groupLabel,
|
||||
canDeselect, max, strict, closeOnSelect, closeOnDeselect, groups: groupped, reverse, infinite,
|
||||
groupOptions, groupHideEmpty, groupSelect, onCreate, disabledProp, searchStart, searchFilter,
|
||||
} = toRefs(props)
|
||||
|
||||
const $this = getCurrentInstance().proxy
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const iv = dep.iv
|
||||
const ev = dep.ev
|
||||
const search = dep.search
|
||||
const clearSearch = dep.clearSearch
|
||||
const update = dep.update
|
||||
const pointer = dep.pointer
|
||||
const setPointer = dep.setPointer
|
||||
const clearPointer = dep.clearPointer
|
||||
const focus = dep.focus
|
||||
const deactivate = dep.deactivate
|
||||
const close = dep.close
|
||||
const localize = dep.localize
|
||||
|
||||
// ================ DATA ================
|
||||
|
||||
// no export
|
||||
// appendedOptions
|
||||
const ap = ref([])
|
||||
|
||||
// no export
|
||||
// resolvedOptions
|
||||
const ro = ref([])
|
||||
|
||||
const resolving = ref(false)
|
||||
|
||||
// no export
|
||||
const searchWatcher = ref(null)
|
||||
|
||||
const offset = ref(infinite.value && limit.value === -1 ? 10 : limit.value)
|
||||
|
||||
// ============== COMPUTED ==============
|
||||
|
||||
const resolvedOptions = computed({
|
||||
get: () => ro.value,
|
||||
set: (v) => ro.value = v
|
||||
})
|
||||
|
||||
// no export
|
||||
const createOption = toRef(() => {
|
||||
return createTag.value || createOption_.value || false
|
||||
})
|
||||
|
||||
// no export
|
||||
const appendNewOption = toRef(() => {
|
||||
if (appendNewTag.value !== undefined) {
|
||||
return appendNewTag.value
|
||||
} else if (appendNewOption_.value !== undefined) {
|
||||
return appendNewOption_.value
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
// no export
|
||||
// extendedOptions
|
||||
const eo = computed(() => {
|
||||
if (groupped.value) {
|
||||
let groups = eg.value || /* istanbul ignore next */ []
|
||||
|
||||
let eo = []
|
||||
|
||||
groups.forEach((group) => {
|
||||
optionsToArray(group[groupOptions.value]).forEach((option) => {
|
||||
eo.push(Object.assign({}, option, group[disabledProp.value] ? { [disabledProp.value]: true } : {}))
|
||||
})
|
||||
})
|
||||
|
||||
return eo
|
||||
} else {
|
||||
let eo = optionsToArray(ro.value || /* istanbul ignore next */ [])
|
||||
|
||||
if (ap.value.length) {
|
||||
eo = eo.concat(ap.value)
|
||||
}
|
||||
|
||||
return eo
|
||||
}
|
||||
})
|
||||
|
||||
// preFilteredOptions
|
||||
const pfo = computed(() => {
|
||||
let options = eo.value
|
||||
|
||||
if (reverse.value) {
|
||||
options = options.reverse()
|
||||
}
|
||||
|
||||
if (createdOption.value.length) {
|
||||
options = createdOption.value.concat(options)
|
||||
}
|
||||
|
||||
return filterOptions(options)
|
||||
})
|
||||
|
||||
// filteredOptions
|
||||
const fo = computed(() => {
|
||||
let options = pfo.value
|
||||
|
||||
if (offset.value > 0) {
|
||||
options = options.slice(0, offset.value)
|
||||
}
|
||||
|
||||
return options
|
||||
})
|
||||
|
||||
// no export
|
||||
// extendedGroups
|
||||
const eg = computed(() => {
|
||||
if (!groupped.value) {
|
||||
return []
|
||||
}
|
||||
|
||||
let eg = []
|
||||
let groups = ro.value || /* istanbul ignore next */ []
|
||||
|
||||
if (ap.value.length) {
|
||||
eg.push({
|
||||
[groupLabel.value]: ' ',
|
||||
[groupOptions.value]: [...ap.value],
|
||||
__CREATE__: true
|
||||
})
|
||||
}
|
||||
|
||||
return eg.concat(groups)
|
||||
})
|
||||
|
||||
// preFilteredGroups
|
||||
const pfg = computed(() => {
|
||||
let groups = [...eg.value].map(g => ({...g}))
|
||||
|
||||
if (createdOption.value.length) {
|
||||
if (groups[0] && groups[0].__CREATE__) {
|
||||
groups[0][groupOptions.value] = [...createdOption.value, ...groups[0][groupOptions.value]]
|
||||
} else {
|
||||
groups = [{
|
||||
[groupLabel.value]: ' ',
|
||||
[groupOptions.value]: [...createdOption.value],
|
||||
__CREATE__: true
|
||||
}].concat(groups)
|
||||
}
|
||||
}
|
||||
|
||||
return groups
|
||||
})
|
||||
|
||||
// filteredGroups
|
||||
const fg = computed(() => {
|
||||
if (!groupped.value) {
|
||||
return []
|
||||
}
|
||||
|
||||
let options = pfg.value
|
||||
|
||||
return filterGroups((options || /* istanbul ignore next */ []).map((group, index) => {
|
||||
const arrayOptions = optionsToArray(group[groupOptions.value])
|
||||
|
||||
return {
|
||||
...group,
|
||||
index,
|
||||
group: true,
|
||||
[groupOptions.value]: filterOptions(arrayOptions, false).map(o => Object.assign({}, o, group[disabledProp.value] ? { [disabledProp.value]: true } : {})),
|
||||
__VISIBLE__: filterOptions(arrayOptions).map(o => Object.assign({}, o, group[disabledProp.value] ? { [disabledProp.value]: true } : {})),
|
||||
}
|
||||
// Difference between __VISIBLE__ and {groupOptions}: visible does not contain selected options when hideSelected=true
|
||||
}))
|
||||
})
|
||||
|
||||
const hasSelected = computed(() => {
|
||||
switch (mode.value) {
|
||||
case 'single':
|
||||
return !isNullish(iv.value[valueProp.value])
|
||||
|
||||
case 'multiple':
|
||||
case 'tags':
|
||||
return !isNullish(iv.value) && iv.value.length > 0
|
||||
}
|
||||
})
|
||||
|
||||
const multipleLabelText = computed(() => {
|
||||
return multipleLabel.value !== undefined
|
||||
? multipleLabel.value(iv.value, $this)
|
||||
: (iv.value && iv.value.length > 1 ? `${iv.value.length} options selected` : `1 option selected`)
|
||||
})
|
||||
|
||||
const noOptions = toRef(() => {
|
||||
return !eo.value.length && !resolving.value && !createdOption.value.length
|
||||
})
|
||||
|
||||
|
||||
const noResults = toRef(() => {
|
||||
return eo.value.length > 0 && fo.value.length == 0 && ((search.value && groupped.value) || !groupped.value)
|
||||
})
|
||||
|
||||
// no export
|
||||
const createdOption = computed(() => {
|
||||
if (createOption.value === false || !search.value) {
|
||||
return []
|
||||
}
|
||||
|
||||
if (getOptionByTrackBy(search.value) !== -1) {
|
||||
return []
|
||||
}
|
||||
|
||||
return [{
|
||||
[valueProp.value]: search.value,
|
||||
[trackBy.value[0]]: search.value,
|
||||
[label.value]: search.value,
|
||||
__CREATE__: true,
|
||||
}]
|
||||
})
|
||||
|
||||
const trackBy = computed(() => {
|
||||
return trackBy_.value ? (Array.isArray(trackBy_.value) ? trackBy_.value : [trackBy_.value]) : [label.value]
|
||||
})
|
||||
|
||||
// no export
|
||||
const nullValue = toRef(() => {
|
||||
switch (mode.value) {
|
||||
case 'single':
|
||||
return null
|
||||
|
||||
case 'multiple':
|
||||
case 'tags':
|
||||
return []
|
||||
}
|
||||
})
|
||||
|
||||
const busy = toRef(() => {
|
||||
return loading.value || resolving.value
|
||||
})
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
/**
|
||||
* @param {array|object|string|number} option
|
||||
*/
|
||||
const select = (option) => {
|
||||
if (typeof option !== 'object') {
|
||||
option = getOption(option)
|
||||
}
|
||||
|
||||
switch (mode.value) {
|
||||
case 'single':
|
||||
update(option)
|
||||
break
|
||||
|
||||
case 'multiple':
|
||||
case 'tags':
|
||||
update((iv.value).concat(option))
|
||||
break
|
||||
}
|
||||
|
||||
context.emit('select', finalValue(option), option, $this)
|
||||
}
|
||||
|
||||
const deselect = (option) => {
|
||||
if (typeof option !== 'object') {
|
||||
option = getOption(option)
|
||||
}
|
||||
|
||||
switch (mode.value) {
|
||||
case 'single':
|
||||
clear()
|
||||
break
|
||||
|
||||
case 'tags':
|
||||
case 'multiple':
|
||||
update(Array.isArray(option)
|
||||
? iv.value.filter(v => option.map(o => o[valueProp.value]).indexOf(v[valueProp.value]) === -1)
|
||||
: iv.value.filter(v => v[valueProp.value] != option[valueProp.value]))
|
||||
break
|
||||
}
|
||||
|
||||
context.emit('deselect', finalValue(option), option, $this)
|
||||
}
|
||||
|
||||
// no export
|
||||
const finalValue = (option) => {
|
||||
return object.value ? option : option[valueProp.value]
|
||||
}
|
||||
|
||||
const remove = (option) => {
|
||||
deselect(option)
|
||||
}
|
||||
|
||||
const handleTagRemove = (option, e) => {
|
||||
if (e.button !== 0) {
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
|
||||
remove(option)
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
update(nullValue.value)
|
||||
context.emit('clear', $this)
|
||||
}
|
||||
|
||||
const isSelected = (option) => {
|
||||
if (option.group !== undefined) {
|
||||
return mode.value === 'single' ? false : areAllSelected(option[groupOptions.value]) && option[groupOptions.value].length
|
||||
}
|
||||
|
||||
switch (mode.value) {
|
||||
case 'single':
|
||||
return !isNullish(iv.value) && (
|
||||
iv.value[valueProp.value] == option[valueProp.value] ||
|
||||
(typeof iv.value[valueProp.value] === 'object' && typeof option[valueProp.value] === 'object' && objectsEqual(iv.value[valueProp.value], option[valueProp.value]))
|
||||
)
|
||||
|
||||
case 'tags':
|
||||
case 'multiple':
|
||||
return !isNullish(iv.value) && iv.value.map(o => o[valueProp.value]).indexOf(option[valueProp.value]) !== -1
|
||||
}
|
||||
}
|
||||
|
||||
const isDisabled = (option) => {
|
||||
return option[disabledProp.value] === true
|
||||
}
|
||||
|
||||
const isMax = () => {
|
||||
if (max === undefined || max.value === -1 || (!hasSelected.value && max.value > 0)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return iv.value.length >= max.value
|
||||
}
|
||||
|
||||
const handleOptionClick = (option) => {
|
||||
if (isDisabled(option)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (onCreate.value && !isSelected(option) && option.__CREATE__) {
|
||||
option = { ...option }
|
||||
delete option.__CREATE__
|
||||
|
||||
option = onCreate.value(option, $this)
|
||||
|
||||
if (option instanceof Promise) {
|
||||
resolving.value = true
|
||||
option.then((result) => {
|
||||
resolving.value = false
|
||||
handleOptionSelect(result)
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
handleOptionSelect(option)
|
||||
}
|
||||
|
||||
const handleOptionSelect = (option) => {
|
||||
if (option.__CREATE__) {
|
||||
option = { ...option }
|
||||
delete option.__CREATE__
|
||||
}
|
||||
|
||||
switch (mode.value) {
|
||||
case 'single':
|
||||
if (option && isSelected(option)) {
|
||||
if (canDeselect.value) {
|
||||
deselect(option)
|
||||
}
|
||||
|
||||
if (closeOnDeselect.value) {
|
||||
clearPointer()
|
||||
close()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (option) {
|
||||
handleOptionAppend(option)
|
||||
}
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (clearOnSelect.value) {
|
||||
clearSearch()
|
||||
}
|
||||
|
||||
if (closeOnSelect.value) {
|
||||
clearPointer()
|
||||
close()
|
||||
}
|
||||
|
||||
if (option) {
|
||||
select(option)
|
||||
}
|
||||
break
|
||||
|
||||
case 'multiple':
|
||||
if (option && isSelected(option)) {
|
||||
deselect(option)
|
||||
|
||||
if (closeOnDeselect.value) {
|
||||
clearPointer()
|
||||
close()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (isMax()) {
|
||||
context.emit('max', $this)
|
||||
return
|
||||
}
|
||||
|
||||
if (option) {
|
||||
handleOptionAppend(option)
|
||||
select(option)
|
||||
}
|
||||
|
||||
if (clearOnSelect.value) {
|
||||
clearSearch()
|
||||
}
|
||||
|
||||
if (hideSelected.value) {
|
||||
clearPointer()
|
||||
}
|
||||
|
||||
if (closeOnSelect.value) {
|
||||
close()
|
||||
}
|
||||
break
|
||||
|
||||
case 'tags':
|
||||
if (option && isSelected(option)) {
|
||||
deselect(option)
|
||||
|
||||
if (closeOnDeselect.value) {
|
||||
clearPointer()
|
||||
close()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (isMax()) {
|
||||
context.emit('max', $this)
|
||||
return
|
||||
}
|
||||
|
||||
if (option) {
|
||||
handleOptionAppend(option)
|
||||
}
|
||||
|
||||
if (clearOnSelect.value) {
|
||||
clearSearch()
|
||||
}
|
||||
|
||||
if (option) {
|
||||
select(option)
|
||||
}
|
||||
|
||||
if (hideSelected.value) {
|
||||
clearPointer()
|
||||
}
|
||||
|
||||
if (closeOnSelect.value) {
|
||||
close()
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if (!closeOnSelect.value) {
|
||||
focus()
|
||||
}
|
||||
}
|
||||
|
||||
const handleGroupClick = (group) => {
|
||||
if (isDisabled(group) || mode.value === 'single' || !groupSelect.value) {
|
||||
return
|
||||
}
|
||||
|
||||
switch (mode.value) {
|
||||
case 'multiple':
|
||||
case 'tags':
|
||||
if (areAllEnabledSelected(group[groupOptions.value])) {
|
||||
deselect(group[groupOptions.value])
|
||||
} else {
|
||||
select(group[groupOptions.value]
|
||||
.filter(o => iv.value.map(v => v[valueProp.value]).indexOf(o[valueProp.value]) === -1)
|
||||
.filter(o => !o[disabledProp.value])
|
||||
.filter((o, k) => iv.value.length + 1 + k <= max.value || max.value === -1)
|
||||
)
|
||||
}
|
||||
|
||||
if (hideSelected.value && pointer.value) {
|
||||
// Refresh pointer because pointer.__VISIBLE__ are not reactive #354
|
||||
setPointer(fg.value.filter(g => !g[disabledProp.value])[pointer.value.index])
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if (closeOnSelect.value) {
|
||||
deactivate()
|
||||
}
|
||||
}
|
||||
|
||||
const handleOptionAppend = (option) => {
|
||||
if (getOption(option[valueProp.value]) === undefined && createOption.value) {
|
||||
context.emit('tag', option[valueProp.value], $this)
|
||||
context.emit('option', option[valueProp.value], $this)
|
||||
context.emit('create', option[valueProp.value], $this)
|
||||
|
||||
if (appendNewOption.value) {
|
||||
appendOption(option)
|
||||
}
|
||||
|
||||
clearSearch()
|
||||
}
|
||||
}
|
||||
|
||||
const selectAll = () => {
|
||||
if (mode.value === 'single') {
|
||||
return
|
||||
}
|
||||
|
||||
select(fo.value.filter(o => !o.disabled && !isSelected(o)))
|
||||
}
|
||||
|
||||
// no export
|
||||
const areAllEnabledSelected = (options) => {
|
||||
return options.find(o => !isSelected(o) && !o[disabledProp.value]) === undefined
|
||||
}
|
||||
|
||||
// no export
|
||||
const areAllSelected = (options) => {
|
||||
return options.find(o => !isSelected(o)) === undefined
|
||||
}
|
||||
|
||||
const getOption = (val) => {
|
||||
return eo.value[eo.value.map(o => String(o[valueProp.value])).indexOf(String(val))]
|
||||
}
|
||||
|
||||
// no export
|
||||
const getOptionByTrackBy = (val) => {
|
||||
return eo.value.findIndex((o) => {
|
||||
return trackBy.value.some((track) => {
|
||||
return (parseInt(o[track]) == o[track] ? parseInt(o[track]) : o[track]) === (parseInt(val) == val ? parseInt(val) : val)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// no export
|
||||
const shouldHideOption = (option) => {
|
||||
return ['tags', 'multiple'].indexOf(mode.value) !== -1 && hideSelected.value && isSelected(option)
|
||||
}
|
||||
|
||||
// no export
|
||||
const appendOption = (option) => {
|
||||
ap.value.push(option)
|
||||
}
|
||||
|
||||
// no export
|
||||
const filterGroups = (groups) => {
|
||||
// If the search has value we need to filter among
|
||||
// the ones that are visible to the user to avoid
|
||||
// displaying groups which technically have options
|
||||
// based on search but that option is already selected.
|
||||
return groupHideEmpty.value
|
||||
? groups.filter(g => search.value
|
||||
? g.__VISIBLE__.length
|
||||
: g[groupOptions.value].length
|
||||
)
|
||||
: groups.filter(g => search.value ? g.__VISIBLE__.length : true)
|
||||
}
|
||||
|
||||
// no export
|
||||
const filterOptions = (options, excludeHideSelected = true) => {
|
||||
let fo = options
|
||||
|
||||
if (search.value && filterResults.value) {
|
||||
let filter = searchFilter.value
|
||||
|
||||
if (!filter) {
|
||||
filter = (option, query, $this) => {
|
||||
return trackBy.value.some(track => {
|
||||
let target = normalize(localize(option[track]), strict.value);
|
||||
|
||||
return searchStart.value
|
||||
? target.startsWith(normalize(query, strict.value))
|
||||
: target.indexOf(normalize(query, strict.value)) !== -1;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fo = fo.filter((o) => {
|
||||
return filter(o, search.value, $this)
|
||||
})
|
||||
}
|
||||
|
||||
if (hideSelected.value && excludeHideSelected) {
|
||||
fo = fo.filter((option) => !shouldHideOption(option))
|
||||
}
|
||||
|
||||
return fo
|
||||
}
|
||||
|
||||
// no export
|
||||
const optionsToArray = (options) => {
|
||||
let uo = options
|
||||
|
||||
// Transforming an object to an array of objects
|
||||
if (isObject(uo)) {
|
||||
uo = Object.keys(uo).map((key) => {
|
||||
let val = uo[key]
|
||||
|
||||
return { [valueProp.value]: key, [trackBy.value[0]]: val, [label.value]: val}
|
||||
})
|
||||
}
|
||||
|
||||
// Transforming an plain arrays to an array of objects
|
||||
/* istanbul ignore else */
|
||||
if (uo && Array.isArray(uo)) {
|
||||
uo = uo.map((val) => {
|
||||
return typeof val === 'object' ? val : { [valueProp.value]: val, [trackBy.value[0]]: val, [label.value]: val}
|
||||
})
|
||||
} else {
|
||||
uo = []
|
||||
}
|
||||
|
||||
return uo
|
||||
}
|
||||
|
||||
// no export
|
||||
const initInternalValue = () => {
|
||||
if (!isNullish(ev.value)) {
|
||||
iv.value = makeInternal(ev.value)
|
||||
}
|
||||
}
|
||||
|
||||
const resolveOptions = (callback) => {
|
||||
resolving.value = true
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
options.value(search.value, $this).then((response) => {
|
||||
ro.value = response || []
|
||||
|
||||
if (typeof callback == 'function') {
|
||||
callback(response)
|
||||
}
|
||||
|
||||
resolving.value = false
|
||||
}).catch((e) => {
|
||||
console.error(e)
|
||||
|
||||
ro.value = []
|
||||
|
||||
resolving.value = false
|
||||
}).finally(() => {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// no export
|
||||
const refreshLabels = () => {
|
||||
if (!hasSelected.value) {
|
||||
return
|
||||
}
|
||||
|
||||
if (mode.value === 'single') {
|
||||
let option = getOption(iv.value[valueProp.value])
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (option !== undefined) {
|
||||
let newLabel = option[label.value]
|
||||
|
||||
iv.value[label.value] = newLabel
|
||||
|
||||
if (object.value) {
|
||||
ev.value[label.value] = newLabel
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iv.value.forEach((val, i) => {
|
||||
let option = getOption(iv.value[i][valueProp.value])
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (option !== undefined) {
|
||||
let newLabel = option[label.value]
|
||||
|
||||
iv.value[i][label.value] = newLabel
|
||||
|
||||
if (object.value) {
|
||||
ev.value[i][label.value] = newLabel
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const refreshOptions = (callback) => {
|
||||
resolveOptions(callback)
|
||||
}
|
||||
|
||||
// no export
|
||||
const makeInternal = (val) => {
|
||||
if (isNullish(val)) {
|
||||
return mode.value === 'single' ? {} : []
|
||||
}
|
||||
|
||||
if (object.value) {
|
||||
return val
|
||||
}
|
||||
|
||||
// If external should be plain transform value object to plain values
|
||||
return mode.value === 'single' ? getOption(val) || (allowAbsent.value ? {
|
||||
[label.value]: val,
|
||||
[valueProp.value]: val,
|
||||
[trackBy.value[0]]: val,
|
||||
} : {}) : val.filter(v => !!getOption(v) || allowAbsent.value).map(v => getOption(v) || {
|
||||
[label.value]: v,
|
||||
[valueProp.value]: v,
|
||||
[trackBy.value[0]]: v,
|
||||
})
|
||||
}
|
||||
|
||||
// no export
|
||||
const initSearchWatcher = () => {
|
||||
searchWatcher.value = watch(search, (query) => {
|
||||
if (query.length < minChars.value || (!query && minChars.value !== 0)) {
|
||||
return
|
||||
}
|
||||
|
||||
resolving.value = true
|
||||
|
||||
if (clearOnSearch.value) {
|
||||
ro.value = []
|
||||
}
|
||||
setTimeout(() => {
|
||||
if (query != search.value) {
|
||||
return
|
||||
}
|
||||
|
||||
options.value(search.value, $this).then((response) => {
|
||||
if (query == search.value || !search.value) {
|
||||
ro.value = response
|
||||
pointer.value = fo.value.filter(o => o[disabledProp.value] !== true)[0] || null
|
||||
resolving.value = false
|
||||
}
|
||||
}).catch( /* istanbul ignore next */ (e) => {
|
||||
console.error(e)
|
||||
})
|
||||
}, delay.value)
|
||||
|
||||
}, { flush: 'sync' })
|
||||
}
|
||||
|
||||
// ================ HOOKS ===============
|
||||
|
||||
if (mode.value !== 'single' && !isNullish(ev.value) && !Array.isArray(ev.value)) {
|
||||
throw new Error(`v-model must be an array when using "${mode.value}" mode`)
|
||||
}
|
||||
|
||||
if (options && typeof options.value == 'function') {
|
||||
if (resolveOnLoad.value) {
|
||||
resolveOptions(initInternalValue)
|
||||
} else if (object.value == true) {
|
||||
initInternalValue()
|
||||
}
|
||||
}
|
||||
else {
|
||||
ro.value = options.value
|
||||
|
||||
initInternalValue()
|
||||
}
|
||||
|
||||
// ============== WATCHERS ==============
|
||||
|
||||
if (delay.value > -1) {
|
||||
initSearchWatcher()
|
||||
}
|
||||
|
||||
watch(delay, (value, old) => {
|
||||
/* istanbul ignore else */
|
||||
if (searchWatcher.value) {
|
||||
searchWatcher.value()
|
||||
}
|
||||
|
||||
if (value >= 0) {
|
||||
initSearchWatcher()
|
||||
}
|
||||
})
|
||||
|
||||
watch(ev, (newValue) => {
|
||||
if (isNullish(newValue)) {
|
||||
update(makeInternal(newValue), false)
|
||||
return
|
||||
}
|
||||
|
||||
switch (mode.value) {
|
||||
case 'single':
|
||||
if (object.value ? newValue[valueProp.value] != iv.value[valueProp.value] : newValue != iv.value[valueProp.value]) {
|
||||
update(makeInternal(newValue), false)
|
||||
}
|
||||
break
|
||||
|
||||
case 'multiple':
|
||||
case 'tags':
|
||||
if (!arraysEqual(object.value ? newValue.map(o => o[valueProp.value]) : newValue, iv.value.map(o => o[valueProp.value]))) {
|
||||
update(makeInternal(newValue), false)
|
||||
}
|
||||
break
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
watch(options, (n, o) => {
|
||||
if (typeof props.options === 'function') {
|
||||
if (resolveOnLoad.value && (!o || (n && n.toString() !== o.toString()))) {
|
||||
resolveOptions()
|
||||
}
|
||||
} else {
|
||||
ro.value = props.options
|
||||
|
||||
if (!Object.keys(iv.value).length) {
|
||||
initInternalValue()
|
||||
}
|
||||
|
||||
refreshLabels()
|
||||
}
|
||||
})
|
||||
|
||||
watch(label, refreshLabels)
|
||||
|
||||
watch(limit, (n,o) => {
|
||||
offset.value = infinite.value && n === -1 ? 10 : n
|
||||
})
|
||||
|
||||
return {
|
||||
resolvedOptions,
|
||||
pfo,
|
||||
fo,
|
||||
filteredOptions: fo,
|
||||
hasSelected,
|
||||
multipleLabelText,
|
||||
eo,
|
||||
extendedOptions: eo,
|
||||
eg,
|
||||
extendedGroups: eg,
|
||||
fg,
|
||||
filteredGroups: fg,
|
||||
noOptions,
|
||||
noResults,
|
||||
resolving,
|
||||
busy,
|
||||
offset,
|
||||
select,
|
||||
deselect,
|
||||
remove,
|
||||
selectAll,
|
||||
clear,
|
||||
isSelected,
|
||||
isDisabled,
|
||||
isMax,
|
||||
getOption,
|
||||
handleOptionClick,
|
||||
handleGroupClick,
|
||||
handleTagRemove,
|
||||
refreshOptions,
|
||||
resolveOptions,
|
||||
refreshLabels,
|
||||
}
|
||||
}
|
||||
34
client/node_modules/@vueform/multiselect/src/composables/usePointer.js
generated
vendored
Normal file
34
client/node_modules/@vueform/multiselect/src/composables/usePointer.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import { ref, toRefs } from 'vue'
|
||||
|
||||
export default function usePointer (props, context, dep)
|
||||
{
|
||||
const { groupSelect, mode, groups, disabledProp } = toRefs(props)
|
||||
|
||||
// ================ DATA ================
|
||||
|
||||
const pointer = ref(null)
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
const setPointer = (option) => {
|
||||
if (option === undefined || (option !== null && option[disabledProp.value])) {
|
||||
return
|
||||
}
|
||||
|
||||
if (groups.value && option && option.group && (mode.value === 'single' || !groupSelect.value)) {
|
||||
return
|
||||
}
|
||||
|
||||
pointer.value = option
|
||||
}
|
||||
|
||||
const clearPointer = () => {
|
||||
setPointer(null)
|
||||
}
|
||||
|
||||
return {
|
||||
pointer,
|
||||
setPointer,
|
||||
clearPointer,
|
||||
}
|
||||
}
|
||||
274
client/node_modules/@vueform/multiselect/src/composables/usePointerAction.js
generated
vendored
Normal file
274
client/node_modules/@vueform/multiselect/src/composables/usePointerAction.js
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
import { toRefs, watch, nextTick, computed } from 'vue'
|
||||
import toRef from './../utils/toRef'
|
||||
|
||||
export default function usePointer (props, context, dep)
|
||||
{
|
||||
const {
|
||||
valueProp, showOptions, searchable, groupLabel,
|
||||
groups: groupped, mode, groupSelect, disabledProp,
|
||||
groupOptions,
|
||||
} = toRefs(props)
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const fo = dep.fo
|
||||
const fg = dep.fg
|
||||
const handleOptionClick = dep.handleOptionClick
|
||||
const handleGroupClick = dep.handleGroupClick
|
||||
const search = dep.search
|
||||
const pointer = dep.pointer
|
||||
const setPointer = dep.setPointer
|
||||
const clearPointer = dep.clearPointer
|
||||
const multiselect = dep.multiselect
|
||||
const isOpen = dep.isOpen
|
||||
|
||||
// ============== COMPUTED ==============
|
||||
|
||||
// no export
|
||||
const options = computed(() => {
|
||||
return fo.value.filter(o => !o[disabledProp.value])
|
||||
})
|
||||
|
||||
const groups = computed(() => {
|
||||
return fg.value.filter(g => !g[disabledProp.value])
|
||||
})
|
||||
|
||||
const canPointGroups = toRef(() => {
|
||||
return mode.value !== 'single' && groupSelect.value
|
||||
})
|
||||
|
||||
const isPointerGroup = toRef(() => {
|
||||
return pointer.value && pointer.value.group
|
||||
})
|
||||
|
||||
const currentGroup = computed(() => {
|
||||
return getParentGroup(pointer.value)
|
||||
})
|
||||
|
||||
const prevGroup = computed(() => {
|
||||
const group = isPointerGroup.value ? pointer.value : /* istanbul ignore next */ getParentGroup(pointer.value)
|
||||
const groupIndex = groups.value.map(g => g[groupLabel.value]).indexOf(group[groupLabel.value])
|
||||
let prevGroup = groups.value[groupIndex - 1]
|
||||
|
||||
if (prevGroup === undefined) {
|
||||
prevGroup = lastGroup.value
|
||||
}
|
||||
|
||||
return prevGroup
|
||||
})
|
||||
|
||||
const nextGroup = computed(() => {
|
||||
let nextIndex = groups.value.map(g => g.label).indexOf(isPointerGroup.value
|
||||
? pointer.value[groupLabel.value]
|
||||
: getParentGroup(pointer.value)[groupLabel.value]) + 1
|
||||
|
||||
if (groups.value.length <= nextIndex) {
|
||||
nextIndex = 0
|
||||
}
|
||||
|
||||
return groups.value[nextIndex]
|
||||
})
|
||||
|
||||
const lastGroup = computed(() => {
|
||||
return [...groups.value].slice(-1)[0]
|
||||
})
|
||||
|
||||
const currentGroupFirstEnabledOption = computed(() => {
|
||||
return pointer.value.__VISIBLE__.filter(o => !o[disabledProp.value])[0]
|
||||
})
|
||||
|
||||
const currentGroupPrevEnabledOption = computed(() => {
|
||||
const options = currentGroup.value.__VISIBLE__.filter(o => !o[disabledProp.value])
|
||||
return options[options.map(o => o[valueProp.value]).indexOf(pointer.value[valueProp.value]) - 1]
|
||||
})
|
||||
|
||||
const currentGroupNextEnabledOption = computed(() => {
|
||||
const options = getParentGroup(pointer.value).__VISIBLE__.filter(o => !o[disabledProp.value])
|
||||
return options[options.map(o => o[valueProp.value]).indexOf(pointer.value[valueProp.value]) + 1]
|
||||
})
|
||||
|
||||
const prevGroupLastEnabledOption = computed(() => {
|
||||
return [...prevGroup.value.__VISIBLE__.filter(o => !o[disabledProp.value])].slice(-1)[0]
|
||||
})
|
||||
|
||||
const lastGroupLastEnabledOption = computed(() => {
|
||||
return [...lastGroup.value.__VISIBLE__.filter(o => !o[disabledProp.value])].slice(-1)[0]
|
||||
})
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
const isPointed = (option) => {
|
||||
return (!!pointer.value && (
|
||||
(!option.group && pointer.value[valueProp.value] === option[valueProp.value]) ||
|
||||
(option.group !== undefined && pointer.value[groupLabel.value] === option[groupLabel.value])
|
||||
)) ? true : undefined
|
||||
}
|
||||
|
||||
const setPointerFirst = () => {
|
||||
setPointer(options.value[0] || null)
|
||||
}
|
||||
|
||||
const selectPointer = () => {
|
||||
if (!pointer.value || pointer.value[disabledProp.value] === true) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isPointerGroup.value) {
|
||||
handleGroupClick(pointer.value)
|
||||
} else {
|
||||
handleOptionClick(pointer.value)
|
||||
}
|
||||
}
|
||||
|
||||
const forwardPointer = () => {
|
||||
if (pointer.value === null) {
|
||||
setPointer((groupped.value && canPointGroups.value ? (!groups.value[0].__CREATE__ ? groups.value[0] : options.value[0]) : options.value[0]) || null)
|
||||
}
|
||||
else if (groupped.value && canPointGroups.value) {
|
||||
let nextPointer = isPointerGroup.value ? currentGroupFirstEnabledOption.value : currentGroupNextEnabledOption.value
|
||||
|
||||
if (nextPointer === undefined) {
|
||||
nextPointer = nextGroup.value
|
||||
|
||||
if (nextPointer.__CREATE__) {
|
||||
nextPointer = nextPointer[groupOptions.value][0]
|
||||
}
|
||||
}
|
||||
|
||||
setPointer(nextPointer || /* istanbul ignore next */ null)
|
||||
} else {
|
||||
let next = options.value.map(o => o[valueProp.value]).indexOf(pointer.value[valueProp.value]) + 1
|
||||
|
||||
if (options.value.length <= next) {
|
||||
next = 0
|
||||
}
|
||||
|
||||
setPointer(options.value[next] || null)
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
adjustWrapperScrollToPointer()
|
||||
})
|
||||
}
|
||||
|
||||
const backwardPointer = () => {
|
||||
if (pointer.value === null) {
|
||||
let prevPointer = options.value[options.value.length - 1]
|
||||
|
||||
if (groupped.value && canPointGroups.value) {
|
||||
prevPointer = lastGroupLastEnabledOption.value
|
||||
|
||||
if (prevPointer === undefined) {
|
||||
prevPointer = lastGroup.value
|
||||
}
|
||||
}
|
||||
|
||||
setPointer(prevPointer || null)
|
||||
}
|
||||
else if (groupped.value && canPointGroups.value) {
|
||||
let prevPointer = isPointerGroup.value ? prevGroupLastEnabledOption.value : currentGroupPrevEnabledOption.value
|
||||
|
||||
if (prevPointer === undefined) {
|
||||
prevPointer = isPointerGroup.value ? prevGroup.value : currentGroup.value
|
||||
|
||||
if (prevPointer.__CREATE__) {
|
||||
prevPointer = prevGroupLastEnabledOption.value
|
||||
|
||||
if (prevPointer === undefined) {
|
||||
prevPointer = prevGroup.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setPointer(prevPointer || /* istanbul ignore next */ null)
|
||||
} else {
|
||||
let prevIndex = options.value.map(o => o[valueProp.value]).indexOf(pointer.value[valueProp.value]) - 1
|
||||
|
||||
if (prevIndex < 0) {
|
||||
prevIndex = options.value.length - 1
|
||||
}
|
||||
|
||||
setPointer(options.value[prevIndex] || null)
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
adjustWrapperScrollToPointer()
|
||||
})
|
||||
}
|
||||
|
||||
const getParentGroup = (option) => {
|
||||
return groups.value.find((group) => {
|
||||
return group.__VISIBLE__.map(o => o[valueProp.value]).indexOf(option[valueProp.value]) !== -1
|
||||
})
|
||||
}
|
||||
|
||||
// no export
|
||||
/* istanbul ignore next */
|
||||
const adjustWrapperScrollToPointer = () => {
|
||||
let pointedOption = multiselect.value.querySelector(`[data-pointed]`)
|
||||
|
||||
if (!pointedOption) {
|
||||
return
|
||||
}
|
||||
|
||||
let wrapper = pointedOption.parentElement.parentElement
|
||||
|
||||
if (groupped.value) {
|
||||
wrapper = isPointerGroup.value
|
||||
? pointedOption.parentElement.parentElement.parentElement
|
||||
: pointedOption.parentElement.parentElement.parentElement.parentElement
|
||||
}
|
||||
|
||||
if (pointedOption.offsetTop + pointedOption.offsetHeight > wrapper.clientHeight + wrapper.scrollTop) {
|
||||
wrapper.scrollTop = pointedOption.offsetTop + pointedOption.offsetHeight - wrapper.clientHeight
|
||||
}
|
||||
|
||||
if (pointedOption.offsetTop < wrapper.scrollTop) {
|
||||
wrapper.scrollTop = pointedOption.offsetTop
|
||||
}
|
||||
}
|
||||
|
||||
// ============== WATCHERS ==============
|
||||
|
||||
watch(search, (val) => {
|
||||
if (searchable.value) {
|
||||
if (val.length && showOptions.value) {
|
||||
setPointerFirst()
|
||||
} else {
|
||||
clearPointer()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
watch(isOpen, (val) => {
|
||||
if (val && multiselect && multiselect.value) {
|
||||
let firstSelected = multiselect.value.querySelectorAll(`[data-selected]`)[0]
|
||||
|
||||
if (!firstSelected) {
|
||||
return
|
||||
}
|
||||
|
||||
let wrapper = firstSelected.parentElement.parentElement
|
||||
|
||||
nextTick(() => {
|
||||
// Removed because of #406
|
||||
/* istanbul ignore next */
|
||||
// if (wrapper.scrollTop > 0) {
|
||||
// return
|
||||
// }
|
||||
|
||||
wrapper.scrollTop = firstSelected.offsetTop
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
pointer,
|
||||
canPointGroups,
|
||||
isPointed,
|
||||
setPointerFirst,
|
||||
selectPointer,
|
||||
forwardPointer,
|
||||
backwardPointer,
|
||||
}
|
||||
}
|
||||
24
client/node_modules/@vueform/multiselect/src/composables/useRefs.js
generated
vendored
Normal file
24
client/node_modules/@vueform/multiselect/src/composables/useRefs.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
export default function useRefs (props, context, dep)
|
||||
{
|
||||
// ================ DATA ================
|
||||
|
||||
const multiselect = shallowRef(null)
|
||||
|
||||
const wrapper = shallowRef(null)
|
||||
|
||||
const tags = shallowRef(null)
|
||||
|
||||
const input = shallowRef(null)
|
||||
|
||||
const dropdown = shallowRef(null)
|
||||
|
||||
return {
|
||||
multiselect,
|
||||
wrapper,
|
||||
tags,
|
||||
input,
|
||||
dropdown,
|
||||
}
|
||||
}
|
||||
100
client/node_modules/@vueform/multiselect/src/composables/useScroll.js
generated
vendored
Normal file
100
client/node_modules/@vueform/multiselect/src/composables/useScroll.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
import { toRefs, watch, nextTick, onMounted, ref, shallowRef, computed } from 'vue'
|
||||
import toRef from '../utils/toRef'
|
||||
|
||||
export default function useScroll (props, context, dep)
|
||||
{
|
||||
const {
|
||||
limit, infinite,
|
||||
} = toRefs(props)
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const isOpen = dep.isOpen
|
||||
const offset = dep.offset
|
||||
const search = dep.search
|
||||
const pfo = dep.pfo
|
||||
const eo = dep.eo
|
||||
|
||||
// ================ DATA ================
|
||||
|
||||
// no export
|
||||
const observer = ref(null)
|
||||
|
||||
const infiniteLoader = shallowRef(null)
|
||||
|
||||
// ============== COMPUTED ==============
|
||||
|
||||
const hasMore = toRef(() => {
|
||||
return offset.value < pfo.value.length
|
||||
})
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
// no export
|
||||
/* istanbul ignore next */
|
||||
const handleIntersectionObserver = (entries) => {
|
||||
const { isIntersecting, target } = entries[0]
|
||||
|
||||
if (isIntersecting) {
|
||||
const parent = target.offsetParent
|
||||
const scrollTop = parent.scrollTop
|
||||
|
||||
offset.value += limit.value == -1 ? 10 : limit.value
|
||||
|
||||
nextTick(() => {
|
||||
parent.scrollTop = scrollTop
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const observe = () => {
|
||||
/* istanbul ignore else */
|
||||
if (isOpen.value && offset.value < pfo.value.length) {
|
||||
observer.value.observe(infiniteLoader.value)
|
||||
} else if (!isOpen.value && observer.value) {
|
||||
observer.value.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
// ============== WATCHERS ==============
|
||||
|
||||
watch(isOpen, () => {
|
||||
if (!infinite.value) {
|
||||
return
|
||||
}
|
||||
|
||||
observe()
|
||||
})
|
||||
|
||||
watch(search, () => {
|
||||
if (!infinite.value) {
|
||||
return
|
||||
}
|
||||
|
||||
offset.value = limit.value
|
||||
|
||||
observe()
|
||||
}, { flush: 'post' })
|
||||
|
||||
watch(eo, () => {
|
||||
if (!infinite.value) {
|
||||
return
|
||||
}
|
||||
|
||||
observe()
|
||||
}, { immediate: false, flush: 'post' })
|
||||
|
||||
// ================ HOOKS ===============
|
||||
|
||||
onMounted(() => {
|
||||
/* istanbul ignore else */
|
||||
if (window && window.IntersectionObserver) {
|
||||
observer.value = new IntersectionObserver(handleIntersectionObserver)
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
hasMore,
|
||||
infiniteLoader,
|
||||
}
|
||||
}
|
||||
78
client/node_modules/@vueform/multiselect/src/composables/useSearch.js
generated
vendored
Normal file
78
client/node_modules/@vueform/multiselect/src/composables/useSearch.js
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
import { ref, getCurrentInstance, watch, toRefs } from 'vue'
|
||||
|
||||
export default function useSearch (props, context, dep)
|
||||
{
|
||||
const { regex } = toRefs(props)
|
||||
|
||||
const $this = getCurrentInstance().proxy
|
||||
|
||||
// ============ DEPENDENCIES ============
|
||||
|
||||
const isOpen = dep.isOpen
|
||||
const open = dep.open
|
||||
|
||||
// ================ DATA ================
|
||||
|
||||
const search = ref(null)
|
||||
|
||||
// =============== METHODS ==============
|
||||
|
||||
const clearSearch = () => {
|
||||
search.value = ''
|
||||
}
|
||||
|
||||
const handleSearchInput = (e) => {
|
||||
search.value = e.target.value
|
||||
}
|
||||
|
||||
const handleKeypress = (e) => {
|
||||
if (regex.value) {
|
||||
let regexp = regex.value
|
||||
|
||||
if (typeof regexp === 'string') {
|
||||
regexp = new RegExp(regexp)
|
||||
}
|
||||
|
||||
if (!e.key.match(regexp)) {
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handlePaste = (e) => {
|
||||
if (regex.value) {
|
||||
let clipboardData = e.clipboardData || /* istanbul ignore next */ window.clipboardData
|
||||
let pastedData = clipboardData.getData('Text')
|
||||
|
||||
let regexp = regex.value
|
||||
|
||||
if (typeof regexp === 'string') {
|
||||
regexp = new RegExp(regexp)
|
||||
}
|
||||
|
||||
if (!pastedData.split('').every(c => !!c.match(regexp))) {
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
context.emit('paste', e, $this)
|
||||
}
|
||||
|
||||
// ============== WATCHERS ==============
|
||||
|
||||
watch(search, (val) => {
|
||||
if (!isOpen.value && val) {
|
||||
open()
|
||||
}
|
||||
|
||||
context.emit('search-change', val, $this)
|
||||
})
|
||||
|
||||
return {
|
||||
search,
|
||||
clearSearch,
|
||||
handleSearchInput,
|
||||
handleKeypress,
|
||||
handlePaste,
|
||||
}
|
||||
}
|
||||
37
client/node_modules/@vueform/multiselect/src/composables/useValue.js
generated
vendored
Normal file
37
client/node_modules/@vueform/multiselect/src/composables/useValue.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
import { computed, toRefs, ref } from 'vue'
|
||||
import toRef from '../utils/toRef'
|
||||
|
||||
export default function useValue (props, context)
|
||||
{
|
||||
const { value, modelValue, mode, valueProp } = toRefs(props)
|
||||
|
||||
// ================ DATA ================
|
||||
|
||||
// internalValue
|
||||
const iv = ref(mode.value !== 'single' ? [] : {})
|
||||
|
||||
// ============== COMPUTED ==============
|
||||
|
||||
/* istanbul ignore next */
|
||||
// externalValue
|
||||
const ev = toRef(() => {
|
||||
return modelValue.value !== undefined ? modelValue.value : value.value
|
||||
})
|
||||
|
||||
const plainValue = computed(() => {
|
||||
return mode.value === 'single' ? iv.value[valueProp.value] : iv.value.map(v=>v[valueProp.value])
|
||||
})
|
||||
|
||||
const textValue = toRef(() => {
|
||||
return mode.value !== 'single' ? iv.value.map(v=>v[valueProp.value]).join(',') : iv.value[valueProp.value]
|
||||
})
|
||||
|
||||
return {
|
||||
iv,
|
||||
internalValue: iv,
|
||||
ev,
|
||||
externalValue: ev,
|
||||
textValue,
|
||||
plainValue,
|
||||
}
|
||||
}
|
||||
1
client/node_modules/@vueform/multiselect/src/index.d.ts
generated
vendored
Normal file
1
client/node_modules/@vueform/multiselect/src/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from './Multiselect';
|
||||
11
client/node_modules/@vueform/multiselect/src/utils/arraysEqual.js
generated
vendored
Normal file
11
client/node_modules/@vueform/multiselect/src/utils/arraysEqual.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export default function arraysEqual (array1, array2) {
|
||||
if (array1.length !== array2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const array2Sorted = array2.slice().sort()
|
||||
|
||||
return array1.slice().sort().every(function(value, index) {
|
||||
return value === array2Sorted[index];
|
||||
})
|
||||
}
|
||||
3
client/node_modules/@vueform/multiselect/src/utils/isNullish.js
generated
vendored
Normal file
3
client/node_modules/@vueform/multiselect/src/utils/isNullish.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function isNullish (val) {
|
||||
return val === null || val === undefined
|
||||
}
|
||||
3
client/node_modules/@vueform/multiselect/src/utils/isObject.js
generated
vendored
Normal file
3
client/node_modules/@vueform/multiselect/src/utils/isObject.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function isObject (variable) {
|
||||
return Object.prototype.toString.call(variable) === '[object Object]'
|
||||
}
|
||||
11
client/node_modules/@vueform/multiselect/src/utils/normalize.js
generated
vendored
Normal file
11
client/node_modules/@vueform/multiselect/src/utils/normalize.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export default function normalize (str, strict = true) {
|
||||
return strict
|
||||
? String(str).toLowerCase().trim()
|
||||
: String(str).toLowerCase()
|
||||
.normalize('NFD')
|
||||
.trim()
|
||||
.replace(/æ/g, 'ae')
|
||||
.replace(/œ/g, 'oe')
|
||||
.replace(/ø/g, 'o')
|
||||
.replace(/\p{Diacritic}/gu, '')
|
||||
}
|
||||
38
client/node_modules/@vueform/multiselect/src/utils/objectsEqual.js
generated
vendored
Normal file
38
client/node_modules/@vueform/multiselect/src/utils/objectsEqual.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/* istanbul ignore next */
|
||||
const objectsEqual = (obj1, obj2) => {
|
||||
// If both are strictly equal, return true
|
||||
if (obj1 === obj2) {
|
||||
return true
|
||||
}
|
||||
|
||||
// If either is not an object or is null, return false (handles primitive types and null)
|
||||
if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Get the keys of both objects
|
||||
const keys1 = Object.keys(obj1)
|
||||
const keys2 = Object.keys(obj2)
|
||||
|
||||
// If they have a different number of keys, they're not equal
|
||||
if (keys1.length !== keys2.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Compare each key-value pair recursively
|
||||
for (let key of keys1) {
|
||||
// Check if both objects have the same key
|
||||
if (!keys2.includes(key)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Recursively compare the values
|
||||
if (!objectsEqual(obj1[key], obj2[key])) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export default objectsEqual
|
||||
10
client/node_modules/@vueform/multiselect/src/utils/resolveDeps.js
generated
vendored
Normal file
10
client/node_modules/@vueform/multiselect/src/utils/resolveDeps.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
export default function (props, context, features, deps = {}) {
|
||||
features.forEach((composable) => {
|
||||
deps = {
|
||||
...deps,
|
||||
...composable(props, context, deps)
|
||||
}
|
||||
})
|
||||
|
||||
return deps
|
||||
}
|
||||
7
client/node_modules/@vueform/multiselect/src/utils/toRef.js
generated
vendored
Normal file
7
client/node_modules/@vueform/multiselect/src/utils/toRef.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { customRef } from 'vue'
|
||||
|
||||
// Polyfill for Vue <3.3 for getters only
|
||||
// https://vuejs.org/api/reactivity-utilities.html#toref
|
||||
export default function toRef (get) {
|
||||
return customRef(() => ({ get, set: /* istanbul ignore next */ () => { } }))
|
||||
}
|
||||
1
client/node_modules/@vueform/multiselect/themes/default.css
generated
vendored
Normal file
1
client/node_modules/@vueform/multiselect/themes/default.css
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
525
client/node_modules/@vueform/multiselect/themes/default.scss
generated
vendored
Normal file
525
client/node_modules/@vueform/multiselect/themes/default.scss
generated
vendored
Normal file
@@ -0,0 +1,525 @@
|
||||
.multiselect {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
border: var(--ms-border-width, 1px) solid var(--ms-border-color, #D1D5DB);
|
||||
border-radius: var(--ms-radius, 4px);
|
||||
background: var(--ms-bg, #FFFFFF);
|
||||
font-size: var(--ms-font-size, 1rem);
|
||||
min-height: calc(2 * var(--ms-border-width, 1px) + var(--ms-font-size, 1rem) * var(--ms-line-height, 1.375) + 2 * var(--ms-py, 0.5rem));
|
||||
|
||||
&.is-open {
|
||||
border-radius: var(--ms-radius, 4px) var(--ms-radius, 4px) 0 0;
|
||||
}
|
||||
|
||||
&.is-open-top {
|
||||
border-radius: 0 0 var(--ms-radius, 4px) var(--ms-radius, 4px);
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
cursor: default;
|
||||
background: var(--ms-bg-disabled, #F3F4F6);
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
border: var(--ms-border-width-active, var(--ms-border-width, 1px)) solid var(--ms-border-color-active, var(--ms-border-color, #D1D5DB));
|
||||
box-shadow: 0 0 0 var(--ms-ring-width, 3px) var(--ms-ring-color, #10B98130);
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-wrapper {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
min-height: calc(2 * var(--ms-border-width, 1px) + var(--ms-font-size, 1rem) * var(--ms-line-height, 1.375) + 2 * var(--ms-py, 0.5rem));
|
||||
}
|
||||
|
||||
.multiselect-multiple-label,
|
||||
.multiselect-single-label,
|
||||
.multiselect-placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
pointer-events: none;
|
||||
background: transparent;
|
||||
line-height: var(--ms-line-height, 1.375);
|
||||
padding-left: var(--ms-px, 0.875rem);
|
||||
padding-right: calc(1.25rem + var(--ms-px, 0.875rem) * 3);
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.multiselect-placeholder {
|
||||
color: var(--ms-placeholder-color, #9CA3AF);
|
||||
}
|
||||
|
||||
.multiselect-single-label-text {
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.multiselect-search {
|
||||
width: 100%;
|
||||
height: 100%; // for FF
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
background: var(--ms-bg, #FFFFFF);
|
||||
border-radius: var(--ms-radius, 4px);
|
||||
padding-left: var(--ms-px, 0.875rem);
|
||||
|
||||
&::-webkit-search-decoration,
|
||||
&::-webkit-search-cancel-button,
|
||||
&::-webkit-search-results-button,
|
||||
&::-webkit-search-results-decoration {
|
||||
-webkit-appearance:none;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-tags {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: var(--ms-tag-my, 0.25rem) 0 0;
|
||||
padding-left: var(--ms-py, 0.5rem);
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.multiselect-tag {
|
||||
background: var(--ms-tag-bg, #10B981);
|
||||
color: var(--ms-tag-color, #FFFFFF);
|
||||
font-size: var(--ms-tag-font-size, 0.875rem);
|
||||
line-height: var(--ms-tag-line-height, 1.25rem);
|
||||
font-weight: var(--ms-tag-font-weight, 600);
|
||||
padding: var(--ms-tag-py, 0.125rem) 0 var(--ms-tag-py, 0.125rem) var(--ms-tag-px, 0.5rem);
|
||||
border-radius: var(--ms-tag-radius, 4px);
|
||||
margin-right: var(--ms-tag-mx, 0.25rem);
|
||||
margin-bottom: var(--ms-tag-my, 0.25rem);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
min-width: 0;
|
||||
|
||||
&.is-disabled {
|
||||
padding-right: var(--ms-tag-px, 0.5rem);
|
||||
background: var(--ms-tag-bg-disabled, #9CA3AF);
|
||||
color: var(--ms-tag-color-disabled, #FFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-tag-wrapper {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.multiselect-tag-wrapper-break {
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.multiselect-tag-remove {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--ms-tag-remove-py, 0.25rem) var(--ms-tag-remove-px, 0.25rem);
|
||||
margin: var(--ms-tag-remove-my, 0rem) var(--ms-tag-remove-mx, 0.125rem);
|
||||
border-radius: var(--ms-tag-remove-radius, 4px);
|
||||
|
||||
&:hover {
|
||||
background: #00000010;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-tag-remove-icon {
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 320 512' fill='currentColor' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z'%3E%3C/path%3E%3C/svg%3E");
|
||||
mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 320 512' fill='currentColor' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z'%3E%3C/path%3E%3C/svg%3E");
|
||||
-webkit-mask-position: center;
|
||||
mask-position: center;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-size: contain;
|
||||
mask-size: contain;
|
||||
background-color: currentColor;
|
||||
opacity: 0.8;
|
||||
display: inline-block;
|
||||
width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
}
|
||||
|
||||
.multiselect-tags-search-wrapper {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin: 0 var(--ms-tag-mx, 4px) var(--ms-tag-my, 4px);
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.multiselect-tags-search-copy {
|
||||
visibility: hidden;
|
||||
white-space: pre-wrap;
|
||||
display: inline-block;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.multiselect-tags-search {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
appearance: none;
|
||||
|
||||
&::-webkit-search-decoration,
|
||||
&::-webkit-search-cancel-button,
|
||||
&::-webkit-search-results-button,
|
||||
&::-webkit-search-results-decoration {
|
||||
-webkit-appearance:none;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-inifite {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: calc(2 * var(--ms-border-width, 1px) + var(--ms-font-size, 1rem) * var(--ms-line-height, 1.375) + 2 * var(--ms-py, 0.5rem));
|
||||
}
|
||||
|
||||
.multiselect-spinner,
|
||||
.multiselect-inifite-spinner {
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 512 512' fill='currentColor' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z'%3E%3C/path%3E%3C/svg%3E");
|
||||
mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 512 512' fill='currentColor' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z'%3E%3C/path%3E%3C/svg%3E");
|
||||
-webkit-mask-position: center;
|
||||
mask-position: center;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-size: contain;
|
||||
mask-size: contain;
|
||||
background-color: var(--ms-spinner-color, #10B981);
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
z-index: 10;
|
||||
animation: multiselect-spin 1s linear infinite;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.multiselect-spinner {
|
||||
margin: 0 var(--ms-px, 0.875rem) 0 0;
|
||||
}
|
||||
|
||||
.multiselect-clear {
|
||||
padding: 0 var(--ms-px, 0.875rem) 0 0px;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
opacity: 1;
|
||||
transition: .3s;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
display: flex;
|
||||
|
||||
&:hover .multiselect-clear-icon {
|
||||
background-color: var(--ms-clear-color-hover, #000000);
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-clear-icon {
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 320 512' fill='currentColor' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z'%3E%3C/path%3E%3C/svg%3E");
|
||||
mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 320 512' fill='currentColor' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z'%3E%3C/path%3E%3C/svg%3E");
|
||||
-webkit-mask-position: center;
|
||||
mask-position: center;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-size: contain;
|
||||
mask-size: contain;
|
||||
background-color: var(--ms-clear-color, #999999);
|
||||
width: 0.625rem;
|
||||
height: 1.125rem;
|
||||
display: inline-block;
|
||||
transition: .3s;
|
||||
}
|
||||
|
||||
.multiselect-caret {
|
||||
transform: rotate(0deg);
|
||||
transition: .3s transform;
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 320 512' fill='currentColor' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z'%3E%3C/path%3E%3C/svg%3E");
|
||||
mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 320 512' fill='currentColor' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z'%3E%3C/path%3E%3C/svg%3E");
|
||||
-webkit-mask-position: center;
|
||||
mask-position: center;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-size: contain;
|
||||
mask-size: contain;
|
||||
background-color: var(--ms-caret-color, #999999);
|
||||
width: 0.625rem;
|
||||
height: 1.125rem;
|
||||
margin: 0 var(--ms-px, 0.875rem) 0 0;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
pointer-events: none;
|
||||
|
||||
&.is-open {
|
||||
transform: rotate(180deg);
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-dropdown {
|
||||
position: absolute;
|
||||
left: calc(var(--ms-border-width, 1px) * -1);
|
||||
right: calc(var(--ms-border-width, 1px) * -1);
|
||||
bottom: 0;
|
||||
transform: translateY(100%);
|
||||
border: var(--ms-dropdown-border-width, 1px) solid var(--ms-dropdown-border-color, #D1D5DB);
|
||||
margin-top: calc(var(--ms-border-width, 1px) * -1);
|
||||
overflow-y: scroll;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
z-index: 100;
|
||||
background: var(--ms-dropdown-bg, #FFFFFF);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 0 0 var(--ms-dropdown-radius, 4px) var(--ms-dropdown-radius, 4px);
|
||||
outline: none;
|
||||
max-height: var(--ms-max-height, 10rem);
|
||||
|
||||
&.is-top {
|
||||
transform: translateY(-100%);
|
||||
top: var(--ms-border-width, 1px);
|
||||
bottom: auto;
|
||||
border-radius: var(--ms-dropdown-radius, 4px) var(--ms-dropdown-radius, 4px) 0 0;
|
||||
}
|
||||
|
||||
&.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-options {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.multiselect-group {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.multiselect-group-label {
|
||||
padding: var(--ms-group-label-py, 0.3rem) var(--ms-group-label-px, 0.75rem);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
background: var(--ms-group-label-bg, #E5E7EB);
|
||||
color: var(--ms-group-label-color, #374151);
|
||||
cursor: default;
|
||||
line-height: var(--ms-group-label-line-height, 1.375);
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
text-decoration: none;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
text-align: left;
|
||||
|
||||
&.is-pointable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.is-pointed {
|
||||
background: var(--ms-group-label-bg-pointed, #D1D5DB);
|
||||
color: var(--ms-group-label-color-pointed, #374151);
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
background: var(--ms-group-label-bg-selected, #059669);
|
||||
color: var(--ms-group-label-color-selected, #FFFFFF);
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
background: var(--ms-group-label-bg-disabled, #F3F4F6);
|
||||
color: var(--ms-group-label-color-disabled, #D1D5DB);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.is-selected.is-pointed {
|
||||
background: var(--ms-group-label-bg-selected-pointed, #0c9e70);
|
||||
color: var(--ms-group-label-color-selected-pointed, #FFFFFF);
|
||||
}
|
||||
|
||||
&.is-selected.is-disabled {
|
||||
background: var(--ms-group-label-bg-selected-disabled, #75cfb1);
|
||||
color: var(--ms-group-label-color-selected-disabled, #D1FAE5);
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-group-options {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.multiselect-option {
|
||||
padding: var(--ms-option-py, 0.5rem) var(--ms-option-px, 0.75rem);
|
||||
font-size: var(--ms-option-font-size, 1rem);
|
||||
line-height: var(--ms-option-line-height, 1.375);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
text-decoration: none;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
text-align: left;
|
||||
|
||||
&.is-pointed {
|
||||
background: var(--ms-option-bg-pointed, #F3F4F6);
|
||||
color: var(--ms-option-color-pointed, #1F2937);
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
background: var(--ms-option-bg-selected, #10B981);
|
||||
color: var(--ms-option-color-selected, #FFFFFF);
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
background: var(--ms-option-bg-disabled, #FFFFFF);
|
||||
color: var(--ms-option-color-disabled, #D1D5DB);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.is-selected.is-pointed {
|
||||
background: var(--ms-option-bg-selected-pointed, #26c08e);
|
||||
color: var(--ms-option-color-selected-pointed, #FFFFFF);
|
||||
}
|
||||
|
||||
&.is-selected.is-disabled {
|
||||
background: var(--ms-option-bg-selected-disabled, #87dcc0);
|
||||
color: var(--ms-option-color-selected-disabled, #D1FAE5);
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-no-options,
|
||||
.multiselect-no-results {
|
||||
padding: var(--ms-option-py, 0.5rem) var(--ms-option-px, 0.75rem);
|
||||
color: var(--ms-empty-color, #4B5563);
|
||||
}
|
||||
|
||||
.multiselect-fake-input {
|
||||
background: transparent;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -1px;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
font-size: 0;
|
||||
outline: none;
|
||||
|
||||
&:active, &:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-assistive-text {
|
||||
position: absolute;
|
||||
margin: -1px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
}
|
||||
|
||||
.multiselect-spacer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[dir="rtl"] {
|
||||
.multiselect-multiple-label,
|
||||
.multiselect-single-label,
|
||||
.multiselect-placeholder {
|
||||
padding-right: var(--ms-px, 0.875rem);
|
||||
padding-left: calc(1.25rem + var(--ms-px, 0.875rem) * 3);
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.multiselect-search {
|
||||
padding-left: 0;
|
||||
padding-right: var(--ms-px, 0.875rem);
|
||||
}
|
||||
|
||||
.multiselect-tags {
|
||||
padding-left: 0;
|
||||
padding-right: var(--ms-py, 0.5rem);
|
||||
}
|
||||
|
||||
.multiselect-tag {
|
||||
padding: var(--ms-tag-py, 0.125rem) var(--ms-tag-px, 0.5rem) var(--ms-tag-py, 0.125rem) 0;
|
||||
margin-right: 0;
|
||||
margin-left: var(--ms-tag-mx, 0.25rem);
|
||||
|
||||
&.is-disabled {
|
||||
padding-left: var(--ms-tag-px, 0.5rem);
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-spinner,
|
||||
.multiselect-caret {
|
||||
margin: 0 0 0 var(--ms-px, 0.875rem);
|
||||
}
|
||||
|
||||
.multiselect-clear {
|
||||
padding: 0 0 0 var(--ms-px, 0.875rem);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes multiselect-spin {
|
||||
from {
|
||||
transform: rotate(0);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
193
client/node_modules/@vueform/multiselect/themes/tailwind.css
generated
vendored
Normal file
193
client/node_modules/@vueform/multiselect/themes/tailwind.css
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
.multiselect {
|
||||
@apply relative mx-auto w-full flex items-center justify-end box-border cursor-pointer border border-gray-300 rounded bg-white text-base leading-snug outline-none;
|
||||
}
|
||||
.multiselect.is-disabled {
|
||||
@apply cursor-default bg-gray-100;
|
||||
}
|
||||
.multiselect.is-open {
|
||||
@apply rounded-b-none;
|
||||
}
|
||||
.multiselect.is-open-top {
|
||||
@apply rounded-t-none;
|
||||
}
|
||||
.multiselect.is-active {
|
||||
@apply ring ring-green-500 ring-opacity-30;
|
||||
}
|
||||
|
||||
.multiselect-wrapper {
|
||||
@apply relative mx-auto w-full flex items-center justify-end box-border cursor-pointer outline-none;
|
||||
}
|
||||
|
||||
.multiselect-single-label {
|
||||
@apply flex items-center h-full max-w-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 pr-16 box-border rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5;
|
||||
}
|
||||
|
||||
.multiselect-single-label-text {
|
||||
@apply overflow-ellipsis overflow-hidden block whitespace-nowrap max-w-full;
|
||||
}
|
||||
|
||||
.multiselect-multiple-label {
|
||||
@apply flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5;
|
||||
}
|
||||
|
||||
.multiselect-search {
|
||||
@apply w-full absolute inset-0 outline-none focus:ring-0 appearance-none box-border border-0 text-base font-sans bg-white rounded pl-3.5 rtl:pl-0 rtl:pr-3.5;
|
||||
}
|
||||
|
||||
.multiselect-tags {
|
||||
@apply flex-grow flex-shrink flex flex-wrap items-center mt-1 pl-2 min-w-0 rtl:pl-0 rtl:pr-2;
|
||||
}
|
||||
|
||||
.multiselect-tag {
|
||||
@apply bg-green-500 text-white text-sm font-semibold py-0.5 pl-2 rounded mr-1 mb-1 flex items-center whitespace-nowrap min-w-0 rtl:pl-0 rtl:pr-2 rtl:mr-0 rtl:ml-1;
|
||||
}
|
||||
.multiselect-tag.is-disabled {
|
||||
@apply pr-2 opacity-50 rtl:pl-2;
|
||||
}
|
||||
|
||||
.multiselect-tag-wrapper {
|
||||
@apply whitespace-nowrap overflow-hidden overflow-ellipsis;
|
||||
}
|
||||
|
||||
.multiselect-tag-wrapper-break {
|
||||
@apply whitespace-normal break-all;
|
||||
}
|
||||
|
||||
.multiselect-tag-remove {
|
||||
@apply flex items-center justify-center p-1 mx-0.5 rounded-sm hover:bg-black hover:bg-opacity-10;
|
||||
}
|
||||
|
||||
.multiselect-tag-remove-icon {
|
||||
@apply bg-multiselect-remove bg-center bg-no-repeat opacity-30 inline-block w-3 h-3;
|
||||
}
|
||||
|
||||
.multiselect-tag-remove:hover .multiselect-tag-remove-icon {
|
||||
@apply opacity-60;
|
||||
}
|
||||
|
||||
.multiselect-tags-search-wrapper {
|
||||
@apply inline-block relative mx-1 mb-1 flex-grow flex-shrink h-full;
|
||||
}
|
||||
|
||||
.multiselect-tags-search {
|
||||
@apply absolute inset-0 border-0 outline-none focus:ring-0 appearance-none p-0 text-base font-sans box-border w-full;
|
||||
}
|
||||
|
||||
.multiselect-tags-search-copy {
|
||||
@apply invisible whitespace-pre-wrap inline-block h-px;
|
||||
}
|
||||
|
||||
.multiselect-placeholder {
|
||||
@apply flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 text-gray-400 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5;
|
||||
}
|
||||
|
||||
.multiselect-caret {
|
||||
@apply bg-multiselect-caret bg-center bg-no-repeat w-2.5 h-4 py-px box-content mr-3.5 relative z-10 opacity-40 flex-shrink-0 flex-grow-0 transition-transform transform pointer-events-none rtl:mr-0 rtl:ml-3.5;
|
||||
}
|
||||
.multiselect-caret.is-open {
|
||||
@apply rotate-180 pointer-events-auto;
|
||||
}
|
||||
|
||||
.multiselect-clear {
|
||||
@apply pr-3.5 relative z-10 opacity-40 transition duration-300 flex-shrink-0 flex-grow-0 flex hover:opacity-80 rtl:pr-0 rtl:pl-3.5;
|
||||
}
|
||||
|
||||
.multiselect-clear-icon {
|
||||
@apply bg-multiselect-remove bg-center bg-no-repeat w-2.5 h-4 py-px box-content inline-block;
|
||||
}
|
||||
|
||||
.multiselect-spinner {
|
||||
@apply bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 mr-3.5 animate-spin flex-shrink-0 flex-grow-0 rtl:mr-0 rtl:ml-3.5;
|
||||
}
|
||||
|
||||
.multiselect-inifite {
|
||||
@apply flex items-center justify-center w-full;
|
||||
}
|
||||
|
||||
.multiselect-inifite-spinner {
|
||||
@apply bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 animate-spin flex-shrink-0 flex-grow-0 m-3.5;
|
||||
}
|
||||
|
||||
.multiselect-dropdown {
|
||||
@apply max-h-60 absolute -left-px -right-px bottom-0 transform translate-y-full border border-gray-300 -mt-px overflow-y-scroll z-50 bg-white flex flex-col rounded-b;
|
||||
}
|
||||
.multiselect-dropdown.is-top {
|
||||
@apply -translate-y-full top-px bottom-auto rounded-b-none rounded-t;
|
||||
}
|
||||
.multiselect-dropdown.is-hidden {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.multiselect-options {
|
||||
@apply flex flex-col p-0 m-0 list-none;
|
||||
}
|
||||
|
||||
.multiselect-group {
|
||||
@apply p-0 m-0;
|
||||
}
|
||||
|
||||
.multiselect-group-label {
|
||||
@apply flex text-sm box-border items-center justify-start text-left py-1 px-3 font-semibold bg-gray-200 cursor-default leading-normal;
|
||||
}
|
||||
.multiselect-group-label.is-pointable {
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
.multiselect-group-label.is-pointed {
|
||||
@apply bg-gray-300 text-gray-700;
|
||||
}
|
||||
.multiselect-group-label.is-selected {
|
||||
@apply bg-green-600 text-white;
|
||||
}
|
||||
.multiselect-group-label.is-disabled {
|
||||
@apply bg-gray-100 text-gray-300 cursor-not-allowed;
|
||||
}
|
||||
.multiselect-group-label.is-selected.is-pointed {
|
||||
@apply bg-green-600 text-white opacity-90;
|
||||
}
|
||||
.multiselect-group-label.is-selected.is-disabled {
|
||||
@apply text-green-100 bg-green-600 bg-opacity-50 cursor-not-allowed;
|
||||
}
|
||||
|
||||
.multiselect-group-options {
|
||||
@apply p-0 m-0;
|
||||
}
|
||||
|
||||
.multiselect-option {
|
||||
@apply flex items-center justify-start box-border text-left cursor-pointer text-base leading-snug py-2 px-3;
|
||||
}
|
||||
.multiselect-option.is-pointed {
|
||||
@apply text-gray-800 bg-gray-100;
|
||||
}
|
||||
.multiselect-option.is-selected {
|
||||
@apply text-white bg-green-500;
|
||||
}
|
||||
.multiselect-option.is-disabled {
|
||||
@apply text-gray-300 cursor-not-allowed;
|
||||
}
|
||||
.multiselect-option.is-selected.is-pointed {
|
||||
@apply text-white bg-green-500 opacity-90;
|
||||
}
|
||||
.multiselect-option.is-selected.is-disabled {
|
||||
@apply text-green-100 bg-green-500 bg-opacity-50 cursor-not-allowed;
|
||||
}
|
||||
|
||||
.multiselect-no-options {
|
||||
@apply py-2 px-3 text-gray-600 bg-white text-left rtl:text-right;
|
||||
}
|
||||
|
||||
.multiselect-no-results {
|
||||
@apply py-2 px-3 text-gray-600 bg-white text-left rtl:text-right;
|
||||
}
|
||||
|
||||
.multiselect-fake-input {
|
||||
@apply bg-transparent absolute left-0 right-0 -bottom-px w-full h-px border-0 p-0 appearance-none outline-none text-transparent;
|
||||
}
|
||||
|
||||
.multiselect-assistive-text {
|
||||
@apply absolute -m-px w-px h-px overflow-hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
}
|
||||
|
||||
.multiselect-spacer {
|
||||
@apply h-9 py-px box-content;
|
||||
}
|
||||
212
client/node_modules/@vueform/multiselect/themes/tailwind.scss
generated
vendored
Normal file
212
client/node_modules/@vueform/multiselect/themes/tailwind.scss
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
.multiselect {
|
||||
@apply relative mx-auto w-full flex items-center justify-end box-border cursor-pointer border border-gray-300 rounded bg-white text-base leading-snug outline-none;
|
||||
|
||||
&.is-disabled {
|
||||
@apply cursor-default bg-gray-100;
|
||||
}
|
||||
|
||||
&.is-open {
|
||||
@apply rounded-b-none;
|
||||
}
|
||||
|
||||
&.is-open-top {
|
||||
@apply rounded-t-none;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
@apply ring ring-green-500 ring-opacity-30;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-wrapper {
|
||||
@apply relative mx-auto w-full flex items-center justify-end box-border cursor-pointer outline-none;
|
||||
}
|
||||
|
||||
.multiselect-single-label {
|
||||
@apply flex items-center h-full max-w-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 pr-16 box-border rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5;
|
||||
}
|
||||
|
||||
.multiselect-single-label-text {
|
||||
@apply overflow-ellipsis overflow-hidden block whitespace-nowrap max-w-full;
|
||||
}
|
||||
|
||||
.multiselect-multiple-label {
|
||||
@apply flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5;
|
||||
}
|
||||
|
||||
.multiselect-search {
|
||||
@apply w-full absolute inset-0 outline-none focus:ring-0 appearance-none box-border border-0 text-base font-sans bg-white rounded pl-3.5 rtl:pl-0 rtl:pr-3.5;
|
||||
}
|
||||
|
||||
.multiselect-tags {
|
||||
@apply flex-grow flex-shrink flex flex-wrap items-center mt-1 pl-2 min-w-0 rtl:pl-0 rtl:pr-2;
|
||||
}
|
||||
|
||||
.multiselect-tag {
|
||||
@apply bg-green-500 text-white text-sm font-semibold py-0.5 pl-2 rounded mr-1 mb-1 flex items-center whitespace-nowrap min-w-0 rtl:pl-0 rtl:pr-2 rtl:mr-0 rtl:ml-1;
|
||||
|
||||
&.is-disabled {
|
||||
@apply pr-2 opacity-50 rtl:pl-2;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-tag-wrapper {
|
||||
@apply whitespace-nowrap overflow-hidden overflow-ellipsis;
|
||||
}
|
||||
|
||||
.multiselect-tag-wrapper-break {
|
||||
@apply whitespace-normal break-all;
|
||||
}
|
||||
|
||||
.multiselect-tag-remove {
|
||||
@apply flex items-center justify-center p-1 mx-0.5 rounded-sm hover:bg-black hover:bg-opacity-10;
|
||||
}
|
||||
|
||||
.multiselect-tag-remove-icon {
|
||||
@apply bg-multiselect-remove bg-center bg-no-repeat opacity-30 inline-block w-3 h-3;
|
||||
}
|
||||
|
||||
.multiselect-tag-remove:hover .multiselect-tag-remove-icon {
|
||||
@apply opacity-60;
|
||||
}
|
||||
|
||||
.multiselect-tags-search-wrapper {
|
||||
@apply inline-block relative mx-1 mb-1 flex-grow flex-shrink h-full;
|
||||
}
|
||||
|
||||
.multiselect-tags-search {
|
||||
@apply absolute inset-0 border-0 outline-none focus:ring-0 appearance-none p-0 text-base font-sans box-border w-full;
|
||||
}
|
||||
|
||||
.multiselect-tags-search-copy {
|
||||
@apply invisible whitespace-pre-wrap inline-block h-px;
|
||||
}
|
||||
|
||||
.multiselect-placeholder {
|
||||
@apply flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 text-gray-400 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5;
|
||||
}
|
||||
|
||||
.multiselect-caret {
|
||||
@apply bg-multiselect-caret bg-center bg-no-repeat w-2.5 h-4 py-px box-content mr-3.5 relative z-10 opacity-40 flex-shrink-0 flex-grow-0 transition-transform transform pointer-events-none rtl:mr-0 rtl:ml-3.5;
|
||||
|
||||
&.is-open {
|
||||
@apply rotate-180 pointer-events-auto;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-clear {
|
||||
@apply pr-3.5 relative z-10 opacity-40 transition duration-300 flex-shrink-0 flex-grow-0 flex hover:opacity-80 rtl:pr-0 rtl:pl-3.5;
|
||||
}
|
||||
|
||||
.multiselect-clear-icon {
|
||||
@apply bg-multiselect-remove bg-center bg-no-repeat w-2.5 h-4 py-px box-content inline-block;
|
||||
}
|
||||
|
||||
.multiselect-spinner {
|
||||
@apply bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 mr-3.5 animate-spin flex-shrink-0 flex-grow-0 rtl:mr-0 rtl:ml-3.5;
|
||||
}
|
||||
|
||||
.multiselect-inifite {
|
||||
@apply flex items-center justify-center w-full;
|
||||
}
|
||||
|
||||
.multiselect-inifite-spinner {
|
||||
@apply bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 animate-spin flex-shrink-0 flex-grow-0 m-3.5;
|
||||
}
|
||||
|
||||
.multiselect-dropdown {
|
||||
@apply max-h-60 absolute -left-px -right-px bottom-0 transform translate-y-full border border-gray-300 -mt-px overflow-y-scroll z-50 bg-white flex flex-col rounded-b;
|
||||
|
||||
&.is-top {
|
||||
@apply -translate-y-full top-px bottom-auto rounded-b-none rounded-t;
|
||||
}
|
||||
|
||||
&.is-hidden {
|
||||
@apply hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-options {
|
||||
@apply flex flex-col p-0 m-0 list-none;
|
||||
}
|
||||
|
||||
.multiselect-group {
|
||||
@apply p-0 m-0;
|
||||
}
|
||||
|
||||
.multiselect-group-label {
|
||||
@apply flex text-sm box-border items-center justify-start text-left py-1 px-3 font-semibold bg-gray-200 cursor-default leading-normal;
|
||||
|
||||
&.is-pointable {
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
&.is-pointed {
|
||||
@apply bg-gray-300 text-gray-700;
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
@apply bg-green-600 text-white;
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
@apply bg-gray-100 text-gray-300 cursor-not-allowed;
|
||||
}
|
||||
|
||||
&.is-selected.is-pointed {
|
||||
@apply bg-green-600 text-white opacity-90;
|
||||
}
|
||||
|
||||
&.is-selected.is-disabled {
|
||||
@apply text-green-100 bg-green-600 bg-opacity-50 cursor-not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-group-options {
|
||||
@apply p-0 m-0;
|
||||
}
|
||||
|
||||
.multiselect-option {
|
||||
@apply flex items-center justify-start box-border text-left cursor-pointer text-base leading-snug py-2 px-3;
|
||||
|
||||
&.is-pointed {
|
||||
@apply text-gray-800 bg-gray-100;
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
@apply text-white bg-green-500;
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
@apply text-gray-300 cursor-not-allowed;
|
||||
}
|
||||
|
||||
&.is-selected.is-pointed {
|
||||
@apply text-white bg-green-500 opacity-90;
|
||||
}
|
||||
|
||||
&.is-selected.is-disabled {
|
||||
@apply text-green-100 bg-green-500 bg-opacity-50 cursor-not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.multiselect-no-options {
|
||||
@apply py-2 px-3 text-gray-600 bg-white text-left rtl:text-right;
|
||||
}
|
||||
|
||||
.multiselect-no-results {
|
||||
@apply py-2 px-3 text-gray-600 bg-white text-left rtl:text-right;
|
||||
}
|
||||
|
||||
.multiselect-fake-input {
|
||||
@apply bg-transparent absolute left-0 right-0 -bottom-px w-full h-px border-0 p-0 appearance-none outline-none text-transparent;
|
||||
}
|
||||
|
||||
.multiselect-assistive-text {
|
||||
@apply absolute -m-px w-px h-px overflow-hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
}
|
||||
|
||||
.multiselect-spacer {
|
||||
@apply h-9 py-px box-content;
|
||||
}
|
||||
Reference in New Issue
Block a user