@redis-ui/components 42.8.0 → 43.2.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/AutoCompleteSelect/AutoCompleteSelect.cjs +7 -1
- package/dist/AutoCompleteSelect/AutoCompleteSelect.js +7 -1
- package/dist/AutoCompleteSelect/hooks/useAutoCompleteSelect.cjs +7 -1
- package/dist/AutoCompleteSelect/hooks/useAutoCompleteSelect.d.ts +8 -1
- package/dist/AutoCompleteSelect/hooks/useAutoCompleteSelect.js +7 -1
- package/dist/BoxSelectionGroup/components/Item/components/BoxStateIndicator/BoxStateIndicator.cjs +8 -4
- package/dist/BoxSelectionGroup/components/Item/components/BoxStateIndicator/BoxStateIndicator.js +8 -4
- package/dist/BoxSelectionGroup/components/Item/components/Compose/Compose.style.cjs +18 -4
- package/dist/BoxSelectionGroup/components/Item/components/Compose/Compose.style.js +18 -4
- package/dist/BoxSelectionGroup/hooks/useBoxSelectionGroup.cjs +3 -1
- package/dist/BoxSelectionGroup/hooks/useBoxSelectionGroup.js +3 -1
- package/dist/Button/Button.style.cjs +4 -1
- package/dist/Button/Button.style.js +4 -1
- package/dist/Button/Button.style.utils.cjs +16 -1
- package/dist/Button/Button.style.utils.js +16 -1
- package/dist/Button/Button.types.cjs +1 -1
- package/dist/Button/Button.types.d.ts +1 -1
- package/dist/Button/Button.types.js +1 -1
- package/dist/Button/CopyToClipboardButton/CopyToClipboardButton.cjs +59 -0
- package/dist/Button/CopyToClipboardButton/CopyToClipboardButton.d.ts +4 -0
- package/dist/Button/CopyToClipboardButton/CopyToClipboardButton.js +57 -0
- package/dist/Button/CopyToClipboardButton/CopyToClipboardButton.style.cjs +40 -0
- package/dist/Button/CopyToClipboardButton/CopyToClipboardButton.style.d.ts +8 -0
- package/dist/Button/CopyToClipboardButton/CopyToClipboardButton.style.js +38 -0
- package/dist/Button/CopyToClipboardButton/CopyToClipboardButton.types.d.ts +5 -0
- package/dist/Button/TextButton/TextButton.style.cjs +4 -1
- package/dist/Button/TextButton/TextButton.style.js +4 -1
- package/dist/Button/TextButton/TextButton.types.cjs +1 -1
- package/dist/Button/TextButton/TextButton.types.d.ts +1 -1
- package/dist/Button/TextButton/TextButton.types.js +1 -1
- package/dist/Button/index.d.ts +2 -0
- package/dist/Checkbox/components/Label/Label.style.cjs +15 -3
- package/dist/Checkbox/components/Label/Label.style.js +15 -3
- package/dist/Chip/components/CloseButton/CloseButton.cjs +3 -1
- package/dist/Chip/components/CloseButton/CloseButton.js +3 -1
- package/dist/Chip/components/Compose/Compose.style.cjs +4 -1
- package/dist/Chip/components/Compose/Compose.style.js +4 -1
- package/dist/Drawer/components/Description/Description.cjs +3 -1
- package/dist/Drawer/components/Description/Description.js +3 -1
- package/dist/Helpers/contexts/Popper/PopperCollisionBoundaryManager.cjs +3 -1
- package/dist/Helpers/contexts/Popper/PopperCollisionBoundaryManager.js +3 -1
- package/dist/Helpers/contexts/PrimitiveContextState.cjs +28 -16
- package/dist/Helpers/contexts/PrimitiveContextState.js +28 -16
- package/dist/Helpers/contexts/SharedId.context.cjs +9 -5
- package/dist/Helpers/contexts/SharedId.context.js +9 -5
- package/dist/Helpers/css.utils.cjs +18 -4
- package/dist/Helpers/css.utils.d.ts +15 -3
- package/dist/Helpers/css.utils.js +18 -4
- package/dist/Helpers/hooks/useScrollable.cjs +3 -1
- package/dist/Helpers/hooks/useScrollable.js +3 -1
- package/dist/Helpers/react.utils.cjs +6 -2
- package/dist/Helpers/react.utils.js +6 -2
- package/dist/HighlightedIcon/HighlightedIcon.cjs +26 -0
- package/dist/HighlightedIcon/HighlightedIcon.d.ts +3 -0
- package/dist/HighlightedIcon/HighlightedIcon.js +26 -0
- package/dist/HighlightedIcon/HighlightedIcon.style.cjs +49 -0
- package/dist/HighlightedIcon/HighlightedIcon.style.d.ts +5 -0
- package/dist/HighlightedIcon/HighlightedIcon.style.js +47 -0
- package/dist/HighlightedIcon/HighlightedIcon.types.d.ts +8 -0
- package/dist/HighlightedIcon/index.d.ts +3 -0
- package/dist/Inputs/QuantityCounter/components/InputGroup/components/ValueLabel/ValueLabel.cjs +9 -5
- package/dist/Inputs/QuantityCounter/components/InputGroup/components/ValueLabel/ValueLabel.js +9 -5
- package/dist/Inputs/components/Compose/Compose.style.cjs +29 -6
- package/dist/Inputs/components/Compose/Compose.style.js +29 -6
- package/dist/Inputs/hooks/numericInput/numericInput.utils.cjs +12 -4
- package/dist/Inputs/hooks/numericInput/numericInput.utils.js +12 -4
- package/dist/Inputs/hooks/numericInput/useNumericInput.cjs +15 -3
- package/dist/Inputs/hooks/numericInput/useNumericInput.js +15 -3
- package/dist/Loader/Loader.cjs +1 -0
- package/dist/Loader/Loader.js +1 -0
- package/dist/Menu/components/Content/components/Item/Components/Compose/Compose.style.cjs +19 -4
- package/dist/Menu/components/Content/components/Item/Components/Compose/Compose.style.js +19 -4
- package/dist/Menu/components/Content/components/Label/components/Compose/Compose.style.cjs +4 -1
- package/dist/Menu/components/Content/components/Label/components/Compose/Compose.style.js +4 -1
- package/dist/Modal/components/Content/components/Compose/Compose.cjs +3 -1
- package/dist/Modal/components/Content/components/Compose/Compose.js +3 -1
- package/dist/Modal/components/Content/components/Description/Description.cjs +3 -1
- package/dist/Modal/components/Content/components/Description/Description.js +3 -1
- package/dist/MultiSelect/components/Compose/hooks/useMultiSelectContextApi.cjs +3 -1
- package/dist/MultiSelect/components/Compose/hooks/useMultiSelectContextApi.js +3 -1
- package/dist/MultiSelect/components/Trigger/components/MultiValue/MultiValue.cjs +3 -1
- package/dist/MultiSelect/components/Trigger/components/MultiValue/MultiValue.js +3 -1
- package/dist/Overflow/Overflow.cjs +3 -1
- package/dist/Overflow/Overflow.js +3 -1
- package/dist/Overflow/Overflow.utils.cjs +15 -6
- package/dist/Overflow/Overflow.utils.js +15 -6
- package/dist/Overflow/components/OverflowContainer/OverflowContainer.cjs +3 -1
- package/dist/Overflow/components/OverflowContainer/OverflowContainer.js +3 -1
- package/dist/Pagination/components/PageSizeSelect.cjs +3 -1
- package/dist/Pagination/components/PageSizeSelect.js +3 -1
- package/dist/Popover/components/Content/Content.cjs +3 -1
- package/dist/Popover/components/Content/Content.js +3 -1
- package/dist/Popover/components/Content/components/Footer/Footer.cjs +3 -1
- package/dist/Popover/components/Content/components/Footer/Footer.js +3 -1
- package/dist/RadioGroup/components/Item/components/Label/Label.style.cjs +15 -3
- package/dist/RadioGroup/components/Item/components/Label/Label.style.js +15 -3
- package/dist/ScreenReaderAnnounce/ScreenReaderAnnounce.cjs +3 -1
- package/dist/ScreenReaderAnnounce/ScreenReaderAnnounce.js +3 -1
- package/dist/Section/components/Header/components/CollapseButton/CollapseButton.cjs +3 -1
- package/dist/Section/components/Header/components/CollapseButton/CollapseButton.js +3 -1
- package/dist/Select/components/Content/components/Option/components/Compose/Compose.style.cjs +16 -4
- package/dist/Select/components/Content/components/Option/components/Compose/Compose.style.js +16 -4
- package/dist/Select/components/Content/components/OptionList/OptionList.cjs +6 -4
- package/dist/Select/components/Content/components/OptionList/OptionList.js +6 -4
- package/dist/Select/components/Content/components/OptionList/Virtual.cjs +9 -5
- package/dist/Select/components/Content/components/OptionList/Virtual.js +9 -5
- package/dist/Select/components/Context/hooks/useSearch.cjs +3 -1
- package/dist/Select/components/Context/hooks/useSearch.js +3 -1
- package/dist/Select/components/Trigger/components/Compose/Compose.style.cjs +33 -7
- package/dist/Select/components/Trigger/components/Compose/Compose.style.js +33 -7
- package/dist/SideBar/components/Item/Item.style.cjs +14 -3
- package/dist/SideBar/components/Item/Item.style.js +14 -3
- package/dist/Skeleton/components/Circle/Circle.cjs +1 -1
- package/dist/Skeleton/components/Circle/Circle.js +1 -1
- package/dist/Skeleton/components/Square/Square.cjs +1 -1
- package/dist/Skeleton/components/Square/Square.js +1 -1
- package/dist/Slider/components/Label/Compose/Compose.cjs +3 -1
- package/dist/Slider/components/Label/Compose/Compose.js +3 -1
- package/dist/Slider/components/Mark/Compose/Compose.cjs +3 -1
- package/dist/Slider/components/Mark/Compose/Compose.js +3 -1
- package/dist/Slider/hooks/useOffset.cjs +3 -1
- package/dist/Slider/hooks/useOffset.js +3 -1
- package/dist/Stepper/Stepper.cjs +14 -5
- package/dist/Stepper/Stepper.d.ts +2 -0
- package/dist/Stepper/Stepper.js +14 -5
- package/dist/Stepper/Stepper.utils.cjs +12 -0
- package/dist/Stepper/Stepper.utils.d.ts +2 -0
- package/dist/Stepper/Stepper.utils.js +12 -0
- package/dist/Stepper/components/Compose/Compose.d.ts +1 -0
- package/dist/Stepper/components/Step/Step.cjs +2 -0
- package/dist/Stepper/components/Step/Step.d.ts +1 -0
- package/dist/Stepper/components/Step/Step.js +2 -0
- package/dist/Stepper/components/Step/components/Compose/Compose.cjs +5 -10
- package/dist/Stepper/components/Step/components/Compose/Compose.js +5 -10
- package/dist/Stepper/components/Step/components/Separator/Separator.cjs +15 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.d.ts +3 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.js +15 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.style.cjs +24 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.style.d.ts +1 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.style.js +22 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.types.d.ts +5 -0
- package/dist/Stepper/hooks/useStepperInteractive.cjs +12 -4
- package/dist/Stepper/hooks/useStepperInteractive.js +12 -4
- package/dist/Switch/components/Switcher/Switcher.cjs +3 -1
- package/dist/Switch/components/Switcher/Switcher.js +3 -1
- package/dist/Switch/components/Switcher/Switcher.style.cjs +31 -8
- package/dist/Switch/components/Switcher/Switcher.style.js +31 -8
- package/dist/Tabs/components/TabBar/components/Trigger/components/Marker/Marker.style.cjs +24 -5
- package/dist/Tabs/components/TabBar/components/Trigger/components/Marker/Marker.style.js +24 -5
- package/dist/Tabs/components/TabBar/components/Trigger/components/Tab/Tab.style.cjs +24 -5
- package/dist/Tabs/components/TabBar/components/Trigger/components/Tab/Tab.style.js +24 -5
- package/dist/ThemeModeSwitch/useThemeModeSwitch.cjs +6 -2
- package/dist/ThemeModeSwitch/useThemeModeSwitch.js +6 -2
- package/dist/Toast/core/content.helper.cjs +8 -4
- package/dist/Toast/core/content.helper.js +8 -4
- package/dist/Tooltip/components/Content/Content.cjs +3 -1
- package/dist/Tooltip/components/Content/Content.js +3 -1
- package/dist/TreeView/TreeView.cjs +3 -1
- package/dist/TreeView/TreeView.js +3 -1
- package/dist/TreeView/components/TreeItem/components/Compose/Compose.cjs +6 -4
- package/dist/TreeView/components/TreeItem/components/Compose/Compose.js +6 -4
- package/dist/Typography/Typography.types.cjs +4 -0
- package/dist/Typography/Typography.types.d.ts +2 -1
- package/dist/Typography/Typography.types.js +4 -0
- package/dist/index.cjs +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +98 -90
- package/package.json +10 -9
- package/skills/redis-ui-components/SKILL.md +126 -0
- package/skills/redis-ui-components/references/ActionIconButton.md +96 -0
- package/skills/redis-ui-components/references/AppBar.md +161 -0
- package/skills/redis-ui-components/references/AppSelectionMenu.md +184 -0
- package/skills/redis-ui-components/references/AutoCompleteSelect.md +193 -0
- package/skills/redis-ui-components/references/Badge.md +77 -0
- package/skills/redis-ui-components/references/Banner.md +563 -0
- package/skills/redis-ui-components/references/BoxSelectionGroup.md +487 -0
- package/skills/redis-ui-components/references/Breadcrumbs.md +214 -0
- package/skills/redis-ui-components/references/Button.md +169 -0
- package/skills/redis-ui-components/references/ButtonGroup.md +126 -0
- package/skills/redis-ui-components/references/Card.md +56 -0
- package/skills/redis-ui-components/references/Checkbox.md +171 -0
- package/skills/redis-ui-components/references/Chip.md +154 -0
- package/skills/redis-ui-components/references/ChipList.md +307 -0
- package/skills/redis-ui-components/references/CopyToClipboardButton.md +47 -0
- package/skills/redis-ui-components/references/CountryFlag.md +57 -0
- package/skills/redis-ui-components/references/Drawer.md +298 -0
- package/skills/redis-ui-components/references/Filters.md +162 -0
- package/skills/redis-ui-components/references/FlexDivider.md +152 -0
- package/skills/redis-ui-components/references/FlexGroup.md +149 -0
- package/skills/redis-ui-components/references/FlexItem.md +58 -0
- package/skills/redis-ui-components/references/FlexSplit.md +37 -0
- package/skills/redis-ui-components/references/FormField.md +678 -0
- package/skills/redis-ui-components/references/IconButton.md +63 -0
- package/skills/redis-ui-components/references/Input.md +295 -0
- package/skills/redis-ui-components/references/KeyValueList.md +501 -0
- package/skills/redis-ui-components/references/Label.md +238 -0
- package/skills/redis-ui-components/references/Link.md +402 -0
- package/skills/redis-ui-components/references/Loader.md +100 -0
- package/skills/redis-ui-components/references/Menu.md +988 -0
- package/skills/redis-ui-components/references/MidBar.md +358 -0
- package/skills/redis-ui-components/references/Modal.md +525 -0
- package/skills/redis-ui-components/references/MoreInfoIcon.md +119 -0
- package/skills/redis-ui-components/references/MultiSelect.md +558 -0
- package/skills/redis-ui-components/references/NumericInput.md +322 -0
- package/skills/redis-ui-components/references/Overflow.md +127 -0
- package/skills/redis-ui-components/references/Pagination.md +151 -0
- package/skills/redis-ui-components/references/PasswordInput.md +262 -0
- package/skills/redis-ui-components/references/Popover.md +868 -0
- package/skills/redis-ui-components/references/ProfileIcon.md +65 -0
- package/skills/redis-ui-components/references/ProgressBar.md +103 -0
- package/skills/redis-ui-components/references/QuantityCounter.md +555 -0
- package/skills/redis-ui-components/references/RadioGroup.md +265 -0
- package/skills/redis-ui-components/references/ScreenReaderAnnounce.md +147 -0
- package/skills/redis-ui-components/references/SearchBar.md +242 -0
- package/skills/redis-ui-components/references/SearchInput.md +213 -0
- package/skills/redis-ui-components/references/Section.md +349 -0
- package/skills/redis-ui-components/references/Select.md +517 -0
- package/skills/redis-ui-components/references/SideBar.md +468 -0
- package/skills/redis-ui-components/references/Slider.md +398 -0
- package/skills/redis-ui-components/references/Stepper.md +288 -0
- package/skills/redis-ui-components/references/Switch.md +193 -0
- package/skills/redis-ui-components/references/Tabs.md +383 -0
- package/skills/redis-ui-components/references/TextArea.md +139 -0
- package/skills/redis-ui-components/references/TextButton.md +217 -0
- package/skills/redis-ui-components/references/Toast.md +399 -0
- package/skills/redis-ui-components/references/ToggleButton.md +163 -0
- package/skills/redis-ui-components/references/Tooltip.md +636 -0
- package/skills/redis-ui-components/references/Typography.md +323 -0
|
@@ -0,0 +1,868 @@
|
|
|
1
|
+
# Popover
|
|
2
|
+
|
|
3
|
+
Popup component with trigger/content composition and a richer `Popover.Card` surface for formatted content.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Popover } from '@redislabsdev/redis-ui-components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
If you use the story examples that rely on icons, also import them from `@redislabsdev/redis-ui-icons`.
|
|
12
|
+
|
|
13
|
+
## Props
|
|
14
|
+
|
|
15
|
+
| Prop | Type | Default | Description |
|
|
16
|
+
|------|------|---------|-------------|
|
|
17
|
+
| children | `React.ReactNode` | required | Trigger content rendered inside the popover |
|
|
18
|
+
| content | `React.ReactNode` | - | Content rendered inside the popover popup |
|
|
19
|
+
| defaultOpen | `boolean` | - | Uncontrolled initial open state |
|
|
20
|
+
| open | `boolean` | `visible` | Controlled open state |
|
|
21
|
+
| onOpenChange | `(open: boolean) => void` | `onVisibilityChange` | Controlled open-state callback |
|
|
22
|
+
| disabled | `boolean` | - | Disables opening and closes controlled content |
|
|
23
|
+
| visible | `boolean` | - | Deprecated alias for `open` |
|
|
24
|
+
| onVisibilityChange | `(open: boolean) => void` | - | Deprecated alias for `onOpenChange` |
|
|
25
|
+
| withButton | `boolean` | - | Wraps the trigger in an invisible button when needed |
|
|
26
|
+
| placement | `'top' \| 'bottom' \| 'left' \| 'right'` | `bottom` | Preferred popup side |
|
|
27
|
+
| sideOffset | `number` | `5` | Offset between trigger and popup |
|
|
28
|
+
| persistent | `boolean` | `false` | Prevents closing on outside click |
|
|
29
|
+
| onClickOutside | `(event) => void` | - | Outside click handler |
|
|
30
|
+
| alignOffset | `number` | - | Additional alignment offset |
|
|
31
|
+
| align | `'start' \| 'center' \| 'end'` | `center` | Alignment against the trigger |
|
|
32
|
+
| maxWidth | `string` | - | Max popup width override |
|
|
33
|
+
| portal | `HTMLElement \| null` | `document.body` | Portal container or `null` to render inline |
|
|
34
|
+
| collisionBoundary | `RadixPopover.PopoverContentProps['collisionBoundary']` | - | Radix collision boundary override |
|
|
35
|
+
| windowBar | `WindowBarProps` | - | Deprecated `Popover.Content` alias for `Popover.Card` window bar content |
|
|
36
|
+
| title | `string` | - | Deprecated `Popover.Content` alias for card header title |
|
|
37
|
+
| text | `ContentBodyProps['text']` | - | Deprecated `Popover.Content` alias for card body text |
|
|
38
|
+
| actionButtonText | `string` | - | Deprecated `Popover.Content` alias for card footer action label |
|
|
39
|
+
| actionButtonHandler | `(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void` | - | Deprecated `Popover.Content` alias for card footer action callback |
|
|
40
|
+
| link | `string` | - | Deprecated `Popover.Content` alias for card footer link |
|
|
41
|
+
| linkText | `string` | - | Deprecated `Popover.Content` alias for card footer link text |
|
|
42
|
+
|
|
43
|
+
## Sub-components
|
|
44
|
+
|
|
45
|
+
- `Popover.Compose` - Controlled root wrapper.
|
|
46
|
+
- `Popover.Trigger` - Trigger wrapper for button and non-button triggers.
|
|
47
|
+
- `Popover.Content` - Popup content surface.
|
|
48
|
+
- `Popover.Card` - Rich content card surface.
|
|
49
|
+
- `Popover.Content.Text` - Text wrapper for string content inside `Popover.Content`.
|
|
50
|
+
- `Popover.Card.Close` - Close button alias for `Popover.Content.Close`.
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
### Playground
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
58
|
+
|
|
59
|
+
<Popover content="Popovers can display any content" onOpenChange={() => {}}>
|
|
60
|
+
<Button>Click me</Button>
|
|
61
|
+
</Popover>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### TriggerWithButton
|
|
65
|
+
|
|
66
|
+
> `Popover.Trigger` has a `withButton` prop that wraps trigger elements with an invisible button.
|
|
67
|
+
>
|
|
68
|
+
> Use it when you have multiple trigger elements or when the trigger content does not work as a button, such as SVG or plain text.
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { Popover } from '@redislabsdev/redis-ui-components';
|
|
72
|
+
import { InfoIcon } from '@redislabsdev/redis-ui-icons';
|
|
73
|
+
import { useViewMode } from '../../helpers/useViewMode';
|
|
74
|
+
|
|
75
|
+
function Render() {
|
|
76
|
+
const { inStory } = useViewMode();
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<>
|
|
80
|
+
<Popover content="Plain text trigger" withButton defaultOpen={inStory}>
|
|
81
|
+
Plain text
|
|
82
|
+
</Popover>
|
|
83
|
+
<Popover content="SVG trigger" withButton defaultOpen={inStory}>
|
|
84
|
+
<InfoIcon />
|
|
85
|
+
</Popover>
|
|
86
|
+
<Popover content="Multiple elements trigger" withButton defaultOpen={inStory}>
|
|
87
|
+
<strong>Multiple</strong> <em>Elements</em>
|
|
88
|
+
</Popover>
|
|
89
|
+
</>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### ProgrammaticallyOpened
|
|
95
|
+
|
|
96
|
+
> `Popover` can be controlled by setting `open` and `onOpenChange`.
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import { useEffect, useState } from 'react';
|
|
100
|
+
import { Button, Popover, Switch, Typography } from '@redislabsdev/redis-ui-components';
|
|
101
|
+
import { StoryHList } from '../../helpers/Story.style';
|
|
102
|
+
|
|
103
|
+
function Render() {
|
|
104
|
+
const [open, setOpen] = useState(false);
|
|
105
|
+
const [enabled, setEnabled] = useState(false);
|
|
106
|
+
const [countDown, setCountDown] = useState(0);
|
|
107
|
+
|
|
108
|
+
const resetTimer = () => {
|
|
109
|
+
setCountDown(3);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (enabled) {
|
|
114
|
+
if (countDown > 0) {
|
|
115
|
+
const timer = setTimeout(() => {
|
|
116
|
+
setCountDown(countDown - 1);
|
|
117
|
+
}, 1000);
|
|
118
|
+
|
|
119
|
+
return () => clearTimeout(timer);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
setOpen(true);
|
|
123
|
+
} else {
|
|
124
|
+
resetTimer();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return undefined;
|
|
128
|
+
}, [countDown, enabled]);
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<StoryHList $gap="2rem">
|
|
132
|
+
<Switch checked={enabled} onCheckedChange={setEnabled} />
|
|
133
|
+
{enabled ? (
|
|
134
|
+
<>
|
|
135
|
+
<Typography.Heading size="M">
|
|
136
|
+
Popover will be open in {countDown} seconds
|
|
137
|
+
</Typography.Heading>
|
|
138
|
+
<Popover
|
|
139
|
+
open={open}
|
|
140
|
+
onOpenChange={(toOpen) => {
|
|
141
|
+
if (!toOpen) {
|
|
142
|
+
setOpen(false);
|
|
143
|
+
setEnabled(false);
|
|
144
|
+
}
|
|
145
|
+
}}
|
|
146
|
+
content={
|
|
147
|
+
<div
|
|
148
|
+
style={{
|
|
149
|
+
display: 'flex',
|
|
150
|
+
flexDirection: 'column',
|
|
151
|
+
alignItems: 'center',
|
|
152
|
+
gap: 20
|
|
153
|
+
}}
|
|
154
|
+
>
|
|
155
|
+
<div>This Popover is opened programmatically</div>
|
|
156
|
+
<Button
|
|
157
|
+
onClick={() => {
|
|
158
|
+
setOpen(false);
|
|
159
|
+
setEnabled(false);
|
|
160
|
+
}}
|
|
161
|
+
>
|
|
162
|
+
Close
|
|
163
|
+
</Button>
|
|
164
|
+
</div>
|
|
165
|
+
}
|
|
166
|
+
withButton
|
|
167
|
+
>
|
|
168
|
+
Popover will be opened here
|
|
169
|
+
</Popover>
|
|
170
|
+
</>
|
|
171
|
+
) : (
|
|
172
|
+
<Typography.Heading size="M">Switch timer ON</Typography.Heading>
|
|
173
|
+
)}
|
|
174
|
+
</StoryHList>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### PopoverPlacements
|
|
180
|
+
|
|
181
|
+
> Use `placement` to choose the preferred side of the trigger. The popover can flip when collisions occur.
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
185
|
+
import { useViewMode } from '../../helpers/useViewMode';
|
|
186
|
+
|
|
187
|
+
function Render() {
|
|
188
|
+
const { inStory } = useViewMode();
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<>
|
|
192
|
+
<Popover open={inStory} content="Left" placement="left">
|
|
193
|
+
<Button>Left</Button>
|
|
194
|
+
</Popover>
|
|
195
|
+
<Popover open={inStory} content="Top" placement="top">
|
|
196
|
+
<Button>Top</Button>
|
|
197
|
+
</Popover>
|
|
198
|
+
<Popover open={inStory} content="Bottom" placement="bottom">
|
|
199
|
+
<Button>Bottom</Button>
|
|
200
|
+
</Popover>
|
|
201
|
+
<Popover open={inStory} content="Right" placement="right">
|
|
202
|
+
<Button>Right</Button>
|
|
203
|
+
</Popover>
|
|
204
|
+
</>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### PopoverAlign
|
|
210
|
+
|
|
211
|
+
> Use `align` to choose the preferred alignment against the trigger. `alignOffset` can nudge the popup slightly.
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
215
|
+
import { useViewMode } from '../../helpers/useViewMode';
|
|
216
|
+
|
|
217
|
+
function Render() {
|
|
218
|
+
const { inStory } = useViewMode();
|
|
219
|
+
|
|
220
|
+
return (
|
|
221
|
+
<>
|
|
222
|
+
<Popover
|
|
223
|
+
open={inStory}
|
|
224
|
+
content={
|
|
225
|
+
<>
|
|
226
|
+
Popover with <strong>align: end</strong> and <strong>alignOffset</strong>
|
|
227
|
+
</>
|
|
228
|
+
}
|
|
229
|
+
placement="top"
|
|
230
|
+
align="end"
|
|
231
|
+
alignOffset={-20}
|
|
232
|
+
>
|
|
233
|
+
<Button>align: end</Button>
|
|
234
|
+
</Popover>
|
|
235
|
+
<Popover
|
|
236
|
+
open={inStory}
|
|
237
|
+
content={
|
|
238
|
+
<>
|
|
239
|
+
Popover with <strong>align: center</strong>
|
|
240
|
+
</>
|
|
241
|
+
}
|
|
242
|
+
placement="top"
|
|
243
|
+
align="center"
|
|
244
|
+
>
|
|
245
|
+
<Button>align: center</Button>
|
|
246
|
+
</Popover>
|
|
247
|
+
<Popover
|
|
248
|
+
open={inStory}
|
|
249
|
+
content={
|
|
250
|
+
<>
|
|
251
|
+
Popover with <strong>align: start</strong>
|
|
252
|
+
</>
|
|
253
|
+
}
|
|
254
|
+
placement="top"
|
|
255
|
+
align="start"
|
|
256
|
+
>
|
|
257
|
+
<Button>align: start</Button>
|
|
258
|
+
</Popover>
|
|
259
|
+
</>
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### LongText
|
|
265
|
+
|
|
266
|
+
> Long text in the popover content will wrap.
|
|
267
|
+
|
|
268
|
+
```tsx
|
|
269
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
270
|
+
import { useViewMode } from '../../helpers/useViewMode';
|
|
271
|
+
|
|
272
|
+
function Render() {
|
|
273
|
+
const { inStory } = useViewMode();
|
|
274
|
+
|
|
275
|
+
return (
|
|
276
|
+
<Popover
|
|
277
|
+
defaultOpen={inStory}
|
|
278
|
+
content="This is Popover content with a really really really really really really really really really really really really long text"
|
|
279
|
+
>
|
|
280
|
+
<Button>Click me</Button>
|
|
281
|
+
</Popover>
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### CustomMaxWidth
|
|
287
|
+
|
|
288
|
+
> `maxWidth` can make long text or wider content layout more consistently.
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
292
|
+
import { useViewMode } from '../../helpers/useViewMode';
|
|
293
|
+
|
|
294
|
+
function Render() {
|
|
295
|
+
const { inStory } = useViewMode();
|
|
296
|
+
|
|
297
|
+
return (
|
|
298
|
+
<Popover
|
|
299
|
+
defaultOpen={inStory}
|
|
300
|
+
maxWidth="1000rem"
|
|
301
|
+
content="Custom maxWidth can be defined to make very long text laid out more consistently or contain wider content"
|
|
302
|
+
>
|
|
303
|
+
<Button>Click me</Button>
|
|
304
|
+
</Popover>
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### PersistentPopover
|
|
310
|
+
|
|
311
|
+
> Use `persistent` when the popover should not close accidentally on outside click.
|
|
312
|
+
>
|
|
313
|
+
> Add a `Close` button so users can dismiss it explicitly.
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
317
|
+
|
|
318
|
+
<Popover
|
|
319
|
+
persistent
|
|
320
|
+
content={
|
|
321
|
+
<>
|
|
322
|
+
<Popover.Content.Close />
|
|
323
|
+
If Popover should not be accidentally closed, <strong>persistent</strong> flag can be used
|
|
324
|
+
<Popover.Card.Footer
|
|
325
|
+
actionButtonText="Click me"
|
|
326
|
+
linkText="Read me"
|
|
327
|
+
actionButtonHandler={() => {}}
|
|
328
|
+
link="#"
|
|
329
|
+
/>
|
|
330
|
+
</>
|
|
331
|
+
}
|
|
332
|
+
>
|
|
333
|
+
<Button>Click me</Button>
|
|
334
|
+
</Popover>
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### ClickOutsideEvent
|
|
338
|
+
|
|
339
|
+
> `onClickOutside` lets you react when the user clicks outside an opened popover.
|
|
340
|
+
>
|
|
341
|
+
> In this example, clicking outside causes the green indicator to flash.
|
|
342
|
+
|
|
343
|
+
```tsx
|
|
344
|
+
import { useState } from 'react';
|
|
345
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
346
|
+
import * as S from './PopoverStory.style';
|
|
347
|
+
|
|
348
|
+
function useAnimTrigger() {
|
|
349
|
+
const [counter, setCounter] = useState(0);
|
|
350
|
+
|
|
351
|
+
return [counter, () => setCounter((c) => c + 1)] as const;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function Render() {
|
|
355
|
+
const [state, turnOnIndicator] = useAnimTrigger();
|
|
356
|
+
|
|
357
|
+
return (
|
|
358
|
+
<>
|
|
359
|
+
<Popover
|
|
360
|
+
onClickOutside={turnOnIndicator}
|
|
361
|
+
content="Click outside of this popup. The green indicator should show that the event has fired."
|
|
362
|
+
>
|
|
363
|
+
<Button>Regular</Button>
|
|
364
|
+
</Popover>
|
|
365
|
+
<S.Indicator key={state} $state={state} />
|
|
366
|
+
<Popover
|
|
367
|
+
persistent
|
|
368
|
+
onClickOutside={turnOnIndicator}
|
|
369
|
+
content={
|
|
370
|
+
<>
|
|
371
|
+
<Popover.Content.Close />
|
|
372
|
+
Click outside of this popup. The green indicator should show that the event has fired.
|
|
373
|
+
</>
|
|
374
|
+
}
|
|
375
|
+
>
|
|
376
|
+
<Button>Persistent</Button>
|
|
377
|
+
</Popover>
|
|
378
|
+
</>
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### DisabledAndEmptyPopover
|
|
384
|
+
|
|
385
|
+
> An empty `content` value or the `disabled` flag prevents the popover from opening.
|
|
386
|
+
|
|
387
|
+
```tsx
|
|
388
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
389
|
+
|
|
390
|
+
<>
|
|
391
|
+
<Popover
|
|
392
|
+
content={
|
|
393
|
+
<>
|
|
394
|
+
Popover with empty (falsy) content or Popover with <strong>disabled</strong> flag will
|
|
395
|
+
not be visible
|
|
396
|
+
</>
|
|
397
|
+
}
|
|
398
|
+
>
|
|
399
|
+
<Button>Click me</Button>
|
|
400
|
+
</Popover>
|
|
401
|
+
<Popover content="Disabled" disabled open>
|
|
402
|
+
<Button>Disabled</Button>
|
|
403
|
+
</Popover>
|
|
404
|
+
<Popover content="" open>
|
|
405
|
+
<Button>Empty content</Button>
|
|
406
|
+
</Popover>
|
|
407
|
+
</>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Portal
|
|
411
|
+
|
|
412
|
+
> `Popover` can render without a portal or inside a custom portal container.
|
|
413
|
+
|
|
414
|
+
```tsx
|
|
415
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
416
|
+
import { useViewMode } from '../../helpers/useViewMode';
|
|
417
|
+
|
|
418
|
+
function Render() {
|
|
419
|
+
const { inStory } = useViewMode();
|
|
420
|
+
|
|
421
|
+
return (
|
|
422
|
+
<>
|
|
423
|
+
<Popover
|
|
424
|
+
open={inStory}
|
|
425
|
+
maxWidth="20vw"
|
|
426
|
+
content="This Popover is rendered with default portal (document.body)"
|
|
427
|
+
>
|
|
428
|
+
<Button>With portal</Button>
|
|
429
|
+
</Popover>
|
|
430
|
+
<Popover open={inStory} portal={null} content="This Popover is rendered without portal">
|
|
431
|
+
<Button>No portal</Button>
|
|
432
|
+
</Popover>
|
|
433
|
+
</>
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### InModal
|
|
439
|
+
|
|
440
|
+
> `Popover` opened from `Modal` should appear over the modal.
|
|
441
|
+
|
|
442
|
+
```tsx
|
|
443
|
+
import { Button, Modal, Popover } from '@redislabsdev/redis-ui-components';
|
|
444
|
+
|
|
445
|
+
<Modal.Compose>
|
|
446
|
+
<Modal.Trigger>
|
|
447
|
+
<Button variant="primary">Open Modal</Button>
|
|
448
|
+
</Modal.Trigger>
|
|
449
|
+
<Modal.Content.Compose style={{ width: '400px', height: '200px' }}>
|
|
450
|
+
<Modal.Content.Header title="Modal Title" />
|
|
451
|
+
<Modal.Content.Body.Compose>
|
|
452
|
+
<Popover content="This Popover is opened from Modal">
|
|
453
|
+
<Button>Open popover</Button>
|
|
454
|
+
</Popover>
|
|
455
|
+
</Modal.Content.Body.Compose>
|
|
456
|
+
</Modal.Content.Compose>
|
|
457
|
+
</Modal.Compose>
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### ComposePopover
|
|
461
|
+
|
|
462
|
+
> `Popover` can be composed with `Popover.Trigger`, `Popover.Content`, and `Popover.Content.Text`.
|
|
463
|
+
>
|
|
464
|
+
> `Popover.Card` is available for richer content.
|
|
465
|
+
>
|
|
466
|
+
> With composition, `backgroundColor` also applies to the popup arrow.
|
|
467
|
+
|
|
468
|
+
```tsx
|
|
469
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
470
|
+
import { InfoIcon } from '@redislabsdev/redis-ui-icons';
|
|
471
|
+
import * as S from './PopoverStory.style';
|
|
472
|
+
import { useViewMode } from '../../helpers/useViewMode';
|
|
473
|
+
|
|
474
|
+
function Render() {
|
|
475
|
+
const { inStory } = useViewMode();
|
|
476
|
+
|
|
477
|
+
return (
|
|
478
|
+
<Popover.Compose defaultOpen={inStory}>
|
|
479
|
+
<Popover.Trigger withButton>
|
|
480
|
+
<InfoIcon />
|
|
481
|
+
Click me
|
|
482
|
+
</Popover.Trigger>
|
|
483
|
+
<Popover.Content.Compose backgroundColor="#eff9f5">
|
|
484
|
+
<S.PopoverContentText>This Popover is composed</S.PopoverContentText>
|
|
485
|
+
</Popover.Content.Compose>
|
|
486
|
+
</Popover.Compose>
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### AsyncContent
|
|
492
|
+
|
|
493
|
+
> Popover with async content.
|
|
494
|
+
|
|
495
|
+
```tsx
|
|
496
|
+
import { useEffect, useState } from 'react';
|
|
497
|
+
import { Button, Loader, Popover } from '@redislabsdev/redis-ui-components';
|
|
498
|
+
|
|
499
|
+
function AsyncContentComponent() {
|
|
500
|
+
const [loading, setLoading] = useState(true);
|
|
501
|
+
|
|
502
|
+
useEffect(() => {
|
|
503
|
+
const timeout = setTimeout(setLoading, 1500, false);
|
|
504
|
+
|
|
505
|
+
return () => clearTimeout(timeout);
|
|
506
|
+
}, []);
|
|
507
|
+
|
|
508
|
+
return loading ? (
|
|
509
|
+
<Loader size="15" />
|
|
510
|
+
) : (
|
|
511
|
+
<div>
|
|
512
|
+
<p>Async content:</p>
|
|
513
|
+
<p>Loaded</p>
|
|
514
|
+
</div>
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
function Render() {
|
|
519
|
+
return (
|
|
520
|
+
<Popover content={<AsyncContentComponent />}>
|
|
521
|
+
<Button>Get async content</Button>
|
|
522
|
+
</Popover>
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Popover API
|
|
528
|
+
|
|
529
|
+
### `Popover.Compose` Props
|
|
530
|
+
|
|
531
|
+
| Prop | Type | Default | Description |
|
|
532
|
+
|------|------|---------|-------------|
|
|
533
|
+
| children | `React.ReactNode` | required | Popover composition tree |
|
|
534
|
+
| defaultOpen | `boolean` | - | Uncontrolled initial open state |
|
|
535
|
+
| open | `boolean` | `visible` | Controlled open state |
|
|
536
|
+
| onOpenChange | `(open: boolean) => void` | `onVisibilityChange` | Controlled open-state callback |
|
|
537
|
+
| disabled | `boolean` | - | Disables the popover root |
|
|
538
|
+
| visible | `boolean` | - | Deprecated alias for `open` |
|
|
539
|
+
| onVisibilityChange | `(open: boolean) => void` | - | Deprecated alias for `onOpenChange` |
|
|
540
|
+
|
|
541
|
+
### `Popover.Trigger` Props
|
|
542
|
+
|
|
543
|
+
| Prop | Type | Default | Description |
|
|
544
|
+
|------|------|---------|-------------|
|
|
545
|
+
| children | `React.ReactNode` | required | Trigger content |
|
|
546
|
+
| withButton | `boolean` | - | Wraps the trigger in an invisible button |
|
|
547
|
+
|
|
548
|
+
### `Popover.Content` Props
|
|
549
|
+
|
|
550
|
+
| Prop | Type | Default | Description |
|
|
551
|
+
|------|------|---------|-------------|
|
|
552
|
+
| content | `React.ReactNode` | - | Popup content |
|
|
553
|
+
| backgroundColor | `string` | - | Popup background color override |
|
|
554
|
+
| placement | `'top' \| 'bottom' \| 'left' \| 'right'` | `bottom` | Preferred popup side |
|
|
555
|
+
| sideOffset | `number` | `5` | Offset between trigger and popup |
|
|
556
|
+
| persistent | `boolean` | `false` | Prevents closing on outside click |
|
|
557
|
+
| onClickOutside | `(event) => void` | - | Outside click handler |
|
|
558
|
+
| alignOffset | `number` | - | Additional alignment offset |
|
|
559
|
+
| align | `'start' \| 'center' \| 'end'` | `center` | Alignment against the trigger |
|
|
560
|
+
| maxWidth | `string` | - | Max popup width override |
|
|
561
|
+
| portal | `HTMLElement \| null` | `document.body` | Portal container or `null` to render inline |
|
|
562
|
+
| collisionBoundary | `RadixPopover.PopoverContentProps['collisionBoundary']` | - | Radix collision boundary override |
|
|
563
|
+
| windowBar | `WindowBarProps` | - | Deprecated alias for `Popover.Card.WindowBar` content |
|
|
564
|
+
| title | `string` | - | Deprecated alias for `Popover.Card.Header` title |
|
|
565
|
+
| text | `ContentBodyProps['text']` | - | Deprecated alias for `Popover.Card.Body` text |
|
|
566
|
+
| actionButtonText | `string` | - | Deprecated alias for `Popover.Card.Footer` action label |
|
|
567
|
+
| actionButtonHandler | `(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void` | - | Deprecated alias for `Popover.Card.Footer` action callback |
|
|
568
|
+
| link | `string` | - | Deprecated alias for `Popover.Card.Footer` link |
|
|
569
|
+
| linkText | `string` | - | Deprecated alias for `Popover.Card.Footer` link text |
|
|
570
|
+
| other div props | `Omit<PopoverContentComposeProps, 'children'>` | - | Standard popup container props forwarded to the composed content |
|
|
571
|
+
|
|
572
|
+
### `Popover.Content.Compose` Props
|
|
573
|
+
|
|
574
|
+
| Prop | Type | Default | Description |
|
|
575
|
+
|------|------|---------|-------------|
|
|
576
|
+
| children | `React.ReactNode` | required | Popup content |
|
|
577
|
+
| backgroundColor | `string` | - | Popup background color override |
|
|
578
|
+
| placement | `'top' \| 'bottom' \| 'left' \| 'right'` | `bottom` | Preferred popup side |
|
|
579
|
+
| sideOffset | `number` | `5` | Offset between trigger and popup |
|
|
580
|
+
| persistent | `boolean` | `false` | Prevents closing on outside click |
|
|
581
|
+
| onClickOutside | `(event) => void` | - | Outside click handler |
|
|
582
|
+
| alignOffset | `number` | - | Additional alignment offset |
|
|
583
|
+
| align | `'start' \| 'center' \| 'end'` | `center` | Alignment against the trigger |
|
|
584
|
+
| maxWidth | `string` | - | Max popup width override |
|
|
585
|
+
| portal | `HTMLElement \| null` | `document.body` | Portal container or `null` to render inline |
|
|
586
|
+
| collisionBoundary | `RadixPopover.PopoverContentProps['collisionBoundary']` | - | Radix collision boundary override |
|
|
587
|
+
| other div props | `PopoverContentComposeProps` | - | Standard popup container props |
|
|
588
|
+
|
|
589
|
+
### `Popover.Content.Close` Props
|
|
590
|
+
|
|
591
|
+
| Prop | Type | Default | Description |
|
|
592
|
+
|------|------|---------|-------------|
|
|
593
|
+
| icon | `IconType` | `CancelIcon` | Override icon used by the close button |
|
|
594
|
+
| other button props | `PopoverCloseProps` | - | Standard button props forwarded to the close button |
|
|
595
|
+
|
|
596
|
+
### `Popover.Content.Text`
|
|
597
|
+
|
|
598
|
+
Inherits `TypographyBodyProps`. This is the styled text wrapper used when `Popover.content` is a string.
|
|
599
|
+
|
|
600
|
+
### `Popover.Content.Header` Props
|
|
601
|
+
|
|
602
|
+
| Prop | Type | Default | Description |
|
|
603
|
+
|------|------|---------|-------------|
|
|
604
|
+
| title | `string` | - | Header title text |
|
|
605
|
+
| hideCloseButton | `boolean` | `false` | Hides the close button |
|
|
606
|
+
| other div props | `ContentHeaderComposeProps` | - | Standard header container props |
|
|
607
|
+
|
|
608
|
+
### `Popover.Content.Header.Compose` Props
|
|
609
|
+
|
|
610
|
+
| Prop | Type | Default | Description |
|
|
611
|
+
|------|------|---------|-------------|
|
|
612
|
+
| other div props | `ContentHeaderComposeProps` | - | Standard header container props |
|
|
613
|
+
|
|
614
|
+
### `Popover.Content.Header.Title`
|
|
615
|
+
|
|
616
|
+
Inherits `TypographyHeadingProps`. The wrapper renders the title with `size="S"` by default.
|
|
617
|
+
|
|
618
|
+
### `Popover.Content.Body` Props
|
|
619
|
+
|
|
620
|
+
| Prop | Type | Default | Description |
|
|
621
|
+
|------|------|---------|-------------|
|
|
622
|
+
| text | `string` | - | Body text |
|
|
623
|
+
| other div props | `ContentBodyComposeProps` | - | Standard body container props |
|
|
624
|
+
|
|
625
|
+
### `Popover.Content.Body.Compose` Props
|
|
626
|
+
|
|
627
|
+
| Prop | Type | Default | Description |
|
|
628
|
+
|------|------|---------|-------------|
|
|
629
|
+
| other div props | `ContentBodyComposeProps` | - | Standard body container props |
|
|
630
|
+
|
|
631
|
+
### `Popover.Content.Body.Text`
|
|
632
|
+
|
|
633
|
+
Inherits `TypographyBodyProps`.
|
|
634
|
+
|
|
635
|
+
### `Popover.Content.Footer` Props
|
|
636
|
+
|
|
637
|
+
| Prop | Type | Default | Description |
|
|
638
|
+
|------|------|---------|-------------|
|
|
639
|
+
| actionButtonText | `string` | - | Action button label |
|
|
640
|
+
| actionButtonHandler | `(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void` | - | Action button click handler |
|
|
641
|
+
| link | `string` | - | Footer link URL |
|
|
642
|
+
| linkText | `string` | - | Footer link label |
|
|
643
|
+
| other div props | `ContentFooterComposeProps` | - | Standard footer container props |
|
|
644
|
+
|
|
645
|
+
### `Popover.Content.Footer.Compose` Props
|
|
646
|
+
|
|
647
|
+
| Prop | Type | Default | Description |
|
|
648
|
+
|------|------|---------|-------------|
|
|
649
|
+
| other div props | `ContentFooterComposeProps` | - | Standard footer container props |
|
|
650
|
+
|
|
651
|
+
### `Popover.Content.WindowBar` Props
|
|
652
|
+
|
|
653
|
+
| Prop | Type | Default | Description |
|
|
654
|
+
|------|------|---------|-------------|
|
|
655
|
+
| title | `string` | `''` | Window bar title text |
|
|
656
|
+
| variant | `BadgeVariants` | `default` | Semantic window bar variant |
|
|
657
|
+
| hideCloseButton | `boolean` | `false` | Hides the close button |
|
|
658
|
+
| withIcon | `boolean` | `true` | Shows the icon slot when a variant icon is available |
|
|
659
|
+
| icon | `IconType` | - | Custom icon override |
|
|
660
|
+
| other div props | `WindowBarComposeProps` | - | Standard window bar container props |
|
|
661
|
+
|
|
662
|
+
### `Popover.Content.WindowBar.Compose` Props
|
|
663
|
+
|
|
664
|
+
| Prop | Type | Default | Description |
|
|
665
|
+
|------|------|---------|-------------|
|
|
666
|
+
| variant | `BadgeVariants` | - | Semantic window bar variant |
|
|
667
|
+
| other div props | `WindowBarComposeProps` | - | Standard window bar container props |
|
|
668
|
+
|
|
669
|
+
### `Popover.Content.WindowBar.Header` Props
|
|
670
|
+
|
|
671
|
+
| Prop | Type | Default | Description |
|
|
672
|
+
|------|------|---------|-------------|
|
|
673
|
+
| children | `React.ReactNode` | required | Header content |
|
|
674
|
+
|
|
675
|
+
### `Popover.Content.WindowBar.Heading`
|
|
676
|
+
|
|
677
|
+
Inherits `TypographyHeadingProps`. The styled wrapper keeps the heading line-height tight.
|
|
678
|
+
|
|
679
|
+
### `Popover.Content.WindowBar.Icon`
|
|
680
|
+
|
|
681
|
+
Uses `BadgeIconProps`. Story usage passes `variant`, `icon`, `size`, and `customColor`.
|
|
682
|
+
|
|
683
|
+
### `Popover.Content.WindowBar.Close` Props
|
|
684
|
+
|
|
685
|
+
| Prop | Type | Default | Description |
|
|
686
|
+
|------|------|---------|-------------|
|
|
687
|
+
| icon | `IconType` | `CancelIcon` | Override icon used by the close button |
|
|
688
|
+
| other button props | `React.HTMLAttributes<HTMLButtonElement>` | - | Standard button props forwarded to the close button |
|
|
689
|
+
|
|
690
|
+
## Popover.Card
|
|
691
|
+
|
|
692
|
+
### Props
|
|
693
|
+
|
|
694
|
+
| Prop | Type | Default | Description |
|
|
695
|
+
|------|------|---------|-------------|
|
|
696
|
+
| title | `string` | - | Card header title |
|
|
697
|
+
| text | `ContentBodyProps['text']` | - | Card body text |
|
|
698
|
+
| actionButtonText | `string` | - | Footer action button label |
|
|
699
|
+
| actionButtonHandler | `(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void` | - | Footer action button callback |
|
|
700
|
+
| link | `string` | - | Footer link URL |
|
|
701
|
+
| linkText | `string` | - | Footer link label |
|
|
702
|
+
| windowBar | `WindowBarProps` | - | Optional semantic window bar content |
|
|
703
|
+
| persistent | `boolean` | - | Keeps the content open on outside click |
|
|
704
|
+
| other div props | `Omit<ComposeProps, 'children' | 'title'>` | - | Standard card container props |
|
|
705
|
+
|
|
706
|
+
### Sub-components
|
|
707
|
+
|
|
708
|
+
- `Popover.Card.Compose` - Card container surface.
|
|
709
|
+
- `Popover.Card.Header` - Alias of `Popover.Content.Header`.
|
|
710
|
+
- `Popover.Card.Body` - Alias of `Popover.Content.Body`.
|
|
711
|
+
- `Popover.Card.Footer` - Alias of `Popover.Content.Footer`.
|
|
712
|
+
- `Popover.Card.WindowBar` - Alias of `Popover.Content.WindowBar`.
|
|
713
|
+
- `Popover.Card.WindowBar.Header` - Alias of `Popover.Content.WindowBar.Header`.
|
|
714
|
+
- `Popover.Card.WindowBar.Icon` - Alias of `Popover.Content.WindowBar.Icon`.
|
|
715
|
+
- `Popover.Card.WindowBar.Close` - Alias of `Popover.Content.WindowBar.Close`.
|
|
716
|
+
|
|
717
|
+
### `Popover.Card.Compose` Props
|
|
718
|
+
|
|
719
|
+
| Prop | Type | Default | Description |
|
|
720
|
+
|------|------|---------|-------------|
|
|
721
|
+
| children | `React.ReactNode` | required | Card content |
|
|
722
|
+
| other div props | `ComposeProps` | - | Standard card container props |
|
|
723
|
+
|
|
724
|
+
### `Popover.Card.Close`
|
|
725
|
+
|
|
726
|
+
Uses the same props as `Popover.Content.Close`.
|
|
727
|
+
|
|
728
|
+
### `Popover.Card Header / Body / Footer / WindowBar`
|
|
729
|
+
|
|
730
|
+
These aliases reuse the same prop surfaces as the corresponding `Popover.Content.*` subcomponents. The card stories exercise them through the composed card example.
|
|
731
|
+
|
|
732
|
+
### `Popover.Card` Notes
|
|
733
|
+
|
|
734
|
+
- `Popover.Card.WindowBar` supports semantic variants. When you compose the bar manually, apply the variant to the icon as well.
|
|
735
|
+
- `Popover.Card` is the preferred replacement for the deprecated `Popover.Content` card-style props.
|
|
736
|
+
|
|
737
|
+
## Popover.Card Examples
|
|
738
|
+
|
|
739
|
+
### Playground
|
|
740
|
+
|
|
741
|
+
```tsx
|
|
742
|
+
import { Popover } from '@redislabsdev/redis-ui-components';
|
|
743
|
+
import { PhoneIcon } from '@redislabsdev/redis-ui-icons';
|
|
744
|
+
|
|
745
|
+
<Popover
|
|
746
|
+
open
|
|
747
|
+
content={
|
|
748
|
+
<Popover.Card
|
|
749
|
+
windowBar={{
|
|
750
|
+
title: 'WindowBar Title',
|
|
751
|
+
withIcon: true,
|
|
752
|
+
variant: 'default',
|
|
753
|
+
icon: PhoneIcon
|
|
754
|
+
}}
|
|
755
|
+
title="Popover Card title"
|
|
756
|
+
text="Popover Card displays formatted content"
|
|
757
|
+
link="#"
|
|
758
|
+
actionButtonHandler={() => {}}
|
|
759
|
+
actionButtonText="Action"
|
|
760
|
+
/>
|
|
761
|
+
}
|
|
762
|
+
>
|
|
763
|
+
<span />
|
|
764
|
+
</Popover>
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
### CardVariants
|
|
768
|
+
|
|
769
|
+
> `Popover.Card.WindowBar` supports semantic variants. To set the variant, use the `variant` prop on `WindowBar` or on the `windowBar` prop.
|
|
770
|
+
>
|
|
771
|
+
> In composition, apply the same variant to the icon as well.
|
|
772
|
+
|
|
773
|
+
```tsx
|
|
774
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
775
|
+
import { useViewMode } from '../../helpers/useViewMode';
|
|
776
|
+
|
|
777
|
+
const variants = ['default', 'informative', 'notice', 'danger', 'attention', 'success'] as const;
|
|
778
|
+
|
|
779
|
+
function Render() {
|
|
780
|
+
const { inStory } = useViewMode();
|
|
781
|
+
|
|
782
|
+
return (
|
|
783
|
+
<>
|
|
784
|
+
{variants.map((variant) => (
|
|
785
|
+
<Popover
|
|
786
|
+
key={variant}
|
|
787
|
+
open={inStory}
|
|
788
|
+
content={
|
|
789
|
+
<Popover.Card
|
|
790
|
+
windowBar={{ variant, title: 'WindowBar title' }}
|
|
791
|
+
title="Header title"
|
|
792
|
+
text="Body text"
|
|
793
|
+
actionButtonText="Action"
|
|
794
|
+
actionButtonHandler={() => {}}
|
|
795
|
+
link="#"
|
|
796
|
+
/>
|
|
797
|
+
}
|
|
798
|
+
>
|
|
799
|
+
<Button>{variant}</Button>
|
|
800
|
+
</Popover>
|
|
801
|
+
))}
|
|
802
|
+
</>
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
### ComposeCard
|
|
808
|
+
|
|
809
|
+
> `Popover.Card` can be composed from `WindowBar`, `Header`, `Body`, and `Footer` pieces.
|
|
810
|
+
|
|
811
|
+
```tsx
|
|
812
|
+
import { Button, Popover } from '@redislabsdev/redis-ui-components';
|
|
813
|
+
import { PhoneIcon } from '@redislabsdev/redis-ui-icons';
|
|
814
|
+
import { useViewMode } from '../../helpers/useViewMode';
|
|
815
|
+
|
|
816
|
+
function Render() {
|
|
817
|
+
const { inStory } = useViewMode();
|
|
818
|
+
|
|
819
|
+
return (
|
|
820
|
+
<Popover
|
|
821
|
+
defaultOpen={inStory}
|
|
822
|
+
content={
|
|
823
|
+
<Popover.Card.Compose>
|
|
824
|
+
<Popover.Card.WindowBar.Compose>
|
|
825
|
+
<Popover.Card.WindowBar.Header>
|
|
826
|
+
<Popover.Card.WindowBar.Icon
|
|
827
|
+
icon={PhoneIcon}
|
|
828
|
+
variant="default"
|
|
829
|
+
size="L"
|
|
830
|
+
customColor="currentColor"
|
|
831
|
+
/>
|
|
832
|
+
<Popover.Card.WindowBar.Heading size="S">
|
|
833
|
+
Custom WindowBar.Header
|
|
834
|
+
</Popover.Card.WindowBar.Heading>
|
|
835
|
+
</Popover.Card.WindowBar.Header>
|
|
836
|
+
<Popover.Card.WindowBar.Close />
|
|
837
|
+
</Popover.Card.WindowBar.Compose>
|
|
838
|
+
<Popover.Card.Header.Compose>
|
|
839
|
+
<Popover.Card.Header.Title>Custom Header title</Popover.Card.Header.Title>
|
|
840
|
+
</Popover.Card.Header.Compose>
|
|
841
|
+
<Popover.Card.Body.Compose>
|
|
842
|
+
<Popover.Card.Body.Text>Custom Body text</Popover.Card.Body.Text>
|
|
843
|
+
</Popover.Card.Body.Compose>
|
|
844
|
+
<Popover.Card.Footer.Compose>
|
|
845
|
+
<Button>Custom Footer button</Button>
|
|
846
|
+
</Popover.Card.Footer.Compose>
|
|
847
|
+
</Popover.Card.Compose>
|
|
848
|
+
}
|
|
849
|
+
>
|
|
850
|
+
<Button>Click me</Button>
|
|
851
|
+
</Popover>
|
|
852
|
+
);
|
|
853
|
+
}
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
## Notes
|
|
857
|
+
|
|
858
|
+
- `visible` and `onVisibilityChange` are deprecated aliases for `open` and `onOpenChange`.
|
|
859
|
+
- `Popover.Content` still accepts deprecated card-style props (`windowBar`, `title`, `text`, `actionButtonText`, `actionButtonHandler`, `link`, `linkText`), but `Popover.Card` is the preferred API.
|
|
860
|
+
- `Popover.Trigger` with `withButton` is useful when the trigger content is plain text, SVG, or multiple elements.
|
|
861
|
+
- `Popover.Content.Text` is the string-content wrapper used by the default `Popover` render path.
|
|
862
|
+
- `Popover.Card.Close` mirrors `Popover.Content.Close`.
|
|
863
|
+
- Use `placement`, `align`, and `alignOffset` together for positioning control; collisions can still flip the popup.
|
|
864
|
+
- `persistent` prevents outside clicks from closing the popup, so pair it with an explicit close control.
|
|
865
|
+
- `onClickOutside` fires when the user clicks outside the popover.
|
|
866
|
+
- Empty or falsy `content` and `disabled` popovers will not open.
|
|
867
|
+
- `portal={null}` renders the popover inline instead of through a portal.
|
|
868
|
+
- `Popover.Content.WindowBar` returns `null` when it has no title.
|