@hortiview/shared-components 2.27.4 → 2.28.0-alpha.fb31ea7e.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/{dist/AlertBanner-C9TvBTkH.js → AlertBanner-2rv7mRmR.js} +1 -1
- package/{dist/GenericCard-2v0lBsVu.js → GenericCard-DglXAprV.js} +6 -6
- package/{dist/ListAreaService-PaN1DrXf.js → ListAreaService-DkGcBcwz.js} +6 -6
- package/{dist/component-DYpB_4EP.js → component-9vrShqiY.js} +37 -37
- package/{dist/components → components}/AlertBanner/AlertBanner.d.ts +1 -1
- package/{dist/components → components}/AlertBanner/AlertBanner.js +2 -2
- package/{dist/components → components}/AlertBanner/LinkBanner.d.ts +1 -2
- package/{dist/components → components}/AlertBanner/LinkBanner.js +2 -2
- package/{dist/components → components}/Allowed/Allowed.d.ts +1 -2
- package/{dist/components → components}/AllowedButton/AllowedButton.d.ts +1 -2
- package/{dist/components → components}/AllowedButton/AllowedButton.js +1 -1
- package/{dist/components → components}/AllowedIconButton/AllowedIconButton.d.ts +1 -2
- package/{dist/components → components}/AllowedIconButton/AllowedIconButton.js +1 -1
- package/{dist/components → components}/BaseView/BaseView.d.ts +1 -2
- package/{dist/components → components}/BaseView/BaseView.js +1 -1
- package/{dist/components → components}/BasicHeading/BasicHeading.d.ts +1 -2
- package/{dist/components → components}/BasicHeading/BasicHeading.js +5 -5
- package/{dist/components → components}/BlockView/BlockView.d.ts +1 -2
- package/{dist/components → components}/BlockView/BlockView.js +2 -2
- package/{dist/components → components}/ButtonCard/ButtonCard.d.ts +1 -2
- package/{dist/components → components}/ButtonCard/ButtonCard.js +5 -5
- package/{dist/components → components}/ChipCard/ChipCard.d.ts +1 -1
- package/{dist/components → components}/ChipCard/ChipCard.js +2 -2
- package/{dist/components → components}/ConfirmationModal/ConfirmationModal.d.ts +1 -2
- package/{dist/components → components}/ConfirmationModal/ConfirmationModal.js +7 -7
- package/{dist/components → components}/ContextMenu/ContextMenu.d.ts +1 -2
- package/{dist/components → components}/ContextMenu/ContextMenu.js +3 -3
- package/{dist/components → components}/DeleteModal/DeleteModal.d.ts +1 -2
- package/{dist/components → components}/DeleteModal/DeleteModal.js +7 -7
- package/{dist/components → components}/DetailContentWrapper/DetailContentWrapper.d.ts +1 -2
- package/{dist/components → components}/Disclaimer/Disclaimer.d.ts +1 -1
- package/{dist/components → components}/Disclaimer/Disclaimer.js +1 -1
- package/{dist/components → components}/EmptyView/EmptyView.d.ts +1 -2
- package/{dist/components → components}/EmptyView/EmptyView.js +5 -5
- package/{dist/components → components}/Filter/Filter.d.ts +1 -2
- package/{dist/components → components}/Filter/Filter.js +9 -9
- package/{dist/components → components}/FloatingActionButton/FloatingActionButton.d.ts +1 -2
- package/{dist/components → components}/FloatingActionButton/FloatingActionButton.js +3 -3
- package/{dist/components → components}/FormComponents/FormCheckBox/FormCheckBox.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormCheckBox/FormCheckBox.js +1 -1
- package/{dist/components → components}/FormComponents/FormDatePicker/FormDatePicker.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormDatePicker/FormDatePicker.js +1 -1
- package/{dist/components → components}/FormComponents/FormNumber/CustomTextField.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormNumber/CustomTextField.js +5 -5
- package/{dist/components → components}/FormComponents/FormNumber/FormNumber.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormNumber/FormNumber.js +1 -1
- package/{dist/components → components}/FormComponents/FormRadio/FormRadio.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormRadio/FormRadio.js +1 -1
- package/{dist/components → components}/FormComponents/FormSelect/FormSelect.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormSelect/FormSelect.js +2 -2
- package/{dist/components → components}/FormComponents/FormSelect/FormSelectService.d.ts +0 -1
- package/{dist/components → components}/FormComponents/FormSelect/SelectTooltipText.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormSelect/SelectTooltipText.js +1 -1
- package/{dist/components → components}/FormComponents/FormSlider/FormSlider.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormSlider/FormSlider.js +2 -2
- package/{dist/components → components}/FormComponents/FormText/FormText.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormText/FormText.js +2 -2
- package/{dist/components → components}/FormComponents/FormToggle/FormToggle.d.ts +1 -2
- package/{dist/components → components}/FormComponents/FormToggle/FormToggle.js +2 -2
- package/{dist/components → components}/FormattedNumberDisplay/FormattedNumberDisplay.d.ts +1 -2
- package/{dist/components → components}/FormattedNumberDisplay/FormattedNumberDisplay.js +1 -1
- package/{dist/components → components}/GenericTable/GenericTable.d.ts +1 -2
- package/{dist/components → components}/GenericTable/GenericTable.js +670 -670
- package/{dist/components → components}/GenericTable/GenericTableService.d.ts +0 -1
- package/{dist/components → components}/GenericTable/Mobile/GenericCard.d.ts +1 -2
- package/{dist/components → components}/GenericTable/Mobile/GenericCard.js +3 -3
- package/{dist/components → components}/GenericTable/Mobile/GenericCardList.d.ts +0 -1
- package/{dist/components → components}/GenericTable/Mobile/GenericCardList.js +2 -2
- package/{dist/components → components}/HashTabView/HashTabView.d.ts +1 -2
- package/{dist/components → components}/HashTabView/HashTabView.js +2 -2
- package/{dist/components → components}/HeaderFilter/HeaderFilter.d.ts +1 -2
- package/{dist/components → components}/HeaderFilter/HeaderFilter.js +1 -1
- package/{dist/components → components}/Iconify/Iconify.d.ts +0 -1
- package/{dist/components → components}/InfoCard/InfoCard.d.ts +1 -1
- package/{dist/components → components}/InfoCard/InfoCard.js +2 -2
- package/{dist/components → components}/InfoGroup/InfoGroup.d.ts +1 -2
- package/{dist/components → components}/InfoGroup/InfoGroup.js +3 -3
- package/{dist/components → components}/ListArea/ListArea.d.ts +1 -2
- package/{dist/components → components}/ListArea/ListArea.js +2 -2
- package/{dist/components → components}/ListArea/ListAreaService.d.ts +4 -5
- package/{dist/components → components}/ListArea/ListAreaService.js +2 -2
- package/{dist/components → components}/LoadingSpinner/Big/BigLoadingSpinner.d.ts +1 -1
- package/{dist/components → components}/LoadingSpinner/Big/BigLoadingSpinner.js +1 -1
- package/{dist/components → components}/LoadingSpinner/Default/LoadingSpinner.d.ts +1 -1
- package/{dist/components → components}/LoadingSpinner/Default/LoadingSpinner.js +6 -6
- package/{dist/components → components}/Modal/Modal.d.ts +1 -2
- package/{dist/components → components}/Modal/Modal.js +3 -3
- package/{dist/components → components}/ModulePadding/ModulePadding.d.ts +1 -2
- package/{dist/components → components}/ModulePadding/ModulePadding.js +7 -7
- package/{dist/components → components}/OfflineView/OfflineView.d.ts +1 -1
- package/{dist/components → components}/OfflineView/OfflineView.js +2 -2
- package/{dist/components → components}/OnboardingBanner/OnboardingBanner.d.ts +1 -2
- package/{dist/components → components}/OnboardingBanner/OnboardingBanner.js +4 -4
- package/{dist/components → components}/OverflowTooltip/OverflowTooltip.d.ts +1 -1
- package/{dist/components → components}/OverflowTooltip/OverflowTooltip.js +2 -2
- package/{dist/components → components}/PermissionChecks/PermissionService.d.ts +0 -1
- package/{dist/components → components}/SafeForm/SafeForm.d.ts +1 -1
- package/{dist/components → components}/SearchBar/SearchBar.d.ts +1 -2
- package/{dist/components → components}/SearchBar/SearchBar.js +2 -2
- package/{dist/components → components}/Select/Select.d.ts +1 -2
- package/{dist/components → components}/Select/Select.js +4 -4
- package/{dist/components → components}/SharedComponentsPermissionProvider/PermissionContext.d.ts +0 -1
- package/{dist/components → components}/SharedComponentsPermissionProvider/SharedComponentsPermissionProvider.d.ts +1 -2
- package/{dist/components → components}/Stepper/Stepper.d.ts +1 -2
- package/{dist/components → components}/Stepper/components/StepperButton.d.ts +2 -3
- package/{dist/components → components}/Stepper/components/StepperButton.js +1 -1
- package/{dist/components → components}/Stepper/components/StepperHeader.d.ts +1 -2
- package/{dist/components → components}/Stepper/components/StepperHeader.js +2 -2
- package/{dist/components → components}/Stepper/components/StepperItem.d.ts +1 -2
- package/{dist/components → components}/Stepper/components/StepperItem.js +1 -1
- package/{dist/components → components}/Stepper/stepperTypes.d.ts +0 -1
- package/{dist/components → components}/TopBarBanner/TopBarBanner.d.ts +1 -1
- package/{dist/components → components}/TopBarBanner/TopBarBanner.js +2 -2
- package/{dist/components → components}/VerticalDivider/VerticalDivider.d.ts +1 -1
- package/{dist/hooks → hooks}/useBreakpoints.d.ts +7 -19
- package/hooks/useBreakpoints.js +6 -0
- package/{dist/hooks → hooks}/useContainerWidth.d.ts +0 -1
- package/hooks/useDesktopBreakpoints.d.ts +19 -0
- package/hooks/useDesktopBreakpoints.js +4 -0
- package/{dist/hooks → hooks}/useHelperText.d.ts +0 -1
- package/{dist/index.es-CxQjsRHK.js → index.es-74LdeLp0.js} +9 -9
- package/{dist/index.es-BSaDtduL.js → index.es-B7KXUg_Y.js} +1 -1
- package/{dist/index.es-B1cewJEy.js → index.es-B9C7vzr4.js} +1 -1
- package/{dist/index.es-_PSuLbjQ.js → index.es-BIgjyLDa.js} +6 -6
- package/{dist/index.es-DPGGEmi5.js → index.es-BTF3Ci4c.js} +1 -1
- package/{dist/index.es-BZkGOjEo.js → index.es-BwhRJBEH.js} +1 -1
- package/{dist/index.es-CpPnZRt7.js → index.es-ByqU-v6T.js} +166 -166
- package/{dist/index.es-BajVPGKH.js → index.es-C2dbad7Y.js} +4 -4
- package/{dist/index.es-5Wxrzmtf.js → index.es-CJIPOFSz.js} +2 -2
- package/{dist/index.es-EXzC8zuP.js → index.es-CdZp67J9.js} +4 -4
- package/{dist/index.es-CwgwR6SB.js → index.es-CduUloMP.js} +1 -1
- package/{dist/index.es-BVW2k-5y.js → index.es-DCWPAtXu.js} +1 -1
- package/{dist/index.es-DHL1mFb3.js → index.es-DglJcc2r.js} +2 -2
- package/{dist/isString-C0tJxuT4.js → isString-LDbI4UeI.js} +1 -1
- package/{dist/main.d.ts → main.d.ts} +9 -6
- package/{dist/main.js → main.js} +61 -60
- package/{dist/omit-BWQrFyQ-.js → omit-DUqu4lDk.js} +196 -203
- package/package.json +12 -91
- package/{dist/react-number-format.es-pczkQ4lQ.js → react-number-format.es-8jxpHyYy.js} +192 -183
- package/react-tooltip.min-DKaGxvdz.js +1411 -0
- package/react.esm-B3AK8zW1.js +15136 -0
- package/{dist/services → services}/BlockService.d.ts +0 -1
- package/{dist/services → services}/NumberService.d.ts +0 -1
- package/{dist/services → services}/UtilService.d.ts +0 -1
- package/{dist/services → services}/UtilService.js +4 -4
- package/{dist/test-utils.d.ts → test-utils.d.ts} +1 -2
- package/{dist/test-utils.js → test-utils.js} +1 -1
- package/{dist/types → types}/GenericTable.d.ts +0 -1
- package/{dist/types → types}/ListElement.d.ts +0 -1
- package/{dist/hooks/useBreakpoints.js → useBreakpoints-DDrM9Cfx.js} +27 -25
- package/CHANGELOG.md +0 -786
- package/README.md +0 -1387
- package/dist/react-tooltip.min-D7xPMD-P.js +0 -1390
- package/dist/react.esm-DF7i80eN.js +0 -13658
- /package/{dist/_Map-BYxTn6ob.js → _Map-BYxTn6ob.js} +0 -0
- /package/{dist/_commonjsHelpers-ByX85dGu.js → _commonjsHelpers-ByX85dGu.js} +0 -0
- /package/{dist/animationframe-CqXArbwZ.js → animationframe-CqXArbwZ.js} +0 -0
- /package/{dist/assets → assets}/AlertBanner.css +0 -0
- /package/{dist/assets → assets}/BaseView.css +0 -0
- /package/{dist/assets → assets}/BasicHeading.css +0 -0
- /package/{dist/assets → assets}/BigLoadingSpinner.css +0 -0
- /package/{dist/assets → assets}/BlockView.css +0 -0
- /package/{dist/assets → assets}/ButtonCard.css +0 -0
- /package/{dist/assets → assets}/ChipCard.css +0 -0
- /package/{dist/assets → assets}/ConfirmationModal.css +0 -0
- /package/{dist/assets → assets}/ContextMenu.css +0 -0
- /package/{dist/assets → assets}/CustomTextField.css +0 -0
- /package/{dist/assets → assets}/DeleteModal.css +0 -0
- /package/{dist/assets → assets}/DetailContentWrapper.css +0 -0
- /package/{dist/assets → assets}/Disclaimer.css +0 -0
- /package/{dist/assets → assets}/EmptyView.css +0 -0
- /package/{dist/assets → assets}/Filter.css +0 -0
- /package/{dist/assets → assets}/FloatingActionButton.css +0 -0
- /package/{dist/assets → assets}/FormCheckBox.css +0 -0
- /package/{dist/assets → assets}/FormDatePicker.css +0 -0
- /package/{dist/assets → assets}/FormSelect.css +0 -0
- /package/{dist/assets → assets}/FormText.css +0 -0
- /package/{dist/assets → assets}/GenericCard.css +0 -0
- /package/{dist/assets → assets}/GenericTable.css +0 -0
- /package/{dist/assets → assets}/HashTabView.css +0 -0
- /package/{dist/assets → assets}/HeaderFilter.css +0 -0
- /package/{dist/assets → assets}/Iconify.css +0 -0
- /package/{dist/assets → assets}/InfoCard.css +0 -0
- /package/{dist/assets → assets}/InfoGroup.css +0 -0
- /package/{dist/assets → assets}/ListAreaService.css +0 -0
- /package/{dist/assets → assets}/LoadingSpinner.css +0 -0
- /package/{dist/assets → assets}/Modal.css +0 -0
- /package/{dist/assets → assets}/ModulePadding.css +0 -0
- /package/{dist/assets → assets}/OfflineView.css +0 -0
- /package/{dist/assets → assets}/OnboardingBanner.css +0 -0
- /package/{dist/assets → assets}/OverflowTooltip.css +0 -0
- /package/{dist/assets → assets}/Scrollbar.css +0 -0
- /package/{dist/assets → assets}/SearchBar.css +0 -0
- /package/{dist/assets → assets}/Select.css +0 -0
- /package/{dist/assets → assets}/TopBarBanner.css +0 -0
- /package/{dist/assets → assets}/VerticalDivider.css +0 -0
- /package/{dist/assets → assets}/stepper.css +0 -0
- /package/{dist/component-By6nyiBU.js → component-By6nyiBU.js} +0 -0
- /package/{dist/components → components}/Allowed/Allowed.js +0 -0
- /package/{dist/components → components}/BaseView/BaseView.service.d.ts +0 -0
- /package/{dist/components → components}/BaseView/BaseView.service.js +0 -0
- /package/{dist/components → components}/DetailContentWrapper/DetailContentWrapper.js +0 -0
- /package/{dist/components → components}/FormComponents/FormDatePicker/FormDatePickerService.d.ts +0 -0
- /package/{dist/components → components}/FormComponents/FormDatePicker/FormDatePickerService.js +0 -0
- /package/{dist/components → components}/FormComponents/FormSelect/FormSelectService.js +0 -0
- /package/{dist/components → components}/GenericTable/GenericTableService.js +0 -0
- /package/{dist/components → components}/Iconify/Iconify.js +0 -0
- /package/{dist/components → components}/OverflowTooltip/OverflowTooltipService.d.ts +0 -0
- /package/{dist/components → components}/OverflowTooltip/OverflowTooltipService.js +0 -0
- /package/{dist/components → components}/PermissionChecks/PermissionService.js +0 -0
- /package/{dist/components → components}/PermissionChecks/mockedPermissions.d.ts +0 -0
- /package/{dist/components → components}/PermissionChecks/mockedPermissions.js +0 -0
- /package/{dist/components → components}/SafeForm/SafeForm.js +0 -0
- /package/{dist/components → components}/Scrollbar/Scrollbar.d.ts +0 -0
- /package/{dist/components → components}/Scrollbar/Scrollbar.js +0 -0
- /package/{dist/components → components}/SharedComponentsPermissionProvider/PermissionContext.js +0 -0
- /package/{dist/components → components}/SharedComponentsPermissionProvider/SharedComponentsPermissionProvider.js +0 -0
- /package/{dist/components → components}/Stepper/Stepper.js +0 -0
- /package/{dist/components → components}/Stepper/stepperStyles.d.ts +0 -0
- /package/{dist/components → components}/Stepper/stepperStyles.js +0 -0
- /package/{dist/components → components}/Stepper/stepperTypes.js +0 -0
- /package/{dist/components → components}/VerticalDivider/VerticalDivider.js +0 -0
- /package/{dist/defineProperty-SoB5opr-.js → defineProperty-SoB5opr-.js} +0 -0
- /package/{dist/enums → enums}/AvailableCustomIcons.d.ts +0 -0
- /package/{dist/enums → enums}/AvailableCustomIcons.js +0 -0
- /package/{dist/enums → enums}/ThemeColor.d.ts +0 -0
- /package/{dist/enums → enums}/ThemeColor.js +0 -0
- /package/{dist/es.string.iterator-BrOvr7F6.js → es.string.iterator-BrOvr7F6.js} +0 -0
- /package/{dist/find-OaLSg5iu.js → find-OaLSg5iu.js} +0 -0
- /package/{dist/get-BLvvbtML.js → get-BLvvbtML.js} +0 -0
- /package/{dist/get-CBFiuc3f.js → get-CBFiuc3f.js} +0 -0
- /package/{dist/hooks → hooks}/useContainerWidth.js +0 -0
- /package/{dist/hooks → hooks}/useHelperText.js +0 -0
- /package/{dist/identity-B0bbReND.js → identity-B0bbReND.js} +0 -0
- /package/{dist/includes-CSD_V_RY.js → includes-CSD_V_RY.js} +0 -0
- /package/{dist/index-CuHybtft.js → index-CuHybtft.js} +0 -0
- /package/{dist/index-_-9ybP20.js → index-_-9ybP20.js} +0 -0
- /package/{dist/index.es-0SkNh4dU.js → index.es-0SkNh4dU.js} +0 -0
- /package/{dist/index.es-BE1XL1dD.js → index.es-BE1XL1dD.js} +0 -0
- /package/{dist/index.es-C2ejWpji.js → index.es-C2ejWpji.js} +0 -0
- /package/{dist/index.es-C8AExypY.js → index.es-C8AExypY.js} +0 -0
- /package/{dist/index.es-CNrSvjAv.js → index.es-CNrSvjAv.js} +0 -0
- /package/{dist/index.es-CTKwa3Es.js → index.es-CTKwa3Es.js} +0 -0
- /package/{dist/index.es-DRC-9PLs.js → index.es-DRC-9PLs.js} +0 -0
- /package/{dist/index.es-LckFzDz-.js → index.es-LckFzDz-.js} +0 -0
- /package/{dist/index.es-Pc5KKhcb.js → index.es-Pc5KKhcb.js} +0 -0
- /package/{dist/index.es-eZDofmng.js → index.es-eZDofmng.js} +0 -0
- /package/{dist/isArray-Ce1Q96lU.js → isArray-Ce1Q96lU.js} +0 -0
- /package/{dist/isArray-olhCpv2e.js → isArray-olhCpv2e.js} +0 -0
- /package/{dist/isEmpty-l2xQKl4x.js → isEmpty-l2xQKl4x.js} +0 -0
- /package/{dist/isTypedArray-D39qzPYE.js → isTypedArray-D39qzPYE.js} +0 -0
- /package/{dist/keyboard-DQ9O_Ke1.js → keyboard-DQ9O_Ke1.js} +0 -0
- /package/{dist/map-BErBeya5.js → map-BErBeya5.js} +0 -0
- /package/{dist/orderBy-Ce85KqD6.js → orderBy-Ce85KqD6.js} +0 -0
- /package/{dist/parse-int-BYd7r_4n.js → parse-int-BYd7r_4n.js} +0 -0
- /package/{dist/services → services}/BlockService.js +0 -0
- /package/{dist/services → services}/NumberService.js +0 -0
- /package/{dist/slicedToArray-C2Ed3239.js → slicedToArray-C2Ed3239.js} +0 -0
- /package/{dist/stepper.module-C_EMu-Fl.js → stepper.module-C_EMu-Fl.js} +0 -0
- /package/{dist/string-trim-v5pkXsl2.js → string-trim-v5pkXsl2.js} +0 -0
- /package/{dist/toString-D5bEU-DN.js → toString-D5bEU-DN.js} +0 -0
- /package/{dist/tslib.es6-BDCynO9F.js → tslib.es6-BDCynO9F.js} +0 -0
- /package/{dist/types → types}/Filter.d.ts +0 -0
- /package/{dist/types → types}/Filter.js +0 -0
- /package/{dist/types → types}/GenericTable.js +0 -0
- /package/{dist/types → types}/HashTab.d.ts +0 -0
- /package/{dist/types → types}/HashTab.js +0 -0
- /package/{dist/types → types}/Languages.d.ts +0 -0
- /package/{dist/types → types}/Languages.js +0 -0
- /package/{dist/types → types}/ListElement.js +0 -0
- /package/{dist/types → types}/Permission.d.ts +0 -0
- /package/{dist/types → types}/Permission.js +0 -0
- /package/{dist/types → types}/Time.d.ts +0 -0
- /package/{dist/types → types}/Time.js +0 -0
- /package/{dist/types → types}/internal/Block.d.ts +0 -0
- /package/{dist/types → types}/internal/Block.js +0 -0
- /package/{dist/types → types}/internal/ChangeValueType.d.ts +0 -0
- /package/{dist/types → types}/internal/ChangeValueType.js +0 -0
- /package/{dist/types → types}/internal/ReactRouterTypes.d.ts +0 -0
- /package/{dist/types → types}/internal/ReactRouterTypes.js +0 -0
- /package/{dist/uniqueId-CJo-XRQb.js → uniqueId-CJo-XRQb.js} +0 -0
- /package/{dist/util-CBo-ipCE.js → util-CBo-ipCE.js} +0 -0
- /package/{dist/vite-env.d.js → vite-env.d.js} +0 -0
package/README.md
DELETED
|
@@ -1,1387 +0,0 @@
|
|
|
1
|
-
# HortiView Shared Components
|
|
2
|
-
|
|
3
|
-
This is a shared components library. It should be used in the HortiView platform and its modules.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
`npm i @hortiview/shared-components`
|
|
8
|
-
|
|
9
|
-
`yarn add @hortiview/shared-components`
|
|
10
|
-
|
|
11
|
-
## Prerequisites
|
|
12
|
-
|
|
13
|
-
This library is based on a public version of Bayer's Element component library.
|
|
14
|
-
|
|
15
|
-
Use `yarn add @element-public/react-components @element-public/themes` or `npm i @element-public/react-components @element-public/themes` to add the packages to your solution.
|
|
16
|
-
|
|
17
|
-
## Remarks
|
|
18
|
-
|
|
19
|
-
For the best experience use [react-router](https://reactrouter.com/en/main) in your solution, because some of the component rely on properties like pathname, hash or components like `Link` out of `react-router`.
|
|
20
|
-
|
|
21
|
-
Additionally the library provides form components using [react-hook-form](https://react-hook-form.com/get-started). When you want to use these components please install `react-hook-form` before using them.
|
|
22
|
-
|
|
23
|
-
## Available Components:
|
|
24
|
-
|
|
25
|
-
1. [AlertBanner](#alertbanner)
|
|
26
|
-
1. [BaseView](#baseview)
|
|
27
|
-
1. [BasicHeading](#basicheading)
|
|
28
|
-
1. [BlockView](#blockview)
|
|
29
|
-
1. [ChipCard](#chipcard)
|
|
30
|
-
1. [ContextMenu](#contextmenu)
|
|
31
|
-
1. [DeleteModal](#deletemodal)
|
|
32
|
-
1. [Disclaimer](#disclaimer)
|
|
33
|
-
1. [EmptyView](#emptyview)
|
|
34
|
-
1. [ErrorBanner] (#errorbanner)
|
|
35
|
-
1. [Filter](#filter)
|
|
36
|
-
1. [FloatingActionButton](#floatingactionbutton)
|
|
37
|
-
1. [FormattedNumberDisplay](#formattednumberdisplay)
|
|
38
|
-
1. [FormComponents](#formcomponents)
|
|
39
|
-
1. [FormCheckBox](#formcheckbox)
|
|
40
|
-
1. [FormDatePicker](#formdatepicker)
|
|
41
|
-
1. [FormNumber](#formnumber)
|
|
42
|
-
1. [FormRadio](#formradio)
|
|
43
|
-
1. [FormSelect](#formselect)
|
|
44
|
-
1. [FormSlider](#formslider)
|
|
45
|
-
1. [FormText](#formtext)
|
|
46
|
-
1. [GenericTable](#generictable)
|
|
47
|
-
1. [HashTabView](#hashtabview)
|
|
48
|
-
1. [HeaderFilter](#headerfilter)
|
|
49
|
-
1. [InfoCard](#infocard)
|
|
50
|
-
1. [InfoGroup](#infogroup)
|
|
51
|
-
1. [Iconify](#iconify)
|
|
52
|
-
1. [ListArea](#listarea)
|
|
53
|
-
1. [LoadingSpinner](#loadingspinner)
|
|
54
|
-
1. [Modal](#modal)
|
|
55
|
-
1. [ModulePadding](#modulepadding)
|
|
56
|
-
1. [OfflineView](#offlineview)
|
|
57
|
-
1. [OnboardingBanner](#onboardingbanner)
|
|
58
|
-
1. [OverflowTooltip](#overflowtooltip)
|
|
59
|
-
1. [Permissions](#permissions)
|
|
60
|
-
1. [SafeForm](#safeform)
|
|
61
|
-
1. [ScrollBar](#scrollbar)
|
|
62
|
-
1. [SearchBar](#searchbar)
|
|
63
|
-
1. [Select](#select)
|
|
64
|
-
1. [Stepper](#stepper)
|
|
65
|
-
1. [VerticalDivider](#verticaldivider)
|
|
66
|
-
|
|
67
|
-
## Available Utility Functions:
|
|
68
|
-
|
|
69
|
-
1. [useBreakpoints](#usebreakpoints)
|
|
70
|
-
1. [capitalizeFirstLetters](#capitalizefirstletters)
|
|
71
|
-
1. [trimLeadingAndTrailingSpaces](#trimleadingandtrailingspaces)
|
|
72
|
-
1. [getNumberAsLocaleString](#getnumberaslocalestring)
|
|
73
|
-
1. [getFormattedDateTime](#getformatteddatetime)
|
|
74
|
-
|
|
75
|
-
## Available constants
|
|
76
|
-
|
|
77
|
-
1. [Languages and countries](#languages-and-countries)
|
|
78
|
-
|
|
79
|
-
## Changelog
|
|
80
|
-
|
|
81
|
-
[Changelog](./Changelog.md)
|
|
82
|
-
|
|
83
|
-
## Available Components:
|
|
84
|
-
|
|
85
|
-
### AlertBanner
|
|
86
|
-
|
|
87
|
-
Presents an Banner containing important messages. Can used in different colors and you can add an optional action.
|
|
88
|
-
|
|
89
|
-
```jsx
|
|
90
|
-
import { AlertBanner } from '@hortiview/shared-components';
|
|
91
|
-
|
|
92
|
-
<AlertBanner
|
|
93
|
-
text='My Alert'
|
|
94
|
-
color='danger' // | 'info' | 'success'
|
|
95
|
-
action={<MyButton />}
|
|
96
|
-
/>;
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### BaseView
|
|
100
|
-
|
|
101
|
-
Can be used to show a kind off main and detail view. On the left side you will have a list of elements and on the right a detail section of the element selected.
|
|
102
|
-
|
|
103
|
-
```jsx
|
|
104
|
-
import { BaseListElement, BaseView } from '@hortiview/shared-components';
|
|
105
|
-
import { Link, useLocation } from 'react-router-dom';
|
|
106
|
-
|
|
107
|
-
const { pathname } = useLocation();
|
|
108
|
-
|
|
109
|
-
const elements: BaseListElement[] = [
|
|
110
|
-
{
|
|
111
|
-
id: '1',
|
|
112
|
-
title: 'First',
|
|
113
|
-
subTitle: 'First Subtilte',
|
|
114
|
-
type: 'Primary',
|
|
115
|
-
icon: 'grid_view',
|
|
116
|
-
route: '/first',
|
|
117
|
-
component: <MyComponentToShowOnClick />,
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
id: '2',
|
|
121
|
-
title: 'Second',
|
|
122
|
-
subTitle: 'Second Subtilte',
|
|
123
|
-
type: 'Primary',
|
|
124
|
-
icon: 'add',
|
|
125
|
-
route: '/second',
|
|
126
|
-
component: <MyComponentToShowOnClickSecond />,
|
|
127
|
-
},
|
|
128
|
-
];
|
|
129
|
-
|
|
130
|
-
return (
|
|
131
|
-
<BaseView
|
|
132
|
-
routerLinkElement={Link}
|
|
133
|
-
pathname={pathname}
|
|
134
|
-
elements={elements}
|
|
135
|
-
heading='Header'
|
|
136
|
-
hasSearch
|
|
137
|
-
emptyText='Empty'
|
|
138
|
-
/>
|
|
139
|
-
);
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### BasicHeading
|
|
143
|
-
|
|
144
|
-
Provides a heading component with optional children which are rendered on the right side of the heading.
|
|
145
|
-
|
|
146
|
-
```jsx
|
|
147
|
-
import { BasicHeading } from '@hortiview/shared-components';
|
|
148
|
-
|
|
149
|
-
<BasicHeading heading={'Header'}>
|
|
150
|
-
<button>Test</button>
|
|
151
|
-
</BasicHeading>;
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### BlockView
|
|
155
|
-
|
|
156
|
-
This is a component showing blocks in a row/column view.
|
|
157
|
-
|
|
158
|
-
```jsx
|
|
159
|
-
import { BlockView, BlockDto } from '@hortiview/shared-components';
|
|
160
|
-
|
|
161
|
-
const blocks: BlockDto = [
|
|
162
|
-
{
|
|
163
|
-
position: { row: 1, column: 1 },
|
|
164
|
-
fieldId: '1',
|
|
165
|
-
},
|
|
166
|
-
];
|
|
167
|
-
|
|
168
|
-
<BlockView blocks={blocks} columns={1} rows={1} />;
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### ChipCard
|
|
172
|
-
|
|
173
|
-
A card with a chip inside, used for displaying entities. The chip displays an icon and a label. Furthermore, it is wrapped by [OverflowTooltip](#overflowtooltip) to truncate long labels. The card takes per default the width of the parent container. You can also provide custom CSS via the `className` property.
|
|
174
|
-
|
|
175
|
-
```jsx
|
|
176
|
-
import { ChipCard } form '@hortiview/shared-components'
|
|
177
|
-
|
|
178
|
-
<ChipCard icon='domain' label='Example Label' className='custom' />
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### ContextMenu
|
|
182
|
-
|
|
183
|
-
This is a component to render a menu button, that opens several action-points in a context-menu
|
|
184
|
-
|
|
185
|
-
```jsx
|
|
186
|
-
import { ContextMenu } from '@hortiview/shared-components';
|
|
187
|
-
|
|
188
|
-
const actions = [
|
|
189
|
-
{
|
|
190
|
-
primaryText: 'Edit',
|
|
191
|
-
secondaryText: 'Open the edit dialog',
|
|
192
|
-
onClick: () => openEdit(param),
|
|
193
|
-
leadingBlock: 'edit',
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
primaryText: 'Delete',
|
|
197
|
-
secondaryText: 'Delete the item'
|
|
198
|
-
onClick: deleteItem,
|
|
199
|
-
leadingBlock: 'delete',
|
|
200
|
-
},
|
|
201
|
-
];
|
|
202
|
-
|
|
203
|
-
<ContextMenu actions={actions} />;
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### DeleteModal
|
|
207
|
-
|
|
208
|
-
A modal to confirm a deletion.
|
|
209
|
-
|
|
210
|
-
It provides a loading state for the delete button to prevent multiple deletion attempts in a row. In this case, the button is disabled and a spinner is shown in the button.
|
|
211
|
-
|
|
212
|
-
If a deletion is not possible, the button is also disabled and the specified `impossibleDeleteHeader` is shown.
|
|
213
|
-
|
|
214
|
-
The button is also disabled when the user is offline, indicated by the `isOnline` prop. In this case, the [OfflineView](#offlineview) is shown.
|
|
215
|
-
|
|
216
|
-
```jsx
|
|
217
|
-
import { DeleteModal } from '@hortiview/shared-components';
|
|
218
|
-
|
|
219
|
-
const [open, setOpen] = useState<string>();
|
|
220
|
-
const onDelete = () => {
|
|
221
|
-
console.log('deleted');
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
<DeleteModal
|
|
225
|
-
icon='block'
|
|
226
|
-
open={open}
|
|
227
|
-
setOpen={setOpen}
|
|
228
|
-
onDelete={onDelete}
|
|
229
|
-
title={'DELETE'}
|
|
230
|
-
confirmButtonLabel={'Remove'}
|
|
231
|
-
cancelButtonLabel={'Cancel'}
|
|
232
|
-
deleteHeader={'Delete my block'}
|
|
233
|
-
impossibleDeleteHeader={'Block cannot be deleted'}
|
|
234
|
-
deleteBody={['block 1', 'block 2', 'block 3']}
|
|
235
|
-
isDeletePossible
|
|
236
|
-
isDeletePending={isDeleteRequestPending}
|
|
237
|
-
isOnline={isOnline}
|
|
238
|
-
/>;
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### Disclaimer
|
|
242
|
-
|
|
243
|
-
A red notice or hint with to show in the ui.
|
|
244
|
-
|
|
245
|
-
```jsx
|
|
246
|
-
|
|
247
|
-
import { Disclaimer } form '@hortiview/shared-components'
|
|
248
|
-
|
|
249
|
-
<Disclaimer text='Currently not available' subtext='Please try again later' icon='wifi_off' />
|
|
250
|
-
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### EmptyView
|
|
254
|
-
|
|
255
|
-
A basic view if no content is available.
|
|
256
|
-
|
|
257
|
-
```jsx
|
|
258
|
-
import { EmptyView } from '@hortiview/shared-components';
|
|
259
|
-
|
|
260
|
-
<EmptyView title='No Content' subtitle='nothing' icon='grass' />;
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### ErrorBanner
|
|
264
|
-
|
|
265
|
-
Displays an error message with optional actions. Can be used below a header (default) or as a standalone banner (e.g., in a modal).
|
|
266
|
-
|
|
267
|
-
```jsx
|
|
268
|
-
import { ErrorBanner } from '@hortiview/shared-components';
|
|
269
|
-
|
|
270
|
-
<ErrorBanner
|
|
271
|
-
title='Something went wrong'
|
|
272
|
-
description='An unexpected error occurred. Please try again or contact support.'
|
|
273
|
-
showBanner={true}
|
|
274
|
-
isOpen={true}
|
|
275
|
-
isStandalone={false} // set true for standalone usage
|
|
276
|
-
primaryActionLabel='Retry'
|
|
277
|
-
onPrimaryAction={() => alert('Retry clicked')}
|
|
278
|
-
secondaryActionLabel='Contact Support'
|
|
279
|
-
onSecondaryAction={() => alert('Support clicked')}
|
|
280
|
-
/>;
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
**Usage notes:**
|
|
284
|
-
|
|
285
|
-
- Use `isStandalone` for modal usage. Default style is for inline placement below a header.
|
|
286
|
-
- Both action buttons are optional; omit their labels to hide them.
|
|
287
|
-
|
|
288
|
-
### Filter
|
|
289
|
-
|
|
290
|
-
A filter component, which provides a well designed filter experience. It contains a filter button and a modal for different select inputs.
|
|
291
|
-
You need to provide some filter options in a `FilterData` array and handle the current filter selections.
|
|
292
|
-
|
|
293
|
-
```jsx
|
|
294
|
-
import { Filter } from '@hortiview/shared-components';
|
|
295
|
-
import { useState } from 'react';
|
|
296
|
-
|
|
297
|
-
const MyComponent = () => {
|
|
298
|
-
const [selectedFilters, setSelectedFilters] = useState([]);
|
|
299
|
-
|
|
300
|
-
const options = [
|
|
301
|
-
{
|
|
302
|
-
id: 'cars',
|
|
303
|
-
title: 'Cars',
|
|
304
|
-
availableOptions: [
|
|
305
|
-
{
|
|
306
|
-
id: 'bmw';
|
|
307
|
-
text: 'BMW';
|
|
308
|
-
icon: 'car';
|
|
309
|
-
},
|
|
310
|
-
{
|
|
311
|
-
id: 'vw';
|
|
312
|
-
text: 'Volkswagen';
|
|
313
|
-
icon: 'car';
|
|
314
|
-
}
|
|
315
|
-
],
|
|
316
|
-
},
|
|
317
|
-
{
|
|
318
|
-
id: 'food',
|
|
319
|
-
title: 'Food',
|
|
320
|
-
availableOptions: [
|
|
321
|
-
{
|
|
322
|
-
id: 'icecream';
|
|
323
|
-
text: 'Icecream';
|
|
324
|
-
icon: 'food';
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
id: 'burger';
|
|
328
|
-
text: 'Burger';
|
|
329
|
-
icon: 'food';
|
|
330
|
-
}
|
|
331
|
-
],
|
|
332
|
-
},
|
|
333
|
-
];
|
|
334
|
-
|
|
335
|
-
return (
|
|
336
|
-
<Filter
|
|
337
|
-
modalCancelButtonText={'cancel'}
|
|
338
|
-
modalConfirmButtonText={'useFilter'}
|
|
339
|
-
clearFilterText={'clearFilter'}
|
|
340
|
-
closeCallback={filter => setSelectedFilters(filter)}
|
|
341
|
-
currentFilter={selectedFilters}
|
|
342
|
-
filterButtonText={'filterButton'}
|
|
343
|
-
filterModalTitle={'filterResults'}
|
|
344
|
-
filters={options}
|
|
345
|
-
/>
|
|
346
|
-
);
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
export default MyComponent;
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
### FloatingActionButton
|
|
353
|
-
|
|
354
|
-
A component to show a floating action button for mobile and tablet views, giving users quick access to one or
|
|
355
|
-
more contextual actions without taking permanent space in layout.
|
|
356
|
-
|
|
357
|
-
It automatically hides when no visible/allowed actions exist,
|
|
358
|
-
can trigger a single action directly or open a menu for multiple actions,
|
|
359
|
-
supports an offline fallback view.
|
|
360
|
-
|
|
361
|
-
You can control the offset from the screen edges using `floatingButtonScreenOffsetType`, which includes
|
|
362
|
-
presets for full-screen implementations and screens with a BottomAppBar.
|
|
363
|
-
|
|
364
|
-
To prevent the FAB from blocking any elements in the rendered view, provide a DOM element selector to
|
|
365
|
-
`floatingButtonPaddingInsertTarget`. A spacer element will be attached to this target, increasing its
|
|
366
|
-
height by the appropriate amount.
|
|
367
|
-
|
|
368
|
-
```jsx
|
|
369
|
-
import { FloatingActionButton } from '@hortiview/shared-components';
|
|
370
|
-
|
|
371
|
-
const actions = [...];
|
|
372
|
-
|
|
373
|
-
<FloatingActionButton
|
|
374
|
-
actions={actions}
|
|
375
|
-
floatingButtonPaddingInsertTarget={'#fab-padding-target'}
|
|
376
|
-
isSingleActionTriggeredOnClick={false}
|
|
377
|
-
hasActionIconForSingleAction={false}
|
|
378
|
-
/>;
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
### FormattedNumberDisplay
|
|
382
|
-
|
|
383
|
-
A component to display a formatted number based on the given language code, wrapped in a given typography component to style it as needed.
|
|
384
|
-
|
|
385
|
-
The typography component that is passed to the FormattedNumberDisplay needs the "children" property to which the formatted number will be added.
|
|
386
|
-
|
|
387
|
-
```jsx
|
|
388
|
-
import { FormattedNumberDisplay } from '@hortiview/shared-components';
|
|
389
|
-
|
|
390
|
-
const TypoDisplay3 = (props: { children: React.ReactNode }) => {
|
|
391
|
-
return <TypoDisplay level={3}>{props.children}</TypoDisplay>;
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
<FormattedNumberDisplay typographyComponent={TypoDisplay3} languageCode='en-MX' value={12345.67} />;
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
### FormComponents
|
|
398
|
-
|
|
399
|
-
The library provides some form components based on [react-hook-form](https://react-hook-form.com/). The components can only be use within a form provided by react-hook-form.
|
|
400
|
-
So please add the package before you use the components.
|
|
401
|
-
|
|
402
|
-
```
|
|
403
|
-
yarn add react-hook-form
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
or
|
|
407
|
-
|
|
408
|
-
```
|
|
409
|
-
npm install react-hook-form
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
#### FormCheckBox
|
|
413
|
-
|
|
414
|
-
Provides a checkbox form component
|
|
415
|
-
|
|
416
|
-
```jsx
|
|
417
|
-
import { FormCheckBox } from '@hortiview/shared-components';
|
|
418
|
-
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form';
|
|
419
|
-
|
|
420
|
-
const formMethods = useForm<{ check: boolean }>({
|
|
421
|
-
mode: 'onSubmit',
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
const { handleSubmit } = formMethods;
|
|
425
|
-
|
|
426
|
-
<FormProvider {...formMethods}>
|
|
427
|
-
<SafeForm onSubmit={handleSubmit(onSubmit)}>
|
|
428
|
-
<FormCheckBox<{ check: boolean }>
|
|
429
|
-
propertyName={`check`}
|
|
430
|
-
label={'My Checkbox'}
|
|
431
|
-
onChange={() => additionalOnChange()}
|
|
432
|
-
validate={validateFn}
|
|
433
|
-
/>
|
|
434
|
-
</SafeForm>
|
|
435
|
-
</FormProvider>;
|
|
436
|
-
```
|
|
437
|
-
|
|
438
|
-
#### FormDatePicker
|
|
439
|
-
|
|
440
|
-
Provides a datepicker form component
|
|
441
|
-
|
|
442
|
-
```jsx
|
|
443
|
-
import { FormDatePicker } from '@hortiview/shared-components';
|
|
444
|
-
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form';
|
|
445
|
-
|
|
446
|
-
const formMethods = useForm<{ birthday: string }>({
|
|
447
|
-
mode: 'onSubmit',
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
const { handleSubmit } = formMethods;
|
|
451
|
-
|
|
452
|
-
<FormProvider {...formMethods}>
|
|
453
|
-
<SafeForm onSubmit={handleSubmit(onSubmit)}>
|
|
454
|
-
<FormDatePicker<{ birthday: string }>
|
|
455
|
-
propertyName={'birthday'}
|
|
456
|
-
label={'user.date-of-birth'}
|
|
457
|
-
maxRangeYear={0}
|
|
458
|
-
/>
|
|
459
|
-
</SafeForm>
|
|
460
|
-
</FormProvider>;
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
#### FormNumber
|
|
464
|
-
|
|
465
|
-
Number input field that formats the users input depending on the user language. The component automatically sets the language specific thousand separators and only allows the language specific decimal separators.
|
|
466
|
-
|
|
467
|
-
```jsx
|
|
468
|
-
import { FormNumber } from '@hortiview/shared-components';
|
|
469
|
-
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form';
|
|
470
|
-
|
|
471
|
-
const formMethods = useForm<{ birthday: string }>({
|
|
472
|
-
mode: 'onSubmit',
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
const { handleSubmit } = formMethods;
|
|
476
|
-
|
|
477
|
-
<FormProvider {...formMethods}>
|
|
478
|
-
<SafeForm onSubmit={handleSubmit(onSubmit)}>
|
|
479
|
-
<FormNumber<{ price: number }>
|
|
480
|
-
propertyName='price'
|
|
481
|
-
label='module.price'
|
|
482
|
-
languageCode="es-MX"
|
|
483
|
-
decimalScale={5}
|
|
484
|
-
fixedDecimalScale={true}
|
|
485
|
-
allowNegative={false}
|
|
486
|
-
allowLeadingZeros={false}
|
|
487
|
-
prefix=" €"
|
|
488
|
-
/>
|
|
489
|
-
</SafeForm>
|
|
490
|
-
</FormProvider>;
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
#### FormRadio
|
|
494
|
-
|
|
495
|
-
Provides a radio button form component
|
|
496
|
-
|
|
497
|
-
```jsx
|
|
498
|
-
import { FormRadio } from '@hortiview/shared-components';
|
|
499
|
-
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form';
|
|
500
|
-
|
|
501
|
-
const formMethods = useForm<{ radioValue: string }>({
|
|
502
|
-
mode: 'onSubmit',
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
const { handleSubmit } = formMethods;
|
|
506
|
-
|
|
507
|
-
<FormProvider {...formMethods}>
|
|
508
|
-
<SafeForm onSubmit={handleSubmit(onSubmit)}>
|
|
509
|
-
<FormRadio<{ radioValue: string }>
|
|
510
|
-
propertyName='radioValue'
|
|
511
|
-
options={[
|
|
512
|
-
{ value: 'priced', label: 'Priced' },
|
|
513
|
-
{ value: 'free', label: 'Free },
|
|
514
|
-
]}
|
|
515
|
-
/>
|
|
516
|
-
</SafeForm>
|
|
517
|
-
</FormProvider>;
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
#### FormSelect
|
|
521
|
-
|
|
522
|
-
Provides a select form component.
|
|
523
|
-
|
|
524
|
-
> **Warning**: Don't set `menuPosition` when `hoisted` is true.
|
|
525
|
-
|
|
526
|
-
```jsx
|
|
527
|
-
import { FormSelect } from '@hortiview/shared-components';
|
|
528
|
-
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form';
|
|
529
|
-
|
|
530
|
-
const formMethods = useForm<{ type: string }>({
|
|
531
|
-
mode: 'onSubmit',
|
|
532
|
-
});
|
|
533
|
-
|
|
534
|
-
const { handleSubmit } = formMethods;
|
|
535
|
-
|
|
536
|
-
const typeOptions = [
|
|
537
|
-
{
|
|
538
|
-
id: 1,
|
|
539
|
-
value: 'Car',
|
|
540
|
-
},
|
|
541
|
-
{
|
|
542
|
-
id: 2,
|
|
543
|
-
value: 'Bike',
|
|
544
|
-
},
|
|
545
|
-
];
|
|
546
|
-
|
|
547
|
-
<FormProvider {...formMethods}>
|
|
548
|
-
<SafeForm onSubmit={handleSubmit(onSubmit)}>
|
|
549
|
-
<FormSelect<{ type: string }>
|
|
550
|
-
propertyName='type'
|
|
551
|
-
label='Type'
|
|
552
|
-
options={typeOptions}
|
|
553
|
-
valueKey='id'
|
|
554
|
-
textKey='value'
|
|
555
|
-
requiredText='required'
|
|
556
|
-
required
|
|
557
|
-
/>
|
|
558
|
-
</SafeForm>
|
|
559
|
-
</FormProvider>;
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
#### FormSlider
|
|
563
|
-
|
|
564
|
-
Provides a slider form component
|
|
565
|
-
|
|
566
|
-
```jsx
|
|
567
|
-
import { FormSlider } from '@hortiview/shared-components';
|
|
568
|
-
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form';
|
|
569
|
-
|
|
570
|
-
const formMethods = useForm<{ range: string }>({
|
|
571
|
-
mode: 'onSubmit',
|
|
572
|
-
});
|
|
573
|
-
|
|
574
|
-
const { handleSubmit } = formMethods;
|
|
575
|
-
|
|
576
|
-
<FormProvider {...formMethods}>
|
|
577
|
-
<SafeForm onSubmit={handleSubmit(onSubmit)}>
|
|
578
|
-
<FormSlider<{ range: string }> propertyName='range' minValue={30} maxValue={90} step={30} />
|
|
579
|
-
</SafeForm>
|
|
580
|
-
</FormProvider>;
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
#### FormText
|
|
584
|
-
|
|
585
|
-
Provides a text form component
|
|
586
|
-
|
|
587
|
-
```jsx
|
|
588
|
-
import { FormText } from '@hortiview/shared-components';
|
|
589
|
-
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form';
|
|
590
|
-
|
|
591
|
-
const formMethods = useForm<{ address: string }>({
|
|
592
|
-
mode: 'onSubmit',
|
|
593
|
-
});
|
|
594
|
-
|
|
595
|
-
const { handleSubmit } = formMethods;
|
|
596
|
-
|
|
597
|
-
<FormProvider {...formMethods}>
|
|
598
|
-
<SafeForm onSubmit={handleSubmit(onSubmit)}>
|
|
599
|
-
<FormText<{ address: string }>
|
|
600
|
-
maxLength={200}
|
|
601
|
-
label='address'
|
|
602
|
-
propertyName='address'
|
|
603
|
-
required
|
|
604
|
-
requiredText='required'
|
|
605
|
-
textarea
|
|
606
|
-
/>
|
|
607
|
-
</SafeForm>
|
|
608
|
-
</FormProvider>;
|
|
609
|
-
```
|
|
610
|
-
|
|
611
|
-
### GenericTable
|
|
612
|
-
|
|
613
|
-
A dynamic table, that renders a table based on a type and an array of data (of the specified type). It renders a card list if your are in mobile or tablet mode.
|
|
614
|
-
|
|
615
|
-
```jsx
|
|
616
|
-
import { GenericTable, CellTemplateProps, CellTemplate } from '@hortiview/shared-components';
|
|
617
|
-
import {useTranslation} from 'react-router-dom';
|
|
618
|
-
|
|
619
|
-
type DataType = {
|
|
620
|
-
id: string;
|
|
621
|
-
name: string;
|
|
622
|
-
users: User[];
|
|
623
|
-
description: string
|
|
624
|
-
field1: Date;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
const filterArea = [
|
|
628
|
-
<Select onClick={filterLogic} />
|
|
629
|
-
];
|
|
630
|
-
|
|
631
|
-
const templates: CellTemplate = {
|
|
632
|
-
field1: (props: CellTemplateProps<DataType>) => {
|
|
633
|
-
const { field1 } = props.row.original;
|
|
634
|
-
return <Badge text={field1.toLocaleString()}/>
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
const getAction = (dataObject: DataType) => {
|
|
639
|
-
return [
|
|
640
|
-
{
|
|
641
|
-
primaryText: 'Edit Element',
|
|
642
|
-
secondaryText: 'in Modal',
|
|
643
|
-
onClick: () => openEdit(dataObject.id),
|
|
644
|
-
leadingBlock: 'edit',
|
|
645
|
-
},
|
|
646
|
-
]
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
const { t } = useTranslation();
|
|
650
|
-
const data: DataType[] = LoadData();
|
|
651
|
-
|
|
652
|
-
const filteredData = useMemo(() => {
|
|
653
|
-
return filterLogic(data)
|
|
654
|
-
})
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
return <GenericTable<DataType>
|
|
658
|
-
data={filteredData}
|
|
659
|
-
tableActions={filterArea}
|
|
660
|
-
hiddenColumns={['id', 'users']}
|
|
661
|
-
order={[
|
|
662
|
-
'name',
|
|
663
|
-
'description',
|
|
664
|
-
'field1'
|
|
665
|
-
]}
|
|
666
|
-
cellTemplates={templates}
|
|
667
|
-
headerTranslation={key => t(`overview.${key}`)}
|
|
668
|
-
noContentText={t('noText')}
|
|
669
|
-
pagination
|
|
670
|
-
getRowActions={getActions}
|
|
671
|
-
/>
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
### HashTabView
|
|
675
|
-
|
|
676
|
-
A tab view component, which can use the hash value in the url to render the tab regarding to the hash.
|
|
677
|
-
Pass `window.location.hash` as hash prop as it is the most reliable hash value.
|
|
678
|
-
When navigating back from a page with a `HashTabView`, the last page without hash will be shown.
|
|
679
|
-
|
|
680
|
-
```jsx
|
|
681
|
-
import { HashTabView, HashTab } from '@hortiview/shared-components';
|
|
682
|
-
|
|
683
|
-
const tabs: HashTab[] = [
|
|
684
|
-
{
|
|
685
|
-
title: 'My Map',
|
|
686
|
-
hash: 'map',
|
|
687
|
-
leadingIcon: 'map',
|
|
688
|
-
component: <>My map Component to show in the tab</>,
|
|
689
|
-
},
|
|
690
|
-
];
|
|
691
|
-
|
|
692
|
-
<HashTabView tabs={tabs} elevation={1} />;
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
### HeaderFilter
|
|
696
|
-
|
|
697
|
-
A filter dropdown component which can be used in headers like a tabview header. It supports a single filter value only.
|
|
698
|
-
|
|
699
|
-
```jsx
|
|
700
|
-
import { HeaderFilter } from '@hortiview/shared-components';
|
|
701
|
-
|
|
702
|
-
const [filterValue, setFilterValue] = useState<string>();
|
|
703
|
-
|
|
704
|
-
<HeaderFilter
|
|
705
|
-
heading={'Test'}
|
|
706
|
-
setFilter={setFilterValue}
|
|
707
|
-
filterValue={filterValue}
|
|
708
|
-
filterOptions={[
|
|
709
|
-
{ value: 'test', label: 'Test' },
|
|
710
|
-
{ value: 'different', label: 'Different' },
|
|
711
|
-
]}
|
|
712
|
-
/>
|
|
713
|
-
```
|
|
714
|
-
|
|
715
|
-
### InfoCard
|
|
716
|
-
|
|
717
|
-
A screen that can be used to inform the user about the status of a process. It can be used if the check for database health, iot health or HV platform health fails. Please use the following `title` and `subtitle` for each type to ensure a consistent user experience.
|
|
718
|
-
|
|
719
|
-
Note: These specific titles have been included in the default components.
|
|
720
|
-
|
|
721
|
-
```jsx
|
|
722
|
-
import { InfoCard } from '@hortiview/shared-components';
|
|
723
|
-
|
|
724
|
-
if (isPlatformHealthy === false) {
|
|
725
|
-
return (
|
|
726
|
-
<InfoCard
|
|
727
|
-
title='The platform data used by this module cannot be retrieved currently.'
|
|
728
|
-
subtitle='Please wait or come back later.'
|
|
729
|
-
type='platform'
|
|
730
|
-
/>
|
|
731
|
-
);
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
if (isDbHealthy === false) {
|
|
735
|
-
return (
|
|
736
|
-
<InfoCard
|
|
737
|
-
title='The data for this module is loading!'
|
|
738
|
-
subtitle='Please wait or come back later.'
|
|
739
|
-
type='database'
|
|
740
|
-
/>
|
|
741
|
-
);
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
if (isIotServiceHealthy === false) {
|
|
745
|
-
return (
|
|
746
|
-
<InfoCard
|
|
747
|
-
title='The data of your devices cannot be retrieved currently.'
|
|
748
|
-
subtitle='The problem is being addressed by our technical team. Please come back later.'
|
|
749
|
-
type='iot'
|
|
750
|
-
/>
|
|
751
|
-
);
|
|
752
|
-
}
|
|
753
|
-
```
|
|
754
|
-
|
|
755
|
-
Set the type to `other` to catch generic errors. Again, please use the `title` and `subtitle` as listed here to ensure a consistent user experience:
|
|
756
|
-
|
|
757
|
-
```jsx
|
|
758
|
-
<ParentWithVisibleBorders>
|
|
759
|
-
<InfoCard
|
|
760
|
-
title='Sorry, something went wrong!'
|
|
761
|
-
subtitle='The problem is being addressed by our technical team. Please come back later.'
|
|
762
|
-
type='other'
|
|
763
|
-
/>
|
|
764
|
-
</ParentWithVisibleBorders>
|
|
765
|
-
```
|
|
766
|
-
|
|
767
|
-
You can also control if the card is outlined or not, depending on the position in the UI. The card has a default outline. For design consistency, this prop should only be set to `false` if the card is embedded, e.g. in a table or any other parent that already has a border:
|
|
768
|
-
|
|
769
|
-
```jsx
|
|
770
|
-
<ParentWithVisibleBorders>
|
|
771
|
-
<InfoCard
|
|
772
|
-
title='Sorry, something went wrong!'
|
|
773
|
-
subtitle='The problem is being addressed by our technical team. Please come back later.'
|
|
774
|
-
type='other'
|
|
775
|
-
isOutlined={false}
|
|
776
|
-
/>
|
|
777
|
-
</ParentWithVisibleBorders>
|
|
778
|
-
```
|
|
779
|
-
|
|
780
|
-
### InfoGroup
|
|
781
|
-
|
|
782
|
-
Renders a section with several information rendered next to each other (or below for mobile view)
|
|
783
|
-
|
|
784
|
-
```jsx
|
|
785
|
-
import { InfoGroup } from '@hortiview/shared-components';
|
|
786
|
-
|
|
787
|
-
const fields: FieldItem[] = [
|
|
788
|
-
{ label: 'FieldTitle', value: 'Value' },
|
|
789
|
-
{ label: 'AnotherFieldTitle', value: 'ValueButInPrimaryColor', themeColor: 'primary' },
|
|
790
|
-
//render a component below the label
|
|
791
|
-
{ label: 'StatusBadge', variant: 'embedded', component: <LabelBadge label='redLabel' themeColor='red'>}
|
|
792
|
-
//render a complex component without label
|
|
793
|
-
{ label: 'ComplexComponent', component: <ComplexComponent />}
|
|
794
|
-
]
|
|
795
|
-
|
|
796
|
-
<InfoGroup fields={fields} />
|
|
797
|
-
```
|
|
798
|
-
|
|
799
|
-
You can also render a multiline section, that receives an array if FieldItem-Arrays instead of a single FieldItem-Array
|
|
800
|
-
|
|
801
|
-
```jsx
|
|
802
|
-
import { InfoGroup } from '@hortiview/shared-components';
|
|
803
|
-
|
|
804
|
-
const multiLineFields: FieldItem[][] = [
|
|
805
|
-
[
|
|
806
|
-
{ label: 'FieldTitle', value: 'Value' },
|
|
807
|
-
{ label: 'AnotherFieldTitle', value: 'ValueButInPrimaryColor', themeColor: 'primary' }
|
|
808
|
-
],
|
|
809
|
-
[
|
|
810
|
-
{ label: 'LongField', value: 'VeryLongValueThatNeedsToBeDisplayedInANewLine'}
|
|
811
|
-
],
|
|
812
|
-
[
|
|
813
|
-
{ label: 'ComplexComponent', component: <ComplexComponent />},
|
|
814
|
-
{ label: 'FieldTitle2', value: 'Value2' },
|
|
815
|
-
{ label: 'FieldTitle3', value: 'Value3' },
|
|
816
|
-
{ label: 'FieldTitle4', value: 'Value4' },
|
|
817
|
-
]
|
|
818
|
-
]
|
|
819
|
-
|
|
820
|
-
<InfoGroup fields={multiLineFields} />
|
|
821
|
-
|
|
822
|
-
```
|
|
823
|
-
|
|
824
|
-
### Iconify
|
|
825
|
-
|
|
826
|
-
Provides some custom icons based on the elements Icon API. Currently supported:
|
|
827
|
-
|
|
828
|
-
- battery_0 | battery_20 | battery_50 | battery_80 | battery_100
|
|
829
|
-
- block
|
|
830
|
-
- block-delete
|
|
831
|
-
- cloud-rain
|
|
832
|
-
- cloud-sunny
|
|
833
|
-
- cloud
|
|
834
|
-
- farm-delete
|
|
835
|
-
- farm
|
|
836
|
-
- greenhouse-delete
|
|
837
|
-
- subscription
|
|
838
|
-
- wind
|
|
839
|
-
|
|
840
|
-
```jsx
|
|
841
|
-
import { Iconify } from '@hortiview/shared-components';
|
|
842
|
-
|
|
843
|
-
<Iconify icon='wind' iconSize='large' />;
|
|
844
|
-
```
|
|
845
|
-
|
|
846
|
-
### ListArea
|
|
847
|
-
|
|
848
|
-
Shows some items in a list. The list can be used as a navigation list and provides search. For the best experience use `react-router`.
|
|
849
|
-
|
|
850
|
-
```jsx
|
|
851
|
-
import { BaseListElement, ListArea } from '@hortiview/shared-components';
|
|
852
|
-
import { Link, useLocation } from 'react-router-dom';
|
|
853
|
-
|
|
854
|
-
const { pathname } = useLocation();
|
|
855
|
-
|
|
856
|
-
const elements: BaseListElement[] = [{
|
|
857
|
-
route: `/my/route/${1}`,
|
|
858
|
-
id: 1,
|
|
859
|
-
title: 'name',
|
|
860
|
-
subTitle: 'sub-name',
|
|
861
|
-
icon: <Icon icon={'grass'} />,
|
|
862
|
-
}]
|
|
863
|
-
|
|
864
|
-
<ListArea
|
|
865
|
-
hasSearch
|
|
866
|
-
searchPlaceholder={'Search....'}
|
|
867
|
-
elements={elements}
|
|
868
|
-
isSorted={false}
|
|
869
|
-
pathname={pathname}
|
|
870
|
-
routerLinkElement={Link}
|
|
871
|
-
/>;
|
|
872
|
-
```
|
|
873
|
-
|
|
874
|
-
### LoadingSpinner
|
|
875
|
-
|
|
876
|
-
Renders a loading spinner. The loading spinner can be customized in size, text and color. It can also be centered.
|
|
877
|
-
|
|
878
|
-
```JSX
|
|
879
|
-
import { LoadingSpinner } from '@hortiview/shared-components';
|
|
880
|
-
|
|
881
|
-
const [loading, setLoading] = useState(false)
|
|
882
|
-
|
|
883
|
-
//logic that changes state of loading to true
|
|
884
|
-
|
|
885
|
-
if(loading) return <LoadingSpinner />
|
|
886
|
-
return <DefaultComponent />
|
|
887
|
-
```
|
|
888
|
-
|
|
889
|
-
There is also a big loading spinner, that blurs the background and renders an spinning hortiview-logo.
|
|
890
|
-
|
|
891
|
-
```JSX
|
|
892
|
-
import { LoadingSpinner } from '@hortiview/shared-components';
|
|
893
|
-
|
|
894
|
-
const [loading, setLoading] = useState(false)
|
|
895
|
-
|
|
896
|
-
const onSubmit = () => {
|
|
897
|
-
setLoading(true);
|
|
898
|
-
await someComplexLogic();
|
|
899
|
-
setLoading(false);
|
|
900
|
-
}
|
|
901
|
-
return <>
|
|
902
|
-
{loading && <LoadingSpinner size='big' text='Loading something ...' />}
|
|
903
|
-
<Form obSubmit={onSubmit} />
|
|
904
|
-
<Button type='submit' />
|
|
905
|
-
</>
|
|
906
|
-
```
|
|
907
|
-
|
|
908
|
-
The Loading spinner will automatically change to another text, after a certain waiting time, the text and time are adjustable.
|
|
909
|
-
This behavior is enabled per default (10 seconds) - it can be disabled by passing `null` to impatienceMessage.
|
|
910
|
-
|
|
911
|
-
```JSX
|
|
912
|
-
import { LoadingSpinner } from '@hortiview/shared-components';
|
|
913
|
-
|
|
914
|
-
const [loading, setLoading] = useState(false)
|
|
915
|
-
|
|
916
|
-
const onSubmit = () => {
|
|
917
|
-
setLoading(true);
|
|
918
|
-
await someComplexLogicThatTakesVeryLong();
|
|
919
|
-
setLoading(false);
|
|
920
|
-
}
|
|
921
|
-
return <>
|
|
922
|
-
{loading && <LoadingSpinner text='Loading something ...' impatienceTimeout={20} impatienceMessage={'Something takes longer than expected'} />}
|
|
923
|
-
<Form obSubmit={onSubmit} />
|
|
924
|
-
<Button type='submit' />
|
|
925
|
-
</>
|
|
926
|
-
```
|
|
927
|
-
|
|
928
|
-
### Modal
|
|
929
|
-
|
|
930
|
-
Provides the normal Element modal with one additional change. If you are on fullscreen modal size the max-height and max-width is set to 100svh/svw (Smallest ViewPort height/width).
|
|
931
|
-
This will set the modal size on an area between the mobile controls.
|
|
932
|
-
|
|
933
|
-
The modal also includes a custom header, which has a close button of type `button`.
|
|
934
|
-
The base Element design button has type `submit`, which breaks forms inside of the modal.
|
|
935
|
-
Please provide `onClose` and `title` props to get it work properly.
|
|
936
|
-
|
|
937
|
-
```jsx
|
|
938
|
-
import { Modal } from '@hortiview/shared-components';
|
|
939
|
-
|
|
940
|
-
<Modal modalSize='fullscreen'>
|
|
941
|
-
<div>Content</div>
|
|
942
|
-
</Modal>;
|
|
943
|
-
```
|
|
944
|
-
|
|
945
|
-
### ModulePadding
|
|
946
|
-
|
|
947
|
-
Provides a responsive padding component for modules according to the HV platform UI guidelines, based on the Bayer Element padding component.
|
|
948
|
-
|
|
949
|
-
Currently, the padding is set to 8px on mobile/tablet and 16px on desktop.
|
|
950
|
-
|
|
951
|
-
> **Strong recommendation**: If your module does not require any fullscreen features, we highly encourage you to add the `ModulePadding` around your module content to ensure a consistent user experience within the rest of the platform.
|
|
952
|
-
|
|
953
|
-
```jsx
|
|
954
|
-
import { ModulePadding } from '@hortiview/shared-components';
|
|
955
|
-
|
|
956
|
-
<ModulePadding>
|
|
957
|
-
<div>Content</div>
|
|
958
|
-
</ModulePadding>;
|
|
959
|
-
```
|
|
960
|
-
|
|
961
|
-
### OfflineView
|
|
962
|
-
|
|
963
|
-
Shows an offline state with icon, title, and optional subtitle. Use `size` 'small' inline and 'large' for full pages.
|
|
964
|
-
|
|
965
|
-
```jsx
|
|
966
|
-
import { OfflineView } from '@hortiview/shared-components';
|
|
967
|
-
|
|
968
|
-
<OfflineView title='Title' subtitle='Subtitle' />;
|
|
969
|
-
```
|
|
970
|
-
|
|
971
|
-
### OnboardingBanner
|
|
972
|
-
|
|
973
|
-
A responsive onboarding banner that adapts its layout for desktop and mobile.
|
|
974
|
-
|
|
975
|
-
- **Desktop:** Media content is displayed to the _right_ of the description
|
|
976
|
-
- **Mobile:** Media content appears _above_ the description
|
|
977
|
-
|
|
978
|
-
```jsx
|
|
979
|
-
import { OnboardingBanner } from '@hortiview/shared-components';
|
|
980
|
-
|
|
981
|
-
<OnboardingBanner headline='Hello' />;
|
|
982
|
-
```
|
|
983
|
-
|
|
984
|
-
### OverflowTooltip
|
|
985
|
-
|
|
986
|
-
Provides a tooltip and overflow behavior of a given text value.
|
|
987
|
-
|
|
988
|
-
```jsx
|
|
989
|
-
import { OverflowTooltip } from '@hortiview/shared-components';
|
|
990
|
-
import { TypoBody } from '@element-public/react-components';
|
|
991
|
-
|
|
992
|
-
const longText =
|
|
993
|
-
'This is a very long text that needs to be truncated and shown with a tooltip when it overflows.';
|
|
994
|
-
|
|
995
|
-
<OverflowTooltip text={longText}>
|
|
996
|
-
<TypoBody>{longText}</TypoBody>
|
|
997
|
-
</OverflowTooltip>;
|
|
998
|
-
```
|
|
999
|
-
|
|
1000
|
-
### Permissions
|
|
1001
|
-
|
|
1002
|
-
This shared library provides different hooks and component that can be used to check wether a user is allowed to proceed with an action, view a component or not.
|
|
1003
|
-
|
|
1004
|
-
In order for this component to correctly determine whether a user has the appropriate permissions, a basic setup must be implemented. The following section explains how:
|
|
1005
|
-
|
|
1006
|
-
#### Setup
|
|
1007
|
-
|
|
1008
|
-
#### 1. Wrap your app with the SharedComponentsPermissionProvider
|
|
1009
|
-
|
|
1010
|
-
In your main application file (e.g., `App.tsx` or `main.tsx`), wrap your app with the `PermissionProvider`:
|
|
1011
|
-
|
|
1012
|
-
```tsx
|
|
1013
|
-
import { SharedComponentsPermissionProvider } from '@hortiview/shared-components';
|
|
1014
|
-
|
|
1015
|
-
function App() {
|
|
1016
|
-
// Get these values from your store or state management
|
|
1017
|
-
// In this example `Zustand` stores are used
|
|
1018
|
-
const userPermissions = useClaimsIdentityStore(state => state.userPermissions);
|
|
1019
|
-
const activeOrganizationId = useActiveOrganizationStore(state => state.activeOrganization?.id);
|
|
1020
|
-
|
|
1021
|
-
return (
|
|
1022
|
-
<SharedComponentsPermissionProvider
|
|
1023
|
-
userPermissions={userPermissions}
|
|
1024
|
-
activeOrganizationId={activeOrganizationId}
|
|
1025
|
-
>
|
|
1026
|
-
<YourAppComponents />
|
|
1027
|
-
</SharedComponentsPermissionProvider>
|
|
1028
|
-
);
|
|
1029
|
-
}
|
|
1030
|
-
```
|
|
1031
|
-
|
|
1032
|
-
#### 2.1 Use the Allowed component anywhere in your app
|
|
1033
|
-
|
|
1034
|
-
Once the provider is set up, you can use `<Allowed />` anywhere in your component tree without passing props. The wrapped component is conditionally rendered depending on the user permissions:
|
|
1035
|
-
|
|
1036
|
-
```tsx
|
|
1037
|
-
import { Allowed } from '@hortiview/shared-components';
|
|
1038
|
-
|
|
1039
|
-
function MyComponent() {
|
|
1040
|
-
return (
|
|
1041
|
-
<Allowed neededPermissions={["organization-read", "organization-edit"]} entityId={organizationId}>
|
|
1042
|
-
<OrganizationSettings />
|
|
1043
|
-
<Allowed/>
|
|
1044
|
-
);
|
|
1045
|
-
}
|
|
1046
|
-
```
|
|
1047
|
-
|
|
1048
|
-
#### 2.2 Use the useIsAllowed-hook anywhere in your app
|
|
1049
|
-
|
|
1050
|
-
The `useIsAllowed`-hook works similar to the `<Allowed />` component. Instead of being used as a wrapper it returns a boolean. That value can be used to conditionally render components or control application logic based on user permissions.
|
|
1051
|
-
|
|
1052
|
-
```tsx
|
|
1053
|
-
import { useIsAllowed } from '@hortiview/shared-components';
|
|
1054
|
-
|
|
1055
|
-
function MyComponent() {
|
|
1056
|
-
const isAllowed = useIsAllowed();
|
|
1057
|
-
|
|
1058
|
-
// Check if user has permission to edit members for the current organization
|
|
1059
|
-
const canEditMembers = isAllowed(['member-edit', 'member-create'], orgId);
|
|
1060
|
-
|
|
1061
|
-
return <MembersList isDisabled={!canEditMembers} />;
|
|
1062
|
-
}
|
|
1063
|
-
```
|
|
1064
|
-
|
|
1065
|
-
#### 2.3 Use the AllowedButton or AllowedIconButton anywhere in your app
|
|
1066
|
-
|
|
1067
|
-
Once the provider is set up, you can use `AllowedButton` and `AllowedIconButton` anywhere in your component tree without passing props. Both buttons expect a permissions array and call the `useIsAllowed` under the hood.
|
|
1068
|
-
|
|
1069
|
-
> **Note:** Both components will automatically hide (return `null`) if the user doesn't have the required permissions. The button will only render when the user is authorized.
|
|
1070
|
-
|
|
1071
|
-
**AllowedButton Example:**
|
|
1072
|
-
|
|
1073
|
-
```jsx
|
|
1074
|
-
import { AllowedButton, Permission } from '@hortiview/shared-components';
|
|
1075
|
-
|
|
1076
|
-
function FarmActions({ farmId }) {
|
|
1077
|
-
return (
|
|
1078
|
-
<div>
|
|
1079
|
-
<AllowedButton
|
|
1080
|
-
data-testid='edit-season-button'
|
|
1081
|
-
label='Edit Season'
|
|
1082
|
-
permissions={['season-edit']}
|
|
1083
|
-
entityId={organizationId}
|
|
1084
|
-
buttonVariant='filled'
|
|
1085
|
-
onClick={() => handleEditSeason(seasonId)}
|
|
1086
|
-
/>
|
|
1087
|
-
|
|
1088
|
-
<AllowedButton
|
|
1089
|
-
data-testid='delete-season-button'
|
|
1090
|
-
label='Delete Season'
|
|
1091
|
-
permissions={['season-delete']}
|
|
1092
|
-
entityId={organizationId}
|
|
1093
|
-
buttonVariant='danger'
|
|
1094
|
-
onClick={() => handleDeleteSeason(seasonId)}
|
|
1095
|
-
/>
|
|
1096
|
-
</div>
|
|
1097
|
-
);
|
|
1098
|
-
}
|
|
1099
|
-
```
|
|
1100
|
-
|
|
1101
|
-
**AllowedIconButton Example:**
|
|
1102
|
-
|
|
1103
|
-
```jsx
|
|
1104
|
-
import { AllowedIconButton, Permission } from '@hortiview/shared-components';
|
|
1105
|
-
|
|
1106
|
-
function BlockActions({ blockId, farmId }) {
|
|
1107
|
-
return (
|
|
1108
|
-
<div>
|
|
1109
|
-
<AllowedIconButton
|
|
1110
|
-
data-testid='edit-block-icon'
|
|
1111
|
-
icon='edit'
|
|
1112
|
-
permissions={['block-edit', 'block-create']}
|
|
1113
|
-
entityId={farmId}
|
|
1114
|
-
iconButtonVariant='filled-primary'
|
|
1115
|
-
onClick={() => handleEditBlock(blockId)}
|
|
1116
|
-
/>
|
|
1117
|
-
|
|
1118
|
-
<AllowedIconButton
|
|
1119
|
-
data-testid='delete-block-icon'
|
|
1120
|
-
icon='delete'
|
|
1121
|
-
permissions={['block-delete']}
|
|
1122
|
-
entityId={farmId}
|
|
1123
|
-
iconButtonVariant='filled-danger'
|
|
1124
|
-
onClick={() => handleDeleteBlock(blockId)}
|
|
1125
|
-
/>
|
|
1126
|
-
</div>
|
|
1127
|
-
);
|
|
1128
|
-
}
|
|
1129
|
-
```
|
|
1130
|
-
|
|
1131
|
-
### SafeForm
|
|
1132
|
-
|
|
1133
|
-
A wrapper around a form that prevents accidental submission when pressing Enter in input fields.
|
|
1134
|
-
|
|
1135
|
-
- It handles the 'keydown' event and intercepts the Enter key press.
|
|
1136
|
-
- If the focused element is a button, submit button or text area, it allows the default behavior.
|
|
1137
|
-
- Otherwise, it prevents the default action to avoid unintended submissions.
|
|
1138
|
-
|
|
1139
|
-
```jsx
|
|
1140
|
-
import { SafeForm } from '@hortiview/shared-components';
|
|
1141
|
-
|
|
1142
|
-
<FormProvider {...formMethods}>
|
|
1143
|
-
<SafeForm onSubmit={handleSubmit(onSubmitForm)}>
|
|
1144
|
-
<Group direction='vertical' primaryAlign='space-between'>
|
|
1145
|
-
{children}
|
|
1146
|
-
<Button type='submit'>Submit</Button>
|
|
1147
|
-
</Group>
|
|
1148
|
-
</SafeForm>
|
|
1149
|
-
</FormProvider>;
|
|
1150
|
-
```
|
|
1151
|
-
|
|
1152
|
-
### ScrollBar
|
|
1153
|
-
|
|
1154
|
-
Provides a scrollbar in hortiview styling. Add it a classname on your component.
|
|
1155
|
-
|
|
1156
|
-
```jsx
|
|
1157
|
-
|
|
1158
|
-
import { ScrollbarY, ScrollbarX } from '@hortiview/shared-components';
|
|
1159
|
-
|
|
1160
|
-
<div className={`${ScrollbarY}`}>
|
|
1161
|
-
Height content
|
|
1162
|
-
<div>
|
|
1163
|
-
|
|
1164
|
-
<div className={`${ScrollbarX}`}>
|
|
1165
|
-
Wide content
|
|
1166
|
-
<div>
|
|
1167
|
-
|
|
1168
|
-
```
|
|
1169
|
-
|
|
1170
|
-
### SearchBar
|
|
1171
|
-
|
|
1172
|
-
Provides a searchbar component.
|
|
1173
|
-
|
|
1174
|
-
```jsx
|
|
1175
|
-
import { SearchBar } from '@hortiview/shared-components';
|
|
1176
|
-
|
|
1177
|
-
const [searchValue, setSearchValue] = useState('');
|
|
1178
|
-
<SearchBar
|
|
1179
|
-
searchTerm={searchValue}
|
|
1180
|
-
setSearchTerm={setSearchValue}
|
|
1181
|
-
dense
|
|
1182
|
-
placeholder={'Search....'}
|
|
1183
|
-
/>;
|
|
1184
|
-
```
|
|
1185
|
-
|
|
1186
|
-
### Select
|
|
1187
|
-
|
|
1188
|
-
Provides the normal Element select with some additional presets and props:
|
|
1189
|
-
|
|
1190
|
-
- `menuMaxHeight` has a default value of `15rem` (can be overwritten)
|
|
1191
|
-
- custom styles are applied that improve the `hoisted` select menu behavior and avoid two scrolling bars on multi select menus
|
|
1192
|
-
- custom portal styles can be passed via the `portalClassName` prop - only works when `portalContainer` is not set
|
|
1193
|
-
|
|
1194
|
-
> **Warning**: Don't set `menuPosition` when `hoisted` is true.
|
|
1195
|
-
|
|
1196
|
-
```jsx
|
|
1197
|
-
import { Select } from '@hortiview/shared-components';
|
|
1198
|
-
...
|
|
1199
|
-
|
|
1200
|
-
<Select
|
|
1201
|
-
label='Contact during review'
|
|
1202
|
-
options={contacts}
|
|
1203
|
-
hoisted
|
|
1204
|
-
textKey='text'
|
|
1205
|
-
valueKey='id'
|
|
1206
|
-
onChange={handleContactSelect}
|
|
1207
|
-
value={contact}
|
|
1208
|
-
helperText='required'
|
|
1209
|
-
variant='outlined'
|
|
1210
|
-
portalClassName={styles.portal}
|
|
1211
|
-
/>;
|
|
1212
|
-
```
|
|
1213
|
-
|
|
1214
|
-
### Stepper
|
|
1215
|
-
|
|
1216
|
-
Provides a simple stepper component, which contains the step indicators, a title text and buttons to navigate forwards and backwards.
|
|
1217
|
-
The component is available in two types:
|
|
1218
|
-
|
|
1219
|
-
- 'default' (steps as dots and a centered step title below them)
|
|
1220
|
-
- 'description' (n/n numerical progress, description/title right of it)
|
|
1221
|
-
|
|
1222
|
-
**Be aware that you need to control the Stepper flow by your own, like:**
|
|
1223
|
-
|
|
1224
|
-
```jsx
|
|
1225
|
-
import { Step, Stepper } from '@hortiview/shared-components';
|
|
1226
|
-
|
|
1227
|
-
const [currentStep, setCurrentStep] = useState(0);
|
|
1228
|
-
|
|
1229
|
-
const steps: Step[] = [
|
|
1230
|
-
{
|
|
1231
|
-
name: 'first',
|
|
1232
|
-
step: 0,
|
|
1233
|
-
title: 'First Step',
|
|
1234
|
-
optional: false,
|
|
1235
|
-
nextButtonProps: {
|
|
1236
|
-
onClick: () => { setCurrentStep(1)},
|
|
1237
|
-
label: 'Next',
|
|
1238
|
-
showArrowIcon: true,
|
|
1239
|
-
},
|
|
1240
|
-
prevButtonProps: {
|
|
1241
|
-
onClick: () => { // handle cancel action },
|
|
1242
|
-
label: 'Cancel',
|
|
1243
|
-
showArrowIcon: false,
|
|
1244
|
-
},
|
|
1245
|
-
},
|
|
1246
|
-
{
|
|
1247
|
-
name: 'second',
|
|
1248
|
-
step: 1,
|
|
1249
|
-
title: 'Second Step',
|
|
1250
|
-
optional: true,
|
|
1251
|
-
nextButtonProps: {
|
|
1252
|
-
onClick: () => { // handle finish action },
|
|
1253
|
-
label: 'Send',
|
|
1254
|
-
showArrowIcon: false,
|
|
1255
|
-
},
|
|
1256
|
-
prevButtonProps: {
|
|
1257
|
-
onClick: () => { setCurrentStep(0)},
|
|
1258
|
-
label: 'Back',
|
|
1259
|
-
showArrowIcon: false,
|
|
1260
|
-
},
|
|
1261
|
-
},
|
|
1262
|
-
];
|
|
1263
|
-
|
|
1264
|
-
<Stepper
|
|
1265
|
-
type={'default'}
|
|
1266
|
-
steps={steps}
|
|
1267
|
-
currentStep={currentStep}
|
|
1268
|
-
/>;
|
|
1269
|
-
```
|
|
1270
|
-
|
|
1271
|
-
### VerticalDivider
|
|
1272
|
-
|
|
1273
|
-
Provides a simple vertical divider.
|
|
1274
|
-
|
|
1275
|
-
```jsx
|
|
1276
|
-
import { VerticalDivider } from '@hortiview/shared-components';
|
|
1277
|
-
|
|
1278
|
-
<VerticalDivider className={'custom'} height='3rem' />;
|
|
1279
|
-
```
|
|
1280
|
-
|
|
1281
|
-
## Available Utility Functions:
|
|
1282
|
-
|
|
1283
|
-
### useBreakpoints
|
|
1284
|
-
|
|
1285
|
-
Hook that returns the current breakpoint. It uses the following breakpoints:
|
|
1286
|
-
|
|
1287
|
-
- xs: 0-599px
|
|
1288
|
-
- sm: 600-719px
|
|
1289
|
-
- md: 720-839px
|
|
1290
|
-
- lg: 840-1023px
|
|
1291
|
-
- xl: 1024-1439px
|
|
1292
|
-
- xxl: 1440px and up
|
|
1293
|
-
|
|
1294
|
-
Additional breakpoints considering the navbar width
|
|
1295
|
-
|
|
1296
|
-
- lg-nav: (840 + 256) - (1023 + 256)px
|
|
1297
|
-
- xl-nav: (1024 + 256) - (1439 + 256)px
|
|
1298
|
-
- xxl-nav: (1440 + 256)px and up
|
|
1299
|
-
|
|
1300
|
-
They are combined as follows:
|
|
1301
|
-
|
|
1302
|
-
- isMobile: xs
|
|
1303
|
-
- isTablet: sm, md
|
|
1304
|
-
- isDesktop: lg, xl, xxl
|
|
1305
|
-
- isDesktopNavbar: lg-nav, xl-nav, xxl-nav
|
|
1306
|
-
|
|
1307
|
-
### capitalizeFirstLetters
|
|
1308
|
-
|
|
1309
|
-
Capitalizes the first letter of every word in a given text string
|
|
1310
|
-
|
|
1311
|
-
### trimLeadingAndTrailingSpaces
|
|
1312
|
-
|
|
1313
|
-
This function can be used when sending form data to the BE (see the example below).
|
|
1314
|
-
It removes leading and trailing spaces from all object properties that are typeof string.
|
|
1315
|
-
|
|
1316
|
-
```typescript
|
|
1317
|
-
const onSubmit = async (data: Record<string, string>) => {
|
|
1318
|
-
const trimmedData = trimLeadingAndTrailingSpaces(data);
|
|
1319
|
-
|
|
1320
|
-
const loginResponse = await login(trimmedData.email, trimmedData.password);
|
|
1321
|
-
if (loginResponse.ok) {
|
|
1322
|
-
console.log('logged in');
|
|
1323
|
-
}
|
|
1324
|
-
};
|
|
1325
|
-
```
|
|
1326
|
-
|
|
1327
|
-
Important note: If the type from the data is an interface the data need to be spread to avoid the following error.
|
|
1328
|
-
https://github.com/microsoft/TypeScript/issues/15300
|
|
1329
|
-
|
|
1330
|
-
```typescript
|
|
1331
|
-
const trimmedData = trimLeadingAndTrailingSpaces({ ...data });
|
|
1332
|
-
```
|
|
1333
|
-
|
|
1334
|
-
### getNumberAsLocaleString
|
|
1335
|
-
|
|
1336
|
-
Receives a number and returns the value as a locale string.
|
|
1337
|
-
Note: Should only be used for displaying numbers, not for calculations or values that are supposed to be send to the backend.
|
|
1338
|
-
|
|
1339
|
-
```typescript
|
|
1340
|
-
const userLocale = 'es-MX';
|
|
1341
|
-
|
|
1342
|
-
const overlineTitle = `${getNumberAsLocaleString(userLocale, totalArea, 5)} ${t(
|
|
1343
|
-
'squaremeter-unit'
|
|
1344
|
-
)}`;
|
|
1345
|
-
```
|
|
1346
|
-
|
|
1347
|
-
### getFormattedDateTime
|
|
1348
|
-
|
|
1349
|
-
Formats a date (string) with Intl.DateTimeFormat.
|
|
1350
|
-
If locale is a plain code ("en" | "es" | "tr"), it’s mapped to a regional tag ("en-US", "es-MX", "tr-TR").
|
|
1351
|
-
|
|
1352
|
-
For consistency, please use `DATE_FORMAT`, `TIME_FORMAT` and `DATE_TIME_FORMAT`.
|
|
1353
|
-
|
|
1354
|
-
```typescript
|
|
1355
|
-
import { DATE_FORMAT, TIME_FORMAT, DATE_TIME_FORMAT } from '@hortiview/shared-components';
|
|
1356
|
-
|
|
1357
|
-
getFormattedDateTime('2025-10-02T14:30:00Z', 'en-US', DATE_FORMAT);
|
|
1358
|
-
// -> 10/02/2025
|
|
1359
|
-
getFormattedDateTime('2025-10-02T14:30:00Z', 'es-MX', TIME_FORMAT);
|
|
1360
|
-
// -> 04:30 p.m.
|
|
1361
|
-
getFormattedDateTime('2025-10-02T14:30:00Z', 'tr-TR', DATE_TIME_FORMAT);
|
|
1362
|
-
// -> 02.10.2025 ÖS 04:30
|
|
1363
|
-
```
|
|
1364
|
-
|
|
1365
|
-
## Available constants
|
|
1366
|
-
|
|
1367
|
-
### Languages and countries
|
|
1368
|
-
|
|
1369
|
-
The file contains different languages and country constants as well as language ids, which represents the available languages and countries of the hortiview platform.
|
|
1370
|
-
|
|
1371
|
-
The supported languages are:
|
|
1372
|
-
|
|
1373
|
-
- English (en)
|
|
1374
|
-
- Spanish (es)
|
|
1375
|
-
- Turkish (tr)
|
|
1376
|
-
|
|
1377
|
-
The supported countries are:
|
|
1378
|
-
|
|
1379
|
-
- Spain (esp)
|
|
1380
|
-
- Mexico (mex)
|
|
1381
|
-
- Turkey (tur)
|
|
1382
|
-
|
|
1383
|
-
```typescript
|
|
1384
|
-
const languageCode = 'en' as AVAILABLE_LANGUAGE_CODES;
|
|
1385
|
-
const languageCountryCode = LANGUAGE_CODES_MAPPER[languageCode];
|
|
1386
|
-
console.log(languageCountryCode); // 'en-US'
|
|
1387
|
-
```
|