@scottish-government/designsystem-react 0.10.2 → 0.11.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/@types/components/Accordion.d.ts +3 -2
- package/@types/components/ButtonGroup.d.ts +5 -0
- package/@types/components/PageHeader.d.ts +2 -1
- package/@types/components/RadioButton.d.ts +2 -2
- package/@types/components/SearchFacets.d.ts +18 -0
- package/@types/components/SearchFilters.d.ts +14 -0
- package/@types/components/SearchResult.d.ts +30 -0
- package/@types/components/SearchSort.d.ts +9 -0
- package/@types/components/SideNavigation.d.ts +1 -1
- package/CHANGELOG.md +39 -5
- package/dist/common/AbstractNotificationBanner/AbstractNotificationBanner.d.ts +9 -0
- package/dist/common/AbstractNotificationBanner/AbstractNotificationBanner.jsx +62 -0
- package/dist/common/AbstractNotificationBanner/index.d.ts +1 -0
- package/dist/common/AbstractNotificationBanner/index.js +8 -0
- package/dist/common/ActionLink/ActionLink.d.ts +5 -0
- package/dist/common/ActionLink/ActionLink.jsx +19 -0
- package/dist/common/ActionLink/index.d.ts +1 -0
- package/dist/common/ActionLink/index.js +8 -0
- package/dist/common/ConditionalWrapper/ConditionalWrapper.d.ts +8 -0
- package/dist/common/ConditionalWrapper/ConditionalWrapper.jsx +8 -0
- package/dist/common/ConditionalWrapper/index.d.ts +1 -0
- package/dist/common/ConditionalWrapper/index.js +8 -0
- package/dist/common/FileIcon/FileIcon.d.ts +6 -0
- package/dist/common/FileIcon/FileIcon.jsx +46 -0
- package/dist/common/FileIcon/index.d.ts +1 -0
- package/dist/common/FileIcon/index.js +8 -0
- package/dist/common/HintText/HintText.d.ts +5 -0
- package/dist/common/HintText/HintText.jsx +9 -0
- package/dist/common/HintText/index.d.ts +1 -0
- package/dist/common/HintText/index.js +8 -0
- package/dist/common/Icon/Icon.d.ts +6 -0
- package/dist/common/Icon/Icon.jsx +51 -0
- package/dist/common/Icon/index.d.ts +1 -0
- package/dist/common/Icon/index.js +8 -0
- package/dist/common/ScreenReaderText/ScreenReaderText.d.ts +5 -0
- package/dist/common/ScreenReaderText/ScreenReaderText.jsx +9 -0
- package/dist/common/ScreenReaderText/index.d.ts +1 -0
- package/dist/common/ScreenReaderText/index.js +8 -0
- package/dist/common/WrapperTag/WrapperTag.d.ts +8 -0
- package/dist/common/WrapperTag/WrapperTag.jsx +11 -0
- package/dist/common/WrapperTag/index.d.ts +1 -0
- package/dist/common/WrapperTag/index.js +8 -0
- package/dist/common/index.d.ts +8 -0
- package/dist/common/index.js +22 -0
- package/dist/components/Accordion/Accordion.d.ts +10 -0
- package/dist/components/Accordion/Accordion.jsx +8 -3
- package/dist/components/Accordion/index.d.ts +1 -0
- package/dist/components/Accordion/index.js +8 -0
- package/dist/components/AspectBox/AspectBox.d.ts +6 -0
- package/dist/components/AspectBox/index.d.ts +1 -0
- package/dist/components/AspectBox/index.js +8 -0
- package/dist/components/BackToTop/BackToTop.d.ts +5 -0
- package/dist/components/BackToTop/index.d.ts +1 -0
- package/dist/components/BackToTop/index.js +8 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +9 -0
- package/dist/components/Breadcrumbs/index.d.ts +1 -0
- package/dist/components/Breadcrumbs/index.js +8 -0
- package/dist/components/Button/Button.d.ts +5 -0
- package/dist/components/Button/ButtonGroup.d.ts +5 -0
- package/dist/components/Button/ButtonGroup.jsx +13 -0
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/Button/index.js +10 -0
- package/dist/components/ButtonGroup/ButtonGroup.jsx +13 -0
- package/dist/components/CategoryItem/CategoryItem.d.ts +5 -0
- package/dist/components/CategoryItem/index.d.ts +1 -0
- package/dist/components/CategoryItem/index.js +8 -0
- package/dist/components/CategoryList/CategoryList.d.ts +6 -0
- package/dist/components/CategoryList/index.d.ts +1 -0
- package/dist/components/CategoryList/index.js +8 -0
- package/dist/components/Checkbox/Checkbox.d.ts +5 -0
- package/dist/components/Checkbox/CheckboxGroup.d.ts +6 -0
- package/dist/components/Checkbox/index.d.ts +2 -0
- package/dist/components/Checkbox/index.js +10 -0
- package/dist/components/ConfirmationMessage/ConfirmationMessage.d.ts +5 -0
- package/dist/components/ConfirmationMessage/index.d.ts +1 -0
- package/dist/components/ConfirmationMessage/index.js +8 -0
- package/dist/components/ContentsNav/ContentsNav.d.ts +10 -0
- package/dist/components/ContentsNav/index.d.ts +1 -0
- package/dist/components/ContentsNav/index.js +8 -0
- package/dist/components/CookieBanner/CookieBanner.d.ts +9 -0
- package/dist/components/CookieBanner/index.d.ts +1 -0
- package/dist/components/CookieBanner/index.js +8 -0
- package/dist/components/DatePicker/DatePicker.d.ts +5 -0
- package/dist/components/DatePicker/DatePicker.jsx +2 -2
- package/dist/components/DatePicker/index.d.ts +1 -0
- package/dist/components/DatePicker/index.js +8 -0
- package/dist/components/Details/Details.d.ts +5 -0
- package/dist/components/Details/index.d.ts +1 -0
- package/dist/components/Details/index.js +8 -0
- package/dist/components/ErrorMessage/ErrorMessage.d.ts +5 -0
- package/dist/components/ErrorMessage/index.d.ts +1 -0
- package/dist/components/ErrorMessage/index.js +8 -0
- package/dist/components/ErrorSummary/ErrorSummary.d.ts +9 -0
- package/dist/components/ErrorSummary/index.d.ts +1 -0
- package/dist/components/ErrorSummary/index.js +8 -0
- package/dist/components/FeatureHeader/FeatureHeader.d.ts +13 -0
- package/dist/components/FeatureHeader/FeatureHeader.jsx +70 -0
- package/dist/components/FeatureHeader/index.d.ts +1 -0
- package/dist/components/FeatureHeader/index.js +8 -0
- package/dist/components/FileDownload/FileDownload.d.ts +5 -0
- package/dist/components/FileDownload/index.d.ts +1 -0
- package/dist/components/FileDownload/index.js +8 -0
- package/dist/components/HideThisPage/HideThisPage.d.ts +6 -0
- package/dist/components/HideThisPage/index.d.ts +1 -0
- package/dist/components/HideThisPage/index.js +8 -0
- package/dist/components/InsetText/InsetText.d.ts +5 -0
- package/dist/components/InsetText/index.d.ts +1 -0
- package/dist/components/InsetText/index.js +8 -0
- package/dist/components/NotificationBanner/NotificationBanner.d.ts +9 -0
- package/dist/components/NotificationBanner/index.d.ts +1 -0
- package/dist/components/NotificationBanner/index.js +8 -0
- package/dist/components/NotificationPanel/NotificationPanel.d.ts +5 -0
- package/dist/components/NotificationPanel/index.d.ts +1 -0
- package/dist/components/NotificationPanel/index.js +8 -0
- package/dist/components/PageHeader/PageHeader.d.ts +5 -0
- package/dist/components/PageHeader/PageHeader.jsx +2 -2
- package/dist/components/PageHeader/index.d.ts +1 -0
- package/dist/components/PageHeader/index.js +8 -0
- package/dist/components/PageMetadata/PageMetadata.d.ts +9 -0
- package/dist/components/PageMetadata/index.d.ts +1 -0
- package/dist/components/PageMetadata/index.js +8 -0
- package/dist/components/Pagination/Pagination.d.ts +7 -0
- package/dist/components/Pagination/index.d.ts +1 -0
- package/dist/components/Pagination/index.js +8 -0
- package/dist/components/PhaseBanner/PhaseBanner.d.ts +5 -0
- package/dist/components/PhaseBanner/index.d.ts +1 -0
- package/dist/components/PhaseBanner/index.js +8 -0
- package/dist/components/Question/Question.d.ts +5 -0
- package/dist/components/Question/Question.jsx +1 -1
- package/dist/components/Question/index.d.ts +1 -0
- package/dist/components/Question/index.js +8 -0
- package/dist/components/RadioButton/RadioButton.d.ts +5 -0
- package/dist/components/RadioButton/RadioGroup.d.ts +6 -0
- package/dist/components/RadioButton/RadioGroup.jsx +1 -1
- package/dist/components/RadioButton/index.d.ts +2 -0
- package/dist/components/RadioButton/index.js +10 -0
- package/dist/components/SearchFacets/SearchFacets.d.ts +14 -0
- package/dist/components/SearchFacets/SearchFacets.jsx +101 -0
- package/dist/components/SearchFacets/index.d.ts +1 -0
- package/dist/components/SearchFacets/index.js +8 -0
- package/dist/components/SearchFilters/SearchFilters.d.ts +16 -0
- package/dist/components/SearchFilters/SearchFilters.jsx +63 -0
- package/dist/components/SearchFilters/index.d.ts +1 -0
- package/dist/components/SearchFilters/index.js +8 -0
- package/dist/components/SearchResult/SearchResult.d.ts +28 -0
- package/dist/components/SearchResult/SearchResult.jsx +93 -0
- package/dist/components/SearchResult/index.d.ts +1 -0
- package/dist/components/SearchResult/index.js +8 -0
- package/dist/components/SearchSort/SearchSort.d.ts +10 -0
- package/dist/components/SearchSort/SearchSort.jsx +28 -0
- package/dist/components/SearchSort/index.d.ts +1 -0
- package/dist/components/SearchSort/index.js +8 -0
- package/dist/components/Select/Select.d.ts +5 -0
- package/dist/components/Select/Select.jsx +1 -1
- package/dist/components/Select/index.d.ts +1 -0
- package/dist/components/Select/index.js +8 -0
- package/dist/components/SequentialNavigation/SequentialNavigation.d.ts +13 -0
- package/dist/components/SequentialNavigation/SequentialNavigation.jsx +0 -1
- package/dist/components/SequentialNavigation/index.d.ts +1 -0
- package/dist/components/SequentialNavigation/index.js +8 -0
- package/dist/components/SideNavigation/SideNavigation.d.ts +13 -0
- package/dist/components/SideNavigation/SideNavigation.jsx +2 -2
- package/dist/components/SideNavigation/index.d.ts +1 -0
- package/dist/components/SideNavigation/index.js +8 -0
- package/dist/components/SiteFooter/SiteFooter.d.ts +22 -0
- package/dist/components/SiteFooter/index.d.ts +1 -0
- package/dist/components/SiteFooter/index.js +8 -0
- package/dist/components/SiteHeader/SiteHeader.d.ts +22 -0
- package/dist/components/SiteHeader/SiteHeader.jsx +1 -2
- package/dist/components/SiteHeader/index.d.ts +1 -0
- package/dist/components/SiteHeader/index.js +8 -0
- package/dist/components/SiteNavigation/SiteNavigation.d.ts +9 -0
- package/dist/components/SiteNavigation/index.d.ts +1 -0
- package/dist/components/SiteNavigation/index.js +8 -0
- package/dist/components/SiteSearch/SiteSearch.d.ts +5 -0
- package/dist/components/SiteSearch/SiteSearch.jsx +1 -1
- package/dist/components/SiteSearch/index.d.ts +1 -0
- package/dist/components/SiteSearch/index.js +8 -0
- package/dist/components/SkipLinks/SkipLinks.d.ts +10 -0
- package/dist/components/SkipLinks/SkipLinks.jsx +42 -0
- package/dist/components/SkipLinks/index.d.ts +1 -0
- package/dist/components/SkipLinks/index.js +8 -0
- package/dist/components/SummaryCard/SummaryCard.d.ts +10 -0
- package/dist/components/SummaryCard/index.d.ts +1 -0
- package/dist/components/SummaryCard/index.js +8 -0
- package/dist/components/SummaryList/SummaryList.d.ts +18 -0
- package/dist/components/SummaryList/index.d.ts +1 -0
- package/dist/components/SummaryList/index.js +8 -0
- package/dist/components/Table/Table.d.ts +5 -0
- package/dist/components/Table/index.d.ts +1 -0
- package/dist/components/Table/index.js +8 -0
- package/dist/components/Tabs/Tabs.d.ts +10 -0
- package/dist/components/Tabs/index.d.ts +1 -0
- package/dist/components/Tabs/index.js +8 -0
- package/dist/components/Tag/Tag.d.ts +5 -0
- package/dist/components/Tag/index.d.ts +1 -0
- package/dist/components/Tag/index.js +8 -0
- package/dist/components/TaskList/TaskList.d.ts +13 -0
- package/dist/components/TaskList/TaskList.jsx +1 -1
- package/dist/components/TaskList/index.d.ts +1 -0
- package/dist/components/TaskList/index.js +8 -0
- package/dist/components/TextInput/TextInput.d.ts +5 -0
- package/dist/components/TextInput/TextInput.jsx +2 -2
- package/dist/components/TextInput/index.d.ts +1 -0
- package/dist/components/TextInput/index.js +8 -0
- package/dist/components/Textarea/Textarea.d.ts +5 -0
- package/dist/components/Textarea/Textarea.jsx +1 -1
- package/dist/components/Textarea/index.d.ts +1 -0
- package/dist/components/Textarea/index.js +8 -0
- package/dist/components/WarningText/WarningText.d.ts +5 -0
- package/dist/components/WarningText/index.d.ts +1 -0
- package/dist/components/WarningText/index.js +8 -0
- package/dist/components/index.d.ts +46 -0
- package/dist/components/index.js +101 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/useTracking/index.d.ts +1 -0
- package/dist/hooks/useTracking/index.js +8 -0
- package/dist/hooks/useTracking/useTracking.d.ts +1 -0
- package/dist/hooks/useTracking/useTracking.js +21 -0
- package/dist/images/documents/audio.d.ts +4 -0
- package/dist/images/documents/csv.d.ts +4 -0
- package/dist/images/documents/excel.d.ts +4 -0
- package/dist/images/documents/file.d.ts +4 -0
- package/dist/images/documents/generic.d.ts +4 -0
- package/dist/images/documents/geodata.d.ts +4 -0
- package/dist/images/documents/ical.d.ts +4 -0
- package/dist/images/documents/ico.d.ts +4 -0
- package/dist/images/documents/image.d.ts +4 -0
- package/dist/images/documents/index.d.ts +22 -0
- package/dist/images/documents/odf.d.ts +4 -0
- package/dist/images/documents/odg.d.ts +4 -0
- package/dist/images/documents/odp.d.ts +4 -0
- package/dist/images/documents/ods.d.ts +4 -0
- package/dist/images/documents/odt.d.ts +4 -0
- package/dist/images/documents/pdf.d.ts +4 -0
- package/dist/images/documents/ppt.d.ts +4 -0
- package/dist/images/documents/rtf.d.ts +4 -0
- package/dist/images/documents/text.d.ts +4 -0
- package/dist/images/documents/video.d.ts +4 -0
- package/dist/images/documents/word.d.ts +4 -0
- package/dist/images/documents/xml.d.ts +4 -0
- package/dist/images/documents/zip.d.ts +4 -0
- package/dist/images/icons/arrow_upward.d.ts +4 -0
- package/dist/images/icons/calendar_today.d.ts +4 -0
- package/dist/images/icons/cancel.d.ts +4 -0
- package/dist/images/icons/check_circle.d.ts +4 -0
- package/dist/images/icons/chevron_left.d.ts +4 -0
- package/dist/images/icons/chevron_right.d.ts +4 -0
- package/dist/images/icons/close.d.ts +4 -0
- package/dist/images/icons/description.d.ts +4 -0
- package/dist/images/icons/double_chevron_left.d.ts +4 -0
- package/dist/images/icons/double_chevron_right.d.ts +4 -0
- package/dist/images/icons/error.d.ts +4 -0
- package/dist/images/icons/expand_less.d.ts +4 -0
- package/dist/images/icons/expand_more.d.ts +4 -0
- package/dist/images/icons/index.d.ts +17 -0
- package/dist/images/icons/list.d.ts +4 -0
- package/dist/images/icons/menu.d.ts +4 -0
- package/dist/images/icons/priority_high.d.ts +4 -0
- package/dist/images/icons/search.d.ts +4 -0
- package/dist/images/index.d.ts +2 -0
- package/dist/images/index.js +38 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +40 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/context.d.ts +4 -0
- package/package.json +25 -23
- package/src/common/{AbstractNotificationBanner.test.tsx → AbstractNotificationBanner/AbstractNotificationBanner.test.tsx} +1 -1
- package/src/common/{AbstractNotificationBanner.tsx → AbstractNotificationBanner/AbstractNotificationBanner.tsx} +2 -2
- package/src/common/AbstractNotificationBanner/index.ts +1 -0
- package/src/common/ActionLink/index.ts +1 -0
- package/src/common/ConditionalWrapper/index.ts +1 -0
- package/src/common/{FileIcon.tsx → FileIcon/FileIcon.tsx} +1 -1
- package/src/common/FileIcon/index.ts +1 -0
- package/src/common/HintText/index.ts +1 -0
- package/src/common/{Icon.tsx → Icon/Icon.tsx} +1 -1
- package/src/common/Icon/index.ts +1 -0
- package/src/common/ScreenReaderText/index.ts +1 -0
- package/src/common/WrapperTag/index.ts +1 -0
- package/src/common/index.ts +8 -0
- package/src/components/Accordion/Accordion.Item.stories.tsx +10 -9
- package/src/components/Accordion/Accordion.stories.tsx +4 -4
- package/src/components/Accordion/Accordion.test.tsx +48 -14
- package/src/components/Accordion/Accordion.tsx +12 -1
- package/src/components/Accordion/index.ts +1 -0
- package/src/components/AspectBox/index.ts +1 -0
- package/src/components/BackToTop/index.ts +1 -0
- package/src/components/Breadcrumbs/Breadcrumbs.Item.stories.tsx +8 -1
- package/src/components/Breadcrumbs/index.ts +1 -0
- package/src/components/Button/Button.stories.tsx +1 -1
- package/src/components/Button/ButtonGroup.stories.tsx +41 -0
- package/src/components/Button/ButtonGroup.test.tsx +45 -0
- package/src/components/Button/ButtonGroup.tsx +20 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/CategoryItem/index.ts +1 -0
- package/src/components/CategoryList/CategoryList.stories.tsx +1 -1
- package/src/components/CategoryList/CategoryList.test.tsx +1 -1
- package/src/components/CategoryList/index.ts +1 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/ConfirmationMessage/index.ts +1 -0
- package/src/components/ContentsNav/ContentsNav.Item.stories.tsx +8 -0
- package/src/components/ContentsNav/index.ts +1 -0
- package/src/components/CookieBanner/CookieBanner.Buttons.stories.tsx +1 -1
- package/src/components/CookieBanner/CookieBanner.stories.tsx +1 -1
- package/src/components/CookieBanner/index.ts +1 -0
- package/src/components/DatePicker/DatePicker.tsx +2 -2
- package/src/components/DatePicker/index.ts +1 -0
- package/src/components/Details/index.ts +1 -0
- package/src/components/ErrorMessage/index.ts +1 -0
- package/src/components/ErrorSummary/ErrorSummary.Item.stories.tsx +7 -0
- package/src/components/ErrorSummary/index.ts +1 -0
- package/src/components/FeatureHeader/FeatureHeader.stories.tsx +60 -0
- package/src/components/FeatureHeader/FeatureHeader.tsx +94 -0
- package/src/components/FeatureHeader/index.ts +1 -0
- package/src/components/FileDownload/index.ts +1 -0
- package/src/components/HideThisPage/index.ts +1 -0
- package/src/components/InsetText/index.ts +1 -0
- package/src/components/NotificationBanner/index.ts +1 -0
- package/src/components/NotificationPanel/index.ts +1 -0
- package/src/components/PageHeader/PageHeader.stories.tsx +1 -1
- package/src/components/PageHeader/PageHeader.tsx +2 -1
- package/src/components/PageHeader/index.ts +1 -0
- package/src/components/PageMetadata/PageMetadata.Item.stories.tsx +9 -0
- package/src/components/PageMetadata/index.ts +1 -0
- package/src/components/Pagination/index.ts +1 -0
- package/src/components/PhaseBanner/index.ts +1 -0
- package/src/components/Question/Question.stories.tsx +2 -3
- package/src/components/Question/Question.tsx +2 -2
- package/src/components/Question/index.ts +1 -0
- package/src/components/RadioButton/RadioGroup.stories.tsx +1 -2
- package/src/components/RadioButton/RadioGroup.test.tsx +1 -2
- package/src/components/RadioButton/RadioGroup.tsx +2 -2
- package/src/components/RadioButton/index.ts +2 -0
- package/src/components/SearchFacets/SearchFacets.Group.stories.tsx +56 -0
- package/src/components/SearchFacets/SearchFacets.Item.stories.tsx +53 -0
- package/src/components/SearchFacets/SearchFacets.stories.tsx +38 -0
- package/src/components/SearchFacets/SearchFacets.test.tsx +214 -0
- package/src/components/SearchFacets/SearchFacets.tsx +99 -0
- package/src/components/SearchFacets/index.ts +1 -0
- package/src/components/SearchFilters/SearchFilters.Panel.stories.tsx +201 -0
- package/src/components/SearchFilters/SearchFilters.stories.tsx +137 -0
- package/src/components/SearchFilters/SearchFilters.test.tsx +161 -0
- package/src/components/SearchFilters/SearchFilters.tsx +89 -0
- package/src/components/SearchFilters/index.ts +1 -0
- package/src/components/SearchResult/SearchResult.stories.tsx +111 -0
- package/src/components/SearchResult/SearchResult.test.tsx +215 -0
- package/src/components/SearchResult/SearchResult.tsx +137 -0
- package/src/components/SearchResult/index.ts +1 -0
- package/src/components/SearchSort/SearchSort.stories.tsx +32 -0
- package/src/components/SearchSort/SearchSort.test.tsx +129 -0
- package/src/components/SearchSort/SearchSort.tsx +45 -0
- package/src/components/SearchSort/index.ts +1 -0
- package/src/components/Select/Select.tsx +1 -1
- package/src/components/Select/index.ts +1 -0
- package/src/components/SequentialNavigation/SequentialNavigation.Next.stories.tsx +1 -1
- package/src/components/SequentialNavigation/SequentialNavigation.Previous.stories.tsx +1 -1
- package/src/components/SequentialNavigation/SequentialNavigation.tsx +0 -1
- package/src/components/SequentialNavigation/index.ts +1 -0
- package/src/components/SideNavigation/SideNavigation.Item.stories.tsx +9 -0
- package/src/components/SideNavigation/SideNavigation.List.stories.tsx +7 -0
- package/src/components/SideNavigation/SideNavigation.tsx +2 -1
- package/src/components/SideNavigation/index.ts +1 -0
- package/src/components/SiteFooter/SiteFooter.License.stories.tsx +7 -0
- package/src/components/SiteFooter/SiteFooter.Link.stories.tsx +9 -0
- package/src/components/SiteFooter/SiteFooter.Org.stories.tsx +7 -0
- package/src/components/SiteFooter/index.ts +1 -0
- package/src/components/SiteHeader/SiteHeader.stories.tsx +3 -3
- package/src/components/SiteHeader/SiteHeader.test.tsx +3 -3
- package/src/components/SiteHeader/SiteHeader.tsx +1 -3
- package/src/components/SiteHeader/index.ts +1 -0
- package/src/components/SiteNavigation/SiteNavigation.Item.stories.tsx +10 -0
- package/src/components/SiteNavigation/index.ts +1 -0
- package/src/components/SiteSearch/SiteSearch.tsx +1 -1
- package/src/components/SiteSearch/index.ts +1 -0
- package/src/components/SkipLinks/SkipLinks.Item.stories.tsx +11 -1
- package/src/components/SkipLinks/SkipLinks.tsx +10 -0
- package/src/components/SkipLinks/index.ts +1 -0
- package/src/components/SummaryCard/SummaryCard.Action.stories.tsx +7 -0
- package/src/components/SummaryCard/SummaryCard.stories.tsx +8 -1
- package/src/components/SummaryCard/SummaryCard.test.tsx +2 -2
- package/src/components/SummaryCard/index.ts +1 -0
- package/src/components/SummaryList/SummaryList.Item.stories.tsx +15 -0
- package/src/components/SummaryList/SummaryList.Value.stories.tsx +5 -2
- package/src/components/SummaryList/index.ts +1 -0
- package/src/components/Table/index.ts +1 -0
- package/src/components/Tabs/Tabs.Item.stories.tsx +4 -1
- package/src/components/Tabs/index.ts +1 -0
- package/src/components/Tag/index.ts +1 -0
- package/src/components/TaskList/TaskList.Group.stories.tsx +9 -0
- package/src/components/TaskList/TaskList.Item.stories.tsx +7 -0
- package/src/components/TaskList/TaskList.tsx +1 -1
- package/src/components/TaskList/index.ts +1 -0
- package/src/components/TextInput/TextInput.tsx +2 -2
- package/src/components/TextInput/index.ts +1 -0
- package/src/components/Textarea/Textarea.tsx +1 -1
- package/src/components/Textarea/index.ts +1 -0
- package/src/components/WarningText/index.ts +1 -0
- package/src/components/index.ts +46 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useTracking/index.ts +1 -0
- package/src/images/index.ts +2 -0
- package/src/index.ts +4 -0
- package/tsconfig.json +14 -14
- package/vite.config.ts +2 -1
- /package/src/common/{ActionLink.test.tsx → ActionLink/ActionLink.test.tsx} +0 -0
- /package/src/common/{ActionLink.tsx → ActionLink/ActionLink.tsx} +0 -0
- /package/src/common/{ConditionalWrapper.test.tsx → ConditionalWrapper/ConditionalWrapper.test.tsx} +0 -0
- /package/src/common/{ConditionalWrapper.tsx → ConditionalWrapper/ConditionalWrapper.tsx} +0 -0
- /package/src/common/{FileIcon.test.tsx → FileIcon/FileIcon.test.tsx} +0 -0
- /package/src/common/{HintText.test.tsx → HintText/HintText.test.tsx} +0 -0
- /package/src/common/{HintText.tsx → HintText/HintText.tsx} +0 -0
- /package/src/common/{Icon.test.tsx → Icon/Icon.test.tsx} +0 -0
- /package/src/common/{ScreenReaderText.test.tsx → ScreenReaderText/ScreenReaderText.test.tsx} +0 -0
- /package/src/common/{ScreenReaderText.tsx → ScreenReaderText/ScreenReaderText.tsx} +0 -0
- /package/src/common/{WrapperTag.test.tsx → WrapperTag/WrapperTag.test.tsx} +0 -0
- /package/src/common/{WrapperTag.tsx → WrapperTag/WrapperTag.tsx} +0 -0
- /package/src/hooks/{useTracking.test.tsx → useTracking/useTracking.test.tsx} +0 -0
- /package/src/hooks/{useTracking.ts → useTracking/useTracking.ts} +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import argTypes from '../../../.storybook/sgdsArgTypes';
|
|
3
|
+
|
|
4
|
+
import SearchResult from './SearchResult';
|
|
5
|
+
|
|
6
|
+
//@ts-ignore
|
|
7
|
+
import coo from '../../../static/images/highland-cow.jpg';
|
|
8
|
+
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'Components/Search results/Result',
|
|
11
|
+
component: SearchResult,
|
|
12
|
+
argTypes: {
|
|
13
|
+
children: argTypes.children()
|
|
14
|
+
},
|
|
15
|
+
args: {
|
|
16
|
+
title: 'Application incomplete'
|
|
17
|
+
}
|
|
18
|
+
} satisfies Meta<typeof SearchResult>;
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
type Story = StoryObj<typeof meta>;
|
|
22
|
+
|
|
23
|
+
export const Default: Story = {
|
|
24
|
+
render: (args) => (
|
|
25
|
+
<SearchResult href="#foo" title="Greenhouse gas statistics 1990-2022" {...args}>
|
|
26
|
+
<SearchResult.Content>
|
|
27
|
+
Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
|
|
28
|
+
</SearchResult.Content>
|
|
29
|
+
</SearchResult>
|
|
30
|
+
)
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const Metadata: Story = {
|
|
34
|
+
render: (args) => (
|
|
35
|
+
<SearchResult href="#foo" title="Greenhouse gas statistics 1990-2022" {...args}>
|
|
36
|
+
<SearchResult.Content>
|
|
37
|
+
Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
|
|
38
|
+
</SearchResult.Content>
|
|
39
|
+
<SearchResult.Meta>
|
|
40
|
+
<SearchResult.MetaItem name="Publication type">
|
|
41
|
+
Statistics
|
|
42
|
+
</SearchResult.MetaItem>
|
|
43
|
+
<SearchResult.MetaItem name="Date">
|
|
44
|
+
18 June 2024
|
|
45
|
+
</SearchResult.MetaItem>
|
|
46
|
+
</SearchResult.Meta>
|
|
47
|
+
</SearchResult>
|
|
48
|
+
)
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const Context: Story = {
|
|
52
|
+
render: (args) => (
|
|
53
|
+
<SearchResult href="#foo" title="Greenhouse gas statistics 1990-2022" {...args}>
|
|
54
|
+
<SearchResult.Content>
|
|
55
|
+
Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
|
|
56
|
+
</SearchResult.Content>
|
|
57
|
+
<SearchResult.Context title="Part of">
|
|
58
|
+
<SearchResult.ContextItem><a href="#">Environment statistics</a></SearchResult.ContextItem>
|
|
59
|
+
<SearchResult.ContextItem><a href="#">Energy statistics</a></SearchResult.ContextItem>
|
|
60
|
+
</SearchResult.Context>
|
|
61
|
+
</SearchResult>
|
|
62
|
+
)
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const Media: Story = {
|
|
66
|
+
render: (args) => (
|
|
67
|
+
<SearchResult href="#foo" title="Application incomplete" {...args}>
|
|
68
|
+
<SearchResult.Content>
|
|
69
|
+
<SearchResult.Media>
|
|
70
|
+
<img src={coo} alt="" />
|
|
71
|
+
</SearchResult.Media>
|
|
72
|
+
Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
|
|
73
|
+
</SearchResult.Content>
|
|
74
|
+
</SearchResult>
|
|
75
|
+
)
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const Promoted: Story = {
|
|
79
|
+
render: (args) => (
|
|
80
|
+
<SearchResult isPromoted href="#foo" title="Greenhouse gas statistics 1990-2022" {...args}>
|
|
81
|
+
<SearchResult.Content>
|
|
82
|
+
Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
|
|
83
|
+
</SearchResult.Content>
|
|
84
|
+
</SearchResult>
|
|
85
|
+
)
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const KitchenSink: Story = {
|
|
89
|
+
render: (args) => (
|
|
90
|
+
<SearchResult isPromoted href="#foo" title="Application incomplete" {...args}>
|
|
91
|
+
<SearchResult.Content>
|
|
92
|
+
<SearchResult.Media>
|
|
93
|
+
<img src={coo} alt="" />
|
|
94
|
+
</SearchResult.Media>
|
|
95
|
+
Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
|
|
96
|
+
</SearchResult.Content>
|
|
97
|
+
<SearchResult.Meta>
|
|
98
|
+
<SearchResult.MetaItem name="Publication type">
|
|
99
|
+
Statistics
|
|
100
|
+
</SearchResult.MetaItem>
|
|
101
|
+
<SearchResult.MetaItem name="Date">
|
|
102
|
+
18 June 2024
|
|
103
|
+
</SearchResult.MetaItem>
|
|
104
|
+
</SearchResult.Meta>
|
|
105
|
+
<SearchResult.Context title="Part of">
|
|
106
|
+
<SearchResult.ContextItem><a href="#">Environment statistics</a></SearchResult.ContextItem>
|
|
107
|
+
<SearchResult.ContextItem><a href="#">Energy statistics</a></SearchResult.ContextItem>
|
|
108
|
+
</SearchResult.Context>
|
|
109
|
+
</SearchResult>
|
|
110
|
+
)
|
|
111
|
+
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { test, expect } from 'vitest';
|
|
2
|
+
import { render, screen, within } from '@testing-library/react';
|
|
3
|
+
import SearchResult from './SearchResult';
|
|
4
|
+
|
|
5
|
+
const RESULT_TITLE = 'My title';
|
|
6
|
+
const RESULT_HREF = '#foo';
|
|
7
|
+
const RESULT_CONTENT = 'My content';
|
|
8
|
+
const META_KEY = 'My meta key';
|
|
9
|
+
const META_VALUE = 'My meta value';
|
|
10
|
+
const CONTEXT_VALUE = 'My context value';
|
|
11
|
+
|
|
12
|
+
test('search result renders correctly', () => {
|
|
13
|
+
render(
|
|
14
|
+
<SearchResult href={RESULT_HREF} title={RESULT_TITLE} data-testid="searchresult">
|
|
15
|
+
<SearchResult.Content>
|
|
16
|
+
{RESULT_CONTENT}
|
|
17
|
+
</SearchResult.Content>
|
|
18
|
+
<SearchResult.Meta>
|
|
19
|
+
<SearchResult.MetaItem name={META_KEY}>
|
|
20
|
+
{META_VALUE}
|
|
21
|
+
</SearchResult.MetaItem>
|
|
22
|
+
</SearchResult.Meta>
|
|
23
|
+
<SearchResult.Context>
|
|
24
|
+
<SearchResult.ContextItem>{CONTEXT_VALUE}</SearchResult.ContextItem>
|
|
25
|
+
</SearchResult.Context>
|
|
26
|
+
</SearchResult>
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const searchResult = screen.getByTestId('searchresult');
|
|
30
|
+
expect(searchResult).toHaveClass('ds_search-result');
|
|
31
|
+
expect(searchResult).not.toHaveClass('ds_search-result--promoted');
|
|
32
|
+
|
|
33
|
+
const title = screen.getByRole('heading');
|
|
34
|
+
expect(title).toHaveClass('ds_search-result__title');
|
|
35
|
+
expect(title).toHaveTextContent(RESULT_TITLE);
|
|
36
|
+
expect(title?.parentElement).toEqual(searchResult);
|
|
37
|
+
|
|
38
|
+
const link = within(title).getByRole('link');
|
|
39
|
+
expect(link).toHaveClass('ds_search-result__link');
|
|
40
|
+
expect(link).toHaveAttribute('href', RESULT_HREF);
|
|
41
|
+
expect(link.tagName).toBe('A');
|
|
42
|
+
|
|
43
|
+
const content = screen.getByText(RESULT_CONTENT);
|
|
44
|
+
expect(content).toBeInTheDocument();
|
|
45
|
+
expect(content).toHaveClass('ds_search-result__summary');
|
|
46
|
+
expect(content?.previousElementSibling).toEqual(title);
|
|
47
|
+
|
|
48
|
+
const meta = searchResult.querySelector('.ds_metadata');
|
|
49
|
+
expect(meta).toBeInTheDocument();
|
|
50
|
+
expect(meta).toHaveClass('ds_metadata--inline', 'ds_search-result__metadata');
|
|
51
|
+
expect(meta?.previousElementSibling).toEqual(content);
|
|
52
|
+
expect(meta?.tagName).toBe('DL');
|
|
53
|
+
|
|
54
|
+
const metaItem = meta.querySelector('.ds_metadata__item');
|
|
55
|
+
expect(metaItem).toBeInTheDocument();
|
|
56
|
+
expect(metaItem).toHaveClass('ds_metadata__item');
|
|
57
|
+
expect(metaItem?.parentElement).toEqual(meta);
|
|
58
|
+
|
|
59
|
+
const metaTerm = meta.querySelector('dt');
|
|
60
|
+
expect(metaTerm).toBeInTheDocument();
|
|
61
|
+
expect(metaTerm).toHaveClass('ds_metadata__key');
|
|
62
|
+
expect(metaTerm?.textContent).toBe(META_KEY);
|
|
63
|
+
expect(metaTerm?.parentElement).toEqual(metaItem);
|
|
64
|
+
|
|
65
|
+
const metaDesc = meta.querySelector('dd');
|
|
66
|
+
expect(metaDesc).toBeInTheDocument();
|
|
67
|
+
expect(metaDesc).toHaveClass('ds_metadata__value');
|
|
68
|
+
expect(metaDesc?.textContent.trim()).toBe(META_VALUE);
|
|
69
|
+
expect(metaDesc?.parentElement).toEqual(metaItem);
|
|
70
|
+
expect(metaDesc?.previousElementSibling).toEqual(metaTerm);
|
|
71
|
+
|
|
72
|
+
const context = searchResult.querySelector('.ds_search-result__context');
|
|
73
|
+
expect(context).toBeInTheDocument();
|
|
74
|
+
expect(context).toHaveClass('ds_search-result__context');
|
|
75
|
+
expect(context?.tagName).toBe('DL');
|
|
76
|
+
expect(context?.previousElementSibling).toEqual(meta);
|
|
77
|
+
|
|
78
|
+
const contextTitle = context?.querySelector('dt');
|
|
79
|
+
expect(contextTitle).toBeInTheDocument();
|
|
80
|
+
expect(contextTitle).toHaveClass('ds_search-result__context-key');
|
|
81
|
+
expect(contextTitle?.textContent).toBe('Part of:');
|
|
82
|
+
expect(contextTitle?.parentElement).toEqual(context);
|
|
83
|
+
|
|
84
|
+
const contextValue = context?.querySelector('dd');
|
|
85
|
+
expect(contextValue).toBeInTheDocument();
|
|
86
|
+
expect(contextValue).toHaveClass('ds_search-result__context-value');
|
|
87
|
+
expect(contextValue?.textContent).toBe(CONTEXT_VALUE);
|
|
88
|
+
expect(contextValue?.previousElementSibling).toEqual(contextTitle);
|
|
89
|
+
expect(contextValue?.parentElement).toEqual(context);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('promoted search result renders correctly', () => {
|
|
93
|
+
render(
|
|
94
|
+
<SearchResult isPromoted href="#foo" title={RESULT_TITLE} data-testid="searchresult">
|
|
95
|
+
<SearchResult.Content>
|
|
96
|
+
{RESULT_CONTENT}
|
|
97
|
+
</SearchResult.Content>
|
|
98
|
+
</SearchResult>
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const searchResult = screen.getByTestId('searchresult');
|
|
102
|
+
expect(searchResult).toHaveClass('ds_search-result', 'ds_search-result--promoted');
|
|
103
|
+
|
|
104
|
+
const promotedContent = searchResult.querySelector('.ds_search-result--promoted-content');
|
|
105
|
+
expect(promotedContent).toBeInTheDocument();
|
|
106
|
+
expect(promotedContent?.parentElement).toEqual(searchResult);
|
|
107
|
+
expect(promotedContent?.tagName).toBe('DIV');
|
|
108
|
+
|
|
109
|
+
const promotedTitle = promotedContent?.querySelector('.ds_search-result--promoted-title');
|
|
110
|
+
expect(promotedTitle).toBeInTheDocument();
|
|
111
|
+
expect(promotedTitle?.textContent).toBe('Recommended');
|
|
112
|
+
expect(promotedTitle?.parentElement).toEqual(promotedContent);
|
|
113
|
+
|
|
114
|
+
const title = screen.getByRole('heading');
|
|
115
|
+
expect(title).toHaveClass('ds_search-result__title');
|
|
116
|
+
expect(title).toHaveTextContent(RESULT_TITLE);
|
|
117
|
+
expect(title?.parentElement).toEqual(promotedContent);
|
|
118
|
+
|
|
119
|
+
const content = screen.getByText(RESULT_CONTENT);
|
|
120
|
+
expect(content).toBeInTheDocument();
|
|
121
|
+
expect(content?.previousElementSibling).toEqual(title);
|
|
122
|
+
expect(content?.parentElement).toEqual(promotedContent);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('search result with media renders correctly', () => {
|
|
126
|
+
const IMAGE = <img alt=""/>;
|
|
127
|
+
|
|
128
|
+
render(
|
|
129
|
+
<SearchResult href={RESULT_HREF} title={RESULT_TITLE} data-testid="searchresult">
|
|
130
|
+
<SearchResult.Content>
|
|
131
|
+
<SearchResult.Media>
|
|
132
|
+
{IMAGE}
|
|
133
|
+
</SearchResult.Media>
|
|
134
|
+
{RESULT_CONTENT}
|
|
135
|
+
</SearchResult.Content>
|
|
136
|
+
</SearchResult>
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const searchResult = screen.getByTestId('searchresult');
|
|
140
|
+
const title = screen.getByRole('heading');
|
|
141
|
+
|
|
142
|
+
const summary = searchResult.querySelector('.ds_search-result__has-media');
|
|
143
|
+
expect(summary).toBeInTheDocument();
|
|
144
|
+
expect(summary?.tagName).toBe('DIV');
|
|
145
|
+
expect(summary?.parentElement).toEqual(searchResult);
|
|
146
|
+
expect(summary?.previousElementSibling).toEqual(title);
|
|
147
|
+
|
|
148
|
+
const mediaWrapper = summary?.querySelector('.ds_search-result__media-wrapper');
|
|
149
|
+
expect(mediaWrapper).toBeInTheDocument();
|
|
150
|
+
expect(mediaWrapper?.parentElement).toEqual(summary);
|
|
151
|
+
|
|
152
|
+
const mediaLink = mediaWrapper?.querySelector('.ds_search-result__media-link');
|
|
153
|
+
expect(mediaLink).toBeInTheDocument();
|
|
154
|
+
expect(mediaLink).toHaveAttribute('aria-hidden', 'true');
|
|
155
|
+
expect(mediaLink).toHaveAttribute('href', RESULT_HREF);
|
|
156
|
+
expect(mediaLink).toHaveAttribute('tabindex', '-1');
|
|
157
|
+
expect(mediaLink?.parentElement).toEqual(mediaWrapper);
|
|
158
|
+
expect(mediaLink?.tagName).toBe('A');
|
|
159
|
+
|
|
160
|
+
const media = summary?.querySelector('.ds_search-result__media');
|
|
161
|
+
expect(media).toBeInTheDocument();
|
|
162
|
+
expect(media).toHaveClass('ds_aspect-box', 'ds_aspect-box--square');
|
|
163
|
+
expect(media?.parentElement).toEqual(mediaLink);
|
|
164
|
+
expect(media?.tagName).toBe('DIV');
|
|
165
|
+
|
|
166
|
+
const img = media?.querySelector('img');
|
|
167
|
+
expect(img).toBeInTheDocument();
|
|
168
|
+
expect(img?.parentElement).toEqual(media);
|
|
169
|
+
|
|
170
|
+
const content = screen.getByText(RESULT_CONTENT);
|
|
171
|
+
expect(content).toBeInTheDocument();
|
|
172
|
+
expect(content).toHaveClass('ds_search-result__summary');
|
|
173
|
+
expect(content?.parentElement).toEqual(summary);
|
|
174
|
+
expect(content?.previousElementSibling).toEqual(mediaWrapper);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('linkComponent is used for title link', () => {
|
|
178
|
+
render(
|
|
179
|
+
<SearchResult href={RESULT_HREF} title={RESULT_TITLE} data-testid="searchresult" linkComponent={
|
|
180
|
+
({ className, ...props }) => (
|
|
181
|
+
<span role="link" className={className} {...props}/>
|
|
182
|
+
)}>
|
|
183
|
+
<SearchResult.Content>
|
|
184
|
+
{RESULT_CONTENT}
|
|
185
|
+
</SearchResult.Content>
|
|
186
|
+
</SearchResult>
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const title = screen.getByRole('heading');
|
|
190
|
+
|
|
191
|
+
const link = within(title).getByRole('link');
|
|
192
|
+
expect(link).toHaveClass('ds_search-result__link');
|
|
193
|
+
expect(link).toHaveAttribute('href', RESULT_HREF);
|
|
194
|
+
expect(link.tagName).toBe('SPAN');
|
|
195
|
+
expect(link?.parentElement).toEqual(title);
|
|
196
|
+
expect(link?.previousElementSibling).toBeNull();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('passing additional props', () => {
|
|
200
|
+
render(
|
|
201
|
+
<SearchResult data-test="foo" data-testid="searchresult"/>
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
const searchResult = screen.getByTestId('searchresult');
|
|
205
|
+
expect(searchResult?.dataset.test).toEqual('foo');
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test('passing additional CSS classes', () => {
|
|
209
|
+
render(
|
|
210
|
+
<SearchResult className="foo" data-testid="searchresult"/>
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
const searchResult = screen.getByTestId('searchresult');
|
|
214
|
+
expect(searchResult).toHaveClass('foo');
|
|
215
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Children, createContext, useContext } from 'react';
|
|
2
|
+
import ConditionalWrapper from '../../common/ConditionalWrapper';
|
|
3
|
+
import AspectBox from '../AspectBox';
|
|
4
|
+
import Metadata from '../PageMetadata';
|
|
5
|
+
|
|
6
|
+
const SearchResultLinkHrefContext = createContext('');
|
|
7
|
+
|
|
8
|
+
const SearchResultContent = ({
|
|
9
|
+
children
|
|
10
|
+
}: SGDS.Component.SearchResult.Content) => {
|
|
11
|
+
const otherChildren: any[] = [];
|
|
12
|
+
let imageChild: React.ReactNode = null;
|
|
13
|
+
|
|
14
|
+
// assign to slots
|
|
15
|
+
Children.forEach(children, (child: React.ReactNode) => {
|
|
16
|
+
const thisChild = child as React.ReactElement<any>;
|
|
17
|
+
if (thisChild && thisChild.type === SearchResultMedia) {
|
|
18
|
+
imageChild = thisChild;
|
|
19
|
+
} else {
|
|
20
|
+
otherChildren.push(thisChild);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
imageChild ?
|
|
26
|
+
(<div className="ds_search-result__has-media">
|
|
27
|
+
{imageChild}
|
|
28
|
+
<div className="ds_search-result__summary">{otherChildren}</div>
|
|
29
|
+
</div>)
|
|
30
|
+
:
|
|
31
|
+
(<div className="ds_search-result__summary">
|
|
32
|
+
{otherChildren}
|
|
33
|
+
</div>)
|
|
34
|
+
)
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const SearchResultContext = ({
|
|
38
|
+
children,
|
|
39
|
+
title = 'Part of'
|
|
40
|
+
}: SGDS.Component.SearchResult.Context) => {
|
|
41
|
+
return (
|
|
42
|
+
<dl className="ds_search-result__context">
|
|
43
|
+
<dt className="ds_search-result__context-key">{title}:</dt>
|
|
44
|
+
{children}
|
|
45
|
+
</dl>
|
|
46
|
+
)
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const SearchResultContextItem = ({
|
|
50
|
+
children
|
|
51
|
+
}: SGDS.Component.SearchResult.ContextItem) => {
|
|
52
|
+
return (
|
|
53
|
+
<dd className="ds_search-result__context-value">
|
|
54
|
+
{children}
|
|
55
|
+
</dd>
|
|
56
|
+
)
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const SearchResultMedia = ({
|
|
60
|
+
children
|
|
61
|
+
}: SGDS.Component.SearchResult.Media) => {
|
|
62
|
+
return (
|
|
63
|
+
<div className="ds_search-result__media-wrapper">
|
|
64
|
+
<a className="ds_search-result__media-link" href={useContext(SearchResultLinkHrefContext)} tabIndex={-1} aria-hidden="true">
|
|
65
|
+
<AspectBox className="ds_search-result__media" ratio="1:1">
|
|
66
|
+
{children}
|
|
67
|
+
</AspectBox>
|
|
68
|
+
</a>
|
|
69
|
+
</div>
|
|
70
|
+
)
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const SearchResultMeta = ({
|
|
74
|
+
children
|
|
75
|
+
}: SGDS.Component.SearchResult.Meta) => {
|
|
76
|
+
return (
|
|
77
|
+
<Metadata className="ds_search-result__metadata" isInline>
|
|
78
|
+
{children}
|
|
79
|
+
</Metadata>
|
|
80
|
+
)
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const SearchResult = ({
|
|
84
|
+
children,
|
|
85
|
+
href,
|
|
86
|
+
isPromoted,
|
|
87
|
+
linkComponent,
|
|
88
|
+
promotedTitle = 'Recommended',
|
|
89
|
+
title,
|
|
90
|
+
...props
|
|
91
|
+
}: SGDS.Component.SearchResult) => {
|
|
92
|
+
const LINK_CLASS = 'ds_search-result__link';
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div className={[
|
|
96
|
+
'ds_search-result',
|
|
97
|
+
isPromoted ? 'ds_search-result--promoted' : ''
|
|
98
|
+
].join(' ')}
|
|
99
|
+
{...props}
|
|
100
|
+
>
|
|
101
|
+
<ConditionalWrapper
|
|
102
|
+
condition={!!isPromoted}
|
|
103
|
+
wrapper={(children: React.JSX.Element) => <div className="ds_search-result--promoted-content">
|
|
104
|
+
<header className="ds_search-result--promoted-title">{promotedTitle}</header>
|
|
105
|
+
{children}
|
|
106
|
+
</div>}
|
|
107
|
+
>
|
|
108
|
+
<SearchResultLinkHrefContext value={href}>
|
|
109
|
+
<h3 className="ds_search-result__title">
|
|
110
|
+
{linkComponent ?
|
|
111
|
+
linkComponent({ className: LINK_CLASS, children: title, href }) :
|
|
112
|
+
<a className={LINK_CLASS} href={href}>{title}</a>
|
|
113
|
+
}
|
|
114
|
+
</h3>
|
|
115
|
+
|
|
116
|
+
{children}
|
|
117
|
+
</SearchResultLinkHrefContext>
|
|
118
|
+
</ConditionalWrapper>
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
SearchResult.Content = SearchResultContent;
|
|
124
|
+
SearchResult.Context = SearchResultContext;
|
|
125
|
+
SearchResult.ContextItem = SearchResultContextItem;
|
|
126
|
+
SearchResult.Media = SearchResultMedia;
|
|
127
|
+
SearchResult.Meta = SearchResultMeta;
|
|
128
|
+
SearchResult.MetaItem = Metadata.Item;
|
|
129
|
+
|
|
130
|
+
SearchResultContent.displayName = 'SearchResult.Content';
|
|
131
|
+
SearchResultContext.displayName = 'SearchResult.Context';
|
|
132
|
+
SearchResultContextItem.displayName = 'SearchResult.ContextItem';
|
|
133
|
+
SearchResultMedia.displayName = 'SearchResult.Media';
|
|
134
|
+
SearchResultMeta.displayName = 'SearchResult.Meta';
|
|
135
|
+
SearchResult.MetaItem.displayName = 'SearchResult.MetaItem';
|
|
136
|
+
|
|
137
|
+
export default SearchResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './SearchResult';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import argTypes from '../../../.storybook/sgdsArgTypes';
|
|
3
|
+
|
|
4
|
+
import SearchSort from './SearchSort';
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'Components/Search results/Sort',
|
|
8
|
+
component: SearchSort,
|
|
9
|
+
argTypes: {
|
|
10
|
+
children: argTypes.children(),
|
|
11
|
+
id: argTypes.id(),
|
|
12
|
+
label: argTypes.label({ defaultValue: 'Sort by' }),
|
|
13
|
+
onApply: argTypes.onClick({ description: 'Callback function to be called when the Apply sort button is clicked' }),
|
|
14
|
+
},
|
|
15
|
+
args: {
|
|
16
|
+
id: 'sort-by',
|
|
17
|
+
label: 'Sort by'
|
|
18
|
+
}
|
|
19
|
+
} satisfies Meta<typeof SearchSort>;
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<typeof meta>;
|
|
23
|
+
|
|
24
|
+
export const Default: Story = {
|
|
25
|
+
render: (args) => (
|
|
26
|
+
<SearchSort {...args}>
|
|
27
|
+
<SearchSort.Option value="relevance">Most relevant</SearchSort.Option>
|
|
28
|
+
<SearchSort.Option value="date">Updated (newest)</SearchSort.Option>
|
|
29
|
+
<SearchSort.Option value="adate">Updated (oldest)</SearchSort.Option>
|
|
30
|
+
</SearchSort>
|
|
31
|
+
)
|
|
32
|
+
};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { test, expect, vi } from 'vitest';
|
|
2
|
+
import { render, screen, within } from '@testing-library/react';
|
|
3
|
+
import SearchSort from './SearchSort';
|
|
4
|
+
|
|
5
|
+
const SELECT_ID = 'sort-by';
|
|
6
|
+
const LABEL_TEXT = 'Sort by';
|
|
7
|
+
|
|
8
|
+
test('renders correctly', () => {
|
|
9
|
+
render(
|
|
10
|
+
<SearchSort data-testid="search-sort">
|
|
11
|
+
</SearchSort>
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const searchSort = screen.getByTestId('search-sort');
|
|
15
|
+
const select = screen.getByRole('combobox');
|
|
16
|
+
const selectWrapper = select.parentElement;
|
|
17
|
+
const label = selectWrapper?.previousElementSibling;
|
|
18
|
+
const selectArrow = select.nextElementSibling;
|
|
19
|
+
const button = within(searchSort).getByRole('button');
|
|
20
|
+
|
|
21
|
+
expect(select).toHaveClass('ds_select');
|
|
22
|
+
expect(select.id).toEqual(SELECT_ID);
|
|
23
|
+
expect(select).toHaveAttribute('name', SELECT_ID);
|
|
24
|
+
|
|
25
|
+
expect(selectWrapper).toHaveClass('ds_select-wrapper');
|
|
26
|
+
expect(selectWrapper?.tagName).toEqual('DIV');
|
|
27
|
+
|
|
28
|
+
expect(label).toHaveClass('ds_label');
|
|
29
|
+
expect(label).toHaveAttribute('for', SELECT_ID);
|
|
30
|
+
expect(label).toHaveTextContent(LABEL_TEXT);
|
|
31
|
+
|
|
32
|
+
expect(selectArrow).toHaveClass('ds_select-arrow');
|
|
33
|
+
expect(selectArrow).toHaveAttribute('aria-hidden');
|
|
34
|
+
expect(selectArrow?.textContent).toEqual('');
|
|
35
|
+
|
|
36
|
+
expect(searchSort).toBeInTheDocument();
|
|
37
|
+
expect(searchSort).toHaveClass('ds_sort-options');
|
|
38
|
+
expect(searchSort.tagName).toEqual('DIV');
|
|
39
|
+
|
|
40
|
+
expect(button).toHaveClass('ds_button', 'ds_button--small', 'ds_button--secondary');
|
|
41
|
+
expect(button).toHaveTextContent('Apply sort');
|
|
42
|
+
expect(button).toHaveAttribute('type', 'submit');
|
|
43
|
+
expect(button.previousElementSibling).toEqual(selectWrapper);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('custom id and label', () => {
|
|
47
|
+
const CUSTOM_ID = 'custom-sort-by';
|
|
48
|
+
const CUSTOM_LABEL = 'Custom sort by';
|
|
49
|
+
|
|
50
|
+
render(
|
|
51
|
+
<SearchSort id={CUSTOM_ID} label={CUSTOM_LABEL} data-testid="search-sort">
|
|
52
|
+
</SearchSort>
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const select = screen.getByRole('combobox');
|
|
56
|
+
const selectWrapper = select.parentElement;
|
|
57
|
+
const label = selectWrapper?.previousElementSibling;
|
|
58
|
+
|
|
59
|
+
expect(select.id).toEqual(CUSTOM_ID);
|
|
60
|
+
expect(select).toHaveAttribute('name', CUSTOM_ID);
|
|
61
|
+
expect(label).toHaveAttribute('for', CUSTOM_ID);
|
|
62
|
+
expect(label).toHaveTextContent(CUSTOM_LABEL);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('event handler onApply', async () => {
|
|
66
|
+
const onApply = vi.fn();
|
|
67
|
+
render(
|
|
68
|
+
<SearchSort onApply={onApply} data-testid="search-sort">
|
|
69
|
+
</SearchSort>
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const button = within(screen.getByTestId('search-sort')).getByRole('button');
|
|
73
|
+
await button.click();
|
|
74
|
+
expect(onApply).toHaveBeenCalled();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('passing additional props', () => {
|
|
78
|
+
render(
|
|
79
|
+
<SearchSort data-test="foo" data-testid="search-sort">
|
|
80
|
+
</SearchSort>
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const searchSort = screen.getByTestId('search-sort');
|
|
84
|
+
expect(searchSort.dataset.test).toEqual('foo');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('passing additional CSS classes', () => {
|
|
88
|
+
render(
|
|
89
|
+
<SearchSort className="foo" data-testid="search-sort">
|
|
90
|
+
</SearchSort>
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const searchSort = screen.getByTestId('search-sort');
|
|
94
|
+
expect(searchSort).toHaveClass('foo', 'ds_sort-options');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('renders options correctly', () => {
|
|
98
|
+
const OPTION_VALUE_1 = 'relevance';
|
|
99
|
+
const OPTION_TEXT_1 = 'Most relevant';
|
|
100
|
+
const OPTION_VALUE_2 = 'date';
|
|
101
|
+
const OPTION_TEXT_2 = 'Updated (newest)';
|
|
102
|
+
const OPTION_VALUE_3 = 'adate';
|
|
103
|
+
const OPTION_TEXT_3 = 'Updated (oldest)';
|
|
104
|
+
|
|
105
|
+
render(
|
|
106
|
+
<SearchSort data-testid="search-sort">
|
|
107
|
+
<SearchSort.Option value={OPTION_VALUE_1}>{OPTION_TEXT_1}</SearchSort.Option>
|
|
108
|
+
<SearchSort.Option value={OPTION_VALUE_2}>{OPTION_TEXT_2}</SearchSort.Option>
|
|
109
|
+
<SearchSort.Option value={OPTION_VALUE_3}>{OPTION_TEXT_3}</SearchSort.Option>
|
|
110
|
+
</SearchSort>
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const select = screen.getByRole('combobox');
|
|
114
|
+
const options = within(select).getAllByRole('option');
|
|
115
|
+
|
|
116
|
+
expect(options).toHaveLength(4);
|
|
117
|
+
|
|
118
|
+
expect(options[0]).toHaveTextContent('');
|
|
119
|
+
expect(options[0]).toHaveAttribute('value', '');
|
|
120
|
+
|
|
121
|
+
expect(options[1]).toHaveTextContent(OPTION_TEXT_1);
|
|
122
|
+
expect(options[1]).toHaveAttribute('value', OPTION_VALUE_1);
|
|
123
|
+
|
|
124
|
+
expect(options[2]).toHaveTextContent(OPTION_TEXT_2);
|
|
125
|
+
expect(options[2]).toHaveAttribute('value', OPTION_VALUE_2);
|
|
126
|
+
|
|
127
|
+
expect(options[3]).toHaveTextContent(OPTION_TEXT_3);
|
|
128
|
+
expect(options[3]).toHaveAttribute('value', OPTION_VALUE_3);
|
|
129
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AllHTMLAttributes } from "react";
|
|
2
|
+
import Button from "../Button";
|
|
3
|
+
import Select from "../Select";
|
|
4
|
+
|
|
5
|
+
const Option = ({
|
|
6
|
+
children,
|
|
7
|
+
value
|
|
8
|
+
}: AllHTMLAttributes<HTMLOptionElement>) => {
|
|
9
|
+
return (
|
|
10
|
+
<option value={value}>
|
|
11
|
+
{children}
|
|
12
|
+
</option>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const SearchSort = ({
|
|
17
|
+
children,
|
|
18
|
+
className,
|
|
19
|
+
id = 'sort-by',
|
|
20
|
+
label = 'Sort by',
|
|
21
|
+
onApply,
|
|
22
|
+
...props
|
|
23
|
+
}: SGDS.Component.SearchSort) => {
|
|
24
|
+
return (
|
|
25
|
+
<div
|
|
26
|
+
className={[
|
|
27
|
+
'ds_sort-options',
|
|
28
|
+
className
|
|
29
|
+
].join(' ')}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
<Select id={id} label={label}>
|
|
33
|
+
{children}
|
|
34
|
+
</Select>
|
|
35
|
+
|
|
36
|
+
<Button onClick={onApply} isSmall buttonStyle="secondary" type="submit">Apply sort</Button>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
SearchSort.displayName = 'SearchSort';
|
|
42
|
+
Option.displayName = 'SearchSort.Option';
|
|
43
|
+
SearchSort.Option = Option;
|
|
44
|
+
|
|
45
|
+
export default SearchSort;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './SearchSort';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './Select';
|