@arbor-education/design-system.components 0.15.0 → 0.16.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/.gather/skills/write-stories/SKILL.md +207 -271
- package/.storybook/preview.ts +5 -0
- package/CHANGELOG.md +23 -0
- package/README.md +8 -0
- package/component-library.md +144 -13
- package/dist/components/articleCard/ArticleCard.stories.d.ts +137 -11
- package/dist/components/articleCard/ArticleCard.stories.d.ts.map +1 -1
- package/dist/components/articleCard/ArticleCard.stories.js +358 -91
- package/dist/components/articleCard/ArticleCard.stories.js.map +1 -1
- package/dist/components/avatar/Avatar.stories.d.ts +6 -6
- package/dist/components/avatar/Avatar.stories.d.ts.map +1 -1
- package/dist/components/avatar/Avatar.stories.js +393 -49
- package/dist/components/avatar/Avatar.stories.js.map +1 -1
- package/dist/components/avatarGroup/AvatarGroup.stories.d.ts +9 -7
- package/dist/components/avatarGroup/AvatarGroup.stories.d.ts.map +1 -1
- package/dist/components/avatarGroup/AvatarGroup.stories.js +688 -65
- package/dist/components/avatarGroup/AvatarGroup.stories.js.map +1 -1
- package/dist/components/banner/Banner.stories.d.ts.map +1 -1
- package/dist/components/banner/Banner.stories.js +7 -3
- package/dist/components/banner/Banner.stories.js.map +1 -1
- package/dist/components/card/Card.stories.d.ts +105 -4
- package/dist/components/card/Card.stories.d.ts.map +1 -1
- package/dist/components/card/Card.stories.js +336 -18
- package/dist/components/card/Card.stories.js.map +1 -1
- package/dist/components/combobox/Combobox.stories.d.ts +134 -21
- package/dist/components/combobox/Combobox.stories.d.ts.map +1 -1
- package/dist/components/combobox/Combobox.stories.js +676 -175
- package/dist/components/combobox/Combobox.stories.js.map +1 -1
- package/dist/components/datePicker/DatePicker.stories.d.ts +119 -27
- package/dist/components/datePicker/DatePicker.stories.d.ts.map +1 -1
- package/dist/components/datePicker/DatePicker.stories.js +575 -47
- package/dist/components/datePicker/DatePicker.stories.js.map +1 -1
- package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts +155 -39
- package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts.map +1 -1
- package/dist/components/dateTimePicker/DateTimePicker.stories.js +674 -103
- package/dist/components/dateTimePicker/DateTimePicker.stories.js.map +1 -1
- package/dist/components/editableText/EditableText.stories.d.ts +53 -12
- package/dist/components/editableText/EditableText.stories.d.ts.map +1 -1
- package/dist/components/editableText/EditableText.stories.js +401 -64
- package/dist/components/editableText/EditableText.stories.js.map +1 -1
- package/dist/components/formField/FormField.d.ts +4 -0
- package/dist/components/formField/FormField.d.ts.map +1 -1
- package/dist/components/formField/FormField.js +2 -1
- package/dist/components/formField/FormField.js.map +1 -1
- package/dist/components/formField/FormField.test.js +5 -0
- package/dist/components/formField/FormField.test.js.map +1 -1
- package/dist/components/formField/fieldset/Fieldset.stories.d.ts +56 -4
- package/dist/components/formField/fieldset/Fieldset.stories.d.ts.map +1 -1
- package/dist/components/formField/fieldset/Fieldset.stories.js +534 -28
- package/dist/components/formField/fieldset/Fieldset.stories.js.map +1 -1
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts +3 -1
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts.map +1 -1
- package/dist/components/formField/inputs/checkbox/CheckboxInput.js +1 -1
- package/dist/components/formField/inputs/checkbox/CheckboxInput.js.map +1 -1
- package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.d.ts +95 -1
- package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.js +386 -9
- package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.js.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts +6 -2
- package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonGroup.js.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonInput.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js +61 -49
- package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.d.ts +188 -166
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.js +821 -160
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.js.map +1 -1
- package/dist/components/formField/inputs/time/TimeInput.stories.d.ts +176 -22
- package/dist/components/formField/inputs/time/TimeInput.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/time/TimeInput.stories.js +851 -92
- package/dist/components/formField/inputs/time/TimeInput.stories.js.map +1 -1
- package/dist/components/formField/label/Label.stories.d.ts +54 -5
- package/dist/components/formField/label/Label.stories.d.ts.map +1 -1
- package/dist/components/formField/label/Label.stories.js +238 -4
- package/dist/components/formField/label/Label.stories.js.map +1 -1
- package/dist/components/icoText/IcoText.stories.d.ts +32 -6
- package/dist/components/icoText/IcoText.stories.d.ts.map +1 -1
- package/dist/components/icoText/IcoText.stories.js +309 -14
- package/dist/components/icoText/IcoText.stories.js.map +1 -1
- package/dist/components/kpiCard/KPICard.stories.d.ts +100 -2
- package/dist/components/kpiCard/KPICard.stories.d.ts.map +1 -1
- package/dist/components/kpiCard/KPICard.stories.js +354 -10
- package/dist/components/kpiCard/KPICard.stories.js.map +1 -1
- package/dist/components/kvpList/KVPList.stories.d.ts +57 -4
- package/dist/components/kvpList/KVPList.stories.d.ts.map +1 -1
- package/dist/components/kvpList/KVPList.stories.js +403 -10
- package/dist/components/kvpList/KVPList.stories.js.map +1 -1
- package/dist/components/modal/Modal.stories.d.ts +113 -9
- package/dist/components/modal/Modal.stories.d.ts.map +1 -1
- package/dist/components/modal/Modal.stories.js +633 -13
- package/dist/components/modal/Modal.stories.js.map +1 -1
- package/dist/components/modal/modalManager/ModalManager.stories.d.ts +34 -10
- package/dist/components/modal/modalManager/ModalManager.stories.d.ts.map +1 -1
- package/dist/components/modal/modalManager/ModalManager.stories.js +463 -85
- package/dist/components/modal/modalManager/ModalManager.stories.js.map +1 -1
- package/dist/components/pill/Pill.d.ts.map +1 -1
- package/dist/components/pill/Pill.js +1 -1
- package/dist/components/pill/Pill.js.map +1 -1
- package/dist/components/pill/Pill.stories.d.ts.map +1 -1
- package/dist/components/pill/Pill.stories.js +11 -13
- package/dist/components/pill/Pill.stories.js.map +1 -1
- package/dist/components/row/Row.stories.d.ts +1 -2
- package/dist/components/row/Row.stories.d.ts.map +1 -1
- package/dist/components/row/Row.stories.js +360 -50
- package/dist/components/row/Row.stories.js.map +1 -1
- package/dist/components/searchBar/SearchBar.stories.d.ts +52 -4
- package/dist/components/searchBar/SearchBar.stories.d.ts.map +1 -1
- package/dist/components/searchBar/SearchBar.stories.js +428 -36
- package/dist/components/searchBar/SearchBar.stories.js.map +1 -1
- package/dist/components/section/Section.stories.d.ts +11 -41
- package/dist/components/section/Section.stories.d.ts.map +1 -1
- package/dist/components/section/Section.stories.js +494 -56
- package/dist/components/section/Section.stories.js.map +1 -1
- package/dist/components/singleUser/SingleUser.stories.d.ts +5 -4
- package/dist/components/singleUser/SingleUser.stories.d.ts.map +1 -1
- package/dist/components/singleUser/SingleUser.stories.js +303 -31
- package/dist/components/singleUser/SingleUser.stories.js.map +1 -1
- package/dist/components/slideoverManager/SlideoverManager.stories.d.ts +32 -11
- package/dist/components/slideoverManager/SlideoverManager.stories.d.ts.map +1 -1
- package/dist/components/slideoverManager/SlideoverManager.stories.js +380 -84
- package/dist/components/slideoverManager/SlideoverManager.stories.js.map +1 -1
- package/dist/components/table/DSDefaultColDef.d.ts.map +1 -1
- package/dist/components/table/DSDefaultColDef.js +4 -3
- package/dist/components/table/DSDefaultColDef.js.map +1 -1
- package/dist/components/table/Table.d.ts +6 -1
- package/dist/components/table/Table.d.ts.map +1 -1
- package/dist/components/table/Table.js +8 -3
- package/dist/components/table/Table.js.map +1 -1
- package/dist/components/table/Table.stories.d.ts +3 -0
- package/dist/components/table/Table.stories.d.ts.map +1 -1
- package/dist/components/table/Table.stories.js +384 -5
- package/dist/components/table/Table.stories.js.map +1 -1
- package/dist/components/table/Table.test.js +30 -0
- package/dist/components/table/Table.test.js.map +1 -1
- package/dist/components/table/TableFooter.stories.d.ts +49 -0
- package/dist/components/table/TableFooter.stories.d.ts.map +1 -0
- package/dist/components/table/TableFooter.stories.js +137 -0
- package/dist/components/table/TableFooter.stories.js.map +1 -0
- package/dist/components/table/TableHeader.stories.d.ts +93 -0
- package/dist/components/table/TableHeader.stories.d.ts.map +1 -0
- package/dist/components/table/TableHeader.stories.js +176 -0
- package/dist/components/table/TableHeader.stories.js.map +1 -0
- package/dist/components/table/cellEditors/DateCellEditor.stories.d.ts +44 -0
- package/dist/components/table/cellEditors/DateCellEditor.stories.d.ts.map +1 -0
- package/dist/components/table/cellEditors/DateCellEditor.stories.js +186 -0
- package/dist/components/table/cellEditors/DateCellEditor.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.d.ts +40 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.js +209 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.d.ts +48 -0
- package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.js +244 -0
- package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts.map +1 -1
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.js +3 -1
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.js.map +1 -1
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.d.ts +64 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.js +241 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.d.ts +55 -0
- package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.js +245 -0
- package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.d.ts +67 -0
- package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.js +221 -0
- package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.d.ts +75 -0
- package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js +270 -0
- package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js.map +1 -0
- package/dist/components/table/columnFilters/BooleanFilter.stories.d.ts +57 -0
- package/dist/components/table/columnFilters/BooleanFilter.stories.d.ts.map +1 -0
- package/dist/components/table/columnFilters/BooleanFilter.stories.js +198 -0
- package/dist/components/table/columnFilters/BooleanFilter.stories.js.map +1 -0
- package/dist/components/table/columnFilters/TimeFilter.stories.d.ts +58 -0
- package/dist/components/table/columnFilters/TimeFilter.stories.d.ts.map +1 -0
- package/dist/components/table/columnFilters/TimeFilter.stories.js +207 -0
- package/dist/components/table/columnFilters/TimeFilter.stories.js.map +1 -0
- package/dist/components/table/pagination/PaginationPanel.stories.d.ts +113 -0
- package/dist/components/table/pagination/PaginationPanel.stories.d.ts.map +1 -0
- package/dist/components/table/pagination/PaginationPanel.stories.js +272 -0
- package/dist/components/table/pagination/PaginationPanel.stories.js.map +1 -0
- package/dist/components/table/tableControls/HideColumnsDropdown.d.ts.map +1 -1
- package/dist/components/table/tableControls/HideColumnsDropdown.js +9 -3
- package/dist/components/table/tableControls/HideColumnsDropdown.js.map +1 -1
- package/dist/components/table/tableControls/TableControls.stories.d.ts +151 -0
- package/dist/components/table/tableControls/TableControls.stories.d.ts.map +1 -0
- package/dist/components/table/tableControls/TableControls.stories.js +356 -0
- package/dist/components/table/tableControls/TableControls.stories.js.map +1 -0
- package/dist/components/table/tableControls/TableSettingsDropdown.d.ts +27 -1
- package/dist/components/table/tableControls/TableSettingsDropdown.d.ts.map +1 -1
- package/dist/components/table/tableControls/TableSettingsDropdown.js +53 -26
- package/dist/components/table/tableControls/TableSettingsDropdown.js.map +1 -1
- package/dist/components/table/tableControls/TableSettingsDropdown.test.d.ts +2 -0
- package/dist/components/table/tableControls/TableSettingsDropdown.test.d.ts.map +1 -0
- package/dist/components/table/tableControls/TableSettingsDropdown.test.js +178 -0
- package/dist/components/table/tableControls/TableSettingsDropdown.test.js.map +1 -0
- package/dist/components/tabs/Tabs.stories.d.ts +22 -4
- package/dist/components/tabs/Tabs.stories.d.ts.map +1 -1
- package/dist/components/tabs/Tabs.stories.js +398 -22
- package/dist/components/tabs/Tabs.stories.js.map +1 -1
- package/dist/components/tabs/TabsItem.stories.d.ts +54 -1
- package/dist/components/tabs/TabsItem.stories.d.ts.map +1 -1
- package/dist/components/tabs/TabsItem.stories.js +61 -9
- package/dist/components/tabs/TabsItem.stories.js.map +1 -1
- package/dist/components/toast/Toast.stories.d.ts +103 -10
- package/dist/components/toast/Toast.stories.d.ts.map +1 -1
- package/dist/components/toast/Toast.stories.js +409 -47
- package/dist/components/toast/Toast.stories.js.map +1 -1
- package/dist/components/toggle/Toggle.stories.d.ts +61 -46
- package/dist/components/toggle/Toggle.stories.d.ts.map +1 -1
- package/dist/components/toggle/Toggle.stories.js +311 -122
- package/dist/components/toggle/Toggle.stories.js.map +1 -1
- package/dist/components/tooltip/Tooltip.stories.d.ts +78 -6
- package/dist/components/tooltip/Tooltip.stories.d.ts.map +1 -1
- package/dist/components/tooltip/Tooltip.stories.js +413 -7
- package/dist/components/tooltip/Tooltip.stories.js.map +1 -1
- package/dist/components/tooltip/TooltipWrapper.stories.d.ts +71 -7
- package/dist/components/tooltip/TooltipWrapper.stories.d.ts.map +1 -1
- package/dist/components/tooltip/TooltipWrapper.stories.js +238 -10
- package/dist/components/tooltip/TooltipWrapper.stories.js.map +1 -1
- package/dist/index.css +8 -0
- package/dist/index.css.map +1 -1
- package/dist/utils/PopupParentContext.stories.d.ts +17 -0
- package/dist/utils/PopupParentContext.stories.d.ts.map +1 -0
- package/dist/utils/PopupParentContext.stories.js +266 -0
- package/dist/utils/PopupParentContext.stories.js.map +1 -0
- package/dist/utils/getDefaultPopupParent.d.ts.map +1 -1
- package/dist/utils/getDefaultPopupParent.js +6 -0
- package/dist/utils/getDefaultPopupParent.js.map +1 -1
- package/package.json +1 -1
- package/src/components/articleCard/ArticleCard.stories.tsx +524 -111
- package/src/components/avatar/Avatar.stories.tsx +504 -59
- package/src/components/avatarGroup/AvatarGroup.stories.tsx +977 -175
- package/src/components/banner/Banner.stories.tsx +7 -3
- package/src/components/card/Card.stories.tsx +466 -36
- package/src/components/combobox/Combobox.stories.tsx +867 -260
- package/src/components/datePicker/DatePicker.stories.tsx +777 -60
- package/src/components/dateTimePicker/DateTimePicker.stories.tsx +910 -132
- package/src/components/editableText/EditableText.stories.tsx +567 -91
- package/src/components/formField/FormField.test.tsx +6 -0
- package/src/components/formField/FormField.tsx +5 -0
- package/src/components/formField/fieldset/Fieldset.stories.tsx +761 -51
- package/src/components/formField/inputs/checkbox/CheckboxGroup.tsx +1 -1
- package/src/components/formField/inputs/checkbox/CheckboxInput.tsx +1 -1
- package/src/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.tsx +504 -11
- package/src/components/formField/inputs/radio/RadioButtonGroup.tsx +17 -4
- package/src/components/formField/inputs/radio/RadioButtonInput.stories.tsx +71 -59
- package/src/components/formField/inputs/selectDropdown/SelectDropdown.stories.tsx +1079 -168
- package/src/components/formField/inputs/time/TimeInput.stories.tsx +1140 -104
- package/src/components/formField/label/Label.stories.tsx +317 -8
- package/src/components/icoText/IcoText.stories.tsx +442 -31
- package/src/components/kpiCard/KPICard.stories.tsx +475 -30
- package/src/components/kvpList/KVPList.stories.tsx +593 -26
- package/src/components/modal/Modal.stories.tsx +963 -26
- package/src/components/modal/modalManager/ModalManager.stories.tsx +612 -454
- package/src/components/pill/Pill.stories.tsx +11 -13
- package/src/components/pill/Pill.tsx +1 -0
- package/src/components/row/Row.stories.tsx +474 -58
- package/src/components/searchBar/SearchBar.stories.tsx +570 -38
- package/src/components/section/Section.stories.tsx +723 -70
- package/src/components/singleUser/SingleUser.stories.tsx +393 -34
- package/src/components/slideoverManager/SlideoverManager.stories.tsx +572 -342
- package/src/components/table/DSDefaultColDef.ts +25 -5
- package/src/components/table/Table.stories.tsx +460 -5
- package/src/components/table/Table.test.tsx +53 -0
- package/src/components/table/Table.tsx +9 -2
- package/src/components/table/TableFooter.stories.tsx +196 -0
- package/src/components/table/TableHeader.stories.tsx +251 -0
- package/src/components/table/cellEditors/DateCellEditor.stories.tsx +245 -0
- package/src/components/table/cellRenderers/BooleanCellRenderer.stories.tsx +278 -0
- package/src/components/table/cellRenderers/ButtonCellRenderer.stories.tsx +333 -0
- package/src/components/table/cellRenderers/CheckboxCellRenderer.stories.tsx +337 -0
- package/src/components/table/cellRenderers/CheckboxCellRenderer.tsx +5 -1
- package/src/components/table/cellRenderers/DefaultCellRenderer.stories.tsx +342 -0
- package/src/components/table/cellRenderers/InlineTextCellRenderer.stories.tsx +292 -0
- package/src/components/table/cellRenderers/SelectDropdownCellRenderer.stories.tsx +369 -0
- package/src/components/table/columnFilters/BooleanFilter.stories.tsx +268 -0
- package/src/components/table/columnFilters/TimeFilter.stories.tsx +281 -0
- package/src/components/table/pagination/PaginationPanel.stories.tsx +327 -0
- package/src/components/table/tableControls/HideColumnsDropdown.tsx +11 -2
- package/src/components/table/tableControls/TableControls.stories.tsx +415 -0
- package/src/components/table/tableControls/TableSettingsDropdown.test.tsx +207 -0
- package/src/components/table/tableControls/TableSettingsDropdown.tsx +103 -39
- package/src/components/tabs/Tabs.stories.tsx +540 -60
- package/src/components/tabs/TabsItem.stories.tsx +82 -8
- package/src/components/toast/Toast.stories.tsx +539 -77
- package/src/components/toggle/Toggle.stories.tsx +371 -135
- package/src/components/tooltip/Tooltip.stories.tsx +606 -15
- package/src/components/tooltip/TooltipWrapper.stories.tsx +348 -12
- package/src/docs/Contributing.mdx +241 -0
- package/src/docs/UsingComponents.mdx +93 -0
- package/src/docs/Welcome.mdx +68 -0
- package/src/global.scss +7 -0
- package/src/utils/PopupParentContext.stories.tsx +367 -0
- package/src/utils/getDefaultPopupParent.ts +6 -0
- package/.ralph/storybook-upgrade/knowledge.md +0 -308
- package/.ralph/storybook-upgrade/prd.json +0 -777
- package/.ralph/storybook-upgrade/progress.md +0 -342
- package/src/components/table/TableWIP.mdx +0 -3
|
@@ -1,35 +1,626 @@
|
|
|
1
|
-
import type { Meta } from '@storybook/react-vite';
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import {
|
|
3
|
+
Controls,
|
|
4
|
+
Heading as DocHeading,
|
|
5
|
+
Markdown,
|
|
6
|
+
Primary as DocPrimary,
|
|
7
|
+
Stories,
|
|
8
|
+
Subtitle,
|
|
9
|
+
Title,
|
|
10
|
+
} from '@storybook/addon-docs/blocks';
|
|
2
11
|
import { Tooltip } from './Tooltip';
|
|
3
12
|
import { Button } from 'Components/button/Button';
|
|
13
|
+
import { Icon } from 'Components/icon/Icon';
|
|
4
14
|
|
|
5
|
-
|
|
6
|
-
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Docs page content
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
const DESCRIPTION_INTRO = [
|
|
20
|
+
'`Tooltip` is a compound component that shows a floating label when a trigger element is hovered or focused.',
|
|
21
|
+
'It wraps [Radix UI Tooltip](https://www.radix-ui.com/primitives/docs/components/tooltip) and exposes',
|
|
22
|
+
'`Tooltip.Trigger` and `Tooltip.Content` for full compositional control.',
|
|
23
|
+
'',
|
|
24
|
+
'> **Tip:** Most use cases don\'t need full composition control.',
|
|
25
|
+
'> [`TooltipWrapper`](?path=/docs/components-tooltip-tooltipwrapper--docs) handles the wiring in a single component —',
|
|
26
|
+
'> pass your trigger as `children` and your label as `tooltipContent`.',
|
|
27
|
+
].join('\n');
|
|
28
|
+
|
|
29
|
+
const USAGE_GUIDANCE = [
|
|
30
|
+
'### When to use',
|
|
31
|
+
'',
|
|
32
|
+
'- **Icon-only controls** — any clickable icon without visible text needs a tooltip label',
|
|
33
|
+
'- **Abbreviations and truncated text** — reveal the full value on hover',
|
|
34
|
+
'- **Contextual hints** — brief supplementary info about a field or action that doesn\'t fit inline',
|
|
35
|
+
'',
|
|
36
|
+
'---',
|
|
37
|
+
'',
|
|
38
|
+
'### When NOT to use',
|
|
39
|
+
'',
|
|
40
|
+
'| Situation | Use instead |',
|
|
41
|
+
'|---|---|',
|
|
42
|
+
'| Information is essential to complete the task | Put it inline — don\'t hide critical guidance |',
|
|
43
|
+
'| Content is longer than ~2 lines | Use a [`Section`](?path=/docs/components-section--docs) or expand the UI |',
|
|
44
|
+
'| The trigger has no visible focus state | Fix the focusability first — keyboard users won\'t see the tooltip |',
|
|
45
|
+
'| Touch / mobile-primary surfaces | Tooltips only trigger on hover — mobile users never see them |',
|
|
46
|
+
'',
|
|
47
|
+
'---',
|
|
48
|
+
'',
|
|
49
|
+
'### Sub-component API',
|
|
50
|
+
'',
|
|
51
|
+
'#### `Tooltip`',
|
|
52
|
+
'',
|
|
53
|
+
'| Prop | Type | Default | Description |',
|
|
54
|
+
'|---|---|---|---|',
|
|
55
|
+
'| `delayDuration` | `number` | `400` | Milliseconds before the tooltip appears after hover |',
|
|
56
|
+
'| `open` | `boolean` | — | Controlled open state |',
|
|
57
|
+
'| `onOpenChange` | `(open: boolean) => void` | — | Callback for controlled mode |',
|
|
58
|
+
'| `defaultOpen` | `boolean` | — | Initial open state (uncontrolled) |',
|
|
59
|
+
'| `disableHoverableContent` | `boolean` | — | Prevents hovering over the tooltip content itself |',
|
|
60
|
+
'| `children` | `ReactNode` | — | Must include `Tooltip.Trigger` and `Tooltip.Content` |',
|
|
61
|
+
'',
|
|
62
|
+
'#### `Tooltip.Trigger`',
|
|
63
|
+
'',
|
|
64
|
+
'| Prop | Type | Default | Description |',
|
|
65
|
+
'|---|---|---|---|',
|
|
66
|
+
'| `children` | `ReactNode` | — | The element that opens the tooltip. Must be focusable. |',
|
|
67
|
+
'| `className` | `string` | — | Extra CSS class merged onto the trigger child |',
|
|
68
|
+
'',
|
|
69
|
+
'#### `Tooltip.Content`',
|
|
70
|
+
'',
|
|
71
|
+
'| Prop | Type | Default | Description |',
|
|
72
|
+
'|---|---|---|---|',
|
|
73
|
+
'| `children` | `ReactNode` | — | The tooltip body |',
|
|
74
|
+
'| `shouldShowArrow` | `boolean` | `true` | Whether to render the pointing arrow |',
|
|
75
|
+
'| `side` | `"top" \\| "right" \\| "bottom" \\| "left"` | `"top"` | Preferred placement side |',
|
|
76
|
+
'| `sideOffset` | `number` | — | Distance (px) between tooltip and trigger |',
|
|
77
|
+
'| `align` | `"start" \\| "center" \\| "end"` | `"center"` | Alignment along the side |',
|
|
78
|
+
'| `portalProps` | `TooltipPortalProps` | — | Props forwarded to `Radix.Portal` |',
|
|
79
|
+
].join('\n');
|
|
80
|
+
|
|
81
|
+
const DEVELOPER_NOTES = [
|
|
82
|
+
'### `asChild` is built in',
|
|
83
|
+
'',
|
|
84
|
+
'`Tooltip.Trigger` always renders with `asChild` — the Radix trigger props are merged directly onto the child element.',
|
|
85
|
+
'The child must be a focusable element (`<button>`, `<a>`, etc.) or a custom component that forwards its ref.',
|
|
86
|
+
'Wrapping a `<div>` or `<span>` without `tabIndex` will cause keyboard users to miss the tooltip.',
|
|
87
|
+
'',
|
|
88
|
+
'---',
|
|
89
|
+
'',
|
|
90
|
+
'### Portal rendering',
|
|
91
|
+
'',
|
|
92
|
+
'`Tooltip.Content` renders via a Radix portal, controlled by `PopupParentContext`.',
|
|
93
|
+
'Do **not** place containing elements with `overflow: hidden` — the tooltip will be clipped.',
|
|
94
|
+
'If you need to re-parent the portal (e.g. inside a Modal), wrap the tree with',
|
|
95
|
+
'`<PopupParentContext.Provider value={containerRef}>` — see',
|
|
96
|
+
'[`PopupParentContext`](?path=/docs/utils-popupparentcontext--docs).',
|
|
97
|
+
'',
|
|
98
|
+
'---',
|
|
99
|
+
'',
|
|
100
|
+
'### Accessibility',
|
|
101
|
+
'',
|
|
102
|
+
'- Radix automatically sets `role="tooltip"` on the content and wires `aria-describedby` on the trigger — no manual ARIA needed.',
|
|
103
|
+
'- The tooltip is announced by screen readers when the trigger receives focus.',
|
|
104
|
+
'- `delayDuration={0}` is recommended for keyboard-triggered tooltips (focus shouldn\'t require a wait).',
|
|
105
|
+
'- Never put interactive content (buttons, links) inside a tooltip — use a Popup or Dropdown instead.',
|
|
106
|
+
'',
|
|
107
|
+
'---',
|
|
108
|
+
'',
|
|
109
|
+
'### TypeScript types',
|
|
110
|
+
'',
|
|
111
|
+
'```ts',
|
|
112
|
+
"import type { Tooltip } from '@arbor-education/design-system.components';",
|
|
113
|
+
'',
|
|
114
|
+
'type Props = Tooltip.Props; // Tooltip root — extends Radix TooltipProps',
|
|
115
|
+
'type ContentProps = Tooltip.ContentProps; // Tooltip.Content',
|
|
116
|
+
'type TriggerProps = Tooltip.TriggerProps; // Tooltip.Trigger — extends Radix TooltipTriggerProps',
|
|
117
|
+
'```',
|
|
118
|
+
].join('\n');
|
|
119
|
+
|
|
120
|
+
const RELATED_COMPONENTS = [
|
|
121
|
+
'## Related components',
|
|
122
|
+
'',
|
|
123
|
+
'[TooltipWrapper](?path=/docs/components-tooltip-tooltipwrapper--docs) · [Button](?path=/docs/components-button--docs) · [Icon](?path=/docs/components-icon--docs)',
|
|
124
|
+
].join('\n');
|
|
125
|
+
|
|
126
|
+
const PROPS_INTRO = 'The preview below is wired to the **Controls** panel — tweak any prop to see the story update in real time.';
|
|
127
|
+
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// Docs page
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
|
|
132
|
+
function TooltipDocsPage() {
|
|
133
|
+
return (
|
|
134
|
+
<>
|
|
135
|
+
<Title />
|
|
136
|
+
<Subtitle />
|
|
137
|
+
<Markdown>{DESCRIPTION_INTRO}</Markdown>
|
|
138
|
+
<DocHeading>Interactive example</DocHeading>
|
|
139
|
+
<Markdown>{PROPS_INTRO}</Markdown>
|
|
140
|
+
<DocPrimary />
|
|
141
|
+
<Controls />
|
|
142
|
+
<DocHeading>Usage guidance</DocHeading>
|
|
143
|
+
<Markdown>{USAGE_GUIDANCE}</Markdown>
|
|
144
|
+
<DocHeading>Developer notes</DocHeading>
|
|
145
|
+
<Markdown>{DEVELOPER_NOTES}</Markdown>
|
|
146
|
+
<DocHeading>Examples</DocHeading>
|
|
147
|
+
<Stories title="" />
|
|
148
|
+
<Markdown>{RELATED_COMPONENTS}</Markdown>
|
|
149
|
+
</>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// Meta
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
|
|
157
|
+
const meta = {
|
|
158
|
+
title: 'Components/Tooltip',
|
|
7
159
|
component: Tooltip,
|
|
8
160
|
tags: ['autodocs'],
|
|
161
|
+
parameters: {
|
|
162
|
+
layout: 'centered',
|
|
163
|
+
docs: {
|
|
164
|
+
page: TooltipDocsPage,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
argTypes: {
|
|
168
|
+
delayDuration: {
|
|
169
|
+
control: 'number',
|
|
170
|
+
description: 'Milliseconds to wait before the tooltip appears after the trigger is hovered or focused.',
|
|
171
|
+
table: {
|
|
172
|
+
type: { summary: 'number' },
|
|
173
|
+
defaultValue: { summary: '400' },
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
open: {
|
|
177
|
+
control: false,
|
|
178
|
+
description: 'Controlled open state. When provided, pair with `onOpenChange` to manage state externally.',
|
|
179
|
+
table: {
|
|
180
|
+
type: { summary: 'boolean' },
|
|
181
|
+
defaultValue: { summary: 'undefined' },
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
onOpenChange: {
|
|
185
|
+
control: false,
|
|
186
|
+
description: 'Callback fired when the open state changes. Required for controlled mode.',
|
|
187
|
+
table: {
|
|
188
|
+
type: { summary: '(open: boolean) => void' },
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
defaultOpen: {
|
|
192
|
+
control: false,
|
|
193
|
+
description: 'Initial open state for uncontrolled usage.',
|
|
194
|
+
table: {
|
|
195
|
+
type: { summary: 'boolean' },
|
|
196
|
+
defaultValue: { summary: 'false' },
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
children: {
|
|
200
|
+
control: false,
|
|
201
|
+
description: 'Must include `Tooltip.Trigger` and `Tooltip.Content` sub-components.',
|
|
202
|
+
table: {
|
|
203
|
+
type: { summary: 'ReactNode' },
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
} satisfies Meta<typeof Tooltip>;
|
|
9
208
|
|
|
209
|
+
export default meta;
|
|
210
|
+
type Story = StoryObj<typeof meta>;
|
|
211
|
+
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
// Helper
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
|
|
216
|
+
const withDescription = (story: Omit<Story, 'args'>, description: string): Story => ({
|
|
217
|
+
...(story as Story),
|
|
10
218
|
parameters: {
|
|
219
|
+
...story.parameters,
|
|
11
220
|
docs: {
|
|
221
|
+
...story.parameters?.docs,
|
|
12
222
|
description: {
|
|
13
|
-
|
|
223
|
+
story: description,
|
|
14
224
|
},
|
|
15
225
|
},
|
|
16
226
|
},
|
|
17
|
-
};
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// ---------------------------------------------------------------------------
|
|
230
|
+
// Templates
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
|
|
233
|
+
const AllPlacementsTemplate = () => (
|
|
234
|
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--spacing-xxlarge)', padding: 'var(--spacing-xxlarge)' }}>
|
|
235
|
+
{(['top', 'right', 'bottom', 'left'] as const).map(side => (
|
|
236
|
+
<div key={side} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--spacing-small)' }}>
|
|
237
|
+
<span style={{ fontSize: 'var(--font-size-2-13)', color: 'var(--color-grey-600)' }}>{`side="${side}"`}</span>
|
|
238
|
+
<Tooltip delayDuration={0}>
|
|
239
|
+
<Tooltip.Trigger>
|
|
240
|
+
<Button type="secondary">Hover me</Button>
|
|
241
|
+
</Tooltip.Trigger>
|
|
242
|
+
<Tooltip.Content side={side}>
|
|
243
|
+
Tooltip on the
|
|
244
|
+
{' '}
|
|
245
|
+
{side}
|
|
246
|
+
</Tooltip.Content>
|
|
247
|
+
</Tooltip>
|
|
248
|
+
</div>
|
|
249
|
+
))}
|
|
250
|
+
</div>
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
const WithoutArrowTemplate = () => (
|
|
254
|
+
<Tooltip delayDuration={0}>
|
|
255
|
+
<Tooltip.Trigger>
|
|
256
|
+
<Button type="secondary">Hover me</Button>
|
|
257
|
+
</Tooltip.Trigger>
|
|
258
|
+
<Tooltip.Content shouldShowArrow={false}>
|
|
259
|
+
No arrow on this tooltip
|
|
260
|
+
</Tooltip.Content>
|
|
261
|
+
</Tooltip>
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const WithRichContentTemplate = () => (
|
|
265
|
+
<Tooltip delayDuration={0}>
|
|
266
|
+
<Tooltip.Trigger>
|
|
267
|
+
<Button type="secondary">Assessment period</Button>
|
|
268
|
+
</Tooltip.Trigger>
|
|
269
|
+
<Tooltip.Content>
|
|
270
|
+
<div>
|
|
271
|
+
<strong>Autumn 1 2024–25</strong>
|
|
272
|
+
<div>Sep 2 – Oct 25</div>
|
|
273
|
+
</div>
|
|
274
|
+
</Tooltip.Content>
|
|
275
|
+
</Tooltip>
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
const WithIconTriggerTemplate = () => (
|
|
279
|
+
<div style={{ display: 'flex', gap: 'var(--spacing-small)' }}>
|
|
280
|
+
<Tooltip delayDuration={0}>
|
|
281
|
+
<Tooltip.Trigger>
|
|
282
|
+
<button
|
|
283
|
+
type="button"
|
|
284
|
+
aria-label="Download report"
|
|
285
|
+
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 'var(--spacing-xsmall)', display: 'flex' }}
|
|
286
|
+
>
|
|
287
|
+
<Icon name="download" size={24} />
|
|
288
|
+
</button>
|
|
289
|
+
</Tooltip.Trigger>
|
|
290
|
+
<Tooltip.Content>Download report</Tooltip.Content>
|
|
291
|
+
</Tooltip>
|
|
292
|
+
|
|
293
|
+
<Tooltip delayDuration={0}>
|
|
294
|
+
<Tooltip.Trigger>
|
|
295
|
+
<button
|
|
296
|
+
type="button"
|
|
297
|
+
aria-label="Export data"
|
|
298
|
+
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 'var(--spacing-xsmall)', display: 'flex' }}
|
|
299
|
+
>
|
|
300
|
+
<Icon name="share" size={24} />
|
|
301
|
+
</button>
|
|
302
|
+
</Tooltip.Trigger>
|
|
303
|
+
<Tooltip.Content>Export data</Tooltip.Content>
|
|
304
|
+
</Tooltip>
|
|
305
|
+
|
|
306
|
+
<Tooltip delayDuration={0}>
|
|
307
|
+
<Tooltip.Trigger>
|
|
308
|
+
<button
|
|
309
|
+
type="button"
|
|
310
|
+
aria-label="Settings"
|
|
311
|
+
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 'var(--spacing-xsmall)', display: 'flex' }}
|
|
312
|
+
>
|
|
313
|
+
<Icon name="settings" size={24} />
|
|
314
|
+
</button>
|
|
315
|
+
</Tooltip.Trigger>
|
|
316
|
+
<Tooltip.Content>Settings</Tooltip.Content>
|
|
317
|
+
</Tooltip>
|
|
318
|
+
</div>
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
const SlowDelayTemplate = () => (
|
|
322
|
+
<div style={{ display: 'flex', gap: 'var(--spacing-large)', alignItems: 'center' }}>
|
|
323
|
+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--spacing-small)' }}>
|
|
324
|
+
<span style={{ fontSize: 'var(--font-size-2-13)', color: 'var(--color-grey-600)' }}>
|
|
325
|
+
delayDuration=
|
|
326
|
+
{0}
|
|
327
|
+
</span>
|
|
328
|
+
<Tooltip delayDuration={0}>
|
|
329
|
+
<Tooltip.Trigger>
|
|
330
|
+
<Button type="secondary">Instant</Button>
|
|
331
|
+
</Tooltip.Trigger>
|
|
332
|
+
<Tooltip.Content>Shows immediately on hover</Tooltip.Content>
|
|
333
|
+
</Tooltip>
|
|
334
|
+
</div>
|
|
335
|
+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--spacing-small)' }}>
|
|
336
|
+
<span style={{ fontSize: 'var(--font-size-2-13)', color: 'var(--color-grey-600)' }}>
|
|
337
|
+
delayDuration=
|
|
338
|
+
{400}
|
|
339
|
+
{' '}
|
|
340
|
+
(default)
|
|
341
|
+
</span>
|
|
342
|
+
<Tooltip delayDuration={400}>
|
|
343
|
+
<Tooltip.Trigger>
|
|
344
|
+
<Button type="secondary">Default delay</Button>
|
|
345
|
+
</Tooltip.Trigger>
|
|
346
|
+
<Tooltip.Content>Shows after 400ms</Tooltip.Content>
|
|
347
|
+
</Tooltip>
|
|
348
|
+
</div>
|
|
349
|
+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--spacing-small)' }}>
|
|
350
|
+
<span style={{ fontSize: 'var(--font-size-2-13)', color: 'var(--color-grey-600)' }}>
|
|
351
|
+
delayDuration=
|
|
352
|
+
{1000}
|
|
353
|
+
</span>
|
|
354
|
+
<Tooltip delayDuration={1000}>
|
|
355
|
+
<Tooltip.Trigger>
|
|
356
|
+
<Button type="secondary">Slow</Button>
|
|
357
|
+
</Tooltip.Trigger>
|
|
358
|
+
<Tooltip.Content>Shows after 1 second</Tooltip.Content>
|
|
359
|
+
</Tooltip>
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
);
|
|
18
363
|
|
|
19
|
-
|
|
364
|
+
// ---------------------------------------------------------------------------
|
|
365
|
+
// Stories
|
|
366
|
+
// ---------------------------------------------------------------------------
|
|
367
|
+
|
|
368
|
+
export const Default: Story = {
|
|
20
369
|
args: {
|
|
21
|
-
|
|
22
|
-
|
|
370
|
+
delayDuration: 400,
|
|
371
|
+
},
|
|
372
|
+
render: args => (
|
|
373
|
+
<Tooltip {...args}>
|
|
374
|
+
<Tooltip.Trigger>
|
|
375
|
+
<Button type="primary">Hover or focus me</Button>
|
|
376
|
+
</Tooltip.Trigger>
|
|
377
|
+
<Tooltip.Content>
|
|
378
|
+
This is a tooltip
|
|
379
|
+
</Tooltip.Content>
|
|
380
|
+
</Tooltip>
|
|
381
|
+
),
|
|
382
|
+
parameters: {
|
|
383
|
+
docs: {
|
|
384
|
+
description: {
|
|
385
|
+
story: [
|
|
386
|
+
'The `Tooltip` compound component requires `Tooltip.Trigger` and `Tooltip.Content` as children.',
|
|
387
|
+
'The trigger element must be focusable — `Tooltip.Trigger` uses `asChild` to merge props onto the child.',
|
|
388
|
+
'Use the **Controls** panel to adjust `delayDuration`.',
|
|
389
|
+
].join(' '),
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
export const AllPlacements: Story = withDescription(
|
|
396
|
+
{
|
|
397
|
+
render: AllPlacementsTemplate,
|
|
398
|
+
parameters: {
|
|
399
|
+
controls: { disable: true },
|
|
400
|
+
layout: 'centered',
|
|
401
|
+
docs: {
|
|
402
|
+
source: {
|
|
403
|
+
language: 'tsx',
|
|
404
|
+
code: `
|
|
405
|
+
import { Tooltip } from '@arbor-education/design-system.components';
|
|
406
|
+
|
|
407
|
+
function TooltipAllPlacementsExample() {
|
|
408
|
+
return (
|
|
409
|
+
<>
|
|
410
|
+
<Tooltip delayDuration={0}>
|
|
411
|
+
<Tooltip.Trigger>
|
|
412
|
+
<button type="button">Top (default)</button>
|
|
413
|
+
</Tooltip.Trigger>
|
|
414
|
+
<Tooltip.Content side="top">
|
|
415
|
+
Tooltip on the top
|
|
416
|
+
</Tooltip.Content>
|
|
417
|
+
</Tooltip>
|
|
418
|
+
|
|
419
|
+
<Tooltip delayDuration={0}>
|
|
420
|
+
<Tooltip.Trigger>
|
|
421
|
+
<button type="button">Right</button>
|
|
422
|
+
</Tooltip.Trigger>
|
|
423
|
+
<Tooltip.Content side="right">
|
|
424
|
+
Tooltip on the right
|
|
425
|
+
</Tooltip.Content>
|
|
426
|
+
</Tooltip>
|
|
427
|
+
|
|
428
|
+
<Tooltip delayDuration={0}>
|
|
23
429
|
<Tooltip.Trigger>
|
|
24
|
-
<
|
|
430
|
+
<button type="button">Bottom</button>
|
|
25
431
|
</Tooltip.Trigger>
|
|
432
|
+
<Tooltip.Content side="bottom">
|
|
433
|
+
Tooltip on the bottom
|
|
434
|
+
</Tooltip.Content>
|
|
435
|
+
</Tooltip>
|
|
26
436
|
|
|
27
|
-
|
|
28
|
-
|
|
437
|
+
<Tooltip delayDuration={0}>
|
|
438
|
+
<Tooltip.Trigger>
|
|
439
|
+
<button type="button">Left</button>
|
|
440
|
+
</Tooltip.Trigger>
|
|
441
|
+
<Tooltip.Content side="left">
|
|
442
|
+
Tooltip on the left
|
|
29
443
|
</Tooltip.Content>
|
|
30
|
-
|
|
31
|
-
|
|
444
|
+
</Tooltip>
|
|
445
|
+
</>
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
export default TooltipAllPlacementsExample;
|
|
449
|
+
`.trim(),
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
},
|
|
32
453
|
},
|
|
33
|
-
|
|
454
|
+
[
|
|
455
|
+
'Use the `side` prop on `Tooltip.Content` to control which side the tooltip appears on.',
|
|
456
|
+
'Radix will automatically flip to the opposite side if there\'s not enough viewport space.',
|
|
457
|
+
].join(' '),
|
|
458
|
+
);
|
|
34
459
|
|
|
35
|
-
export
|
|
460
|
+
export const WithoutArrow: Story = withDescription(
|
|
461
|
+
{
|
|
462
|
+
render: WithoutArrowTemplate,
|
|
463
|
+
parameters: {
|
|
464
|
+
controls: { disable: true },
|
|
465
|
+
docs: {
|
|
466
|
+
source: {
|
|
467
|
+
language: 'tsx',
|
|
468
|
+
code: `
|
|
469
|
+
import { Tooltip } from '@arbor-education/design-system.components';
|
|
470
|
+
|
|
471
|
+
function TooltipWithoutArrowExample() {
|
|
472
|
+
return (
|
|
473
|
+
<Tooltip delayDuration={0}>
|
|
474
|
+
<Tooltip.Trigger>
|
|
475
|
+
<button type="button">Hover me</button>
|
|
476
|
+
</Tooltip.Trigger>
|
|
477
|
+
<Tooltip.Content shouldShowArrow={false}>
|
|
478
|
+
No arrow on this tooltip
|
|
479
|
+
</Tooltip.Content>
|
|
480
|
+
</Tooltip>
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
export default TooltipWithoutArrowExample;
|
|
484
|
+
`.trim(),
|
|
485
|
+
},
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
[
|
|
490
|
+
'Set `shouldShowArrow={false}` on `Tooltip.Content` to hide the pointing arrow.',
|
|
491
|
+
'Useful when the tooltip is positioned far from the trigger or inside a dense UI.',
|
|
492
|
+
].join(' '),
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
export const WithRichContent: Story = withDescription(
|
|
496
|
+
{
|
|
497
|
+
render: WithRichContentTemplate,
|
|
498
|
+
parameters: {
|
|
499
|
+
controls: { disable: true },
|
|
500
|
+
docs: {
|
|
501
|
+
source: {
|
|
502
|
+
language: 'tsx',
|
|
503
|
+
code: `
|
|
504
|
+
import { Tooltip } from '@arbor-education/design-system.components';
|
|
505
|
+
|
|
506
|
+
function TooltipWithRichContentExample() {
|
|
507
|
+
return (
|
|
508
|
+
<Tooltip delayDuration={0}>
|
|
509
|
+
<Tooltip.Trigger>
|
|
510
|
+
<button type="button">Assessment period</button>
|
|
511
|
+
</Tooltip.Trigger>
|
|
512
|
+
<Tooltip.Content>
|
|
513
|
+
<div>
|
|
514
|
+
<strong>Autumn 1 2024–25</strong>
|
|
515
|
+
<div>Sep 2 – Oct 25</div>
|
|
516
|
+
</div>
|
|
517
|
+
</Tooltip.Content>
|
|
518
|
+
</Tooltip>
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
export default TooltipWithRichContentExample;
|
|
522
|
+
`.trim(),
|
|
523
|
+
},
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
[
|
|
528
|
+
'`Tooltip.Content` accepts any `ReactNode` — use structured markup for richer labels.',
|
|
529
|
+
'Keep content short: tooltips should clarify, not teach.',
|
|
530
|
+
'Never put interactive elements (buttons, links) inside a tooltip.',
|
|
531
|
+
].join(' '),
|
|
532
|
+
);
|
|
533
|
+
|
|
534
|
+
export const WithIconTrigger: Story = withDescription(
|
|
535
|
+
{
|
|
536
|
+
render: WithIconTriggerTemplate,
|
|
537
|
+
parameters: {
|
|
538
|
+
controls: { disable: true },
|
|
539
|
+
docs: {
|
|
540
|
+
source: {
|
|
541
|
+
language: 'tsx',
|
|
542
|
+
code: `
|
|
543
|
+
import { Icon, Tooltip } from '@arbor-education/design-system.components';
|
|
544
|
+
|
|
545
|
+
// Icon-only controls must have both aria-label (for screen readers)
|
|
546
|
+
// and a Tooltip (for sighted users who hover).
|
|
547
|
+
function TooltipWithIconTriggerExample() {
|
|
548
|
+
return (
|
|
549
|
+
<Tooltip delayDuration={0}>
|
|
550
|
+
<Tooltip.Trigger>
|
|
551
|
+
<button
|
|
552
|
+
type="button"
|
|
553
|
+
aria-label="Download report"
|
|
554
|
+
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 'var(--spacing-xsmall)', display: 'flex' }}
|
|
555
|
+
>
|
|
556
|
+
<Icon name="download" size={24} />
|
|
557
|
+
</button>
|
|
558
|
+
</Tooltip.Trigger>
|
|
559
|
+
<Tooltip.Content>Download report</Tooltip.Content>
|
|
560
|
+
</Tooltip>
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
export default TooltipWithIconTriggerExample;
|
|
564
|
+
`.trim(),
|
|
565
|
+
},
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
[
|
|
570
|
+
'Icon-only buttons must have both an `aria-label` (for screen readers) and a `Tooltip` (for sighted mouse users).',
|
|
571
|
+
'The two convey the same information through different channels — they\'re complementary, not redundant.',
|
|
572
|
+
].join(' '),
|
|
573
|
+
);
|
|
574
|
+
|
|
575
|
+
export const HoverDelay: Story = withDescription(
|
|
576
|
+
{
|
|
577
|
+
render: SlowDelayTemplate,
|
|
578
|
+
parameters: {
|
|
579
|
+
controls: { disable: true },
|
|
580
|
+
layout: 'centered',
|
|
581
|
+
docs: {
|
|
582
|
+
source: {
|
|
583
|
+
language: 'tsx',
|
|
584
|
+
code: `
|
|
585
|
+
import { Tooltip } from '@arbor-education/design-system.components';
|
|
586
|
+
|
|
587
|
+
// delayDuration={0} is best for keyboard-triggered tooltips (focus shouldn't wait).
|
|
588
|
+
// The default 400ms prevents flicker when the user is just moving the cursor past buttons.
|
|
589
|
+
function TooltipHoverDelayExample() {
|
|
590
|
+
return (
|
|
591
|
+
<>
|
|
592
|
+
<Tooltip delayDuration={0}>
|
|
593
|
+
<Tooltip.Trigger>
|
|
594
|
+
<button type="button">Instant (0ms)</button>
|
|
595
|
+
</Tooltip.Trigger>
|
|
596
|
+
<Tooltip.Content>Shows immediately on hover</Tooltip.Content>
|
|
597
|
+
</Tooltip>
|
|
598
|
+
|
|
599
|
+
<Tooltip delayDuration={400}>
|
|
600
|
+
<Tooltip.Trigger>
|
|
601
|
+
<button type="button">Default (400ms)</button>
|
|
602
|
+
</Tooltip.Trigger>
|
|
603
|
+
<Tooltip.Content>Shows after 400ms</Tooltip.Content>
|
|
604
|
+
</Tooltip>
|
|
605
|
+
|
|
606
|
+
<Tooltip delayDuration={1000}>
|
|
607
|
+
<Tooltip.Trigger>
|
|
608
|
+
<button type="button">Slow (1000ms)</button>
|
|
609
|
+
</Tooltip.Trigger>
|
|
610
|
+
<Tooltip.Content>Shows after 1 second</Tooltip.Content>
|
|
611
|
+
</Tooltip>
|
|
612
|
+
</>
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
export default TooltipHoverDelayExample;
|
|
616
|
+
`.trim(),
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
[
|
|
622
|
+
'`delayDuration` controls how long the user must hover before the tooltip appears.',
|
|
623
|
+
'The default 400ms prevents noise when the cursor moves across the page.',
|
|
624
|
+
'Use `delayDuration={0}` for icon-only controls where the label is the primary way to understand the action.',
|
|
625
|
+
].join(' '),
|
|
626
|
+
);
|