@k-int/stripes-kint-components 5.30.0 → 5.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/es/index.js +8 -0
- package/es/lib/ButtonTypedown/ButtonTypedown.js +59 -0
- package/es/lib/ButtonTypedown/index.js +13 -0
- package/es/lib/Typedown/Typedown.js +89 -46
- package/es/lib/hooks/typedownHooks/useTypedown.js +148 -85
- package/package.json +1 -1
- package/src/artifacts/coverage-jest/ActionList/ActionList.js.html +1 -1
- package/src/artifacts/coverage-jest/ActionList/ActionListFieldArray.js.html +1 -1
- package/src/artifacts/coverage-jest/ActionList/index.html +1 -1
- package/src/artifacts/coverage-jest/ActionList/index.js.html +1 -1
- package/src/artifacts/coverage-jest/ButtonTypedown/ButtonTypedown.js.html +244 -0
- package/src/artifacts/coverage-jest/ButtonTypedown/index.html +131 -0
- package/src/artifacts/coverage-jest/ButtonTypedown/index.js.html +88 -0
- package/src/artifacts/coverage-jest/ComboButton/ComboButton.js.html +1 -1
- package/src/artifacts/coverage-jest/ComboButton/index.html +1 -1
- package/src/artifacts/coverage-jest/ComboButton/index.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Config/CustomPropertiesLookup.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Config/CustomPropertiesSettings.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Config/CustomPropertyForm.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Config/CustomPropertyView.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Config/index.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Config/index.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Edit/CustomPropertiesEdit.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Edit/CustomPropertiesEditCtx.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Edit/CustomPropertiesListField.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Edit/CustomPropertyField.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Edit/CustomPropertyFormCard.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Edit/index.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Edit/index.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Edit/testResources.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/CustomPropertiesFilter.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/CustomPropertiesFilterField.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/CustomPropertiesFilterFieldArray.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/CustomPropertiesFilterForm.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/CustomPropertiesRule.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/index.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/index.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/testResources.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/useOperators.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/useParseActiveFilterStrings.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/Filter/useValueProps.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/View/CustomPropertiesView.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/View/CustomPropertiesViewCtx.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/View/CustomPropertyCard.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/View/index.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/View/index.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/View/testResources.js.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/index.html +1 -1
- package/src/artifacts/coverage-jest/CustomProperties/index.js.html +1 -1
- package/src/artifacts/coverage-jest/CycleButton/CycleButton.js.html +1 -1
- package/src/artifacts/coverage-jest/CycleButton/index.html +1 -1
- package/src/artifacts/coverage-jest/CycleButton/index.js.html +1 -1
- package/src/artifacts/coverage-jest/FieldLabel/FieldLabel.js.html +1 -1
- package/src/artifacts/coverage-jest/FieldLabel/index.html +1 -1
- package/src/artifacts/coverage-jest/FieldLabel/index.js.html +1 -1
- package/src/artifacts/coverage-jest/FormModal/FormModal.js.html +1 -1
- package/src/artifacts/coverage-jest/FormModal/index.html +1 -1
- package/src/artifacts/coverage-jest/FormModal/index.js.html +1 -1
- package/src/artifacts/coverage-jest/FormattedKintMessage/FormattedKintMessage.js.html +1 -1
- package/src/artifacts/coverage-jest/FormattedKintMessage/index.html +1 -1
- package/src/artifacts/coverage-jest/FormattedKintMessage/index.js.html +1 -1
- package/src/artifacts/coverage-jest/IconSelect/IconSelect.js.html +1 -1
- package/src/artifacts/coverage-jest/IconSelect/index.html +1 -1
- package/src/artifacts/coverage-jest/IconSelect/index.js.html +1 -1
- package/src/artifacts/coverage-jest/NoResultsMessage/NoResultsMessage.js.html +1 -1
- package/src/artifacts/coverage-jest/NoResultsMessage/index.html +1 -1
- package/src/artifacts/coverage-jest/NoResultsMessage/index.js.html +1 -1
- package/src/artifacts/coverage-jest/NumberField/NumberField.js.html +1 -1
- package/src/artifacts/coverage-jest/NumberField/index.html +1 -1
- package/src/artifacts/coverage-jest/NumberField/index.js.html +1 -1
- package/src/artifacts/coverage-jest/QueryTypedown/QueryTypedown.js.html +1 -1
- package/src/artifacts/coverage-jest/QueryTypedown/index.html +1 -1
- package/src/artifacts/coverage-jest/QueryTypedown/index.js.html +1 -1
- package/src/artifacts/coverage-jest/RefdataButtons/RefdataButtons.js.html +1 -1
- package/src/artifacts/coverage-jest/RefdataButtons/index.html +1 -1
- package/src/artifacts/coverage-jest/RefdataButtons/index.js.html +1 -1
- package/src/artifacts/coverage-jest/ResponsiveButtonGroup/ResponsiveButtonGroup.js.html +1 -1
- package/src/artifacts/coverage-jest/ResponsiveButtonGroup/index.html +1 -1
- package/src/artifacts/coverage-jest/ResponsiveButtonGroup/index.js.html +1 -1
- package/src/artifacts/coverage-jest/ResponsiveButtonGroup/useResponsiveButtonGroupSizing.js.html +1 -1
- package/src/artifacts/coverage-jest/RichSelect/RichSelect.js.html +1 -1
- package/src/artifacts/coverage-jest/RichSelect/index.html +1 -1
- package/src/artifacts/coverage-jest/RichSelect/index.js.html +1 -1
- package/src/artifacts/coverage-jest/RichSelect/useSelectedOption.js.html +1 -1
- package/src/artifacts/coverage-jest/SASQLookupComponent/SASQLookupComponent.js.html +1 -1
- package/src/artifacts/coverage-jest/SASQLookupComponent/TableBody/TableBody.js.html +1 -1
- package/src/artifacts/coverage-jest/SASQLookupComponent/TableBody/index.html +1 -1
- package/src/artifacts/coverage-jest/SASQLookupComponent/TableBody/index.js.html +1 -1
- package/src/artifacts/coverage-jest/SASQLookupComponent/index.html +1 -1
- package/src/artifacts/coverage-jest/SASQLookupComponent/index.js.html +1 -1
- package/src/artifacts/coverage-jest/SASQRoute/SASQRoute.js.html +1 -1
- package/src/artifacts/coverage-jest/SASQRoute/index.html +1 -1
- package/src/artifacts/coverage-jest/SASQRoute/index.js.html +1 -1
- package/src/artifacts/coverage-jest/SASQViewComponent/SASQViewComponent.js.html +1 -1
- package/src/artifacts/coverage-jest/SASQViewComponent/index.html +1 -1
- package/src/artifacts/coverage-jest/SASQViewComponent/index.js.html +1 -1
- package/src/artifacts/coverage-jest/SearchField/SearchField.js.html +1 -1
- package/src/artifacts/coverage-jest/SearchField/index.html +1 -1
- package/src/artifacts/coverage-jest/SearchField/index.js.html +1 -1
- package/src/artifacts/coverage-jest/SearchKeyControl/SearchKeyControl.js.html +1 -1
- package/src/artifacts/coverage-jest/SearchKeyControl/index.html +1 -1
- package/src/artifacts/coverage-jest/SearchKeyControl/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableRefdataCategoryList/EditableRefdataCategoryList.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableRefdataCategoryList/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableRefdataCategoryList/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableRefdataList/EditableRefdataList.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableRefdataList/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableRefdataList/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/EditableSettingsList.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/EditableSettingsListFieldArray/EditableSettingsListFieldArray.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/EditableSettingsListFieldArray/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/EditableSettingsListFieldArray/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/SettingField/EditSettingValue/EditSettingValue.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/SettingField/EditSettingValue/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/SettingField/EditSettingValue/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/SettingField/RenderSettingValue/RenderSettingValue.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/SettingField/RenderSettingValue/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/SettingField/RenderSettingValue/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/SettingField/SettingField.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/SettingField/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/SettingField/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/EditableSettingsList/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/RefdataCategoriesSettings/RefdataCategoriesSettings.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/RefdataCategoriesSettings/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/RefdataCategoriesSettings/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/SettingPage/SettingPage.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/SettingPage/SettingPagePane/SettingPagePane.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/SettingPage/SettingPagePane/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/SettingPage/SettingPagePane/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/SettingPage/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/SettingPage/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/SettingsFormContainer/SettingsFormContainer.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/SettingsFormContainer/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/SettingsFormContainer/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/StaticSettingsField/StaticSettingsField.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/StaticSettingsField/StaticSettingsFieldComponent/StaticSettingsFieldComponent.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/StaticSettingsField/StaticSettingsFieldComponent/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/StaticSettingsField/StaticSettingsFieldComponent/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/StaticSettingsField/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/StaticSettingsField/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/constants/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/constants/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/constants/queryKeys.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/contexts/SettingsContext.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/contexts/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/contexts/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/staticSettingsPages/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/staticSettingsPages/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/staticSettingsPages/useSettingCallout/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/staticSettingsPages/useSettingCallout/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/staticSettingsPages/useSettingCallout/useSettingCallout.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/staticSettingsPages/useSettingsSectionInitalValues/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/staticSettingsPages/useSettingsSectionInitalValues/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/staticSettingsPages/useSettingsSectionInitalValues/useSettingsSectionInitalValues.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/staticSettingsPages/useStaticSettingsSection.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/useAppSettings/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/useAppSettings/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/useAppSettings/useAppSettings.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/useSettingSection/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/useSettingSection/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/useSettingSection/useSettingSection.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/useSettings/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/useSettings/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/hooks/useSettings/useSettings.js.html +1 -1
- package/src/artifacts/coverage-jest/Settings/index.html +1 -1
- package/src/artifacts/coverage-jest/Settings/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Tags/Tags.js.html +1 -1
- package/src/artifacts/coverage-jest/Tags/hooks/index.html +1 -1
- package/src/artifacts/coverage-jest/Tags/hooks/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Tags/hooks/useTags.js.html +1 -1
- package/src/artifacts/coverage-jest/Tags/hooks/useTagsEnabled.js.html +1 -1
- package/src/artifacts/coverage-jest/Tags/index.html +1 -1
- package/src/artifacts/coverage-jest/Tags/index.js.html +1 -1
- package/src/artifacts/coverage-jest/Tags/tagsConfig.js.html +1 -1
- package/src/artifacts/coverage-jest/Typedown/Typedown.js.html +230 -62
- package/src/artifacts/coverage-jest/Typedown/index.html +15 -15
- package/src/artifacts/coverage-jest/Typedown/index.js.html +1 -1
- package/src/artifacts/coverage-jest/cobertura-coverage.xml +252 -103
- package/src/artifacts/coverage-jest/constants/comparators.js.html +1 -1
- package/src/artifacts/coverage-jest/constants/customProperties.js.html +1 -1
- package/src/artifacts/coverage-jest/constants/endpoints.js.html +1 -1
- package/src/artifacts/coverage-jest/constants/eventCodes.js.html +1 -1
- package/src/artifacts/coverage-jest/constants/index.html +1 -1
- package/src/artifacts/coverage-jest/constants/pagination.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/useIntlKey/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/useIntlKey/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/useIntlKey/useIntlKey.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/useIntlKeyStore/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/useIntlKeyStore/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/useIntlKeyStore/useIntlKeyStore.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/useKintIntl/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/useKintIntl/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/intlHooks/useKintIntl/useKintIntl.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/typedownHooks/index.html +14 -14
- package/src/artifacts/coverage-jest/hooks/typedownHooks/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/typedownHooks/useTypedown.js.html +318 -105
- package/src/artifacts/coverage-jest/hooks/typedownHooks/useTypedownData.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/typedownHooks/useTypedownToggle.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useActionListRef.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useActiveElement.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useCustomProperties.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useHelperApp.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useInvalidateRefdata/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useInvalidateRefdata/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useInvalidateRefdata/useInvalidateRefdata.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useKiwtFieldArray.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useKiwtSASQuery.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useLocalPageStore.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useLocalStorageState.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useModConfigEntries.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateCustomProperties/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateCustomProperties/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateCustomProperties/useMutateCustomProperties.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateGeneric/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateGeneric/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateGeneric/useMutateGeneric.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateModConfigEntry.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateRefdataCategory/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateRefdataCategory/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateRefdataCategory/useMutateRefdataCategory.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateRefdataValue/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateRefdataValue/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useMutateRefdataValue/useMutateRefdataValue.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/usePrevNextPagination.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useQIndex.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useRefdata.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useSASQQueryMeta.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useStandaloneSASQQueryParameter/index.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useStandaloneSASQQueryParameter/index.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useStandaloneSASQQueryParameter/useStandaloneSASQQueryParameter.js.html +1 -1
- package/src/artifacts/coverage-jest/hooks/useTemplates.js.html +1 -1
- package/src/artifacts/coverage-jest/index.html +40 -25
- package/src/artifacts/coverage-jest/utils/buildUrl.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/filterParsers/deparseKiwtQueryFilters.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/filterParsers/index.html +1 -1
- package/src/artifacts/coverage-jest/utils/filterParsers/index.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/filterParsers/parseKiwtQueryFilters.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/filterParsers/parseKiwtQueryGroups.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/filterParsers/parseKiwtQueryString.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/generateKiwtQuery.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/generateKiwtQueryParams/generateKiwtQueryParams.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/generateKiwtQueryParams/index.html +1 -1
- package/src/artifacts/coverage-jest/utils/generateKiwtQueryParams/index.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/groupCustomPropertiesByCtx.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/highlightString.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/index.html +1 -1
- package/src/artifacts/coverage-jest/utils/index.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/matchString.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/modConfigEntriesQueryKey.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/parseErrorResponse.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/parseModConfigEntry.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/refdataOptions.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/refdataQueryKey/index.html +1 -1
- package/src/artifacts/coverage-jest/utils/refdataQueryKey/index.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/refdataQueryKey/refdataQueryKey.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/selectorSafe.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/sortByLabel.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/toCamelCase.js.html +1 -1
- package/src/artifacts/coverage-jest/utils/typedownQueryKey.js.html +1 -1
- package/src/artifacts/coverage-jest/validators/index.html +1 -1
- package/src/artifacts/coverage-jest/validators/index.js.html +1 -1
- package/src/artifacts/coverage-jest/validators/validators.js.html +1 -1
- package/src/index.js +4 -0
- package/src/lib/ButtonTypedown/ButtonTypedown.js +53 -0
- package/src/lib/ButtonTypedown/README.md +53 -0
- package/src/lib/ButtonTypedown/index.js +1 -0
- package/src/lib/Typedown/README.md +24 -21
- package/src/lib/Typedown/Typedown.js +106 -50
- package/src/lib/hooks/typedownHooks/useTypedown.js +165 -94
- package/styles/TypeDown.css +4 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import classnames from 'classnames';
|
|
4
4
|
|
|
@@ -18,6 +18,7 @@ const Typedown = ({
|
|
|
18
18
|
displayClearItem = true,
|
|
19
19
|
displayValueWhileOpen = true,
|
|
20
20
|
endOfList,
|
|
21
|
+
getDisplayValue, // Can overrule displayValue entirely
|
|
21
22
|
id,
|
|
22
23
|
initialOpenDelay = 800, // Initial opening delay of 800ms (handles any stripes animations)
|
|
23
24
|
input,
|
|
@@ -28,12 +29,15 @@ const Typedown = ({
|
|
|
28
29
|
onChange,
|
|
29
30
|
onType,
|
|
30
31
|
renderFooter = null,
|
|
32
|
+
renderHeader = null,
|
|
31
33
|
renderListItem = null,
|
|
34
|
+
renderTrigger = null,
|
|
32
35
|
required,
|
|
33
36
|
selectedStyles, // A way to pass any styles that need to be applied globally on selection
|
|
34
37
|
uniqueIdentificationPath = 'id'
|
|
35
38
|
}) => {
|
|
36
39
|
const selectedUniqueId = get(input.value, uniqueIdentificationPath);
|
|
40
|
+
const [selectedValue, setSelectedValue] = useState(input.value); // Track what's been selected in state as well
|
|
37
41
|
|
|
38
42
|
// Display data needs to be in line with data options but also able to react to default handleType
|
|
39
43
|
const [displayData, setDisplayData] = useState(dataOptions);
|
|
@@ -47,7 +51,7 @@ const Typedown = ({
|
|
|
47
51
|
}, [dataOptions]);
|
|
48
52
|
|
|
49
53
|
// Setup default handleType
|
|
50
|
-
const handleType = (e) => {
|
|
54
|
+
const handleType = useCallback((e) => {
|
|
51
55
|
const regex = new RegExp(`${e.target.value.toLowerCase()}`);
|
|
52
56
|
if (onType) {
|
|
53
57
|
onType(e);
|
|
@@ -66,20 +70,20 @@ const Typedown = ({
|
|
|
66
70
|
} else {
|
|
67
71
|
setExactMatch(false);
|
|
68
72
|
}
|
|
69
|
-
};
|
|
73
|
+
}, [dataOptions, displayData, filterPath, onType, uniqueIdentificationPath]);
|
|
70
74
|
|
|
71
75
|
// Hook to set up all the essentials
|
|
72
76
|
const {
|
|
73
77
|
refs: {
|
|
74
78
|
listRef,
|
|
75
79
|
triggerRef,
|
|
80
|
+
triggerComponentRef,
|
|
76
81
|
overlayRef,
|
|
77
|
-
footerRef
|
|
82
|
+
footerRef,
|
|
83
|
+
headerRef
|
|
78
84
|
},
|
|
79
85
|
handlers: {
|
|
80
86
|
handleNextFocus,
|
|
81
|
-
listKeyDownHandler,
|
|
82
|
-
searchFieldKeyDownHandler
|
|
83
87
|
},
|
|
84
88
|
variables: {
|
|
85
89
|
open,
|
|
@@ -90,6 +94,7 @@ const Typedown = ({
|
|
|
90
94
|
} = useTypedown(
|
|
91
95
|
input.name,
|
|
92
96
|
{
|
|
97
|
+
dataOptions,
|
|
93
98
|
timeout: initialOpenDelay
|
|
94
99
|
}
|
|
95
100
|
);
|
|
@@ -99,20 +104,53 @@ const Typedown = ({
|
|
|
99
104
|
className={css.listItem}
|
|
100
105
|
>
|
|
101
106
|
{renderListItem ?
|
|
102
|
-
renderListItem(option, currentlyTyped, exactMatch, optionIsSelected) :
|
|
107
|
+
renderListItem(option, currentlyTyped, exactMatch, optionIsSelected, selectedValue) :
|
|
103
108
|
get(option, uniqueIdentificationPath)
|
|
104
109
|
}
|
|
105
110
|
</div>
|
|
106
|
-
), [currentlyTyped, exactMatch, renderListItem, uniqueIdentificationPath]);
|
|
111
|
+
), [currentlyTyped, exactMatch, renderListItem, selectedValue, uniqueIdentificationPath]);
|
|
107
112
|
|
|
108
113
|
const handleChange = useCallback(value => {
|
|
109
114
|
input.onChange(value);
|
|
115
|
+
setSelectedValue(value);
|
|
110
116
|
|
|
111
117
|
if (typeof onChange === 'function') {
|
|
112
118
|
onChange(value);
|
|
113
119
|
}
|
|
114
120
|
}, [input, onChange]);
|
|
115
121
|
|
|
122
|
+
const renderTypedownTrigger = () => {
|
|
123
|
+
const triggerComponentId = `typedown-trigger-${selectorSafe(input.name)}`;
|
|
124
|
+
return (
|
|
125
|
+
<div
|
|
126
|
+
ref={triggerRef}
|
|
127
|
+
id={`typedown-parent-${selectorSafe(input.name)}-trigger`}
|
|
128
|
+
>
|
|
129
|
+
{renderTrigger ?
|
|
130
|
+
renderTrigger({ // Pass all props in that searchfield uses.
|
|
131
|
+
handleType,
|
|
132
|
+
input, // Pass input? Useful when not controlled I guess
|
|
133
|
+
meta,
|
|
134
|
+
selectedValue,
|
|
135
|
+
triggerComponentId,
|
|
136
|
+
triggerComponentRef,
|
|
137
|
+
})
|
|
138
|
+
:
|
|
139
|
+
<SearchField
|
|
140
|
+
ref={triggerComponentRef}
|
|
141
|
+
// Pass meta through so correct styling gets applied to the TextField
|
|
142
|
+
id={triggerComponentId}
|
|
143
|
+
label={label}
|
|
144
|
+
marginBottom0
|
|
145
|
+
meta={meta}
|
|
146
|
+
onChange={handleType}
|
|
147
|
+
required={required}
|
|
148
|
+
/>
|
|
149
|
+
}
|
|
150
|
+
</div>
|
|
151
|
+
);
|
|
152
|
+
};
|
|
153
|
+
|
|
116
154
|
const dropDown = useCallback(() => {
|
|
117
155
|
return (
|
|
118
156
|
<div
|
|
@@ -120,30 +158,53 @@ const Typedown = ({
|
|
|
120
158
|
id={`typedown-parent-${selectorSafe(input.name)}-menu`}
|
|
121
159
|
style={{ '--searchWidth': `${searchWidth}px` }}
|
|
122
160
|
>
|
|
161
|
+
{renderHeader &&
|
|
162
|
+
<div
|
|
163
|
+
ref={headerRef}
|
|
164
|
+
className={css.header}
|
|
165
|
+
id={`typedown-header-${selectorSafe(input.name)}`}
|
|
166
|
+
>
|
|
167
|
+
{/* Adopt a more extensible pattern for renderHeader, renderFooter will eventually follow */}
|
|
168
|
+
{renderHeader({
|
|
169
|
+
currentlyTyped,
|
|
170
|
+
displayData,
|
|
171
|
+
handleType,
|
|
172
|
+
exactMatch
|
|
173
|
+
})}
|
|
174
|
+
</div>
|
|
175
|
+
}
|
|
176
|
+
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
|
|
123
177
|
<div
|
|
124
178
|
ref={listRef}
|
|
125
179
|
className={css.listContainer}
|
|
126
180
|
id="typedown-list"
|
|
181
|
+
/* This is an acceptable exception to the no-static-element-interactions
|
|
182
|
+
* as we are only PREVENTING interactions, namely focus change on scrollbar click
|
|
183
|
+
* Without this, the typedown closes instantly when the scrollbar is clicked or dragged.
|
|
184
|
+
* This does NOT prevent item click, as e.propagation is not prevented.
|
|
185
|
+
*/
|
|
186
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
127
187
|
>
|
|
128
188
|
{displayData?.length ? displayData?.map((d, index) => {
|
|
129
189
|
const isSelectedEval = isSelected ? isSelected(input.value, d) : get(input.value, uniqueIdentificationPath) === get(d, uniqueIdentificationPath);
|
|
130
190
|
|
|
131
191
|
const selectedCSS = selectedStyles ?? css.selectedMenuButton;
|
|
192
|
+
|
|
193
|
+
const uniqueButtonKey = `typedown-button-[${get(d, uniqueIdentificationPath)}]`;
|
|
132
194
|
return (
|
|
133
195
|
<button
|
|
134
|
-
key={
|
|
196
|
+
key={uniqueButtonKey}
|
|
135
197
|
className={classnames(
|
|
136
198
|
css.fullWidth,
|
|
137
199
|
css.menuButton,
|
|
138
200
|
{ [`${selectedCSS}`]: isSelectedEval },
|
|
139
201
|
)}
|
|
140
202
|
data-selected={isSelectedEval}
|
|
141
|
-
id={
|
|
203
|
+
id={uniqueButtonKey}
|
|
142
204
|
onClick={() => {
|
|
143
205
|
handleChange(d);
|
|
144
206
|
handleNextFocus();
|
|
145
207
|
}}
|
|
146
|
-
onKeyDown={listKeyDownHandler}
|
|
147
208
|
type="button"
|
|
148
209
|
>
|
|
149
210
|
{renderItem(d, isSelectedEval)}
|
|
@@ -172,41 +233,52 @@ const Typedown = ({
|
|
|
172
233
|
footerRef,
|
|
173
234
|
handleChange,
|
|
174
235
|
handleNextFocus,
|
|
236
|
+
handleType,
|
|
237
|
+
headerRef,
|
|
175
238
|
input.name,
|
|
176
239
|
input.value,
|
|
177
240
|
isSelected,
|
|
178
|
-
listKeyDownHandler,
|
|
179
241
|
listRef,
|
|
180
242
|
renderFooter,
|
|
243
|
+
renderHeader,
|
|
181
244
|
renderItem,
|
|
182
245
|
searchWidth,
|
|
183
246
|
selectedStyles,
|
|
184
247
|
uniqueIdentificationPath
|
|
185
248
|
]);
|
|
186
249
|
|
|
187
|
-
const
|
|
188
|
-
|
|
250
|
+
const renderSelectedItem = useCallback(() => (
|
|
251
|
+
<div
|
|
252
|
+
className={classnames(
|
|
253
|
+
css.selectedDisplay
|
|
254
|
+
)}
|
|
255
|
+
>
|
|
189
256
|
<div
|
|
190
|
-
|
|
191
|
-
id={`typedown-parent-${selectorSafe(input.name)}-searchField`}
|
|
257
|
+
className={css.selectedItem}
|
|
192
258
|
>
|
|
193
|
-
|
|
194
|
-
// Pass meta through so correct styling gets applied to the TextField
|
|
195
|
-
id={`typedown-searchField-${selectorSafe(input.name)}`}
|
|
196
|
-
label={label}
|
|
197
|
-
marginBottom0
|
|
198
|
-
meta={meta}
|
|
199
|
-
onChange={handleType}
|
|
200
|
-
onKeyDown={searchFieldKeyDownHandler}
|
|
201
|
-
required={required}
|
|
202
|
-
/>
|
|
259
|
+
{renderItem(input.value)}
|
|
203
260
|
</div>
|
|
204
|
-
|
|
205
|
-
|
|
261
|
+
{displayClearItem &&
|
|
262
|
+
<IconButton
|
|
263
|
+
className={css.clearItem}
|
|
264
|
+
icon="times-circle-solid"
|
|
265
|
+
onClick={() => handleChange()}
|
|
266
|
+
/>
|
|
267
|
+
}
|
|
268
|
+
</div>
|
|
269
|
+
), [displayClearItem, handleChange, input.value, renderItem]);
|
|
206
270
|
|
|
207
271
|
const displayValue = useMemo(() => {
|
|
272
|
+
// Allow full control over whether to display the value
|
|
273
|
+
if (getDisplayValue) {
|
|
274
|
+
return getDisplayValue({
|
|
275
|
+
selectedUniqueId,
|
|
276
|
+
open
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
208
280
|
return !!selectedUniqueId && (!open || displayValueWhileOpen);
|
|
209
|
-
}, [displayValueWhileOpen, open, selectedUniqueId]);
|
|
281
|
+
}, [displayValueWhileOpen, getDisplayValue, open, selectedUniqueId]);
|
|
210
282
|
|
|
211
283
|
return (
|
|
212
284
|
<div
|
|
@@ -217,7 +289,7 @@ const Typedown = ({
|
|
|
217
289
|
)}
|
|
218
290
|
id={`typedown-id-${id}`}
|
|
219
291
|
>
|
|
220
|
-
{
|
|
292
|
+
{renderTypedownTrigger()}
|
|
221
293
|
<Popper
|
|
222
294
|
key="typedown-menu-toggle"
|
|
223
295
|
anchorRef={triggerRef}
|
|
@@ -240,26 +312,7 @@ const Typedown = ({
|
|
|
240
312
|
>
|
|
241
313
|
{dropDown()}
|
|
242
314
|
</Popper>
|
|
243
|
-
{displayValue &&
|
|
244
|
-
<div
|
|
245
|
-
className={classnames(
|
|
246
|
-
css.selectedDisplay
|
|
247
|
-
)}
|
|
248
|
-
>
|
|
249
|
-
<div
|
|
250
|
-
className={css.selectedItem}
|
|
251
|
-
>
|
|
252
|
-
{renderItem(input.value)}
|
|
253
|
-
</div>
|
|
254
|
-
{displayClearItem &&
|
|
255
|
-
<IconButton
|
|
256
|
-
className={css.clearItem}
|
|
257
|
-
icon="times-circle-solid"
|
|
258
|
-
onClick={() => handleChange()}
|
|
259
|
-
/>
|
|
260
|
-
}
|
|
261
|
-
</div>
|
|
262
|
-
}
|
|
315
|
+
{displayValue && renderSelectedItem()}
|
|
263
316
|
</div>
|
|
264
317
|
);
|
|
265
318
|
};
|
|
@@ -275,6 +328,7 @@ Typedown.propTypes = {
|
|
|
275
328
|
PropTypes.element
|
|
276
329
|
]),
|
|
277
330
|
filterPath: PropTypes.string,
|
|
331
|
+
getDisplayValue: PropTypes.func,
|
|
278
332
|
id: PropTypes.string,
|
|
279
333
|
initialOpenDelay: PropTypes.number,
|
|
280
334
|
input: PropTypes.object,
|
|
@@ -286,8 +340,10 @@ Typedown.propTypes = {
|
|
|
286
340
|
meta: PropTypes.object,
|
|
287
341
|
onChange: PropTypes.func,
|
|
288
342
|
onType: PropTypes.func,
|
|
343
|
+
renderHeader: PropTypes.func,
|
|
289
344
|
renderFooter: PropTypes.func,
|
|
290
345
|
renderListItem: PropTypes.func,
|
|
346
|
+
renderTrigger: PropTypes.func,
|
|
291
347
|
required: PropTypes.bool,
|
|
292
348
|
selectedStyles: PropTypes.string,
|
|
293
349
|
uniqueIdentificationPath: PropTypes.string
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from 'react';
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { useResizeDetector } from 'react-resize-detector';
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -14,106 +14,180 @@ import {
|
|
|
14
14
|
UP_ARROW
|
|
15
15
|
} from '../../constants/eventCodes';
|
|
16
16
|
|
|
17
|
-
import selectorSafe from '../../utils/selectorSafe';
|
|
18
|
-
|
|
19
17
|
import useTypedownToggle from './useTypedownToggle';
|
|
20
18
|
|
|
21
19
|
const useTypedown = (
|
|
22
20
|
name,
|
|
23
|
-
{
|
|
21
|
+
{
|
|
22
|
+
dataOptions,
|
|
23
|
+
timeout = 800
|
|
24
|
+
} = {}
|
|
24
25
|
) => {
|
|
25
|
-
//
|
|
26
|
-
const
|
|
26
|
+
// SET UP STATE HOLDING DOM ELEMENTS
|
|
27
|
+
const [list, setList] = useState();
|
|
28
|
+
const [trigger, setTrigger] = useState();
|
|
29
|
+
const [footer, setFooter] = useState();
|
|
30
|
+
const [header, setHeader] = useState();
|
|
27
31
|
|
|
28
32
|
// SET UP REFS
|
|
29
|
-
const listRef = useRef();
|
|
30
33
|
const triggerRef = useRef();
|
|
31
34
|
const overlayRef = useRef();
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (footer && footer.getAttribute('hasListener') !== 'true') {
|
|
38
|
-
footer.addEventListener('keydown', e => {
|
|
39
|
-
// We want special behaviour on tab
|
|
40
|
-
if (e.code === TAB) {
|
|
41
|
-
// Prevent the default behaviour
|
|
42
|
-
e.preventDefault();
|
|
43
|
-
const focusFunc = e.shiftKey ? getPreviousFocusable : getNextFocusable;
|
|
44
|
-
const elem = focusFunc(footerRef.current, true, true, false, true);
|
|
45
|
-
|
|
46
|
-
if (elem) {
|
|
47
|
-
// Focus on next focusable element
|
|
48
|
-
elem.focus();
|
|
49
|
-
} else if (e.shiftKey) {
|
|
50
|
-
// We are at the beginning of the list, refocus on search bar
|
|
51
|
-
searchFieldComponent.focus();
|
|
52
|
-
} else {
|
|
53
|
-
// We are at the end of the list, move onto next focusable element in page
|
|
54
|
-
getNextFocusable(searchFieldComponent, false).focus();
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
footer.setAttribute('hasListener', 'true');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// SET UP HANDLERS
|
|
63
|
-
const searchFieldKeyDownHandler = e => {
|
|
64
|
-
if (e.code === UP_ARROW) {
|
|
65
|
-
const elem = getLastFocusable(listRef.current, true, true);
|
|
66
|
-
if (elem) {
|
|
67
|
-
elem.focus();
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (e.code === DOWN_ARROW) {
|
|
72
|
-
const elem = getFirstFocusable(listRef.current, true, true);
|
|
73
|
-
if (elem) {
|
|
74
|
-
elem.focus();
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Tab key (But not while shifting)
|
|
79
|
-
if (e.code === TAB && !e.shiftKey) {
|
|
80
|
-
e.preventDefault();
|
|
81
|
-
// If we have focusable elements in the footer, then focus on them, else unfocus searchbar
|
|
82
|
-
const elem = getNextFocusable(footerRef.current, true, true, true, true);
|
|
83
|
-
if (elem) {
|
|
84
|
-
elem.focus();
|
|
85
|
-
} else {
|
|
86
|
-
getNextFocusable(searchFieldComponent, false).focus();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const listKeyDownHandler = e => {
|
|
92
|
-
if (e.code === DOWN_ARROW) {
|
|
93
|
-
const elem = getNextFocusable(listRef.current, true, true);
|
|
94
|
-
elem.focus();
|
|
95
|
-
}
|
|
35
|
+
const listRef = useCallback(node => setList(node), []);
|
|
36
|
+
const triggerComponentRef = useCallback(node => setTrigger(node), []);
|
|
37
|
+
const footerRef = useCallback(node => setFooter(node), []);
|
|
38
|
+
const headerRef = useCallback(node => setHeader(node), []);
|
|
96
39
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
elem.focus();
|
|
100
|
-
}
|
|
40
|
+
// OVERLAY PORTAL
|
|
41
|
+
const portal = document.getElementById('OverlayContainer');
|
|
101
42
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
} else {
|
|
110
|
-
elem = searchFieldComponent;
|
|
111
|
-
}
|
|
112
|
-
elem.focus();
|
|
43
|
+
const getPreviousToTrigger = useCallback(() => {
|
|
44
|
+
const prevElem = getPreviousFocusable(trigger, false, false, false);
|
|
45
|
+
if (prevElem.closest('[id^=OverlayContainer]') !== null) {
|
|
46
|
+
// If we find ourselves inside the OverlayContainer when heading backwards from the trigger
|
|
47
|
+
// then we must be the first focusable element on the page.
|
|
48
|
+
// From here we need to skip over the overlay container and head backwards
|
|
49
|
+
return getPreviousFocusable(portal, false, false, false);
|
|
113
50
|
}
|
|
114
|
-
|
|
51
|
+
return prevElem;
|
|
52
|
+
}, [portal, trigger]);
|
|
115
53
|
|
|
116
|
-
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
const cleanups = [];
|
|
56
|
+
|
|
57
|
+
// There appears to be some BIZARRE off-by-one issue with selectors here, that can be fixed by introducing a 1ms delay...
|
|
58
|
+
// I hate it but it is effective
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
// Split these out to shut up the linter
|
|
61
|
+
const rawFirstItemInList = (list ? getFirstFocusable(list) : null);
|
|
62
|
+
const rawLastItemInList = (list ? getLastFocusable(list) : null);
|
|
63
|
+
|
|
64
|
+
// If there are no dataOptions, this can get a bit stuck, so deliberately set to null when no dataOptions are present
|
|
65
|
+
const firstItemInList = dataOptions.length > 0 ? rawFirstItemInList : null;
|
|
66
|
+
const lastItemInList = dataOptions.length > 0 ? rawLastItemInList : null;
|
|
67
|
+
|
|
68
|
+
const configs = [
|
|
69
|
+
// --- HEADER CONFIG ---
|
|
70
|
+
{
|
|
71
|
+
element: header,
|
|
72
|
+
allowTabThroughContents: true,
|
|
73
|
+
previousElement: trigger,
|
|
74
|
+
nextElement: (footer ? getFirstFocusable(footer) : null) ?? getNextFocusable(trigger, false),
|
|
75
|
+
downElement: firstItemInList,
|
|
76
|
+
upElement: lastItemInList,
|
|
77
|
+
},
|
|
78
|
+
// --- FOOTER CONFIG ---
|
|
79
|
+
{
|
|
80
|
+
element: footer,
|
|
81
|
+
allowTabThroughContents: true,
|
|
82
|
+
previousElement: (header ? getLastFocusable(header) : null) ?? trigger,
|
|
83
|
+
nextElement: getNextFocusable(trigger, false),
|
|
84
|
+
downElement: firstItemInList,
|
|
85
|
+
upElement: lastItemInList,
|
|
86
|
+
},
|
|
87
|
+
// --- LIST/CONTAINER CONFIG ---
|
|
88
|
+
{
|
|
89
|
+
element: list,
|
|
90
|
+
allowUpDownThroughContents: true,
|
|
91
|
+
previousElement: (header ? getLastFocusable(header) : null) ?? trigger,
|
|
92
|
+
nextElement: (footer ? getFirstFocusable(footer) : null) ?? getNextFocusable(trigger, false)
|
|
93
|
+
},
|
|
94
|
+
// --- TRIGGER CONFIG ---
|
|
95
|
+
{
|
|
96
|
+
element: trigger,
|
|
97
|
+
nextElement: (header ? getFirstFocusable(header) : null) ?? (footer ? getFirstFocusable(footer) : null) ?? getNextFocusable(trigger, false),
|
|
98
|
+
previousElement: getPreviousToTrigger(),
|
|
99
|
+
downElement: firstItemInList,
|
|
100
|
+
upElement: lastItemInList,
|
|
101
|
+
}
|
|
102
|
+
].filter(c => c.element); // Filter out configs where the element (e.g., header) is null
|
|
103
|
+
|
|
104
|
+
const setupListener = (config) => {
|
|
105
|
+
const {
|
|
106
|
+
element,
|
|
107
|
+
allowTabThroughContents,
|
|
108
|
+
previousElement,
|
|
109
|
+
nextElement,
|
|
110
|
+
allowUpDownThroughContents,
|
|
111
|
+
downElement,
|
|
112
|
+
upElement,
|
|
113
|
+
} = config;
|
|
114
|
+
const handleTab = e => {
|
|
115
|
+
const IS_SHIFT = e.shiftKey;
|
|
116
|
+
const tabIgnoreContents = () => {
|
|
117
|
+
if (IS_SHIFT) {
|
|
118
|
+
return previousElement?.focus();
|
|
119
|
+
}
|
|
120
|
+
return nextElement?.focus();
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
if (!allowTabThroughContents) {
|
|
124
|
+
return tabIgnoreContents();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const focusFunc = IS_SHIFT ? getPreviousFocusable : getNextFocusable;
|
|
128
|
+
const elem = focusFunc(element, true, true, false, true);
|
|
129
|
+
if (elem) {
|
|
130
|
+
return elem.focus();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return tabIgnoreContents();
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const handleUpDown = e => {
|
|
137
|
+
// Prevent the default behaviour
|
|
138
|
+
const IS_UP = e.code === UP_ARROW;
|
|
139
|
+
|
|
140
|
+
const upDownIgnoreContents = () => {
|
|
141
|
+
if (IS_UP) {
|
|
142
|
+
return upElement?.focus();
|
|
143
|
+
}
|
|
144
|
+
return downElement?.focus();
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
if (!allowUpDownThroughContents) {
|
|
148
|
+
return upDownIgnoreContents();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const focusFunc = IS_UP ? getPreviousFocusable : getNextFocusable;
|
|
152
|
+
const elem = focusFunc(element, true, true, true, true); // Allow looping through elements
|
|
153
|
+
if (elem) {
|
|
154
|
+
return elem.focus();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return upDownIgnoreContents();
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const handler = (e) => {
|
|
161
|
+
if (!element.contains(document.activeElement)) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (e.code === TAB) {
|
|
166
|
+
e.preventDefault();
|
|
167
|
+
handleTab(e);
|
|
168
|
+
} else if (e.code === DOWN_ARROW || e.code === UP_ARROW) {
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
handleUpDown(e);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// Add event listener and add the removal of said event listener to the cleanup function
|
|
175
|
+
element.addEventListener('keydown', handler);
|
|
176
|
+
cleanups.push(() => element.removeEventListener('keydown', handler));
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// Set up the event listener for each config entry
|
|
180
|
+
configs.forEach(setupListener);
|
|
181
|
+
}, 0);
|
|
182
|
+
|
|
183
|
+
// Cleanup any event listeners
|
|
184
|
+
return () => {
|
|
185
|
+
cleanups.forEach(cleanup => cleanup());
|
|
186
|
+
};
|
|
187
|
+
// Re-add the listener ANY time any of the elements changes (this is why we're using callback refs)
|
|
188
|
+
}, [dataOptions, header, trigger, footer, list, getPreviousToTrigger]);
|
|
189
|
+
|
|
190
|
+
const handleNextFocus = () => getNextFocusable(trigger, false).focus();
|
|
117
191
|
|
|
118
192
|
// SET UP VARIABLES
|
|
119
193
|
const { open } = useTypedownToggle(name);
|
|
@@ -132,20 +206,17 @@ const useTypedown = (
|
|
|
132
206
|
// RESIZE STUFF
|
|
133
207
|
const { width: searchWidth, ref: resizeRef } = useResizeDetector();
|
|
134
208
|
|
|
135
|
-
// OVERLAY PORTAL
|
|
136
|
-
const portal = document.getElementById('OverlayContainer');
|
|
137
|
-
|
|
138
209
|
return {
|
|
139
210
|
refs: {
|
|
140
211
|
listRef,
|
|
141
212
|
triggerRef,
|
|
213
|
+
triggerComponentRef,
|
|
142
214
|
overlayRef,
|
|
143
|
-
footerRef
|
|
215
|
+
footerRef,
|
|
216
|
+
headerRef
|
|
144
217
|
},
|
|
145
218
|
handlers: {
|
|
146
219
|
handleNextFocus,
|
|
147
|
-
listKeyDownHandler,
|
|
148
|
-
searchFieldKeyDownHandler
|
|
149
220
|
},
|
|
150
221
|
variables: {
|
|
151
222
|
open: useOpen ? open : false,
|
package/styles/TypeDown.css
CHANGED
|
@@ -121,3 +121,7 @@ div[class^="overlay"][x-out-of-boundaries=""] > div[class^="dropdownMenu"] > div
|
|
|
121
121
|
.footer {
|
|
122
122
|
padding: var(--gutter-static-one-third) var(--gutter-static-two-thirds)
|
|
123
123
|
}
|
|
124
|
+
|
|
125
|
+
.header {
|
|
126
|
+
padding: var(--gutter-static-one-third) var(--gutter-static-two-thirds)
|
|
127
|
+
}
|