@opentrons/components 0.1.6-alpha.2 → 0.1.6-alpha.21
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/Makefile +5 -1
- package/package.json +6 -7
- package/src/__mocks__/file.js +10 -0
- package/src/alerts/AlertItem.stories.tsx +49 -0
- package/src/alerts/AlertItem.tsx +85 -0
- package/src/alerts/index.ts +3 -0
- package/src/atoms/Checkbox/Checkbox.stories.tsx +24 -0
- package/src/atoms/Checkbox/index.tsx +127 -0
- package/src/atoms/CheckboxField/CheckboxField.stories.tsx +30 -0
- package/src/atoms/CheckboxField/index.tsx +171 -0
- package/src/atoms/Chip/Chip.stories.tsx +59 -0
- package/src/atoms/Chip/index.tsx +172 -0
- package/src/atoms/Divider/index.tsx +15 -0
- package/src/atoms/InputField/InputField.stories.tsx +77 -0
- package/src/atoms/InputField/index.tsx +383 -0
- package/src/atoms/ListButton/ListButton.stories.tsx +133 -0
- package/src/atoms/ListButton/ListButtonChildren/ListButtonAccordion.tsx +65 -0
- package/src/atoms/ListButton/ListButtonChildren/ListButtonAccordionContainer.tsx +23 -0
- package/src/atoms/ListButton/ListButtonChildren/ListButtonRadioButton.tsx +108 -0
- package/src/atoms/ListButton/ListButtonChildren/index.ts +3 -0
- package/src/atoms/ListButton/index.tsx +72 -0
- package/src/atoms/ListItem/ListItem.stories.tsx +96 -0
- package/src/atoms/ListItem/ListItemChildren/ListItemCustomize.tsx +78 -0
- package/src/atoms/ListItem/ListItemChildren/ListItemDescriptor.tsx +42 -0
- package/src/atoms/ListItem/ListItemChildren/index.ts +2 -0
- package/src/atoms/ListItem/index.tsx +89 -0
- package/src/atoms/MenuList/MenuItem.stories.tsx +20 -0
- package/src/atoms/MenuList/MenuItem.tsx +55 -0
- package/src/atoms/MenuList/MenuList.stories.tsx +31 -0
- package/src/atoms/MenuList/OverflowBtn.stories.tsx +17 -0
- package/src/atoms/MenuList/OverflowBtn.tsx +76 -0
- package/src/atoms/MenuList/index.tsx +50 -0
- package/src/atoms/Snackbar/Snackbar.stories.tsx +67 -0
- package/src/atoms/Snackbar/index.tsx +91 -0
- package/src/atoms/StepMeter/index.tsx +53 -0
- package/src/atoms/StyledText/LegacyStyledText.stories.tsx +106 -0
- package/src/atoms/StyledText/LegacyStyledText.tsx +95 -0
- package/src/atoms/StyledText/StyledText.stories.tsx +46 -0
- package/src/atoms/StyledText/StyledText.tsx +323 -0
- package/src/atoms/StyledText/index.ts +2 -0
- package/src/atoms/Tag/Tag.stories.tsx +48 -0
- package/src/atoms/Tag/index.tsx +116 -0
- package/src/atoms/Toast/ODDToast.stories.tsx +68 -0
- package/src/atoms/Toast/Toast.stories.tsx +55 -0
- package/src/atoms/Toast/index.tsx +439 -0
- package/src/atoms/ToggleGroup/ToggleGroup.stories.tsx +39 -0
- package/src/atoms/ToggleGroup/index.tsx +91 -0
- package/src/atoms/Tooltip/Tooltip.stories.tsx +99 -0
- package/src/atoms/Tooltip/index.tsx +38 -0
- package/src/atoms/buttons/AlertPrimaryButton.tsx +26 -0
- package/src/atoms/buttons/AltPrimaryButton.tsx +31 -0
- package/src/atoms/buttons/EmptySelectorButton.stories.tsx +36 -0
- package/src/atoms/buttons/EmptySelectorButton.tsx +83 -0
- package/src/atoms/buttons/LargeButton.stories.tsx +99 -0
- package/src/atoms/buttons/LargeButton.tsx +320 -0
- package/src/atoms/buttons/PrimaryButton.tsx +36 -0
- package/src/atoms/buttons/RadioButton.stories.tsx +35 -0
- package/src/atoms/buttons/RadioButton.tsx +217 -0
- package/src/atoms/buttons/SecondaryButton.tsx +62 -0
- package/src/atoms/buttons/buttons.stories.tsx +78 -0
- package/src/atoms/buttons/index.ts +6 -0
- package/src/atoms/index.ts +20 -0
- package/src/barrel.ts +10 -0
- package/src/buttons/Button.tsx +96 -0
- package/src/buttons/DeprecatedPrimaryButton.tsx +24 -0
- package/src/buttons/FlatButton.tsx +21 -0
- package/src/buttons/IconButton.tsx +37 -0
- package/src/buttons/OutlineButton.tsx +24 -0
- package/src/buttons/index.ts +7 -0
- package/src/controls/ControlInfo.tsx +13 -0
- package/src/controls/LabeledButton.tsx +28 -0
- package/src/controls/LabeledCheckbox.tsx +35 -0
- package/src/controls/LabeledControl.tsx +24 -0
- package/src/controls/LabeledRadioGroup.tsx +27 -0
- package/src/controls/LabeledSelect.tsx +34 -0
- package/src/controls/LabeledToggle.tsx +35 -0
- package/src/controls/StackedLabeledControl.tsx +28 -0
- package/src/controls/ToggleButton.tsx +25 -0
- package/src/controls/index.ts +10 -0
- package/src/forms/DeprecatedCheckboxField.stories.tsx +31 -0
- package/src/forms/DeprecatedCheckboxField.tsx +94 -0
- package/src/forms/DropdownField.stories.tsx +44 -0
- package/src/forms/DropdownField.tsx +106 -0
- package/src/forms/FormGroup.stories.tsx +31 -0
- package/src/forms/FormGroup.tsx +53 -0
- package/src/forms/InputField.stories.tsx +41 -0
- package/src/forms/LegacyInputField.tsx +123 -0
- package/src/forms/RadioGroup.stories.tsx +44 -0
- package/src/forms/RadioGroup.tsx +87 -0
- package/src/forms/Select.stories.tsx +117 -0
- package/src/forms/Select.tsx +132 -0
- package/src/forms/SelectField.tsx +94 -0
- package/src/forms/ToggleField.stories.tsx +31 -0
- package/src/forms/ToggleField.tsx +59 -0
- package/src/forms/index.ts +8 -0
- package/src/hardware-sim/BaseDeck/BaseDeck.stories.tsx +94 -0
- package/src/hardware-sim/BaseDeck/BaseDeck.tsx +423 -0
- package/src/hardware-sim/BaseDeck/SingleSlotFixture.tsx +199 -0
- package/src/hardware-sim/BaseDeck/SlotBase.tsx +5 -0
- package/src/hardware-sim/BaseDeck/SlotClip.tsx +15 -0
- package/src/hardware-sim/BaseDeck/StagingAreaFixture.tsx +114 -0
- package/src/hardware-sim/BaseDeck/WasteChuteFixture.tsx +114 -0
- package/src/hardware-sim/BaseDeck/WasteChuteStagingAreaFixture.tsx +68 -0
- package/src/hardware-sim/BaseDeck/__fixtures__/index.ts +165 -0
- package/src/hardware-sim/BaseDeck/index.ts +5 -0
- package/src/hardware-sim/BaseDeck/something.test.tsx +7 -0
- package/src/hardware-sim/Deck/DeckFromLayers.tsx +58 -0
- package/src/hardware-sim/Deck/FlexTrash.tsx +128 -0
- package/src/hardware-sim/Deck/MoveLabwareOnDeck.stories.tsx +97 -0
- package/src/hardware-sim/Deck/MoveLabwareOnDeck.tsx +251 -0
- package/src/hardware-sim/Deck/OT2Layers.tsx +153 -0
- package/src/hardware-sim/Deck/RobotCoordsForeignDiv.tsx +46 -0
- package/src/hardware-sim/Deck/RobotCoordsForeignObject.tsx +42 -0
- package/src/hardware-sim/Deck/RobotCoordsText.tsx +32 -0
- package/src/hardware-sim/Deck/RobotWorkSpace.tsx +90 -0
- package/src/hardware-sim/Deck/SlotLabels.tsx +111 -0
- package/src/hardware-sim/Deck/__mocks__/getDeckDefinitions.ts +29 -0
- package/src/hardware-sim/Deck/constants.ts +12 -0
- package/src/hardware-sim/Deck/index.tsx +8 -0
- package/src/hardware-sim/DeckConfigurator/AbsorbanceReaderFixture.tsx +91 -0
- package/src/hardware-sim/DeckConfigurator/DeckConfigurator.stories.tsx +110 -0
- package/src/hardware-sim/DeckConfigurator/EmptyConfigFixture.tsx +131 -0
- package/src/hardware-sim/DeckConfigurator/HeaterShakerFixture.tsx +102 -0
- package/src/hardware-sim/DeckConfigurator/MagneticBlockFixture.tsx +130 -0
- package/src/hardware-sim/DeckConfigurator/StagingAreaConfigFixture.tsx +89 -0
- package/src/hardware-sim/DeckConfigurator/StaticFixture.tsx +54 -0
- package/src/hardware-sim/DeckConfigurator/TemperatureModuleFixture.tsx +103 -0
- package/src/hardware-sim/DeckConfigurator/ThermocyclerFixture.tsx +89 -0
- package/src/hardware-sim/DeckConfigurator/TrashBinConfigFixture.tsx +99 -0
- package/src/hardware-sim/DeckConfigurator/WasteChuteConfigFixture.tsx +96 -0
- package/src/hardware-sim/DeckConfigurator/constants.ts +81 -0
- package/src/hardware-sim/DeckConfigurator/index.tsx +285 -0
- package/src/hardware-sim/DeckSlotLocation/index.tsx +88 -0
- package/src/hardware-sim/Labware/Labware.tsx +173 -0
- package/src/hardware-sim/Labware/LabwareAdapter/Opentrons96DeepWellAdapter.tsx +23 -0
- package/src/hardware-sim/Labware/LabwareAdapter/Opentrons96FlatBottomAdapter.tsx +7 -0
- package/src/hardware-sim/Labware/LabwareAdapter/OpentronsAluminumFlatBottomPlate.tsx +13 -0
- package/src/hardware-sim/Labware/LabwareAdapter/OpentronsAutoclavableDeckRiser.tsx +100 -0
- package/src/hardware-sim/Labware/LabwareAdapter/OpentronsFlex96TiprackAdapter.tsx +13 -0
- package/src/hardware-sim/Labware/LabwareAdapter/OpentronsToughPCRAutoSealingLid.tsx +83 -0
- package/src/hardware-sim/Labware/LabwareAdapter/OpentronsUniversalFlatAdapter.tsx +13 -0
- package/src/hardware-sim/Labware/LabwareAdapter/index.tsx +73 -0
- package/src/hardware-sim/Labware/LabwareRender.stories.tsx +96 -0
- package/src/hardware-sim/Labware/LabwareRender.tsx +173 -0
- package/src/hardware-sim/Labware/LabwareStackRender.tsx +272 -0
- package/src/hardware-sim/Labware/index.ts +6 -0
- package/src/hardware-sim/Labware/labwareInternals/FilledWells.tsx +39 -0
- package/src/hardware-sim/Labware/labwareInternals/LabwareOutline.tsx +133 -0
- package/src/hardware-sim/Labware/labwareInternals/LabwareWellLabels.tsx +118 -0
- package/src/hardware-sim/Labware/labwareInternals/StaticLabware.tsx +121 -0
- package/src/hardware-sim/Labware/labwareInternals/StrokedWells.tsx +38 -0
- package/src/hardware-sim/Labware/labwareInternals/StyledWells.tsx +77 -0
- package/src/hardware-sim/Labware/labwareInternals/Well.tsx +74 -0
- package/src/hardware-sim/Labware/labwareInternals/WellLabels.tsx +121 -0
- package/src/hardware-sim/Labware/labwareInternals/index.ts +8 -0
- package/src/hardware-sim/Labware/labwareInternals/types.ts +18 -0
- package/src/hardware-sim/Module/HeaterShaker.tsx +83 -0
- package/src/hardware-sim/Module/MagneticBlock.tsx +49 -0
- package/src/hardware-sim/Module/MagneticModule.tsx +51 -0
- package/src/hardware-sim/Module/Module.stories.tsx +90 -0
- package/src/hardware-sim/Module/ModuleTag.tsx +38 -0
- package/src/hardware-sim/Module/PlateReader.tsx +208 -0
- package/src/hardware-sim/Module/Temperature.tsx +54 -0
- package/src/hardware-sim/Module/Thermocycler/ThermocyclerGEN1.tsx +248 -0
- package/src/hardware-sim/Module/Thermocycler/ThermocyclerGEN2.tsx +286 -0
- package/src/hardware-sim/Module/Thermocycler/index.tsx +49 -0
- package/src/hardware-sim/Module/index.tsx +227 -0
- package/src/hardware-sim/Pipette/EightEmanatingNozzles.tsx +23 -0
- package/src/hardware-sim/Pipette/EmanatingNozzle.tsx +52 -0
- package/src/hardware-sim/Pipette/PipetteRender.stories.tsx +71 -0
- package/src/hardware-sim/Pipette/PipetteRender.tsx +92 -0
- package/src/hardware-sim/Pipette/constants.ts +10 -0
- package/src/hardware-sim/Pipette/index.ts +1 -0
- package/src/hardware-sim/ProtocolDeck/LabwareInfo.tsx +68 -0
- package/src/hardware-sim/ProtocolDeck/ProtocolDeck.stories.tsx +25 -0
- package/src/hardware-sim/ProtocolDeck/__fixtures__/analysis_QIAseqFX24xv4_8.json +47145 -0
- package/src/hardware-sim/ProtocolDeck/index.tsx +174 -0
- package/src/hardware-sim/ProtocolDeck/types.ts +6 -0
- package/src/hardware-sim/ProtocolDeck/utils/getInitiallyLoadedLabwareByAdapter.ts +33 -0
- package/src/hardware-sim/ProtocolDeck/utils/getLabwareInSlots.ts +155 -0
- package/src/hardware-sim/ProtocolDeck/utils/getLabwareInfoByLiquidId.ts +42 -0
- package/src/hardware-sim/ProtocolDeck/utils/getModulesInSlots.ts +129 -0
- package/src/hardware-sim/ProtocolDeck/utils/getStandardDeckViewLayerBlockList.ts +29 -0
- package/src/hardware-sim/ProtocolDeck/utils/getWellFillFromLabwareId.ts +30 -0
- package/src/hardware-sim/ProtocolDeck/utils/index.ts +3 -0
- package/src/hardware-sim/RobotCoordinateSpace/RobotCoordinateSpace.tsx +28 -0
- package/src/hardware-sim/RobotCoordinateSpace/RobotCoordinateSpaceWithRef.tsx +52 -0
- package/src/hardware-sim/RobotCoordinateSpace/index.ts +2 -0
- package/src/hardware-sim/index.ts +11 -0
- package/src/hardware-sim/utils.ts +18 -0
- package/src/helix-design-system/borders.ts +32 -0
- package/src/helix-design-system/colors.ts +100 -0
- package/src/helix-design-system/index.ts +4 -0
- package/src/helix-design-system/product/index.ts +1 -0
- package/src/helix-design-system/product/typography.ts +151 -0
- package/src/helix-design-system/style.ts +2 -0
- package/src/hooks/index.ts +15 -0
- package/src/hooks/useConditionalConfirm.ts +70 -0
- package/src/hooks/useDrag.ts +90 -0
- package/src/hooks/useIdle.ts +68 -0
- package/src/hooks/useInterval.ts +38 -0
- package/src/hooks/useLongPress.ts +83 -0
- package/src/hooks/useMenuHandleClickOutside.tsx +46 -0
- package/src/hooks/useMountEffect.ts +12 -0
- package/src/hooks/usePrevious.ts +19 -0
- package/src/hooks/useScrolling.ts +33 -0
- package/src/hooks/useSelectDeckLocation/SelectDeckLocation.stories.tsx +55 -0
- package/src/hooks/useSelectDeckLocation/index.tsx +331 -0
- package/src/hooks/useSwipe.ts +86 -0
- package/src/hooks/useTimeout.ts +33 -0
- package/src/hooks/useToggle.ts +27 -0
- package/src/icons/Icon.stories.tsx +37 -0
- package/src/icons/Icon.tsx +79 -0
- package/src/icons/IconList.stories.tsx +108 -0
- package/src/icons/ModuleIcon.tsx +48 -0
- package/src/icons/NotificationIcon.tsx +41 -0
- package/src/icons/icon-data.ts +821 -0
- package/src/icons/index.ts +6 -0
- package/src/images/index.ts +1 -0
- package/src/images/labware/index.ts +1 -0
- package/src/images/labware/measurement-guide/images/depth/depth-plate-flat@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/depth/depth-plate-round@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/depth/depth-plate-v@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/depth/depth-reservoir-and-tubes-flat@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/depth/depth-reservoir-and-tubes-round@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/depth/depth-reservoir-and-tubes-v@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/depth/length-tip-rack@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/dimensions/footprint@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/dimensions/height-alum-block-plate@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/dimensions/height-alum-block-tubes@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/dimensions/height-plate-and-reservoir@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/dimensions/height-tip-rack@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/dimensions/height-tube-rack-irregular@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/dimensions/height-tube-rack@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/offset/offset-reservoir@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/offset/offset-well-circular@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/offset/offset-well-rectangular@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/shape/shape-circular@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/shape/shape-rectangular@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/spacing/spacing-reservoir-multi-row@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/spacing/spacing-reservoir@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/spacing/spacing-well-circular@3x.png +0 -0
- package/src/images/labware/measurement-guide/images/spacing/spacing-well-rectangular@3x.png +0 -0
- package/src/images/labware/measurement-guide/index.ts +272 -0
- package/src/index.ts +2 -0
- package/src/instrument/InstrumentDiagram.stories.tsx +42 -0
- package/src/instrument/InstrumentDiagram.tsx +58 -0
- package/src/instrument/InstrumentGroup.stories.tsx +88 -0
- package/src/instrument/InstrumentGroup.tsx +35 -0
- package/src/instrument/InstrumentInfo.tsx +107 -0
- package/src/instrument/PipetteSelect.stories.tsx +40 -0
- package/src/instrument/PipetteSelect.tsx +170 -0
- package/src/instrument/eight-channel-flex.png +0 -0
- package/src/instrument/index.ts +4 -0
- package/src/instrument/multi-channel_GEN1_800px.png +0 -0
- package/src/instrument/multi-channel_GEN2_800px.png +0 -0
- package/src/instrument/ninety-six-channel-gen1.png +0 -0
- package/src/instrument/pipetteGEN2Multi.png +0 -0
- package/src/instrument/pipetteGEN2Single.png +0 -0
- package/src/instrument/pipetteMulti.png +0 -0
- package/src/instrument/pipetteSingle.png +0 -0
- package/src/instrument/single-channel-flex.png +0 -0
- package/src/instrument/single-channel_GEN2_800px.png +0 -0
- package/src/instrument/single_channel_GEN1_800px.png +0 -0
- package/src/interaction-enhancers/ClickOutside.ts +57 -0
- package/src/interaction-enhancers/HandleKeypress.tsx +69 -0
- package/src/interaction-enhancers/index.ts +4 -0
- package/src/interaction-enhancers/useHover.ts +84 -0
- package/src/interaction-enhancers/useOnClickOutside.ts +42 -0
- package/src/legacy-hardware-sim/LabwareNameOverlay.tsx +22 -0
- package/src/legacy-hardware-sim/ModuleItem.tsx +145 -0
- package/src/legacy-hardware-sim/index.ts +2 -0
- package/src/lists/SidePanelGroup.tsx +48 -0
- package/src/lists/TitledList.tsx +155 -0
- package/src/lists/index.ts +3 -0
- package/src/modals/AlertModal.tsx +89 -0
- package/src/modals/ContinueModal.tsx +32 -0
- package/src/modals/LegacyModal.tsx +59 -0
- package/src/modals/Modal.stories.tsx +52 -0
- package/src/modals/Modal.tsx +96 -0
- package/src/modals/ModalHeader.tsx +100 -0
- package/src/modals/ModalShell.tsx +155 -0
- package/src/modals/Overlay.tsx +38 -0
- package/src/modals/SpinnerModal.tsx +35 -0
- package/src/modals/SpinnerModalPage.tsx +30 -0
- package/src/modals/index.ts +10 -0
- package/src/molecules/Banner/Banner.stories.tsx +41 -0
- package/src/molecules/Banner/index.tsx +147 -0
- package/src/molecules/DeckInfoLabel/DeckInfoLabel.stories.tsx +65 -0
- package/src/molecules/DeckInfoLabel/index.tsx +95 -0
- package/src/molecules/DeckLabel/DeckLabel.stories.tsx +31 -0
- package/src/molecules/DeckLabel/index.tsx +80 -0
- package/src/molecules/DropdownMenu/DropdownMenu.stories.tsx +30 -0
- package/src/molecules/DropdownMenu/index.tsx +343 -0
- package/src/molecules/InfoScreen/InfoScreen.stories.tsx +50 -0
- package/src/molecules/InfoScreen/index.tsx +54 -0
- package/src/molecules/LiquidIcon/LiquidIcon.stories.tsx +53 -0
- package/src/molecules/LiquidIcon/index.tsx +68 -0
- package/src/molecules/ParametersTable/ParametersTable.stories.tsx +172 -0
- package/src/molecules/ParametersTable/index.tsx +198 -0
- package/src/molecules/Tabs/Tabs.stories.tsx +74 -0
- package/src/molecules/Tabs/index.tsx +94 -0
- package/src/molecules/index.ts +8 -0
- package/src/nav/SidePanel.stories.tsx +29 -0
- package/src/nav/SidePanel.tsx +21 -0
- package/src/nav/index.ts +2 -0
- package/src/organisms/DeckLabelSet/DeckLabelSet.stories.tsx +46 -0
- package/src/organisms/DeckLabelSet/index.tsx +69 -0
- package/src/organisms/EndUserAgreementFooter/index.tsx +49 -0
- package/src/organisms/Toolbox/Toolbox.stories.tsx +23 -0
- package/src/organisms/Toolbox/index.tsx +160 -0
- package/src/organisms/index.ts +3 -0
- package/src/primitives/Box.stories.tsx +25 -0
- package/src/primitives/Box.tsx +17 -0
- package/src/primitives/Btn.stories.tsx +105 -0
- package/src/primitives/Btn.tsx +266 -0
- package/src/primitives/Flex.stories.tsx +50 -0
- package/src/primitives/Flex.tsx +17 -0
- package/src/primitives/ForeignObject.tsx +70 -0
- package/src/primitives/Link.stories.tsx +27 -0
- package/src/primitives/Link.tsx +32 -0
- package/src/primitives/README.md +188 -0
- package/src/primitives/Svg.stories.tsx +36 -0
- package/src/primitives/Svg.tsx +68 -0
- package/src/primitives/Text.stories.tsx +17 -0
- package/src/primitives/Text.tsx +18 -0
- package/src/primitives/index.ts +10 -0
- package/src/primitives/style-props.ts +197 -0
- package/src/primitives/types.ts +120 -0
- package/src/robot-types.ts +4 -0
- package/src/slotmap/OT2SlotMap.tsx +73 -0
- package/src/slotmap/index.ts +1 -0
- package/src/structure/Card.stories.tsx +28 -0
- package/src/structure/Card.tsx +64 -0
- package/src/structure/LabeledValue.stories.tsx +17 -0
- package/src/structure/LabeledValue.tsx +31 -0
- package/src/structure/Pill.tsx +43 -0
- package/src/structure/Splash.stories.tsx +24 -0
- package/src/structure/Splash.tsx +22 -0
- package/src/structure/TitleBar.stories.tsx +42 -0
- package/src/structure/TitleBar.tsx +81 -0
- package/src/structure/index.ts +7 -0
- package/src/styles/borders.ts +16 -0
- package/src/styles/colors.ts +58 -0
- package/src/styles/cursor.ts +12 -0
- package/src/styles/flexbox.ts +39 -0
- package/src/styles/index.ts +8 -0
- package/src/styles/layout.ts +31 -0
- package/src/styles/position.ts +5 -0
- package/src/styles/spacing.ts +11 -0
- package/src/styles/typography.ts +90 -0
- package/src/testing/utils/index.ts +2 -0
- package/src/testing/utils/matchers.ts +31 -0
- package/src/testing/utils/renderWithProviders.tsx +53 -0
- package/src/tooltips/DeprecatedTooltip.tsx +105 -0
- package/src/tooltips/HoverTooltip.tsx +83 -0
- package/src/tooltips/LegacyTooltip.stories.tsx +98 -0
- package/src/tooltips/LegacyTooltip.tsx +151 -0
- package/src/tooltips/constants.ts +28 -0
- package/src/tooltips/index.ts +10 -0
- package/src/tooltips/styles.ts +20 -0
- package/src/tooltips/types.ts +73 -0
- package/src/tooltips/useHoverTooltip.ts +47 -0
- package/src/tooltips/usePopper.ts +87 -0
- package/src/tooltips/useTooltip.ts +100 -0
- package/src/ui-style-constants/index.ts +4 -0
- package/src/ui-style-constants/responsiveness.ts +15 -0
- package/src/ui-style-constants/spacing.ts +18 -0
- package/src/ui-style-constants/typography.ts +258 -0
- package/src/ui-style-constants/viewport.ts +18 -0
- package/src/utils.ts +56 -0
- package/{vite.config.ts → vite.config.mts} +2 -0
- package/lib/index.mjs +0 -19869
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import { DeprecatedTooltip } from './DeprecatedTooltip'
|
|
4
|
+
|
|
5
|
+
import type { DeprecatedTooltipProps } from './DeprecatedTooltip'
|
|
6
|
+
|
|
7
|
+
const OPEN_DELAY_MS = 300
|
|
8
|
+
const CLOSE_DELAY_MS = 0
|
|
9
|
+
|
|
10
|
+
interface MouseHandlers {
|
|
11
|
+
onMouseEnter: () => void
|
|
12
|
+
onMouseLeave: () => void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type HoverTooltipHandlers = React.PropsWithRef<MouseHandlers>
|
|
16
|
+
|
|
17
|
+
export type HoverTooltipProps = DeprecatedTooltipProps
|
|
18
|
+
|
|
19
|
+
interface HoverTooltipState {
|
|
20
|
+
isOpen: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Tooltip component that triggers on `MouseEnter` and `MouseLeave`. See
|
|
25
|
+
* `Tooltip` for full props list.
|
|
26
|
+
*
|
|
27
|
+
* `props.children` is a function that receives the following props object:
|
|
28
|
+
* ```js
|
|
29
|
+
* type HoverTooltipHandlers = {
|
|
30
|
+
* ref: React.Ref<*>,
|
|
31
|
+
* onMouseEnter: (React.MouseEvent) => void,
|
|
32
|
+
* onMouseLeave: (React.MouseEvent) => void,
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @deprecated Use `Tooltip` and `useHoverTooltip` instead
|
|
37
|
+
*/
|
|
38
|
+
export class HoverTooltip extends React.Component<
|
|
39
|
+
HoverTooltipProps,
|
|
40
|
+
HoverTooltipState
|
|
41
|
+
> {
|
|
42
|
+
openTimeout: number | null
|
|
43
|
+
closeTimeout: number | null
|
|
44
|
+
|
|
45
|
+
constructor(props: HoverTooltipProps) {
|
|
46
|
+
super(props)
|
|
47
|
+
this.openTimeout = null
|
|
48
|
+
this.closeTimeout = null
|
|
49
|
+
this.state = { isOpen: false }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
componentWillUnmount(): void {
|
|
53
|
+
if (this.closeTimeout) clearTimeout(this.closeTimeout)
|
|
54
|
+
if (this.openTimeout) clearTimeout(this.openTimeout)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
delayedOpen: () => void = () => {
|
|
58
|
+
if (this.closeTimeout) clearTimeout(this.closeTimeout)
|
|
59
|
+
this.openTimeout = window.setTimeout(() => {
|
|
60
|
+
this.setState({ isOpen: true })
|
|
61
|
+
}, OPEN_DELAY_MS)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
delayedClose: () => void = () => {
|
|
65
|
+
if (this.openTimeout) clearTimeout(this.openTimeout)
|
|
66
|
+
this.closeTimeout = window.setTimeout(() => {
|
|
67
|
+
this.setState({ isOpen: false })
|
|
68
|
+
}, CLOSE_DELAY_MS)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
render(): JSX.Element {
|
|
72
|
+
return (
|
|
73
|
+
<DeprecatedTooltip
|
|
74
|
+
open={this.state.isOpen}
|
|
75
|
+
childProps={{
|
|
76
|
+
onMouseEnter: this.delayedOpen,
|
|
77
|
+
onMouseLeave: this.delayedClose,
|
|
78
|
+
}}
|
|
79
|
+
{...this.props}
|
|
80
|
+
/>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type * as React from 'react'
|
|
2
|
+
import { LegacyTooltip } from './LegacyTooltip'
|
|
3
|
+
import { useTooltip } from './useTooltip'
|
|
4
|
+
import { useHoverTooltip } from './useHoverTooltip'
|
|
5
|
+
import {
|
|
6
|
+
Box,
|
|
7
|
+
Flex,
|
|
8
|
+
JUSTIFY_CENTER,
|
|
9
|
+
ALIGN_CENTER,
|
|
10
|
+
SIZE_4,
|
|
11
|
+
SIZE_3,
|
|
12
|
+
C_LIGHT_GRAY,
|
|
13
|
+
C_MED_GRAY,
|
|
14
|
+
} from '@opentrons/components'
|
|
15
|
+
|
|
16
|
+
import type { Story, Meta } from '@storybook/react'
|
|
17
|
+
|
|
18
|
+
export default {
|
|
19
|
+
title: 'Library/Atoms/LegacyTooltip',
|
|
20
|
+
decorators: [
|
|
21
|
+
Story => (
|
|
22
|
+
<Flex
|
|
23
|
+
justifyContent={JUSTIFY_CENTER}
|
|
24
|
+
alignItems={ALIGN_CENTER}
|
|
25
|
+
height={SIZE_4}
|
|
26
|
+
width="100%"
|
|
27
|
+
backgroundColor={C_LIGHT_GRAY}
|
|
28
|
+
>
|
|
29
|
+
<Story />
|
|
30
|
+
</Flex>
|
|
31
|
+
),
|
|
32
|
+
],
|
|
33
|
+
} as Meta
|
|
34
|
+
|
|
35
|
+
const Template: Story<React.ComponentProps<typeof LegacyTooltip>> = args => (
|
|
36
|
+
<LegacyTooltip {...args} />
|
|
37
|
+
)
|
|
38
|
+
export const Basic = Template.bind({})
|
|
39
|
+
Basic.args = {
|
|
40
|
+
visible: true,
|
|
41
|
+
children: 'This is a simple tooltip atom.',
|
|
42
|
+
id: 'string-usually-provided-by-useTooltip-hook',
|
|
43
|
+
placement: 'auto',
|
|
44
|
+
style: {},
|
|
45
|
+
arrowRef: () => null,
|
|
46
|
+
arrowStyle: {},
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const StatefulTemplate: Story<
|
|
50
|
+
React.ComponentProps<typeof LegacyTooltip>
|
|
51
|
+
> = args => {
|
|
52
|
+
const { visible, children, placement } = args
|
|
53
|
+
const [targetProps, tooltipProps] = useTooltip({ placement })
|
|
54
|
+
return (
|
|
55
|
+
<>
|
|
56
|
+
<Box
|
|
57
|
+
height={SIZE_3}
|
|
58
|
+
width={SIZE_3}
|
|
59
|
+
backgroundColor={C_MED_GRAY}
|
|
60
|
+
{...targetProps}
|
|
61
|
+
>
|
|
62
|
+
Target
|
|
63
|
+
</Box>
|
|
64
|
+
<LegacyTooltip {...tooltipProps} {...{ visible, children }} />
|
|
65
|
+
</>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
export const WithUseTooltip = StatefulTemplate.bind({})
|
|
69
|
+
WithUseTooltip.args = {
|
|
70
|
+
visible: true,
|
|
71
|
+
children:
|
|
72
|
+
'This is a tooltip that takes advantage of the useTooltip hook to anchor itself to a target.',
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const HoverTemplate: Story<
|
|
76
|
+
React.ComponentProps<typeof LegacyTooltip>
|
|
77
|
+
> = args => {
|
|
78
|
+
const { children } = args
|
|
79
|
+
const [targetProps, tooltipProps] = useHoverTooltip()
|
|
80
|
+
return (
|
|
81
|
+
<>
|
|
82
|
+
<Box
|
|
83
|
+
height={SIZE_3}
|
|
84
|
+
width={SIZE_3}
|
|
85
|
+
backgroundColor={C_MED_GRAY}
|
|
86
|
+
{...targetProps}
|
|
87
|
+
>
|
|
88
|
+
Target
|
|
89
|
+
</Box>
|
|
90
|
+
<LegacyTooltip {...tooltipProps}>{children}</LegacyTooltip>
|
|
91
|
+
</>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
export const WithUseHoverTooltip = HoverTemplate.bind({})
|
|
95
|
+
WithUseHoverTooltip.args = {
|
|
96
|
+
children:
|
|
97
|
+
'This is a tooltip that takes advantage of the useHoverTooltip hook, and only appears when the target is hovered.',
|
|
98
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import { css } from 'styled-components'
|
|
3
|
+
|
|
4
|
+
import { BORDERS, COLORS } from '../helix-design-system'
|
|
5
|
+
import { fontSizeH4 } from '../ui-style-constants/typography'
|
|
6
|
+
import { spacing8 } from '../ui-style-constants/spacing'
|
|
7
|
+
import { ARROW_SIZE_PX } from './styles'
|
|
8
|
+
import { Box } from '../primitives'
|
|
9
|
+
import { CURSOR_POINTER } from '../styles'
|
|
10
|
+
|
|
11
|
+
import type { CSSProperties } from 'react'
|
|
12
|
+
import type { FlattenSimpleInterpolation } from 'styled-components'
|
|
13
|
+
import type { Placement } from './types'
|
|
14
|
+
import type { StyleProps } from '../primitives'
|
|
15
|
+
|
|
16
|
+
export interface LegacyTooltipProps extends StyleProps {
|
|
17
|
+
/** Whether or not the tooltip should be rendered */
|
|
18
|
+
visible: boolean
|
|
19
|
+
/** Contents of the tooltip */
|
|
20
|
+
children?: React.ReactNode
|
|
21
|
+
/**
|
|
22
|
+
* Tooltip element ID (provided by useTooltip). Will match
|
|
23
|
+
* targetProps.aria-describedby
|
|
24
|
+
*/
|
|
25
|
+
id: string
|
|
26
|
+
/** Actual tooltip placement, if known (provided by useTooltip) */
|
|
27
|
+
placement: Placement | null
|
|
28
|
+
/** Inline styles to apply to the tooltip element (provided by useTooltip) */
|
|
29
|
+
style: CSSProperties
|
|
30
|
+
/** React function ref for tooltip's arrow element (provided by useTooltip) */
|
|
31
|
+
arrowRef: React.RefCallback<HTMLElement | null>
|
|
32
|
+
/** Inline styles to apply to arrow element (provided by useTooltip) */
|
|
33
|
+
arrowStyle: CSSProperties
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Tooltip component that renders based on its `visible` prop. For use with the
|
|
38
|
+
* `useTooltip` and `useHoverTooltip` hooks. See examples in `Tooltip.md`.
|
|
39
|
+
*/
|
|
40
|
+
export const LegacyTooltip = React.forwardRef(function TooltipComponent(
|
|
41
|
+
props: LegacyTooltipProps,
|
|
42
|
+
ref: React.ForwardedRef<HTMLDivElement>
|
|
43
|
+
) {
|
|
44
|
+
const {
|
|
45
|
+
visible,
|
|
46
|
+
placement,
|
|
47
|
+
id,
|
|
48
|
+
style,
|
|
49
|
+
arrowRef,
|
|
50
|
+
arrowStyle,
|
|
51
|
+
children,
|
|
52
|
+
width,
|
|
53
|
+
fontSize = fontSizeH4,
|
|
54
|
+
backgroundColor = COLORS.grey50,
|
|
55
|
+
...boxProps
|
|
56
|
+
} = props
|
|
57
|
+
|
|
58
|
+
const TOOLTIP_CSS = css`
|
|
59
|
+
position: absolute;
|
|
60
|
+
z-index: 9001;
|
|
61
|
+
padding: ${spacing8};
|
|
62
|
+
color: ${COLORS.white};
|
|
63
|
+
filter: drop-shadow(0px 1px 3px rgba(0, 0, 0, 0.2));
|
|
64
|
+
cursor: ${CURSOR_POINTER};
|
|
65
|
+
font-size: ${fontSize};
|
|
66
|
+
border-radius: ${BORDERS.borderRadius4};
|
|
67
|
+
`
|
|
68
|
+
|
|
69
|
+
return visible ? (
|
|
70
|
+
<Box
|
|
71
|
+
role="tooltip"
|
|
72
|
+
id={id}
|
|
73
|
+
style={style}
|
|
74
|
+
ref={ref}
|
|
75
|
+
css={TOOLTIP_CSS}
|
|
76
|
+
width={width}
|
|
77
|
+
backgroundColor={backgroundColor}
|
|
78
|
+
{...boxProps}
|
|
79
|
+
>
|
|
80
|
+
{children}
|
|
81
|
+
<Arrow {...{ arrowRef, arrowStyle, placement, backgroundColor }} />
|
|
82
|
+
</Box>
|
|
83
|
+
) : null
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
export interface ArrowProps {
|
|
87
|
+
placement: Placement | null
|
|
88
|
+
arrowRef: React.RefCallback<HTMLElement>
|
|
89
|
+
arrowStyle: CSSProperties
|
|
90
|
+
backgroundColor: string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function Arrow(props: ArrowProps): JSX.Element {
|
|
94
|
+
// shift arrows off the element
|
|
95
|
+
const ARROW_ANCHOR_OFFSET = `-${ARROW_SIZE_PX}px;`
|
|
96
|
+
|
|
97
|
+
// use borders to create arrows
|
|
98
|
+
const ARROW_CSS_BASE = css`
|
|
99
|
+
position: absolute;
|
|
100
|
+
border-width: ${ARROW_SIZE_PX}px;
|
|
101
|
+
border-style: solid;
|
|
102
|
+
border-color: transparent;
|
|
103
|
+
`
|
|
104
|
+
|
|
105
|
+
// arrow pointing down from the top tooltip
|
|
106
|
+
const ARROW_CSS_TOP = css`
|
|
107
|
+
${ARROW_CSS_BASE}
|
|
108
|
+
bottom: ${ARROW_ANCHOR_OFFSET};
|
|
109
|
+
border-bottom-style: none;
|
|
110
|
+
border-top-color: ${props.backgroundColor};
|
|
111
|
+
`
|
|
112
|
+
|
|
113
|
+
// arrow pointing left from the right tooltip
|
|
114
|
+
const ARROW_CSS_RIGHT = css`
|
|
115
|
+
${ARROW_CSS_BASE}
|
|
116
|
+
left: ${ARROW_ANCHOR_OFFSET};
|
|
117
|
+
border-left-style: none;
|
|
118
|
+
border-right-color: ${props.backgroundColor};
|
|
119
|
+
`
|
|
120
|
+
|
|
121
|
+
// arrow pointing up from the bottom tooltip
|
|
122
|
+
const ARROW_CSS_BOTTOM = css`
|
|
123
|
+
${ARROW_CSS_BASE}
|
|
124
|
+
top: ${ARROW_ANCHOR_OFFSET};
|
|
125
|
+
border-top-style: none;
|
|
126
|
+
border-bottom-color: ${props.backgroundColor};
|
|
127
|
+
`
|
|
128
|
+
|
|
129
|
+
// arrow pointing right from the left tooltip
|
|
130
|
+
const ARROW_CSS_LEFT = css`
|
|
131
|
+
${ARROW_CSS_BASE}
|
|
132
|
+
right: ${ARROW_ANCHOR_OFFSET};
|
|
133
|
+
border-right-style: none;
|
|
134
|
+
border-left-color: ${props.backgroundColor};
|
|
135
|
+
`
|
|
136
|
+
|
|
137
|
+
const ARROW_CSS_BY_PLACEMENT_BASE: Record<
|
|
138
|
+
string,
|
|
139
|
+
FlattenSimpleInterpolation
|
|
140
|
+
> = {
|
|
141
|
+
top: ARROW_CSS_TOP,
|
|
142
|
+
right: ARROW_CSS_RIGHT,
|
|
143
|
+
bottom: ARROW_CSS_BOTTOM,
|
|
144
|
+
left: ARROW_CSS_LEFT,
|
|
145
|
+
}
|
|
146
|
+
const placement = props.placement ?? ''
|
|
147
|
+
const placementBase = placement.split('-')[0]
|
|
148
|
+
const arrowCss = ARROW_CSS_BY_PLACEMENT_BASE[placementBase]
|
|
149
|
+
|
|
150
|
+
return <div ref={props.arrowRef} style={props.arrowStyle} css={arrowCss} />
|
|
151
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// placement constants
|
|
2
|
+
// NOTE: these aren't exported from Popper, but they are copied from:
|
|
3
|
+
// @popperjs/core/src/enums.js
|
|
4
|
+
export const TOOLTIP_AUTO: 'auto' = 'auto'
|
|
5
|
+
export const TOOLTIP_AUTO_START: 'auto-start' = 'auto-start'
|
|
6
|
+
export const TOOLTIP_AUTO_END: 'auto-end' = 'auto-end'
|
|
7
|
+
|
|
8
|
+
export const TOOLTIP_TOP: 'top' = 'top'
|
|
9
|
+
export const TOOLTIP_TOP_START: 'top-start' = 'top-start'
|
|
10
|
+
export const TOOLTIP_TOP_END: 'top-end' = 'top-end'
|
|
11
|
+
|
|
12
|
+
export const TOOLTIP_RIGHT: 'right' = 'right'
|
|
13
|
+
export const TOOLTIP_RIGHT_START: 'right-start' = 'right-start'
|
|
14
|
+
export const TOOLTIP_RIGHT_END: 'right-end' = 'right-end'
|
|
15
|
+
|
|
16
|
+
export const TOOLTIP_BOTTOM: 'bottom' = 'bottom'
|
|
17
|
+
export const TOOLTIP_BOTTOM_START: 'bottom-start' = 'bottom-start'
|
|
18
|
+
export const TOOLTIP_BOTTOM_END: 'bottom-end' = 'bottom-end'
|
|
19
|
+
|
|
20
|
+
export const TOOLTIP_LEFT: 'left' = 'left'
|
|
21
|
+
export const TOOLTIP_LEFT_START: 'left-start' = 'left-start'
|
|
22
|
+
export const TOOLTIP_LEFT_END: 'left-end' = 'left-end'
|
|
23
|
+
|
|
24
|
+
// strategy constants
|
|
25
|
+
// NOTE: these aren't exported from Popper, but they are copied from:
|
|
26
|
+
// @popperjs/core/src/types.js
|
|
27
|
+
export const TOOLTIP_ABSOLUTE: 'absolute' = 'absolute'
|
|
28
|
+
export const TOOLTIP_FIXED: 'fixed' = 'fixed'
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// tooltip components
|
|
2
|
+
|
|
3
|
+
export * from './DeprecatedTooltip'
|
|
4
|
+
export * from './HoverTooltip'
|
|
5
|
+
export * from './LegacyTooltip'
|
|
6
|
+
export * from './useTooltip'
|
|
7
|
+
export * from './useHoverTooltip'
|
|
8
|
+
export * from './usePopper'
|
|
9
|
+
export * from './constants'
|
|
10
|
+
export * from './types'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// common style constants
|
|
2
|
+
|
|
3
|
+
export const INITIAL_TOOLTIP_STYLE = {
|
|
4
|
+
// copied from @popperjs/core/src/modifiers/applyStyles.js
|
|
5
|
+
position: 'absolute',
|
|
6
|
+
left: '0',
|
|
7
|
+
top: '0',
|
|
8
|
+
margin: '0',
|
|
9
|
+
} as const
|
|
10
|
+
|
|
11
|
+
export const INITIAL_ARROW_STYLE = {
|
|
12
|
+
// copied from @popperjs/core/src/modifiers/applyStyles.js
|
|
13
|
+
position: 'absolute',
|
|
14
|
+
} as const
|
|
15
|
+
|
|
16
|
+
export const TOOLTIP_OFFSET_PX = 8
|
|
17
|
+
|
|
18
|
+
export const ARROW_OFFSET_PX = 4
|
|
19
|
+
|
|
20
|
+
export const ARROW_SIZE_PX = TOOLTIP_OFFSET_PX - ARROW_OFFSET_PX
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react'
|
|
2
|
+
|
|
3
|
+
import type { Instance, Options, Modifier } from '@popperjs/core/lib/types'
|
|
4
|
+
|
|
5
|
+
import type { UseHoverOptions, HoverHandlers } from '../interaction-enhancers'
|
|
6
|
+
|
|
7
|
+
export type Placement = Options['placement']
|
|
8
|
+
|
|
9
|
+
export type Strategy = Options['strategy']
|
|
10
|
+
|
|
11
|
+
export type PopperInstance = Instance
|
|
12
|
+
|
|
13
|
+
export type PopperOptions = Options
|
|
14
|
+
|
|
15
|
+
export type PopperModifer<T> = Modifier<T>
|
|
16
|
+
|
|
17
|
+
export type HandleStateUpdate = (
|
|
18
|
+
placement: Placement,
|
|
19
|
+
styles: {
|
|
20
|
+
popper?: CSSProperties
|
|
21
|
+
arrow?: CSSProperties
|
|
22
|
+
}
|
|
23
|
+
) => void
|
|
24
|
+
|
|
25
|
+
export interface UsePopperOptions {
|
|
26
|
+
target: Element | null
|
|
27
|
+
tooltip: HTMLElement | null
|
|
28
|
+
arrow: HTMLElement | null
|
|
29
|
+
onStateUpdate: HandleStateUpdate
|
|
30
|
+
placement?: Placement | null
|
|
31
|
+
strategy?: Strategy | null
|
|
32
|
+
offset?: number
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type UsePopperResult = Instance | null
|
|
36
|
+
|
|
37
|
+
export interface UseTooltipOptions {
|
|
38
|
+
placement?: Placement
|
|
39
|
+
strategy?: Strategy
|
|
40
|
+
offset?: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface UseTooltipResultTargetProps {
|
|
44
|
+
ref: React.RefCallback<Element | null>
|
|
45
|
+
'aria-describedby': string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface UseTooltipResultTooltipProps {
|
|
49
|
+
id: string
|
|
50
|
+
ref: React.RefCallback<HTMLElement | null>
|
|
51
|
+
placement: Placement | null
|
|
52
|
+
style: CSSProperties
|
|
53
|
+
arrowRef: React.RefCallback<HTMLElement | null>
|
|
54
|
+
arrowStyle: CSSProperties
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type UseTooltipResult = [
|
|
58
|
+
UseTooltipResultTargetProps,
|
|
59
|
+
UseTooltipResultTooltipProps
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
export type UseHoverTooltipOptions = Partial<
|
|
63
|
+
UseTooltipOptions & UseHoverOptions
|
|
64
|
+
>
|
|
65
|
+
|
|
66
|
+
export interface UseHoverTooltipTargetProps
|
|
67
|
+
extends UseTooltipResultTargetProps,
|
|
68
|
+
HoverHandlers {}
|
|
69
|
+
|
|
70
|
+
export type UseHoverTooltipResult = [
|
|
71
|
+
UseHoverTooltipTargetProps,
|
|
72
|
+
UseTooltipResultTooltipProps & { visible: boolean }
|
|
73
|
+
]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useHover } from '../interaction-enhancers'
|
|
2
|
+
import { useTooltip } from './useTooltip'
|
|
3
|
+
|
|
4
|
+
import type { UseHoverTooltipOptions, UseHoverTooltipResult } from './types'
|
|
5
|
+
|
|
6
|
+
const ENTER_DELAY_MS = 300
|
|
7
|
+
const LEAVE_DELAY_MS = 0
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Hook to position a tooltip component relative to a target component on hover.
|
|
11
|
+
* Adds a default `enterDelay` of 300 ms before the tooltip will show
|
|
12
|
+
*
|
|
13
|
+
* @param {UseHoverTooltipOptions} [options={}] (change default options (see `useTooltip` and `useHover`))
|
|
14
|
+
* @returns {UseHoverTooltipResult}
|
|
15
|
+
* @example
|
|
16
|
+
* ```js
|
|
17
|
+
* import { useHoverTooltip, Tooltip } from '@opentrons/components'
|
|
18
|
+
*
|
|
19
|
+
* export function HelloWorld() {
|
|
20
|
+
* const [targetProps, tooltipProps] = useHoverTooltip()
|
|
21
|
+
*
|
|
22
|
+
* return (
|
|
23
|
+
* <>
|
|
24
|
+
* <span {...targetProps}>Hello</span>
|
|
25
|
+
* <Tooltip {...tooltipProps}>World</Tooltip>
|
|
26
|
+
* </>
|
|
27
|
+
* )
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function useHoverTooltip(
|
|
32
|
+
options: UseHoverTooltipOptions = {}
|
|
33
|
+
): UseHoverTooltipResult {
|
|
34
|
+
const {
|
|
35
|
+
enterDelay = ENTER_DELAY_MS,
|
|
36
|
+
leaveDelay = LEAVE_DELAY_MS,
|
|
37
|
+
...useTooltipOptions
|
|
38
|
+
} = options
|
|
39
|
+
|
|
40
|
+
const [targetProps, tooltipProps] = useTooltip(useTooltipOptions)
|
|
41
|
+
const [visible, hoverHandlers] = useHover({ enterDelay, leaveDelay })
|
|
42
|
+
|
|
43
|
+
return [
|
|
44
|
+
{ ...targetProps, ...hoverHandlers },
|
|
45
|
+
{ ...tooltipProps, visible },
|
|
46
|
+
]
|
|
47
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { useRef, useLayoutEffect } from 'react'
|
|
2
|
+
import { createPopper } from '@popperjs/core'
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
UsePopperOptions,
|
|
6
|
+
UsePopperResult,
|
|
7
|
+
PopperOptions,
|
|
8
|
+
PopperModifer,
|
|
9
|
+
HandleStateUpdate,
|
|
10
|
+
} from './types'
|
|
11
|
+
|
|
12
|
+
const DISABLED_APPLY_STYLES_MODIFIER = {
|
|
13
|
+
name: 'applyStyles',
|
|
14
|
+
enabled: false,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const makeUpdateStateModifier = (
|
|
18
|
+
handleStateUpdate: HandleStateUpdate
|
|
19
|
+
): PopperModifer<{}> => ({
|
|
20
|
+
name: 'updateUsePopperState',
|
|
21
|
+
enabled: true,
|
|
22
|
+
phase: 'write',
|
|
23
|
+
fn: ({ state }) => {
|
|
24
|
+
handleStateUpdate(state.placement, state.styles)
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const makeOffsetModifier = (offset: number): Partial<PopperModifer<{}>> => ({
|
|
29
|
+
name: 'offset',
|
|
30
|
+
options: { offset: [0, offset] },
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const makeArrowModifier = (arrow: Element): Partial<PopperModifer<{}>> => ({
|
|
34
|
+
name: 'arrow',
|
|
35
|
+
options: { element: arrow },
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
export function usePopper(options: UsePopperOptions): UsePopperResult {
|
|
39
|
+
const {
|
|
40
|
+
target,
|
|
41
|
+
tooltip,
|
|
42
|
+
arrow,
|
|
43
|
+
placement,
|
|
44
|
+
strategy,
|
|
45
|
+
offset,
|
|
46
|
+
onStateUpdate,
|
|
47
|
+
} = options
|
|
48
|
+
|
|
49
|
+
const popperRef = useRef<UsePopperResult | null>(null)
|
|
50
|
+
|
|
51
|
+
// useLayoutEffect instead of useEffect to avoid positioning flash
|
|
52
|
+
useLayoutEffect(() => {
|
|
53
|
+
if (target && tooltip) {
|
|
54
|
+
const options: Partial<PopperOptions> &
|
|
55
|
+
Pick<PopperOptions, 'modifiers'> = {
|
|
56
|
+
modifiers: [
|
|
57
|
+
DISABLED_APPLY_STYLES_MODIFIER,
|
|
58
|
+
makeUpdateStateModifier(onStateUpdate),
|
|
59
|
+
],
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (offset != null) {
|
|
63
|
+
options.modifiers.push(makeOffsetModifier(offset))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (arrow) {
|
|
67
|
+
options.modifiers.push(makeArrowModifier(arrow))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (placement != null) options.placement = placement
|
|
71
|
+
if (strategy != null) options.strategy = strategy
|
|
72
|
+
|
|
73
|
+
const popperInstance = createPopper(target, tooltip, options)
|
|
74
|
+
|
|
75
|
+
// immediately force a synchronous update to avoid positioning flash
|
|
76
|
+
popperInstance.forceUpdate()
|
|
77
|
+
popperRef.current = popperInstance
|
|
78
|
+
|
|
79
|
+
return () => {
|
|
80
|
+
popperInstance.destroy()
|
|
81
|
+
popperRef.current = null
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}, [target, tooltip, arrow, placement, strategy, offset, onStateUpdate])
|
|
85
|
+
|
|
86
|
+
return popperRef.current
|
|
87
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { useState, useCallback, useRef } from 'react'
|
|
2
|
+
import uniqueId from 'lodash/uniqueId'
|
|
3
|
+
import { usePopper } from './usePopper'
|
|
4
|
+
import * as Styles from './styles'
|
|
5
|
+
|
|
6
|
+
import type { CSSProperties } from 'react'
|
|
7
|
+
import type { UseTooltipOptions, UseTooltipResult, Placement } from './types'
|
|
8
|
+
|
|
9
|
+
interface TooltipState {
|
|
10
|
+
placement: Placement | null
|
|
11
|
+
tooltipStyle: CSSProperties
|
|
12
|
+
arrowStyle: CSSProperties
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const TOOLTIP_ID_PREFIX = 'Tooltip__'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Hook to position a tooltip component relative to a target component
|
|
19
|
+
*
|
|
20
|
+
* @param {UseTooltipOptions} [options={}] (change the default `position`, `strategy`, or `offset` of the tooltip)
|
|
21
|
+
* @returns {UseTooltipResult}
|
|
22
|
+
* @example
|
|
23
|
+
* ```js
|
|
24
|
+
* import {
|
|
25
|
+
* useTooltip,
|
|
26
|
+
* Tooltip,
|
|
27
|
+
* TOOLTIP_TOP,
|
|
28
|
+
* TOOLTIP_FIXED
|
|
29
|
+
* } from '@opentrons/components'
|
|
30
|
+
*
|
|
31
|
+
* export function HelloWorld() {
|
|
32
|
+
* const [targetProps, tooltipProps] = useTooltip({
|
|
33
|
+
* position: TOOLTIP_TOP,
|
|
34
|
+
* strategy: TOOLTIP_FIXED
|
|
35
|
+
* })
|
|
36
|
+
*
|
|
37
|
+
* return (
|
|
38
|
+
* <>
|
|
39
|
+
* <span {...targetProps}>Hello</span>
|
|
40
|
+
* <Tooltip visible={true} {...tooltipProps}>World</Tooltip>
|
|
41
|
+
* </>
|
|
42
|
+
* )
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export function useTooltip(options: UseTooltipOptions = {}): UseTooltipResult {
|
|
47
|
+
const { placement, strategy, offset = Styles.TOOLTIP_OFFSET_PX } = options
|
|
48
|
+
const tooltipId = useRef(uniqueId(TOOLTIP_ID_PREFIX)).current
|
|
49
|
+
const [target, targetRef] = useState<Element | null>(null)
|
|
50
|
+
const [tooltip, tooltipRef] = useState<HTMLElement | null>(null)
|
|
51
|
+
const [arrow, arrowRef] = useState<HTMLElement | null>(null)
|
|
52
|
+
const [tooltipState, setTooltipState] = useState<TooltipState>({
|
|
53
|
+
placement: null,
|
|
54
|
+
tooltipStyle: Styles.INITIAL_TOOLTIP_STYLE,
|
|
55
|
+
arrowStyle: Styles.INITIAL_ARROW_STYLE,
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const onStateUpdate = useCallback(
|
|
59
|
+
(
|
|
60
|
+
placement: Placement | null,
|
|
61
|
+
styles: {
|
|
62
|
+
popper?: CSSProperties
|
|
63
|
+
arrow?: CSSProperties
|
|
64
|
+
}
|
|
65
|
+
) => {
|
|
66
|
+
setTooltipState({
|
|
67
|
+
placement,
|
|
68
|
+
tooltipStyle: styles.popper ?? Styles.INITIAL_TOOLTIP_STYLE,
|
|
69
|
+
arrowStyle: styles.arrow ?? Styles.INITIAL_ARROW_STYLE,
|
|
70
|
+
})
|
|
71
|
+
},
|
|
72
|
+
[]
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
usePopper({
|
|
76
|
+
target,
|
|
77
|
+
tooltip,
|
|
78
|
+
arrow,
|
|
79
|
+
placement,
|
|
80
|
+
strategy,
|
|
81
|
+
offset,
|
|
82
|
+
onStateUpdate,
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const targetProps = {
|
|
86
|
+
ref: targetRef,
|
|
87
|
+
'aria-describedby': tooltipId,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const tooltipProps = {
|
|
91
|
+
id: tooltipId,
|
|
92
|
+
ref: tooltipRef,
|
|
93
|
+
style: tooltipState.tooltipStyle,
|
|
94
|
+
arrowStyle: tooltipState.arrowStyle,
|
|
95
|
+
placement: tooltipState.placement,
|
|
96
|
+
arrowRef,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return [targetProps, tooltipProps]
|
|
100
|
+
}
|