@pega/cosmos-react-core 7.0.0-build.22.8 → 7.0.0-build.23.0
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/lib/components/AIButton/AIButton.d.ts +30 -2
- package/lib/components/AIButton/AIButton.d.ts.map +1 -1
- package/lib/components/AIButton/AIButton.js +4 -3
- package/lib/components/AIButton/AIButton.js.map +1 -1
- package/lib/components/AppShell/AppHeader.d.ts.map +1 -1
- package/lib/components/AppShell/AppHeader.js +4 -6
- package/lib/components/AppShell/AppHeader.js.map +1 -1
- package/lib/components/AppShell/AppHeader.styles.d.ts.map +1 -1
- package/lib/components/AppShell/AppHeader.styles.js +6 -2
- package/lib/components/AppShell/AppHeader.styles.js.map +1 -1
- package/lib/components/AppShell/AppShell.d.ts.map +1 -1
- package/lib/components/AppShell/AppShell.js +2 -1
- package/lib/components/AppShell/AppShell.js.map +1 -1
- package/lib/components/AppShell/AppShell.styles.d.ts +3 -0
- package/lib/components/AppShell/AppShell.styles.d.ts.map +1 -1
- package/lib/components/AppShell/AppShell.styles.js +12 -0
- package/lib/components/AppShell/AppShell.styles.js.map +1 -1
- package/lib/components/AppShell/AppShell.types.d.ts +4 -0
- package/lib/components/AppShell/AppShell.types.d.ts.map +1 -1
- package/lib/components/AppShell/AppShell.types.js.map +1 -1
- package/lib/components/AppShell/NavigationList.d.ts.map +1 -1
- package/lib/components/AppShell/NavigationList.js +3 -3
- package/lib/components/AppShell/NavigationList.js.map +1 -1
- package/lib/components/AppShell/NavigationListItemWrapper.d.ts.map +1 -1
- package/lib/components/AppShell/NavigationListItemWrapper.js +1 -0
- package/lib/components/AppShell/NavigationListItemWrapper.js.map +1 -1
- package/lib/components/Button/Button.d.ts.map +1 -1
- package/lib/components/Button/Button.js +67 -35
- package/lib/components/Button/Button.js.map +1 -1
- package/lib/components/Card/Card.d.ts.map +1 -1
- package/lib/components/Card/Card.js +8 -0
- package/lib/components/Card/Card.js.map +1 -1
- package/lib/components/ColorPicker/ColorPicker.js +1 -1
- package/lib/components/ColorPicker/ColorPicker.js.map +1 -1
- package/lib/components/ComboBox/ComboBox.styles.d.ts.map +1 -1
- package/lib/components/ComboBox/ComboBox.styles.js +4 -0
- package/lib/components/ComboBox/ComboBox.styles.js.map +1 -1
- package/lib/components/Configuration/Configuration.d.ts +1 -0
- package/lib/components/Configuration/Configuration.d.ts.map +1 -1
- package/lib/components/Configuration/Configuration.js +58 -30
- package/lib/components/Configuration/Configuration.js.map +1 -1
- package/lib/components/Configuration/connected-watcher.d.ts +17 -0
- package/lib/components/Configuration/connected-watcher.d.ts.map +1 -0
- package/lib/components/Configuration/connected-watcher.js +13 -0
- package/lib/components/Configuration/connected-watcher.js.map +1 -0
- package/lib/components/DateTime/Input/MonthInput.d.ts.map +1 -1
- package/lib/components/DateTime/Input/MonthInput.js +21 -10
- package/lib/components/DateTime/Input/MonthInput.js.map +1 -1
- package/lib/components/DateTime/Picker/DatePicker.d.ts.map +1 -1
- package/lib/components/DateTime/Picker/DatePicker.js +5 -32
- package/lib/components/DateTime/Picker/DatePicker.js.map +1 -1
- package/lib/components/DateTime/Picker/utils.d.ts +9 -0
- package/lib/components/DateTime/Picker/utils.d.ts.map +1 -1
- package/lib/components/DateTime/Picker/utils.js +16 -0
- package/lib/components/DateTime/Picker/utils.js.map +1 -1
- package/lib/components/File/FileDisplayList.d.ts +2 -1
- package/lib/components/File/FileDisplayList.d.ts.map +1 -1
- package/lib/components/File/FileDisplayList.js +3 -2
- package/lib/components/File/FileDisplayList.js.map +1 -1
- package/lib/components/File/FileInput.d.ts +2 -2
- package/lib/components/File/FileInput.d.ts.map +1 -1
- package/lib/components/File/FileInput.js +20 -4
- package/lib/components/File/FileInput.js.map +1 -1
- package/lib/components/File/FileInput.styles.d.ts +1 -0
- package/lib/components/File/FileInput.styles.d.ts.map +1 -1
- package/lib/components/File/FileInput.styles.js +14 -1
- package/lib/components/File/FileInput.styles.js.map +1 -1
- package/lib/components/File/FileItem.d.ts.map +1 -1
- package/lib/components/File/FileItem.js +2 -3
- package/lib/components/File/FileItem.js.map +1 -1
- package/lib/components/File/FileList.d.ts +6 -3
- package/lib/components/File/FileList.d.ts.map +1 -1
- package/lib/components/File/FileList.js +25 -7
- package/lib/components/File/FileList.js.map +1 -1
- package/lib/components/Fullscreen/Fullscreen.d.ts +18 -0
- package/lib/components/Fullscreen/Fullscreen.d.ts.map +1 -0
- package/lib/components/Fullscreen/Fullscreen.js +51 -0
- package/lib/components/Fullscreen/Fullscreen.js.map +1 -0
- package/lib/components/Fullscreen/Fullscreen.test-ids.d.ts +2 -0
- package/lib/components/Fullscreen/Fullscreen.test-ids.d.ts.map +1 -0
- package/lib/components/Fullscreen/Fullscreen.test-ids.js +3 -0
- package/lib/components/Fullscreen/Fullscreen.test-ids.js.map +1 -0
- package/lib/components/Fullscreen/FullscreenButton.d.ts +6 -0
- package/lib/components/Fullscreen/FullscreenButton.d.ts.map +1 -0
- package/lib/components/Fullscreen/FullscreenButton.js +33 -0
- package/lib/components/Fullscreen/FullscreenButton.js.map +1 -0
- package/lib/components/Fullscreen/index.d.ts +4 -0
- package/lib/components/Fullscreen/index.d.ts.map +1 -0
- package/lib/components/Fullscreen/index.js +4 -0
- package/lib/components/Fullscreen/index.js.map +1 -0
- package/lib/components/Icon/streamline-icons/dock.icon.d.ts +5 -0
- package/lib/components/Icon/streamline-icons/dock.icon.d.ts.map +1 -0
- package/lib/components/Icon/streamline-icons/dock.icon.js +7 -0
- package/lib/components/Icon/streamline-icons/dock.icon.js.map +1 -0
- package/lib/components/Icon/streamline-icons/undock.icon.d.ts +5 -0
- package/lib/components/Icon/streamline-icons/undock.icon.d.ts.map +1 -0
- package/lib/components/Icon/streamline-icons/undock.icon.js +7 -0
- package/lib/components/Icon/streamline-icons/undock.icon.js.map +1 -0
- package/lib/components/Icon/streamlineIconNames.d.ts +1 -1
- package/lib/components/Icon/streamlineIconNames.d.ts.map +1 -1
- package/lib/components/Icon/streamlineIconNames.js +2 -0
- package/lib/components/Icon/streamlineIconNames.js.map +1 -1
- package/lib/components/ListToolbar/ListToolbar.d.ts.map +1 -1
- package/lib/components/ListToolbar/ListToolbar.js +3 -2
- package/lib/components/ListToolbar/ListToolbar.js.map +1 -1
- package/lib/components/Menu/Menu.styles.d.ts.map +1 -1
- package/lib/components/Menu/Menu.styles.js +2 -1
- package/lib/components/Menu/Menu.styles.js.map +1 -1
- package/lib/components/PageTemplates/PageTemplates.d.ts +1 -0
- package/lib/components/PageTemplates/PageTemplates.d.ts.map +1 -1
- package/lib/components/PageTemplates/PageTemplates.js +82 -29
- package/lib/components/PageTemplates/PageTemplates.js.map +1 -1
- package/lib/components/Tabs/Tab.d.ts.map +1 -1
- package/lib/components/Tabs/Tab.js +4 -0
- package/lib/components/Tabs/Tab.js.map +1 -1
- package/lib/components/Toaster/Toaster.d.ts +1 -1
- package/lib/components/Toaster/Toaster.d.ts.map +1 -1
- package/lib/components/Toaster/Toaster.js +79 -19
- package/lib/components/Toaster/Toaster.js.map +1 -1
- package/lib/components/Toaster/Toaster.types.d.ts +17 -4
- package/lib/components/Toaster/Toaster.types.d.ts.map +1 -1
- package/lib/components/Toaster/Toaster.types.js.map +1 -1
- package/lib/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/lib/components/Tooltip/Tooltip.js +3 -1
- package/lib/components/Tooltip/Tooltip.js.map +1 -1
- package/lib/hooks/useArrows.d.ts.map +1 -1
- package/lib/hooks/useArrows.js +3 -1
- package/lib/hooks/useArrows.js.map +1 -1
- package/lib/hooks/useI18n.d.ts +25 -0
- package/lib/hooks/useI18n.d.ts.map +1 -1
- package/lib/hooks/useScrollToggle.d.ts.map +1 -1
- package/lib/hooks/useScrollToggle.js +1 -0
- package/lib/hooks/useScrollToggle.js.map +1 -1
- package/lib/i18n/default.d.ts +25 -0
- package/lib/i18n/default.d.ts.map +1 -1
- package/lib/i18n/default.js +29 -1
- package/lib/i18n/default.js.map +1 -1
- package/lib/i18n/i18n.d.ts +25 -0
- package/lib/i18n/i18n.d.ts.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/theme/theme.d.ts +6 -0
- package/lib/theme/theme.d.ts.map +1 -1
- package/lib/theme/themeDefinition.json +5 -1
- package/lib/theme/themeOverrides.schema.json +3 -0
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/index.js +1 -0
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/isPositionWithinRect.d.ts +12 -0
- package/lib/utils/isPositionWithinRect.d.ts.map +1 -0
- package/lib/utils/isPositionWithinRect.js +11 -0
- package/lib/utils/isPositionWithinRect.js.map +1 -0
- package/package.json +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tab.js","sourceRoot":"","sources":["../../../src/components/Tabs/Tab.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,KAAK,aAAa,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,OAAO,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,UAAU,MAAM,sBAAsB,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,YAAY,CAAC,aAAa,CAAC,CAAC;AAwB5B,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,CAAA;;;wBAGlB,KAAK;;CAE5B,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,EAC3B,QAAQ,EACR,KAAK,EACmD,EAAE,EAAE;IAC5D,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;IACpD,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/E,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IAE/B,OAAO,GAAG,CAAA;;;;uBAIW,OAAO;0BACJ,OAAO;;;;;eAKlB,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;;;;;;;;;;;;;;;;;;oBAkB3D,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc;iBAC3C,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;;;;;;;;;;QAUpC,WAAW,CAAC,cAAc,CAAC;;;;;;QAM3B,WAAW,CAAC,cAAc,CAAC;oBACf,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC
|
|
1
|
+
{"version":3,"file":"Tab.js","sourceRoot":"","sources":["../../../src/components/Tabs/Tab.tsx"],"names":[],"mappings":"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","sourcesContent":["import { forwardRef } from 'react';\nimport type { FC, ReactNode, PropsWithoutRef, Ref } from 'react';\nimport styled, { css } from 'styled-components';\nimport type { StyledProps } from 'styled-components';\nimport { transparentize } from 'polished';\n\nimport * as warnSolidIcon from '../Icon/icons/warn-solid.icon';\nimport { registerIcon } from '../Icon';\nimport { useConsolidatedRef, useElement, useI18n } from '../../hooks';\nimport Tooltip from '../Tooltip';\nimport { defaultThemeProp } from '../../theme';\nimport { tryCatch } from '../../utils';\nimport { StyledCount } from '../Badges/Count';\nimport type { ForwardProps } from '../../types';\nimport BareButton from '../Button/BareButton';\n\nimport type { TabsProps } from './Tabs.types';\nimport { StyledErrorIcon } from './Tabs.styles';\n\nregisterIcon(warnSolidIcon);\n\nexport interface TabProps {\n /** Indicates if this Tab is active. */\n selected: boolean;\n /** The text to display as the name of the Tab. */\n content: string;\n /** A number to associate with the Tab. */\n count?: ReactNode;\n /** Determines the direction in which the Tab will render. */\n type: TabsProps['type'];\n /** Disables the tab if true */\n disabled?: boolean;\n /** An error to associate with the Tab. */\n errors?: number | boolean;\n /** Ref to the tab element. */\n ref?: Ref<HTMLButtonElement | HTMLAnchorElement>;\n}\n\nexport interface StyledTabProps {\n selected: TabProps['selected'];\n tabType: TabProps['type'];\n}\n\nconst activeStyle = (color: string) => css`\n ::after {\n display: block;\n background-color: ${color};\n }\n`;\n\nconst getHorizontalStyles = ({\n selected,\n theme\n}: Pick<StyledProps<StyledTabProps>, 'theme' | 'selected'>) => {\n const primaryColor = theme.base.palette.interactive;\n const lightenedColor = tryCatch(() => transparentize(0.3, primaryColor)) ?? '';\n const { spacing } = theme.base;\n\n return css`\n align-items: center;\n display: flex;\n flex-direction: row;\n height: calc(4 * ${spacing});\n padding: 0 calc(2 * ${spacing});\n border: none;\n text-decoration: none;\n\n span:first-of-type {\n color: ${selected ? primaryColor : theme.base.palette['foreground-color']};\n display: inline-block;\n\n ::before {\n content: attr(data-content);\n display: block;\n font-weight: bold;\n height: 0;\n overflow: hidden;\n visibility: hidden;\n }\n }\n\n &:first-child {\n margin-left: 0;\n }\n\n ::after {\n background: ${selected ? primaryColor : lightenedColor};\n display: ${selected ? 'block' : 'none'};\n content: '';\n position: absolute;\n height: 0.125rem;\n bottom: 0;\n left: 0;\n right: 0;\n }\n\n &:hover&:not(:disabled) {\n ${activeStyle(lightenedColor)}\n text-decoration: none;\n }\n\n &:focus,\n &:not([disabled]):focus {\n ${activeStyle(lightenedColor)}\n box-shadow: ${theme.base.shadow['focus-inset']};\n text-decoration: none;\n }\n\n @media (pointer: coarse) {\n min-block-size: ${theme.base['hit-area'].finger};\n }\n\n ${StyledCount} {\n margin-inline-start: calc(0.5 * ${spacing});\n }\n `;\n};\n\nconst getVerticalStyles = ({\n selected,\n theme\n}: Pick<StyledProps<StyledTabProps>, 'theme' | 'selected'>) => {\n const borderColor = theme.base.palette['border-line'];\n const primaryColor = theme.base.palette.interactive;\n const lightenedColor = tryCatch(() => transparentize(0.5, primaryColor)) ?? '';\n const { spacing } = theme.base;\n\n return css`\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-style: solid;\n color: ${theme.base.palette['foreground-color']};\n border-width: 0.0625rem 0;\n border-color: ${borderColor};\n height: calc(5.5 * ${spacing});\n margin-top: -0.0625rem;\n padding: 0 calc(2 * ${spacing});\n text-decoration: none;\n\n &:first-child {\n border-top: 0.0625rem solid ${borderColor};\n }\n\n ::after {\n content: '';\n position: absolute;\n display: ${selected ? 'block' : 'none'};\n top: 0;\n bottom: 0;\n right: 0;\n width: 0.25rem;\n background: ${primaryColor};\n }\n\n &:hover&:not(:disabled) {\n ${activeStyle(lightenedColor)}\n text-decoration: none;\n }\n\n &:focus,\n &:not([disabled]):focus {\n ${activeStyle(primaryColor)}\n box-shadow: inset 0 0 0 0.0625rem ${primaryColor};\n text-decoration: none;\n }\n `;\n};\n\nexport const StyledTab = styled(BareButton)<StyledTabProps>(\n ({ theme, tabType, selected }) => css`\n position: relative;\n background: none;\n cursor: pointer;\n white-space: nowrap;\n\n ${selected &&\n css`\n font-weight: bold;\n `}\n\n & + & {\n margin-inline-start: 0;\n }\n\n &:focus {\n outline: none;\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: ${theme.base['disabled-opacity']};\n }\n\n ${tabType === 'horizontal'\n ? getHorizontalStyles({ theme, selected })\n : getVerticalStyles({ theme, selected })}\n\n ${StyledErrorIcon} {\n margin-inline-end: calc(0.5 * ${theme.base.spacing});\n }\n `\n);\n\nStyledTab.defaultProps = defaultThemeProp;\n\nconst Tab: FC<TabProps & ForwardProps> = forwardRef(function Tab(\n { selected, content, count, type, disabled, errors, ...restProps }: PropsWithoutRef<TabProps>,\n ref: TabProps['ref']\n) {\n const t = useI18n();\n const [tabEl, setTabEl] = useElement();\n const tabRef = useConsolidatedRef(ref, setTabEl);\n\n return (\n <StyledTab ref={tabRef} selected={selected} tabType={type} disabled={disabled} {...restProps}>\n <span>\n {!!errors && (\n <>\n <StyledErrorIcon name='warn-solid' />\n <Tooltip target={tabEl} hideDelay='none' showDelay='none'>\n {t('tab_error_tooltip', [content])}\n </Tooltip>\n </>\n )}\n <span data-content={content}>{content}</span>\n </span>\n {count}\n </StyledTab>\n );\n});\n\nexport default Tab;\n"]}
|
|
@@ -8,7 +8,7 @@ declare module '../../init' {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
declare const _default: FunctionComponent<ToasterProps> & {
|
|
11
|
-
getTestIds: (testIdProp?: string | null | undefined) => import("
|
|
11
|
+
getTestIds: (testIdProp?: string | null | undefined) => import("../../types").TestIdsRecord<readonly ["toast"]>;
|
|
12
12
|
};
|
|
13
13
|
export default _default;
|
|
14
14
|
//# sourceMappingURL=Toaster.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../../src/components/Toaster/Toaster.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,iBAAiB,EAGjB,OAAO,EAIR,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Toaster.d.ts","sourceRoot":"","sources":["../../../src/components/Toaster/Toaster.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,iBAAiB,EAGjB,OAAO,EAIR,MAAM,OAAO,CAAC;AA2Bf,OAAO,YAAY,CAAC;AAIpB,OAAO,KAAK,EAAgB,YAAY,EAAoC,MAAM,iBAAiB,CAAC;AAEpG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AA8BrD,OAAO,QAAQ,YAAY,CAAC;IAC1B,UAAiB,aAAa;QAC5B,cAAc,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;KAC/C;CACF;;;;AA+TD,wBAAuD"}
|
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
import { createElement as _createElement } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { jsxs as _jsxs, Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useContext, useReducer, useMemo, useLayoutEffect, useRef, useState, forwardRef, useEffect } from 'react';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
5
|
import styled, { css } from 'styled-components';
|
|
6
6
|
import Button from '../Button';
|
|
7
7
|
import Icon, { registerIcon } from '../Icon';
|
|
8
|
+
import Link, { StyledLink } from '../Link';
|
|
8
9
|
import * as timesIcon from '../Icon/icons/times.icon';
|
|
9
|
-
import { createUID, windowIsAvailable, withTestIds } from '../../utils';
|
|
10
|
-
import { useConfiguration, useI18n, useLiveLog, useTestIds } from '../../hooks';
|
|
10
|
+
import { createUID, windowIsAvailable, withTestIds, hasProp, getActiveElement, getFocusables } from '../../utils';
|
|
11
|
+
import { useConfiguration, useI18n, useLiveLog, useShortcut, useTestIds, useConsolidatedRef, useEscape } from '../../hooks';
|
|
11
12
|
import { defaultThemeProp } from '../../theme';
|
|
12
13
|
import Flex from '../Flex';
|
|
13
14
|
import '../../init';
|
|
15
|
+
import { registerAction } from '../ShortcutManager';
|
|
14
16
|
import { ToasterContext } from './Context';
|
|
15
17
|
import { getToasterTestIds } from './Toaster.test-ids';
|
|
16
18
|
registerIcon(timesIcon);
|
|
19
|
+
registerAction({ id: 'JumpToToast', defaultKeyBinding: 'Alt+Enter' }, { id: 'DismissToast', defaultKeyBinding: 'Alt+Q' });
|
|
17
20
|
const StyledToastButton = styled.button(({ theme }) => css `
|
|
18
21
|
border: none;
|
|
19
22
|
color: inherit;
|
|
20
23
|
padding: 0;
|
|
21
24
|
font-size: 1rem;
|
|
25
|
+
margin-block: calc(${theme.base.spacing} / 2);
|
|
26
|
+
margin-inline-end: calc(${theme.base.spacing} / 2);
|
|
22
27
|
|
|
23
28
|
&:enabled:hover {
|
|
24
29
|
background: #ffffff19;
|
|
@@ -34,10 +39,15 @@ const StyledToastContent = styled.div(({ theme }) => {
|
|
|
34
39
|
display: -webkit-box;
|
|
35
40
|
-webkit-line-clamp: 2;
|
|
36
41
|
-webkit-box-orient: vertical;
|
|
37
|
-
overflow:
|
|
42
|
+
overflow: clip;
|
|
38
43
|
text-overflow: ellipsis;
|
|
39
44
|
font-size: ${theme.base['font-size']};
|
|
40
45
|
margin-inline-start: calc(${theme.base['border-radius']} / 2);
|
|
46
|
+
padding-inline-start: calc(${theme.base.spacing} / 2);
|
|
47
|
+
|
|
48
|
+
${StyledLink} {
|
|
49
|
+
color: ${theme.base.colors.blue.light};
|
|
50
|
+
}
|
|
41
51
|
`;
|
|
42
52
|
});
|
|
43
53
|
StyledToastContent.defaultProps = defaultThemeProp;
|
|
@@ -47,7 +57,6 @@ const StyledToast = styled.div(({ theme }) => {
|
|
|
47
57
|
inset-block-start: 0;
|
|
48
58
|
inset-inline-start: 0;
|
|
49
59
|
width: 100%;
|
|
50
|
-
padding: calc(${theme.base.spacing} / 2);
|
|
51
60
|
background: ${theme.base.colors.slate['extra-dark']};
|
|
52
61
|
color: ${theme.base.colors.white};
|
|
53
62
|
border-radius: calc(${theme.base['border-radius']} / 2);
|
|
@@ -56,17 +65,24 @@ const StyledToast = styled.div(({ theme }) => {
|
|
|
56
65
|
transition-property: transform, opacity;
|
|
57
66
|
transition-duration: ${theme.base.animation.speed};
|
|
58
67
|
transition-timing-function: ${theme.base.animation.timing.ease};
|
|
68
|
+
font-weight: ${theme.base['font-weight']['semi-bold']};
|
|
69
|
+
|
|
70
|
+
:focus {
|
|
71
|
+
box-shadow: ${theme.base.shadow.focus};
|
|
72
|
+
}
|
|
59
73
|
`;
|
|
60
74
|
});
|
|
61
75
|
StyledToast.defaultProps = defaultThemeProp;
|
|
62
|
-
const StyledToaster = styled.div
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
76
|
+
const StyledToaster = styled.div(({ theme }) => {
|
|
77
|
+
return css `
|
|
78
|
+
position: fixed;
|
|
79
|
+
z-index: ${theme.base['z-index'].toast};
|
|
80
|
+
width: min(40ch, calc(100% - 1rem));
|
|
81
|
+
inset-inline-start: 50%;
|
|
82
|
+
transform: translateX(-50%);
|
|
83
|
+
top: 100%;
|
|
84
|
+
`;
|
|
85
|
+
});
|
|
70
86
|
StyledToaster.defaultProps = defaultThemeProp;
|
|
71
87
|
function reducer(current, action) {
|
|
72
88
|
switch (action.type) {
|
|
@@ -83,11 +99,15 @@ function reducer(current, action) {
|
|
|
83
99
|
return current;
|
|
84
100
|
}
|
|
85
101
|
}
|
|
86
|
-
const Toast = forwardRef(function Toast({ id, dispatch, topLevelDismiss,
|
|
102
|
+
const Toast = forwardRef(function Toast({ id, firstToast, dispatch, topLevelDismiss, translateY, onDismiss, dismissAfter, ...restProps }, ref) {
|
|
87
103
|
const [dismissed, setDismissed] = useState(false);
|
|
88
104
|
const timeoutRef = useRef(NaN);
|
|
89
105
|
const t = useI18n();
|
|
90
106
|
const { announcePolite } = useLiveLog();
|
|
107
|
+
const content = hasProp(restProps, 'href') ? t('created') : restProps.content;
|
|
108
|
+
const activeElement = getActiveElement();
|
|
109
|
+
const initiatorRef = activeElement ? new WeakRef(activeElement) : null;
|
|
110
|
+
const containerRef = useConsolidatedRef(ref);
|
|
91
111
|
useEffect(() => {
|
|
92
112
|
announcePolite({ message: content, type: 'acknowledgement' });
|
|
93
113
|
}, []);
|
|
@@ -112,11 +132,36 @@ const Toast = forwardRef(function Toast({ id, dispatch, topLevelDismiss, dismiss
|
|
|
112
132
|
window.clearTimeout(timeoutRef.current);
|
|
113
133
|
};
|
|
114
134
|
}, []);
|
|
115
|
-
|
|
135
|
+
// Alt+Enter focuses on the first focusable element in the first toast.
|
|
136
|
+
// Tab to the next toast if there are multiple.
|
|
137
|
+
useShortcut('JumpToToast', () => {
|
|
138
|
+
if (firstToast && containerRef.current) {
|
|
139
|
+
getFocusables(containerRef.current)[0]?.focus();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
// Alt+Q dismisses the first toast.
|
|
143
|
+
useShortcut('DismissToast', () => {
|
|
144
|
+
if (firstToast)
|
|
145
|
+
dismiss(false)();
|
|
146
|
+
});
|
|
147
|
+
// Escape dismisses the toast and focuses the initiator.
|
|
148
|
+
useEscape(() => {
|
|
149
|
+
const currentFocus = getActiveElement();
|
|
150
|
+
if (containerRef.current?.contains(currentFocus)) {
|
|
151
|
+
dismiss(false)();
|
|
152
|
+
if (initiatorRef) {
|
|
153
|
+
const initiator = initiatorRef.deref();
|
|
154
|
+
if (initiator instanceof HTMLElement) {
|
|
155
|
+
initiator.focus();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
return (_jsxs(Flex, { ...restProps, "data-app-region": true, container: { alignItems: 'center', gap: 0.25 }, as: StyledToast, ref: containerRef, style: {
|
|
116
161
|
'--translateY': `${-translateY}px`,
|
|
117
162
|
'--opacity': dismissed ? '0' : '1',
|
|
118
163
|
'--scale': dismissed ? '0' : '1'
|
|
119
|
-
}, onTransitionEnd: onTransitionEnd, children: [
|
|
164
|
+
}, onTransitionEnd: onTransitionEnd, children: [_jsxs(Flex, { item: { grow: 1 }, as: StyledToastContent, children: [content, hasProp(restProps, 'href') ? (_jsxs(_Fragment, { children: [' ', _jsxs(Link, { href: restProps.href, children: ["(", id, "): ", restProps.label] })] })) : undefined] }), _jsx(Button, { as: StyledToastButton, variant: 'simple', onClick: dismiss(false), icon: true, "aria-label": t('dismiss_label'), children: _jsx(Icon, { name: 'times' }) })] }));
|
|
120
165
|
});
|
|
121
166
|
const Toaster = ({ testId, children, dismissAfter = Infinity, onDismiss }) => {
|
|
122
167
|
const { portalTarget } = useConfiguration();
|
|
@@ -135,7 +180,8 @@ const Toaster = ({ testId, children, dismissAfter = Infinity, onDismiss }) => {
|
|
|
135
180
|
push(incoming) {
|
|
136
181
|
const message = {
|
|
137
182
|
...incoming,
|
|
138
|
-
id: incoming.id ?? createUID()
|
|
183
|
+
id: incoming.id ?? createUID(),
|
|
184
|
+
dismissAfter: hasProp(incoming, 'href') ? 10000 : incoming.dismissAfter
|
|
139
185
|
};
|
|
140
186
|
dispatch({
|
|
141
187
|
type: 'push',
|
|
@@ -155,14 +201,28 @@ const Toaster = ({ testId, children, dismissAfter = Infinity, onDismiss }) => {
|
|
|
155
201
|
return (_jsxs(_Fragment, { children: [_jsx(context.Provider, { value: providerValue, children: children }), !!messages.length &&
|
|
156
202
|
portalTarget &&
|
|
157
203
|
createPortal(_jsx(StyledToaster, { "data-testid": testIds.root, children: messages.map((message, i) => {
|
|
158
|
-
|
|
204
|
+
const sharedProps = {
|
|
205
|
+
translateY: yOffsets[i] ?? 0,
|
|
206
|
+
firstToast: i === 0,
|
|
207
|
+
topLevelDismiss: onDismiss,
|
|
208
|
+
dispatch,
|
|
209
|
+
ref: el => {
|
|
159
210
|
if (el) {
|
|
160
211
|
heightHashRef.current[message.id] = el.offsetHeight;
|
|
161
212
|
}
|
|
162
213
|
else {
|
|
163
214
|
delete heightHashRef.current[message.id];
|
|
164
215
|
}
|
|
165
|
-
}
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
if (hasProp(message, 'href')) {
|
|
219
|
+
return (
|
|
220
|
+
// Toast with Link
|
|
221
|
+
_createElement(Toast, { "data-testid": testIds.toast, ...message, ...sharedProps, key: message.id }));
|
|
222
|
+
}
|
|
223
|
+
return (
|
|
224
|
+
// Base Toast
|
|
225
|
+
_createElement(Toast, { "data-testid": testIds.toast, ...message, ...sharedProps, dismissAfter: message.dismissAfter ?? dismissAfter, key: message.id }));
|
|
166
226
|
}) }), portalTarget)] }));
|
|
167
227
|
};
|
|
168
228
|
export default withTestIds(Toaster, getToasterTestIds);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toaster.js","sourceRoot":"","sources":["../../../src/components/Toaster/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useContext,\n useReducer,\n useMemo,\n useLayoutEffect,\n useRef,\n useState,\n forwardRef,\n useEffect\n} from 'react';\nimport type {\n FunctionComponent,\n CSSProperties,\n TransitionEvent,\n Context,\n PropsWithoutRef,\n Ref,\n Dispatch\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport styled, { css } from 'styled-components';\n\nimport Button from '../Button';\nimport Icon, { registerIcon } from '../Icon';\nimport * as timesIcon from '../Icon/icons/times.icon';\nimport { createUID, windowIsAvailable, withTestIds } from '../../utils';\nimport { useConfiguration, useI18n, useLiveLog, useTestIds } from '../../hooks';\nimport { defaultThemeProp } from '../../theme';\nimport Flex from '../Flex';\nimport '../../init';\n\nimport type { ToastMessage, ToasterProps } from './Toaster.types';\nimport { ToasterContext } from './Context';\nimport type { ToasterContextValue } from './Context';\nimport { getToasterTestIds } from './Toaster.test-ids';\n\nregisterIcon(timesIcon);\n\ninterface ToastState extends ToastMessage {\n id: NonNullable<ToastMessage['id']>;\n}\n\ntype ToastReducerAction =\n | { type: 'push'; payload: ToastState }\n | { type: 'unmount'; payload: ToastState['id'] };\n\ninterface ToastProps extends ToastState {\n topLevelDismiss: ToasterProps['onDismiss'];\n translateY: number;\n dispatch: Dispatch<ToastReducerAction>;\n ref: Ref<HTMLDivElement>;\n}\n\ndeclare module '../../init' {\n export interface CosmosGlobals {\n toasterContext?: Context<ToasterContextValue>;\n }\n}\n\nconst StyledToastButton = styled.button(\n ({ theme }) => css`\n border: none;\n color: inherit;\n padding: 0;\n font-size: 1rem;\n\n &:enabled:hover {\n background: #ffffff19;\n }\n\n &:enabled:focus {\n box-shadow: ${theme.base.shadow.focus};\n }\n `\n);\n\nStyledToastButton.defaultProps = defaultThemeProp;\n\nconst StyledToastContent = styled.div(({ theme }) => {\n return css`\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: ${theme.base['font-size']};\n margin-inline-start: calc(${theme.base['border-radius']} / 2);\n `;\n});\n\nStyledToastContent.defaultProps = defaultThemeProp;\n\nconst StyledToast = styled.div(({ theme }) => {\n return css`\n position: absolute;\n inset-block-start: 0;\n inset-inline-start: 0;\n width: 100%;\n padding: calc(${theme.base.spacing} / 2);\n background: ${theme.base.colors.slate['extra-dark']};\n color: ${theme.base.colors.white};\n border-radius: calc(${theme.base['border-radius']} / 2);\n opacity: var(--opacity);\n transform: translateY(var(--translateY)) scale(var(--scale));\n transition-property: transform, opacity;\n transition-duration: ${theme.base.animation.speed};\n transition-timing-function: ${theme.base.animation.timing.ease};\n `;\n});\n\nStyledToast.defaultProps = defaultThemeProp;\n\nconst StyledToaster = styled.div`\n position: fixed;\n z-index: ${({ theme }) => theme.base['z-index'].toast};\n width: min(40ch, calc(100% - 1rem));\n inset-inline-start: 50%;\n transform: translateX(-50%);\n top: 100%;\n`;\n\nStyledToaster.defaultProps = defaultThemeProp;\n\nfunction reducer(current: ToastState[], action: ToastReducerAction) {\n switch (action.type) {\n case 'push':\n return [\n ...current,\n {\n ...action.payload\n }\n ];\n\n case 'unmount':\n return current.filter(m => m.id !== action.payload);\n\n default:\n return current;\n }\n}\n\nconst Toast: FunctionComponent<ToastProps> = forwardRef(function Toast(\n {\n id,\n dispatch,\n topLevelDismiss,\n dismissAfter,\n content,\n translateY,\n onDismiss,\n ...restProps\n }: PropsWithoutRef<ToastProps>,\n ref: ToastProps['ref']\n) {\n const [dismissed, setDismissed] = useState(false);\n const timeoutRef = useRef(NaN);\n const t = useI18n();\n const { announcePolite } = useLiveLog();\n\n useEffect(() => {\n announcePolite({ message: content, type: 'acknowledgement' });\n }, []);\n\n const onTransitionEnd = (e: TransitionEvent<HTMLDivElement>) => {\n if (dismissed && e.propertyName === 'opacity' && e.target === e.currentTarget) {\n dispatch({ type: 'unmount', payload: id });\n }\n };\n\n const dismiss = (timeout: boolean) => () => {\n clearTimeout(timeoutRef.current);\n if (dismissed) return;\n setDismissed(true);\n onDismiss?.({ id, timeout });\n topLevelDismiss?.({ id, timeout });\n };\n\n useEffect(() => {\n if (Number.isFinite(dismissAfter)) {\n timeoutRef.current = window.setTimeout(dismiss(true), dismissAfter);\n }\n\n return () => {\n window.clearTimeout(timeoutRef.current);\n };\n }, []);\n\n return (\n <Flex\n {...restProps}\n container={{ alignItems: 'center', gap: 0.25 }}\n as={StyledToast}\n ref={ref}\n style={\n {\n '--translateY': `${-translateY}px`,\n '--opacity': dismissed ? '0' : '1',\n '--scale': dismissed ? '0' : '1'\n } as CSSProperties\n }\n onTransitionEnd={onTransitionEnd}\n >\n <Flex item={{ grow: 1 }} as={StyledToastContent}>\n {content}\n </Flex>\n <Button\n as={StyledToastButton}\n variant='simple'\n onClick={dismiss(false)}\n icon\n aria-label={t('dismiss_label')}\n >\n <Icon name='times' />\n </Button>\n </Flex>\n );\n});\n\nconst Toaster: FunctionComponent<ToasterProps> = ({\n testId,\n children,\n dismissAfter = Infinity,\n onDismiss\n}: ToasterProps) => {\n const { portalTarget } = useConfiguration();\n const [messages, dispatch] = useReducer(reducer, []);\n const [yOffsets, setYOffsets] = useState<number[]>([]);\n const heightHashRef = useRef<{\n [id: string]: number;\n }>({});\n const testIds = useTestIds(testId, getToasterTestIds);\n\n // This effect will cause a re-render with a translateY value set for each toast.\n useLayoutEffect(() => {\n const heights = [...messages].reverse().map(({ id }) => heightHashRef.current[id]);\n\n setYOffsets(\n heights\n .map((_, i) => heights.slice(0, i + 1).reduce((sum, cur) => sum + cur + 4, 0))\n .reverse()\n );\n }, [messages.length]);\n\n const providerValue = useMemo(\n () => ({\n push(incoming: ToastMessage) {\n const message: ToastState = {\n ...incoming,\n id: incoming.id ?? createUID()\n };\n\n dispatch({\n type: 'push',\n payload: message\n });\n },\n initialized: true\n }),\n []\n );\n\n // Don't create additional ToasterContext.Providers.\n const context = windowIsAvailable\n ? window.cosmos.toasterContext ?? ToasterContext\n : ToasterContext;\n const priorCtx = useContext(context);\n if (priorCtx.initialized) {\n return <context.Provider value={priorCtx}>{children}</context.Provider>;\n }\n\n return (\n <>\n <context.Provider value={providerValue}>{children}</context.Provider>\n {!!messages.length &&\n portalTarget &&\n createPortal(\n <StyledToaster data-testid={testIds.root}>\n {messages.map((message, i) => {\n return (\n <Toast\n data-testid={testIds.toast}\n {...message}\n translateY={yOffsets[i] ?? 0}\n topLevelDismiss={onDismiss}\n dismissAfter={message.dismissAfter ?? dismissAfter}\n key={message.id}\n dispatch={dispatch}\n ref={el => {\n if (el) {\n heightHashRef.current[message.id] = el.offsetHeight;\n } else {\n delete heightHashRef.current[message.id];\n }\n }}\n />\n );\n })}\n </StyledToaster>,\n portalTarget\n )}\n </>\n );\n};\n\nexport default withTestIds(Toaster, getToasterTestIds);\n"]}
|
|
1
|
+
{"version":3,"file":"Toaster.js","sourceRoot":"","sources":["../../../src/components/Toaster/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useContext,\n useReducer,\n useMemo,\n useLayoutEffect,\n useRef,\n useState,\n forwardRef,\n useEffect\n} from 'react';\nimport type {\n FunctionComponent,\n CSSProperties,\n TransitionEvent,\n Context,\n PropsWithoutRef,\n Ref,\n Dispatch\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport styled, { css } from 'styled-components';\n\nimport Button from '../Button';\nimport Icon, { registerIcon } from '../Icon';\nimport Link, { StyledLink } from '../Link';\nimport * as timesIcon from '../Icon/icons/times.icon';\nimport {\n createUID,\n windowIsAvailable,\n withTestIds,\n hasProp,\n getActiveElement,\n getFocusables\n} from '../../utils';\nimport {\n useConfiguration,\n useI18n,\n useLiveLog,\n useShortcut,\n useTestIds,\n useConsolidatedRef,\n useEscape\n} from '../../hooks';\nimport { defaultThemeProp } from '../../theme';\nimport Flex from '../Flex';\nimport '../../init';\nimport { registerAction } from '../ShortcutManager';\nimport type { OmitStrict } from '../../types';\n\nimport type { ToastMessage, ToasterProps, BaseToastMessage, CreatedMessage } from './Toaster.types';\nimport { ToasterContext } from './Context';\nimport type { ToasterContextValue } from './Context';\nimport { getToasterTestIds } from './Toaster.test-ids';\n\nregisterIcon(timesIcon);\nregisterAction(\n { id: 'JumpToToast', defaultKeyBinding: 'Alt+Enter' },\n { id: 'DismissToast', defaultKeyBinding: 'Alt+Q' }\n);\n\ntype ToastState = (\n | OmitStrict<BaseToastMessage, 'dismissAfter'>\n | OmitStrict<CreatedMessage, 'dismissAfter'>\n) & {\n id: NonNullable<ToastMessage['id']>;\n dismissAfter?: number;\n};\n\ntype ToastReducerAction =\n | { type: 'push'; payload: ToastState }\n | { type: 'unmount'; payload: ToastState['id'] };\n\ntype ToastProps = ToastState & {\n // determines if this is the first toast in the list, used to dismiss the first toast with a shortcut, not exposed outside\n firstToast: boolean;\n topLevelDismiss: ToasterProps['onDismiss'];\n translateY: number;\n dispatch: Dispatch<ToastReducerAction>;\n ref: Ref<HTMLDivElement>;\n};\n\ndeclare module '../../init' {\n export interface CosmosGlobals {\n toasterContext?: Context<ToasterContextValue>;\n }\n}\n\nconst StyledToastButton = styled.button(\n ({ theme }) => css`\n border: none;\n color: inherit;\n padding: 0;\n font-size: 1rem;\n margin-block: calc(${theme.base.spacing} / 2);\n margin-inline-end: calc(${theme.base.spacing} / 2);\n\n &:enabled:hover {\n background: #ffffff19;\n }\n\n &:enabled:focus {\n box-shadow: ${theme.base.shadow.focus};\n }\n `\n);\n\nStyledToastButton.defaultProps = defaultThemeProp;\n\nconst StyledToastContent = styled.div(({ theme }) => {\n return css`\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: clip;\n text-overflow: ellipsis;\n font-size: ${theme.base['font-size']};\n margin-inline-start: calc(${theme.base['border-radius']} / 2);\n padding-inline-start: calc(${theme.base.spacing} / 2);\n\n ${StyledLink} {\n color: ${theme.base.colors.blue.light};\n }\n `;\n});\n\nStyledToastContent.defaultProps = defaultThemeProp;\n\nconst StyledToast = styled.div(({ theme }) => {\n return css`\n position: absolute;\n inset-block-start: 0;\n inset-inline-start: 0;\n width: 100%;\n background: ${theme.base.colors.slate['extra-dark']};\n color: ${theme.base.colors.white};\n border-radius: calc(${theme.base['border-radius']} / 2);\n opacity: var(--opacity);\n transform: translateY(var(--translateY)) scale(var(--scale));\n transition-property: transform, opacity;\n transition-duration: ${theme.base.animation.speed};\n transition-timing-function: ${theme.base.animation.timing.ease};\n font-weight: ${theme.base['font-weight']['semi-bold']};\n\n :focus {\n box-shadow: ${theme.base.shadow.focus};\n }\n `;\n});\n\nStyledToast.defaultProps = defaultThemeProp;\n\nconst StyledToaster = styled.div(({ theme }) => {\n return css`\n position: fixed;\n z-index: ${theme.base['z-index'].toast};\n width: min(40ch, calc(100% - 1rem));\n inset-inline-start: 50%;\n transform: translateX(-50%);\n top: 100%;\n `;\n});\n\nStyledToaster.defaultProps = defaultThemeProp;\n\nfunction reducer(current: ToastState[], action: ToastReducerAction) {\n switch (action.type) {\n case 'push':\n return [\n ...current,\n {\n ...action.payload\n }\n ];\n\n case 'unmount':\n return current.filter(m => m.id !== action.payload);\n\n default:\n return current;\n }\n}\n\nconst Toast: FunctionComponent<ToastProps> = forwardRef(function Toast(\n {\n id,\n firstToast,\n dispatch,\n topLevelDismiss,\n translateY,\n onDismiss,\n dismissAfter,\n ...restProps\n }: PropsWithoutRef<ToastProps>,\n ref: ToastProps['ref']\n) {\n const [dismissed, setDismissed] = useState(false);\n const timeoutRef = useRef(NaN);\n const t = useI18n();\n const { announcePolite } = useLiveLog();\n const content = hasProp(restProps, 'href') ? t('created') : restProps.content;\n const activeElement = getActiveElement();\n const initiatorRef = activeElement ? new WeakRef(activeElement) : null;\n const containerRef = useConsolidatedRef(ref);\n\n useEffect(() => {\n announcePolite({ message: content, type: 'acknowledgement' });\n }, []);\n\n const onTransitionEnd = (e: TransitionEvent<HTMLDivElement>) => {\n if (dismissed && e.propertyName === 'opacity' && e.target === e.currentTarget) {\n dispatch({ type: 'unmount', payload: id });\n }\n };\n\n const dismiss = (timeout: boolean) => () => {\n clearTimeout(timeoutRef.current);\n if (dismissed) return;\n setDismissed(true);\n onDismiss?.({ id, timeout });\n topLevelDismiss?.({ id, timeout });\n };\n\n useEffect(() => {\n if (Number.isFinite(dismissAfter)) {\n timeoutRef.current = window.setTimeout(dismiss(true), dismissAfter);\n }\n\n return () => {\n window.clearTimeout(timeoutRef.current);\n };\n }, []);\n\n // Alt+Enter focuses on the first focusable element in the first toast.\n // Tab to the next toast if there are multiple.\n useShortcut('JumpToToast', () => {\n if (firstToast && containerRef.current) {\n getFocusables(containerRef.current)[0]?.focus();\n }\n });\n\n // Alt+Q dismisses the first toast.\n useShortcut('DismissToast', () => {\n if (firstToast) dismiss(false)();\n });\n\n // Escape dismisses the toast and focuses the initiator.\n useEscape(() => {\n const currentFocus = getActiveElement();\n if (containerRef.current?.contains(currentFocus)) {\n dismiss(false)();\n if (initiatorRef) {\n const initiator = initiatorRef.deref();\n if (initiator instanceof HTMLElement) {\n initiator.focus();\n }\n }\n }\n });\n\n return (\n <Flex\n {...restProps}\n data-app-region\n container={{ alignItems: 'center', gap: 0.25 }}\n as={StyledToast}\n ref={containerRef}\n style={\n {\n '--translateY': `${-translateY}px`,\n '--opacity': dismissed ? '0' : '1',\n '--scale': dismissed ? '0' : '1'\n } as CSSProperties\n }\n onTransitionEnd={onTransitionEnd}\n >\n <Flex item={{ grow: 1 }} as={StyledToastContent}>\n {content}\n {hasProp(restProps, 'href') ? (\n <>\n {' '}\n <Link href={restProps.href}>\n ({id}): {restProps.label}\n </Link>\n </>\n ) : undefined}\n </Flex>\n <Button\n as={StyledToastButton}\n variant='simple'\n onClick={dismiss(false)}\n icon\n aria-label={t('dismiss_label')}\n >\n <Icon name='times' />\n </Button>\n </Flex>\n );\n});\n\nconst Toaster: FunctionComponent<ToasterProps> = ({\n testId,\n children,\n dismissAfter = Infinity,\n onDismiss\n}: ToasterProps) => {\n const { portalTarget } = useConfiguration();\n const [messages, dispatch] = useReducer(reducer, []);\n const [yOffsets, setYOffsets] = useState<number[]>([]);\n const heightHashRef = useRef<{\n [id: string]: number;\n }>({});\n const testIds = useTestIds(testId, getToasterTestIds);\n\n // This effect will cause a re-render with a translateY value set for each toast.\n useLayoutEffect(() => {\n const heights = [...messages].reverse().map(({ id }) => heightHashRef.current[id]);\n\n setYOffsets(\n heights\n .map((_, i) => heights.slice(0, i + 1).reduce((sum, cur) => sum + cur + 4, 0))\n .reverse()\n );\n }, [messages.length]);\n\n const providerValue = useMemo(\n () => ({\n push(incoming: ToastMessage) {\n const message: ToastState = {\n ...incoming,\n id: incoming.id ?? createUID(),\n dismissAfter: hasProp(incoming, 'href') ? 10_000 : incoming.dismissAfter\n };\n\n dispatch({\n type: 'push',\n payload: message\n });\n },\n initialized: true\n }),\n []\n );\n\n // Don't create additional ToasterContext.Providers.\n const context = windowIsAvailable\n ? window.cosmos.toasterContext ?? ToasterContext\n : ToasterContext;\n const priorCtx = useContext(context);\n if (priorCtx.initialized) {\n return <context.Provider value={priorCtx}>{children}</context.Provider>;\n }\n\n return (\n <>\n <context.Provider value={providerValue}>{children}</context.Provider>\n {!!messages.length &&\n portalTarget &&\n createPortal(\n <StyledToaster data-testid={testIds.root}>\n {messages.map((message, i) => {\n const sharedProps = {\n translateY: yOffsets[i] ?? 0,\n firstToast: i === 0,\n topLevelDismiss: onDismiss,\n dispatch,\n ref: el => {\n if (el) {\n heightHashRef.current[message.id] = el.offsetHeight;\n } else {\n delete heightHashRef.current[message.id];\n }\n }\n } satisfies Partial<ToastProps>;\n\n if (hasProp(message, 'href')) {\n return (\n // Toast with Link\n <Toast\n data-testid={testIds.toast}\n {...message}\n {...sharedProps}\n key={message.id}\n />\n );\n }\n\n return (\n // Base Toast\n <Toast\n data-testid={testIds.toast}\n {...message}\n {...sharedProps}\n dismissAfter={message.dismissAfter ?? dismissAfter}\n key={message.id}\n />\n );\n })}\n </StyledToaster>,\n portalTarget\n )}\n </>\n );\n};\n\nexport default withTestIds(Toaster, getToasterTestIds);\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
1
|
+
import type { MouseEventHandler, ReactNode } from 'react';
|
|
2
2
|
import type { TestIdProp } from '../../types';
|
|
3
|
-
export
|
|
3
|
+
export type BaseToastMessage = {
|
|
4
4
|
/** String to identify the specific message. Used as onDismiss callback arg. */
|
|
5
5
|
id?: string;
|
|
6
6
|
/** A short message to provide feedback based upon a user action. */
|
|
@@ -16,12 +16,25 @@ export interface ToastMessage {
|
|
|
16
16
|
id: NonNullable<ToastMessage['id']>;
|
|
17
17
|
timeout: boolean;
|
|
18
18
|
}) => void;
|
|
19
|
-
}
|
|
19
|
+
};
|
|
20
|
+
export type CreatedMessage = Pick<BaseToastMessage, 'onDismiss'> & {
|
|
21
|
+
/** String to identify the newly created record. Used as onDismiss callback arg. */
|
|
22
|
+
id: string;
|
|
23
|
+
/** Text of the link. */
|
|
24
|
+
label: string;
|
|
25
|
+
/** Link to newly created record. */
|
|
26
|
+
href: string;
|
|
27
|
+
/** Called when link is clicked. */
|
|
28
|
+
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
29
|
+
dismissAfter?: never;
|
|
30
|
+
content?: never;
|
|
31
|
+
};
|
|
32
|
+
export type ToastMessage = BaseToastMessage | CreatedMessage;
|
|
20
33
|
export interface ToasterProps extends TestIdProp {
|
|
21
34
|
/** The element(s) responsible for handling the Toaster state. */
|
|
22
35
|
children: ReactNode;
|
|
23
36
|
/**
|
|
24
|
-
* Time in milliseconds to automatically dismiss
|
|
37
|
+
* Time in milliseconds to automatically dismiss toast.
|
|
25
38
|
* Can be set globally on Toaster and overridden individually at a message level.
|
|
26
39
|
* @default Infinity
|
|
27
40
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toaster.types.d.ts","sourceRoot":"","sources":["../../../src/components/Toaster/Toaster.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Toaster.types.d.ts","sourceRoot":"","sources":["../../../src/components/Toaster/Toaster.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,+EAA+E;IAC/E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uIAAuI;IACvI,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;QAAE,EAAE,EAAE,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAClG,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,GAAG;IACjE,mFAAmF;IACnF,EAAE,EAAE,MAAM,CAAC;IACX,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAE7D,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,iEAAiE;IACjE,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IAC5C,uIAAuI;IACvI,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;CACvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toaster.types.js","sourceRoot":"","sources":["../../../src/components/Toaster/Toaster.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ReactNode } from 'react';\n\nimport type { TestIdProp } from '../../types';\n\nexport
|
|
1
|
+
{"version":3,"file":"Toaster.types.js","sourceRoot":"","sources":["../../../src/components/Toaster/Toaster.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { MouseEventHandler, ReactNode } from 'react';\n\nimport type { TestIdProp } from '../../types';\n\nexport type BaseToastMessage = {\n /** String to identify the specific message. Used as onDismiss callback arg. */\n id?: string;\n /** A short message to provide feedback based upon a user action. */\n content: string;\n /**\n * Time in milliseconds to automatically dismiss toast.\n * Can be set globally on Toaster and overridden individually at a message level.\n * @default Infinity\n */\n dismissAfter?: number;\n /** Called when user or timer dismisses toasts. Callback is passed the message id and boolean indicating if the dismissal was timed. */\n onDismiss?: ({ id, timeout }: { id: NonNullable<ToastMessage['id']>; timeout: boolean }) => void;\n};\n\nexport type CreatedMessage = Pick<BaseToastMessage, 'onDismiss'> & {\n /** String to identify the newly created record. Used as onDismiss callback arg. */\n id: string;\n /** Text of the link. */\n label: string;\n /** Link to newly created record. */\n href: string;\n /** Called when link is clicked. */\n onClick?: MouseEventHandler<HTMLAnchorElement>;\n dismissAfter?: never;\n content?: never;\n};\n\nexport type ToastMessage = BaseToastMessage | CreatedMessage;\n\nexport interface ToasterProps extends TestIdProp {\n /** The element(s) responsible for handling the Toaster state. */\n children: ReactNode;\n /**\n * Time in milliseconds to automatically dismiss toast.\n * Can be set globally on Toaster and overridden individually at a message level.\n * @default Infinity\n */\n dismissAfter?: ToastMessage['dismissAfter'];\n /** Called when user or timer dismisses Toasts. Callback is passed the message id and boolean indicating if the dismissal was timed. */\n onDismiss?: ToastMessage['onDismiss'];\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAqC,GAAG,EAAE,MAAM,OAAO,CAAC;AAGvF,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGvE,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAOtD,MAAM,WAAW,YAAa,SAAQ,SAAS,EAAE,UAAU;IACzD,oCAAoC;IACpC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,gDAAgD;IAChD,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;IACtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;CAC3B;AAED,eAAO,MAAM,aAAa,yGAaxB,CAAC;;;;
|
|
1
|
+
{"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAqC,GAAG,EAAE,MAAM,OAAO,CAAC;AAGvF,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGvE,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAOtD,MAAM,WAAW,YAAa,SAAQ,SAAS,EAAE,UAAU;IACzD,oCAAoC;IACpC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,gDAAgD;IAChD,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;IACtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;CAC3B;AAED,eAAO,MAAM,aAAa,yGAaxB,CAAC;;;;AA2IH,wBAAuD"}
|
|
@@ -40,7 +40,9 @@ const Tooltip = forwardRef(function Tooltip({ testId, children, target, showDela
|
|
|
40
40
|
setShow(
|
|
41
41
|
// This approach may result in a tooltip NOT appearing 1px before it should due to browser specifics. Enhance as needed.
|
|
42
42
|
// https://stackoverflow.com/a/64747288
|
|
43
|
-
smart
|
|
43
|
+
smart
|
|
44
|
+
? target.scrollWidth > target.clientWidth || target.scrollHeight > target.clientHeight
|
|
45
|
+
: true);
|
|
44
46
|
};
|
|
45
47
|
const onFocusIn = () => {
|
|
46
48
|
showTooltip();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE7E,OAAO,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,OAAO,MAAM,YAAY,CAAC;AAEjC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAyCvD,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACpD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAEtF,OAAO,GAAG,CAAA;wBACY,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,kBAAkB,CAAC;aACvD,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,kBAAkB,CAAC;iBACxC,QAAQ,CAAC,GAAG;;eAEd,KAAK,CAAC,IAAI,CAAC,OAAO;;;;GAI9B,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAa,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAE9C,MAAM,OAAO,GAAmD,UAAU,CAAC,SAAS,OAAO,CACzF,EACE,MAAM,EACN,QAAQ,EACR,MAAM,EACN,SAAS,GAAG,OAAO,EACnB,SAAS,GAAG,MAAM,EAClB,SAAS,GAAG,QAAQ,EACpB,cAAc,GAAG,IAAI,EACrB,KAAK,EACL,GAAG,SAAS,EACkB,EAChC,GAAwB;IAExB,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,cAAc,GAAyC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,EAAE,MAAM,EAAE,OAAO,EAAc,EAAE,EAAE;QAClC,cAAc,CAAC,OAAO,GAAG,OAAO,CAAC;QACjC,IAAI,OAAO,KAAK,UAAU,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM;YAAE,OAAO;QACjE,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,WAAW,GAAG,GAAG,EAAE;YACvB,OAAO;YACL,wHAAwH;YACxH,uCAAuC;YACvC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CACvD,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,GAAG,EAAE;YACrB,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC;QAEF,MAAM,UAAU,GAAG,GAAG,EAAE;YACtB,IAAI,CAAC,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,EAAE;gBAC5E,OAAO,CAAC,KAAK,CAAC,CAAC;aAChB;YACD,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;QAChC,CAAC,CAAC;QAEF,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC;QAEF,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,IAAI,gBAAgB,EAAE,KAAK,MAAM,EAAE;gBACjC,OAAO,CAAC,KAAK,CAAC,CAAC;aAChB;QACH,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,CAAC,EAAE,GAAG,EAAiB,EAAE,EAAE;YAC3C,IAAI,GAAG,KAAK,QAAQ,IAAI,gBAAgB,EAAE,KAAK,MAAM,EAAE;gBACrD,OAAO,CAAC,KAAK,CAAC,CAAC;aAChB;QACH,CAAC,CAAC;QAEF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChD,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAEpD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC9C,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAEhD,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAEpD,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACnD,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAEvD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACjD,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAEnD,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;YACvD,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACzD,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;IAEjC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,IAAI,cAAc,IAAI,IAAI,EAAE;YACpC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;YAC5D,qDAAqD;YACrD,MAAM,CAAC,YAAY,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SACpF;aAAM,IAAI,MAAM,EAAE;YACjB,wBAAwB;YACxB,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;YAC5D,IAAI,WAAW,EAAE;gBACf,8DAA8D;gBAC9D,IAAI,WAAW,KAAK,EAAE,EAAE;oBACtB,MAAM,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;iBAC5C;qBAAM;oBACL,uGAAuG;oBACvG,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC9E,MAAM,CAAC,YAAY,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;iBACzD;aACF;SACF;IACH,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAEnC,OAAO,CACL,KAAC,OAAO,mBACO,OAAO,CAAC,IAAI,EACzB,EAAE,EAAE,EAAE,KACF,SAAS,EACb,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAC,SAAS,EACjB,QAAQ,EAAC,OAAO,EAChB,EAAE,EAAE,aAAa,EACjB,IAAI,EAAC,SAAS,EACd,MAAM,EAAE,MAAM,EACd,KAAK,QACL,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,WAAW,EACxB,kBAAkB,QAClB,GAAG,EAAE,UAAU,YAEd,QAAQ,GACD,CACX,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,eAAe,WAAW,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC","sourcesContent":["import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';\nimport type { FunctionComponent, MutableRefObject, PropsWithoutRef, Ref } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport type { BaseProps, ForwardProps, TestIdProp } from '../../types';\nimport { defaultThemeProp } from '../../theme';\nimport Popover from '../Popover';\nimport type { Delay, PopoverProps } from '../Popover';\nimport { useConsolidatedRef, useTestIds, useUID } from '../../hooks';\nimport { calculateFontSize } from '../../styles';\nimport { getActiveElement, withTestIds } from '../../utils';\n\nimport { getTooltipTestIds } from './Tooltip.test-ids';\n\nexport interface TooltipProps extends BaseProps, TestIdProp {\n /** Text content for the tooltip. */\n children: string | string[];\n /** Element to serve as the tooltip's target. */\n target: Element | null;\n /**\n * Delay showing the tooltip on mouseenter.\n * @default 'short'\n */\n showDelay?: Delay;\n /**\n * Delay hiding the tooltip on mouseleave.\n * @default 'long'\n */\n hideDelay?: Delay;\n /**\n * If true, the Tooltip will render outside of the current DOM hierarchy in a [portal](https://reactjs.org/docs/portals.html).\n * @default true\n */\n portal?: PopoverProps['portal'];\n /**\n * If true, the Tooltip will automatically apply an aria-describedby attribute to its target.\n * @default true\n */\n describeTarget?: boolean;\n /**\n * Sets the placement of the tooltip relative to the target.\n * @default 'bottom'\n */\n placement?: PopoverProps['placement'];\n /**\n * Conditionally renders a tooltip only if the associated element's text content is truncated.\n * To work, the associated element must be be displayed as a CSS \"block box\" i.e. block, inline-block, etc...\n * @default false\n */\n smart?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\nexport const StyledTooltip = styled.div(({ theme }) => {\n const fontSize = calculateFontSize(theme.base['font-size'], theme.base['font-scale']);\n\n return css`\n background-color: ${theme.components.tooltip['background-color']};\n color: ${theme.components.tooltip['foreground-color']};\n font-size: ${fontSize.xxs};\n max-width: 40ch;\n padding: ${theme.base.spacing};\n white-space: pre-line;\n word-break: break-word;\n pointer-events: none;\n `;\n});\n\nStyledTooltip.defaultProps = defaultThemeProp;\n\nconst Tooltip: FunctionComponent<TooltipProps & ForwardProps> = forwardRef(function Tooltip(\n {\n testId,\n children,\n target,\n showDelay = 'short',\n hideDelay = 'long',\n placement = 'bottom',\n describeTarget = true,\n smart,\n ...restProps\n }: PropsWithoutRef<TooltipProps>,\n ref: Ref<HTMLDivElement>\n) {\n const id = useUID();\n const [show, setShow] = useState(false);\n const tooltipRef = useConsolidatedRef(ref);\n const lastClickedRef: MutableRefObject<EventTarget | null> = useRef(null);\n const testIds = useTestIds(testId, getTooltipTestIds);\n\n const onMouseDown = useCallback(\n ({ target: eTarget }: MouseEvent) => {\n lastClickedRef.current = eTarget;\n if (eTarget === tooltipRef.current || eTarget === target) return;\n setShow(false);\n },\n [target]\n );\n\n useEffect(() => {\n if (!target) return;\n\n const showTooltip = () => {\n setShow(\n // This approach may result in a tooltip NOT appearing 1px before it should due to browser specifics. Enhance as needed.\n // https://stackoverflow.com/a/64747288\n smart ? target.scrollWidth > target.clientWidth : true\n );\n };\n\n const onFocusIn = () => {\n showTooltip();\n };\n\n const onFocusOut = () => {\n if (!lastClickedRef.current || lastClickedRef.current !== tooltipRef.current) {\n setShow(false);\n }\n lastClickedRef.current = null;\n };\n\n const onMouseEnter = () => {\n showTooltip();\n };\n\n const onMouseLeave = () => {\n if (getActiveElement() !== target) {\n setShow(false);\n }\n };\n\n const onKeyDown = ({ key }: KeyboardEvent) => {\n if (key === 'Escape' && getActiveElement() === target) {\n setShow(false);\n }\n };\n\n document.addEventListener('keydown', onKeyDown);\n document.addEventListener('mousedown', onMouseDown);\n\n target.addEventListener('focusin', onFocusIn);\n target.addEventListener('focusout', onFocusOut);\n\n target.addEventListener('mouseenter', onMouseEnter);\n target.addEventListener('mouseleave', onMouseLeave);\n\n return () => {\n document.removeEventListener('keydown', onKeyDown);\n document.removeEventListener('mousedown', onMouseDown);\n\n target.removeEventListener('focusin', onFocusIn);\n target.removeEventListener('focusout', onFocusOut);\n\n target.removeEventListener('mouseenter', onMouseEnter);\n target.removeEventListener('mouseleave', onMouseLeave);\n };\n }, [target, onMouseDown, smart]);\n\n useEffect(() => {\n if (target && describeTarget && show) {\n const describedBy = target.getAttribute('aria-describedby');\n // Set the attribute to the old attribute plus the id\n target.setAttribute('aria-describedby', describedBy ? `${describedBy} ${id}` : id);\n } else if (target) {\n // Get the old attribute\n const describedBy = target.getAttribute('aria-describedby');\n if (describedBy) {\n // If the old attribute matches the id just remove it entirely\n if (describedBy === id) {\n target.removeAttribute('aria-describedby');\n } else {\n // Otherwise we want to just remove the id that was added and reset the attribute to what it was before\n const oldDescribedBy = describedBy.replace(new RegExp(`(?:^|\\\\s+)${id}`), '');\n target.setAttribute('aria-describedby', oldDescribedBy);\n }\n }\n }\n }, [describeTarget, target, show]);\n\n return (\n <Popover\n data-testid={testIds.root}\n id={id}\n {...restProps}\n show={show}\n showDelay={showDelay}\n hideDelay={hideDelay}\n groupId='tooltip'\n strategy='fixed'\n as={StyledTooltip}\n role='tooltip'\n target={target}\n arrow\n placement={placement}\n onMouseDown={onMouseDown}\n hideOnTargetHidden\n ref={tooltipRef}\n >\n {children}\n </Popover>\n );\n});\n\nexport default withTestIds(Tooltip, getTooltipTestIds);\n"]}
|
|
1
|
+
{"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE7E,OAAO,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,OAAO,MAAM,YAAY,CAAC;AAEjC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAyCvD,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACpD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAEtF,OAAO,GAAG,CAAA;wBACY,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,kBAAkB,CAAC;aACvD,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,kBAAkB,CAAC;iBACxC,QAAQ,CAAC,GAAG;;eAEd,KAAK,CAAC,IAAI,CAAC,OAAO;;;;GAI9B,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAa,CAAC,YAAY,GAAG,gBAAgB,CAAC;AAE9C,MAAM,OAAO,GAAmD,UAAU,CAAC,SAAS,OAAO,CACzF,EACE,MAAM,EACN,QAAQ,EACR,MAAM,EACN,SAAS,GAAG,OAAO,EACnB,SAAS,GAAG,MAAM,EAClB,SAAS,GAAG,QAAQ,EACpB,cAAc,GAAG,IAAI,EACrB,KAAK,EACL,GAAG,SAAS,EACkB,EAChC,GAAwB;IAExB,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,cAAc,GAAyC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,EAAE,MAAM,EAAE,OAAO,EAAc,EAAE,EAAE;QAClC,cAAc,CAAC,OAAO,GAAG,OAAO,CAAC;QACjC,IAAI,OAAO,KAAK,UAAU,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM;YAAE,OAAO;QACjE,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,WAAW,GAAG,GAAG,EAAE;YACvB,OAAO;YACL,wHAAwH;YACxH,uCAAuC;YACvC,KAAK;gBACH,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY;gBACtF,CAAC,CAAC,IAAI,CACT,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,GAAG,EAAE;YACrB,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC;QAEF,MAAM,UAAU,GAAG,GAAG,EAAE;YACtB,IAAI,CAAC,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,EAAE;gBAC5E,OAAO,CAAC,KAAK,CAAC,CAAC;aAChB;YACD,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;QAChC,CAAC,CAAC;QAEF,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC;QAEF,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,IAAI,gBAAgB,EAAE,KAAK,MAAM,EAAE;gBACjC,OAAO,CAAC,KAAK,CAAC,CAAC;aAChB;QACH,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,CAAC,EAAE,GAAG,EAAiB,EAAE,EAAE;YAC3C,IAAI,GAAG,KAAK,QAAQ,IAAI,gBAAgB,EAAE,KAAK,MAAM,EAAE;gBACrD,OAAO,CAAC,KAAK,CAAC,CAAC;aAChB;QACH,CAAC,CAAC;QAEF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChD,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAEpD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC9C,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAEhD,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAEpD,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACnD,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YAEvD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACjD,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAEnD,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;YACvD,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QACzD,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;IAEjC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,IAAI,cAAc,IAAI,IAAI,EAAE;YACpC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;YAC5D,qDAAqD;YACrD,MAAM,CAAC,YAAY,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SACpF;aAAM,IAAI,MAAM,EAAE;YACjB,wBAAwB;YACxB,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;YAC5D,IAAI,WAAW,EAAE;gBACf,8DAA8D;gBAC9D,IAAI,WAAW,KAAK,EAAE,EAAE;oBACtB,MAAM,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;iBAC5C;qBAAM;oBACL,uGAAuG;oBACvG,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC9E,MAAM,CAAC,YAAY,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;iBACzD;aACF;SACF;IACH,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAEnC,OAAO,CACL,KAAC,OAAO,mBACO,OAAO,CAAC,IAAI,EACzB,EAAE,EAAE,EAAE,KACF,SAAS,EACb,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAC,SAAS,EACjB,QAAQ,EAAC,OAAO,EAChB,EAAE,EAAE,aAAa,EACjB,IAAI,EAAC,SAAS,EACd,MAAM,EAAE,MAAM,EACd,KAAK,QACL,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,WAAW,EACxB,kBAAkB,QAClB,GAAG,EAAE,UAAU,YAEd,QAAQ,GACD,CACX,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,eAAe,WAAW,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC","sourcesContent":["import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';\nimport type { FunctionComponent, MutableRefObject, PropsWithoutRef, Ref } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport type { BaseProps, ForwardProps, TestIdProp } from '../../types';\nimport { defaultThemeProp } from '../../theme';\nimport Popover from '../Popover';\nimport type { Delay, PopoverProps } from '../Popover';\nimport { useConsolidatedRef, useTestIds, useUID } from '../../hooks';\nimport { calculateFontSize } from '../../styles';\nimport { getActiveElement, withTestIds } from '../../utils';\n\nimport { getTooltipTestIds } from './Tooltip.test-ids';\n\nexport interface TooltipProps extends BaseProps, TestIdProp {\n /** Text content for the tooltip. */\n children: string | string[];\n /** Element to serve as the tooltip's target. */\n target: Element | null;\n /**\n * Delay showing the tooltip on mouseenter.\n * @default 'short'\n */\n showDelay?: Delay;\n /**\n * Delay hiding the tooltip on mouseleave.\n * @default 'long'\n */\n hideDelay?: Delay;\n /**\n * If true, the Tooltip will render outside of the current DOM hierarchy in a [portal](https://reactjs.org/docs/portals.html).\n * @default true\n */\n portal?: PopoverProps['portal'];\n /**\n * If true, the Tooltip will automatically apply an aria-describedby attribute to its target.\n * @default true\n */\n describeTarget?: boolean;\n /**\n * Sets the placement of the tooltip relative to the target.\n * @default 'bottom'\n */\n placement?: PopoverProps['placement'];\n /**\n * Conditionally renders a tooltip only if the associated element's text content is truncated.\n * To work, the associated element must be be displayed as a CSS \"block box\" i.e. block, inline-block, etc...\n * @default false\n */\n smart?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\nexport const StyledTooltip = styled.div(({ theme }) => {\n const fontSize = calculateFontSize(theme.base['font-size'], theme.base['font-scale']);\n\n return css`\n background-color: ${theme.components.tooltip['background-color']};\n color: ${theme.components.tooltip['foreground-color']};\n font-size: ${fontSize.xxs};\n max-width: 40ch;\n padding: ${theme.base.spacing};\n white-space: pre-line;\n word-break: break-word;\n pointer-events: none;\n `;\n});\n\nStyledTooltip.defaultProps = defaultThemeProp;\n\nconst Tooltip: FunctionComponent<TooltipProps & ForwardProps> = forwardRef(function Tooltip(\n {\n testId,\n children,\n target,\n showDelay = 'short',\n hideDelay = 'long',\n placement = 'bottom',\n describeTarget = true,\n smart,\n ...restProps\n }: PropsWithoutRef<TooltipProps>,\n ref: Ref<HTMLDivElement>\n) {\n const id = useUID();\n const [show, setShow] = useState(false);\n const tooltipRef = useConsolidatedRef(ref);\n const lastClickedRef: MutableRefObject<EventTarget | null> = useRef(null);\n const testIds = useTestIds(testId, getTooltipTestIds);\n\n const onMouseDown = useCallback(\n ({ target: eTarget }: MouseEvent) => {\n lastClickedRef.current = eTarget;\n if (eTarget === tooltipRef.current || eTarget === target) return;\n setShow(false);\n },\n [target]\n );\n\n useEffect(() => {\n if (!target) return;\n\n const showTooltip = () => {\n setShow(\n // This approach may result in a tooltip NOT appearing 1px before it should due to browser specifics. Enhance as needed.\n // https://stackoverflow.com/a/64747288\n smart\n ? target.scrollWidth > target.clientWidth || target.scrollHeight > target.clientHeight\n : true\n );\n };\n\n const onFocusIn = () => {\n showTooltip();\n };\n\n const onFocusOut = () => {\n if (!lastClickedRef.current || lastClickedRef.current !== tooltipRef.current) {\n setShow(false);\n }\n lastClickedRef.current = null;\n };\n\n const onMouseEnter = () => {\n showTooltip();\n };\n\n const onMouseLeave = () => {\n if (getActiveElement() !== target) {\n setShow(false);\n }\n };\n\n const onKeyDown = ({ key }: KeyboardEvent) => {\n if (key === 'Escape' && getActiveElement() === target) {\n setShow(false);\n }\n };\n\n document.addEventListener('keydown', onKeyDown);\n document.addEventListener('mousedown', onMouseDown);\n\n target.addEventListener('focusin', onFocusIn);\n target.addEventListener('focusout', onFocusOut);\n\n target.addEventListener('mouseenter', onMouseEnter);\n target.addEventListener('mouseleave', onMouseLeave);\n\n return () => {\n document.removeEventListener('keydown', onKeyDown);\n document.removeEventListener('mousedown', onMouseDown);\n\n target.removeEventListener('focusin', onFocusIn);\n target.removeEventListener('focusout', onFocusOut);\n\n target.removeEventListener('mouseenter', onMouseEnter);\n target.removeEventListener('mouseleave', onMouseLeave);\n };\n }, [target, onMouseDown, smart]);\n\n useEffect(() => {\n if (target && describeTarget && show) {\n const describedBy = target.getAttribute('aria-describedby');\n // Set the attribute to the old attribute plus the id\n target.setAttribute('aria-describedby', describedBy ? `${describedBy} ${id}` : id);\n } else if (target) {\n // Get the old attribute\n const describedBy = target.getAttribute('aria-describedby');\n if (describedBy) {\n // If the old attribute matches the id just remove it entirely\n if (describedBy === id) {\n target.removeAttribute('aria-describedby');\n } else {\n // Otherwise we want to just remove the id that was added and reset the attribute to what it was before\n const oldDescribedBy = describedBy.replace(new RegExp(`(?:^|\\\\s+)${id}`), '');\n target.setAttribute('aria-describedby', oldDescribedBy);\n }\n }\n }\n }, [describeTarget, target, show]);\n\n return (\n <Popover\n data-testid={testIds.root}\n id={id}\n {...restProps}\n show={show}\n showDelay={showDelay}\n hideDelay={hideDelay}\n groupId='tooltip'\n strategy='fixed'\n as={StyledTooltip}\n role='tooltip'\n target={target}\n arrow\n placement={placement}\n onMouseDown={onMouseDown}\n hideOnTargetHidden\n ref={tooltipRef}\n >\n {children}\n </Popover>\n );\n});\n\nexport default withTestIds(Tooltip, getTooltipTestIds);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useArrows.d.ts","sourceRoot":"","sources":["../../src/hooks/useArrows.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAWvD;;;GAGG;AACH,QAAA,MAAM,SAAS,QACR,UAAU,WAAW,CAAC;;;;;;;
|
|
1
|
+
{"version":3,"file":"useArrows.d.ts","sourceRoot":"","sources":["../../src/hooks/useArrows.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAWvD;;;GAGG;AACH,QAAA,MAAM,SAAS,QACR,UAAU,WAAW,CAAC;;;;;;;yCAkI5B,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
package/lib/hooks/useArrows.js
CHANGED
|
@@ -64,7 +64,9 @@ dependencies = []) => {
|
|
|
64
64
|
newFocusIdx = focusIndex === -1 ? 0 : focusIndex;
|
|
65
65
|
}
|
|
66
66
|
else if (e.key === 'End' || (e.key === PrevKey && focusIdx === -1)) {
|
|
67
|
-
|
|
67
|
+
const focusableElements = Array.from(el.querySelectorAll(selector));
|
|
68
|
+
const focusIndex = focusableElements.findIndex(focusEl => focusEl === initialFocusElement);
|
|
69
|
+
newFocusIdx = focusIndex === -1 ? lastIdx : focusIndex;
|
|
68
70
|
}
|
|
69
71
|
else if (e.key === 'Enter') {
|
|
70
72
|
if (updateTabIndex) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useArrows.js","sourceRoot":"","sources":["../../src/hooks/useArrows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAG/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,SAAS,GAAG;;;;;CAKjB,CAAC;AAEF;;;GAGG;AACH,MAAM,SAAS,GAAG,CAChB,GAA2B,EAC3B;AACE,yKAAyK;AACzK,KAAK,GAAG,IAAI;AACZ,wPAAwP;AACxP,QAAQ,GAAG,SAAS;AACpB,uDAAuD;AACvD,GAAG,GAAG,SAAS,EACf,aAAa,GAAG,IAAI,EACpB,cAAc,GAAG,IAAI;AACrB,uFAAuF;AACvF,mBAAmB,KAQjB,EAAE;AACN,uEAAuE;AACvE,eAA+B,EAAE,EACjC,EAAE;IACF,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GACtB,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAE7E,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,EAAe,EAAE,EAAE;QAClB,8IAA8I;QAC9I,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEpE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;YAChC,IAAI,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,KAAK,mBAAmB,CAAC,CAAC;YACzF,IAAI,UAAU,KAAK,CAAC,CAAC;gBAAE,UAAU,GAAG,CAAC,CAAC;YAEtC,IAAI,aAAa;gBAAG,iBAAiB,CAAC,UAAU,CAAiB,CAAC,QAAQ,GAAG,CAAC,CAAC;YAC/E,iBAAiB,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YACxC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAC/B,IAAI,IAAI,YAAY,WAAW,EAAE;oBAC/B,MAAM,OAAO,GAAI,IAAyB,CAAC,OAAO,CAAC;oBACnD,IAAI,CAAC,OAAO;wBAAE,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;iBAClC;YACH,CAAC,CAAC,CAAC;SACJ;IACH,CAAC,EACD,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,YAAY,CAAC,CACjD,CAAC;IAEF,MAAM,QAAQ,GAAG,WAAW,CAC1B,CAAC,CAAgB,EAAE,EAAE;QACnB,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;YAAE,CAAC,CAAC,cAAc,EAAE,CAAC;QAE1E,IAAI,CAAC,mBAAmB;YAAE,OAAO;QAEjC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAC5D,CAAC,IAAI,EAAuB,EAAE,CAAC,IAAI,YAAY,WAAW,CAC3D,CAAC;QAEF,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO;QAE1B,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;QAElC,IAAI,CAAC,CAAC,QAAQ,YAAY,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,YAAY,UAAU,CAAC;YAAE,OAAO;QAEjF,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAA4B,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACjC,IAAI,WAAW,CAAC;QAEhB,IAAI,CAAC,CAAC,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,QAAQ,KAAK,CAAC,CAAC,CAAC,EAAE;YAC9D,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;YACpE,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,KAAK,mBAAmB,CAAC,CAAC;YAC3F,WAAW,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;SAClD;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,QAAQ,KAAK,CAAC,CAAC,CAAC,EAAE;YACpE,WAAW,GAAG,OAAO,CAAC;SACvB;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE;YAC5B,IAAI,cAAc,EAAE;gBAClB,aAAa,CAAC,EAAE,CAAC,CAAC;aACnB;YACD,OAAO;SACR;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE;YAC5B,IAAI,QAAQ,KAAK,OAAO,EAAE;gBACxB,IAAI,CAAC,KAAK;oBAAE,OAAO;gBACnB,WAAW,GAAG,CAAC,CAAC;aACjB;iBAAM;gBACL,WAAW,GAAG,QAAQ,GAAG,CAAC,CAAC;aAC5B;SACF;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE;YAC5B,IAAI,QAAQ,KAAK,CAAC,EAAE;gBAClB,IAAI,CAAC,KAAK;oBAAE,OAAO;gBACnB,WAAW,GAAG,OAAO,CAAC;aACvB;iBAAM;gBACL,WAAW,GAAG,QAAQ,GAAG,CAAC,CAAC;aAC5B;SACF;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK,IAAI,mBAAmB,EAAE;YACjD,+KAA+K;YAC/K,UAAU,CAAC,GAAG,EAAE;gBACb,mBAAmC,CAAC,QAAQ,GAAG,CAAC,CAAC;YACpD,CAAC,EAAE,CAAC,CAAC,CAAC;YACN,OAAO;SACR;aAAM;YACL,OAAO;SACR;QAED,yMAAyM;QACzM,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,IAAI,mBAAmB,EAAE;YAClE,mBAAmC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;SACpD;QAED,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC,EACD,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,GAAG,YAAY,CAAC,CACrE,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,IAAI,cAAc;YAChB,UAAU,CAAC,GAAG,EAAE;gBACd,aAAa,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC,EAAE,CAAC,CAAC,CAAC;QACR,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEzC,OAAO,GAAG,EAAE;YACV,EAAE,CAAC,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;AAC9E,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import { useEffect, useCallback } from 'react';\nimport type { RefObject, DependencyList } from 'react';\n\nimport { documentIsAvailable } from '../utils';\n\nconst focusable = `\n a[href],\n button:enabled,\n input[type='checkbox']:enabled,\n input[type='radio']:enabled\n`;\n\n/**\n * @example useArrows(ref, { cycle, selector });\n * @param ref - A reference to the element that will be navigated through. [React RefObject](https://reactjs.org/docs/refs-and-the-dom.html)\n */\nconst useArrows = (\n ref: RefObject<HTMLElement>,\n {\n /** If true, the down or up arrow key will navigate to the first or last element if the element currently focused is the last or first index of the selected elements. */\n cycle = true,\n /** A query selector that will determine which elements to cycle through with the arrow keys. The selector will be used in conjunction with [querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll#selectors). */\n selector = focusable,\n /** Which keys are used to navigate through the list */\n dir = 'up-down',\n allowTabFocus = true,\n updateTabIndex = true,\n /** When focus enters the ref, which element should receive focus first if available */\n initialFocusElement\n }: {\n cycle?: boolean;\n selector?: string;\n dir?: 'up-down' | 'left-right';\n allowTabFocus?: boolean;\n updateTabIndex?: boolean;\n initialFocusElement?: Element | null;\n } = {},\n /** Pass this prop in the internal dependencies when list is dynamic */\n dependencies: DependencyList = []\n) => {\n const [NextKey, PrevKey] =\n dir === 'up-down' ? ['ArrowDown', 'ArrowUp'] : ['ArrowRight', 'ArrowLeft'];\n\n const setTabIndexes = useCallback(\n (el: HTMLElement) => {\n // don't set tabindex -1 for first element, or the initialFocusElement, or an element with a checked input inside of it to be able to focus it\n const focusableElements = Array.from(el.querySelectorAll(selector));\n\n if (focusableElements.length > 0) {\n let focusIndex = focusableElements.findIndex(focusEl => focusEl === initialFocusElement);\n if (focusIndex === -1) focusIndex = 0;\n\n if (allowTabFocus) (focusableElements[focusIndex] as HTMLElement).tabIndex = 0;\n focusableElements.splice(focusIndex, 1);\n focusableElements.forEach(item => {\n if (item instanceof HTMLElement) {\n const checked = (item as HTMLInputElement).checked;\n if (!checked) item.tabIndex = -1;\n }\n });\n }\n },\n [selector, initialFocusElement, ...dependencies]\n );\n\n const listener = useCallback(\n (e: KeyboardEvent) => {\n const el = ref.current;\n if (!el) return;\n if (['Home', 'End', NextKey, PrevKey].includes(e.key)) e.preventDefault();\n\n if (!documentIsAvailable) return;\n\n const items = Array.from(el.querySelectorAll(selector)).filter(\n (item): item is HTMLElement => item instanceof HTMLElement\n );\n\n if (!items.length) return;\n\n const rootNode = el.getRootNode();\n\n if (!(rootNode instanceof Document) && !(rootNode instanceof ShadowRoot)) return;\n\n const focusIdx = items.indexOf(rootNode.activeElement as HTMLElement);\n const lastIdx = items.length - 1;\n let newFocusIdx;\n\n if (e.key === 'Home' || (e.key === NextKey && focusIdx === -1)) {\n const focusableElements = Array.from(el.querySelectorAll(selector));\n const focusIndex = focusableElements.findIndex(focusEl => focusEl === initialFocusElement);\n newFocusIdx = focusIndex === -1 ? 0 : focusIndex;\n } else if (e.key === 'End' || (e.key === PrevKey && focusIdx === -1)) {\n newFocusIdx = lastIdx;\n } else if (e.key === 'Enter') {\n if (updateTabIndex) {\n setTabIndexes(el);\n }\n return;\n } else if (e.key === NextKey) {\n if (focusIdx === lastIdx) {\n if (!cycle) return;\n newFocusIdx = 0;\n } else {\n newFocusIdx = focusIdx + 1;\n }\n } else if (e.key === PrevKey) {\n if (focusIdx === 0) {\n if (!cycle) return;\n newFocusIdx = lastIdx;\n } else {\n newFocusIdx = focusIdx - 1;\n }\n } else if (e.key === 'Tab' && initialFocusElement) {\n // We need to reset the tabIndex for the initial focused element when leaving the group. 0 second timeout necessary to avoid focusing this element instad of leaving the group.\n setTimeout(() => {\n (initialFocusElement as HTMLElement).tabIndex = 0;\n }, 0);\n return;\n } else {\n return;\n }\n\n // If there is an initial focused element other than the default, the tabIndex must be set to -1 the moment arrow keys are used to prevent that element from being tabbable while within the group focus.\n if ((e.key === PrevKey || e.key === NextKey) && initialFocusElement) {\n (initialFocusElement as HTMLElement).tabIndex = -1;\n }\n\n items[newFocusIdx].focus();\n },\n [ref.current, cycle, selector, initialFocusElement, ...dependencies]\n );\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n if (updateTabIndex)\n setTimeout(() => {\n setTabIndexes(el);\n }, 0);\n el.addEventListener('keydown', listener);\n\n return () => {\n el.removeEventListener('keydown', listener);\n };\n }, [ref.current, selector, listener, initialFocusElement, ...dependencies]);\n};\n\nexport default useArrows;\n"]}
|
|
1
|
+
{"version":3,"file":"useArrows.js","sourceRoot":"","sources":["../../src/hooks/useArrows.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useCallback } from 'react';\nimport type { RefObject, DependencyList } from 'react';\n\nimport { documentIsAvailable } from '../utils';\n\nconst focusable = `\n a[href],\n button:enabled,\n input[type='checkbox']:enabled,\n input[type='radio']:enabled\n`;\n\n/**\n * @example useArrows(ref, { cycle, selector });\n * @param ref - A reference to the element that will be navigated through. [React RefObject](https://reactjs.org/docs/refs-and-the-dom.html)\n */\nconst useArrows = (\n ref: RefObject<HTMLElement>,\n {\n /** If true, the down or up arrow key will navigate to the first or last element if the element currently focused is the last or first index of the selected elements. */\n cycle = true,\n /** A query selector that will determine which elements to cycle through with the arrow keys. The selector will be used in conjunction with [querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll#selectors). */\n selector = focusable,\n /** Which keys are used to navigate through the list */\n dir = 'up-down',\n allowTabFocus = true,\n updateTabIndex = true,\n /** When focus enters the ref, which element should receive focus first if available */\n initialFocusElement\n }: {\n cycle?: boolean;\n selector?: string;\n dir?: 'up-down' | 'left-right';\n allowTabFocus?: boolean;\n updateTabIndex?: boolean;\n initialFocusElement?: Element | null;\n } = {},\n /** Pass this prop in the internal dependencies when list is dynamic */\n dependencies: DependencyList = []\n) => {\n const [NextKey, PrevKey] =\n dir === 'up-down' ? ['ArrowDown', 'ArrowUp'] : ['ArrowRight', 'ArrowLeft'];\n\n const setTabIndexes = useCallback(\n (el: HTMLElement) => {\n // don't set tabindex -1 for first element, or the initialFocusElement, or an element with a checked input inside of it to be able to focus it\n const focusableElements = Array.from(el.querySelectorAll(selector));\n\n if (focusableElements.length > 0) {\n let focusIndex = focusableElements.findIndex(focusEl => focusEl === initialFocusElement);\n if (focusIndex === -1) focusIndex = 0;\n\n if (allowTabFocus) (focusableElements[focusIndex] as HTMLElement).tabIndex = 0;\n focusableElements.splice(focusIndex, 1);\n focusableElements.forEach(item => {\n if (item instanceof HTMLElement) {\n const checked = (item as HTMLInputElement).checked;\n if (!checked) item.tabIndex = -1;\n }\n });\n }\n },\n [selector, initialFocusElement, ...dependencies]\n );\n\n const listener = useCallback(\n (e: KeyboardEvent) => {\n const el = ref.current;\n if (!el) return;\n if (['Home', 'End', NextKey, PrevKey].includes(e.key)) e.preventDefault();\n\n if (!documentIsAvailable) return;\n\n const items = Array.from(el.querySelectorAll(selector)).filter(\n (item): item is HTMLElement => item instanceof HTMLElement\n );\n\n if (!items.length) return;\n\n const rootNode = el.getRootNode();\n\n if (!(rootNode instanceof Document) && !(rootNode instanceof ShadowRoot)) return;\n\n const focusIdx = items.indexOf(rootNode.activeElement as HTMLElement);\n const lastIdx = items.length - 1;\n let newFocusIdx;\n\n if (e.key === 'Home' || (e.key === NextKey && focusIdx === -1)) {\n const focusableElements = Array.from(el.querySelectorAll(selector));\n const focusIndex = focusableElements.findIndex(focusEl => focusEl === initialFocusElement);\n newFocusIdx = focusIndex === -1 ? 0 : focusIndex;\n } else if (e.key === 'End' || (e.key === PrevKey && focusIdx === -1)) {\n const focusableElements = Array.from(el.querySelectorAll(selector));\n const focusIndex = focusableElements.findIndex(focusEl => focusEl === initialFocusElement);\n newFocusIdx = focusIndex === -1 ? lastIdx : focusIndex;\n } else if (e.key === 'Enter') {\n if (updateTabIndex) {\n setTabIndexes(el);\n }\n return;\n } else if (e.key === NextKey) {\n if (focusIdx === lastIdx) {\n if (!cycle) return;\n newFocusIdx = 0;\n } else {\n newFocusIdx = focusIdx + 1;\n }\n } else if (e.key === PrevKey) {\n if (focusIdx === 0) {\n if (!cycle) return;\n newFocusIdx = lastIdx;\n } else {\n newFocusIdx = focusIdx - 1;\n }\n } else if (e.key === 'Tab' && initialFocusElement) {\n // We need to reset the tabIndex for the initial focused element when leaving the group. 0 second timeout necessary to avoid focusing this element instad of leaving the group.\n setTimeout(() => {\n (initialFocusElement as HTMLElement).tabIndex = 0;\n }, 0);\n return;\n } else {\n return;\n }\n\n // If there is an initial focused element other than the default, the tabIndex must be set to -1 the moment arrow keys are used to prevent that element from being tabbable while within the group focus.\n if ((e.key === PrevKey || e.key === NextKey) && initialFocusElement) {\n (initialFocusElement as HTMLElement).tabIndex = -1;\n }\n\n items[newFocusIdx].focus();\n },\n [ref.current, cycle, selector, initialFocusElement, ...dependencies]\n );\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n if (updateTabIndex)\n setTimeout(() => {\n setTabIndexes(el);\n }, 0);\n el.addEventListener('keydown', listener);\n\n return () => {\n el.removeEventListener('keydown', listener);\n };\n }, [ref.current, selector, listener, initialFocusElement, ...dependencies]);\n};\n\nexport default useArrows;\n"]}
|