diff --git a/src/components/Form/fields/FieldBaseAutosuggest.mdx b/src/components/Form/fields/FieldBaseAutosuggest.mdx index fbde357ad..2f74646ed 100644 --- a/src/components/Form/fields/FieldBaseAutosuggest.mdx +++ b/src/components/Form/fields/FieldBaseAutosuggest.mdx @@ -44,5 +44,14 @@ The following autosuggest fields are available to be used. - `FieldControlledVocab` can be used to enter metadata such as keywords and subjects. - `FieldSelectSubmissions` can be used to find and select submissions. +## Customizing options + +The component allows for flexible customization of its options through named slots. This lets you control how suggestions are displayed and interact within the options. See [Custom Options](?path=/story/forms-fieldbaseautosuggest--custom-options) for sample implemenation. + +### Named Slots + +- `input-slot`: Customizes the input area of the combobox. +- `option`: Defines how each suggestion is rendered in the dropdown. + diff --git a/src/components/Form/fields/FieldBaseAutosuggest.stories.js b/src/components/Form/fields/FieldBaseAutosuggest.stories.js index f69830ec8..453ddd119 100644 --- a/src/components/Form/fields/FieldBaseAutosuggest.stories.js +++ b/src/components/Form/fields/FieldBaseAutosuggest.stories.js @@ -1,9 +1,11 @@ import {http, HttpResponse} from 'msw'; import FieldBaseAutosuggest from './FieldBaseAutosuggest.vue'; +import Icon from '@/components/Icon/Icon.vue'; import FieldBaseMock from '../mocks/field-base'; import FieldBaseAutosuggestMock from '../mocks/field-autosuggest'; import UsernamesMock from '@/mocks/usernames.json'; +import InstitutionsMock from '@/mocks/institutions.json'; export default { title: 'Forms/FieldBaseAutosuggest', @@ -97,3 +99,87 @@ export const Inline = { isLabelInline: true, }, }; + +const RORExample = { + extends: FieldBaseAutosuggest, + methods: { + setSuggestions(items) { + // Escape the search phrase for regex + // See: https://stackoverflow.com/a/3561711/1723499 + const regex = new RegExp( + this.inputValue.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'), + 'gi', + ); + + const suggestions = items + .filter((u) => u.fullName.match(regex)) + .filter((u) => !this.currentValue.includes(u.id)) + .map((u) => { + return { + value: u.id, + label: u.fullName, + hasSlot: u.ror, + }; + }); + + this.suggestions = [...suggestions]; + }, + }, +}; + +export const CustomOptions = { + render: (args) => ({ + components: {RORExample, Icon}, + setup() { + function change(name, prop, newValue, localeKey) { + if (localeKey) { + args[prop][localeKey] = newValue; + } else { + args[prop] = newValue; + } + } + + return {args, change}; + }, + template: ` + + + + + `, + }), + args: { + ...FieldBaseMock, + ...FieldBaseAutosuggestMock, + apiUrl: 'https://mock/index.php/publicknowledge/api/v1/users', + label: 'Select Users', + selected: [], + isMultiple: false, + }, + parameters: { + msw: { + handlers: [ + http.get( + 'https://mock/index.php/publicknowledge/api/v1/users', + async (req, res, ctx) => { + return HttpResponse.json(InstitutionsMock); + }, + ), + ], + }, + docs: { + story: { + height: '300px', + }, + }, + }, +}; diff --git a/src/components/Form/fields/FieldBaseAutosuggest.vue b/src/components/Form/fields/FieldBaseAutosuggest.vue index 3e12db31f..1c1483c38 100644 --- a/src/components/Form/fields/FieldBaseAutosuggest.vue +++ b/src/components/Form/fields/FieldBaseAutosuggest.vue @@ -91,6 +91,7 @@ class="pkpAutosuggest__selection" > {{ item.label }} + - - - - -
  • - {{ inputValue }} -
  • -
    - -
  • - {{ suggestion.label }} -
  • -
    -
    -
    + + @@ -176,6 +138,7 @@ diff --git a/src/components/Form/fields/FieldControlledVocab.vue b/src/components/Form/fields/FieldControlledVocab.vue index 6c463b305..b5f2939fc 100644 --- a/src/components/Form/fields/FieldControlledVocab.vue +++ b/src/components/Form/fields/FieldControlledVocab.vue @@ -1,16 +1,19 @@