smarthr-ui 96.0.0 → 96.1.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/Icon/FaIcon.cjs +1 -1
- package/lib/components/Icon/FaIcon.js +1 -1
- package/lib/components/Icon/LanguageIcon.cjs +1 -1
- package/lib/components/Icon/LanguageIcon.js +1 -1
- package/lib/components/Icon/OpenInNewTabIcon.cjs +1 -1
- package/lib/components/Icon/OpenInNewTabIcon.js +1 -1
- package/lib/components/Icon/SparklesIcon.cjs +1 -1
- package/lib/components/Icon/SparklesIcon.js +1 -1
- package/lib/components/Icon/WarningIcon.cjs +1 -1
- package/lib/components/Icon/WarningIcon.js +1 -1
- package/lib/components/Icon/generateIcon.cjs +0 -1
- package/lib/components/Icon/generateIcon.cjs.map +1 -1
- package/lib/components/Icon/generateIcon.js +0 -1
- package/lib/components/Icon/generateIcon.js.map +1 -1
- package/lib/components/Input/InputWithTooltip/InputWithTooltip.cjs +1 -1
- package/lib/components/Input/InputWithTooltip/InputWithTooltip.cjs.map +1 -1
- package/lib/components/Input/InputWithTooltip/InputWithTooltip.js +1 -1
- package/lib/components/Input/InputWithTooltip/InputWithTooltip.js.map +1 -1
- package/lib/components/LineClamp/LineClamp.cjs +3 -5
- package/lib/components/LineClamp/LineClamp.cjs.map +1 -1
- package/lib/components/LineClamp/LineClamp.js +3 -5
- package/lib/components/LineClamp/LineClamp.js.map +1 -1
- package/lib/components/SideNav/SideNavItemButton.cjs.map +1 -1
- package/lib/components/SideNav/SideNavItemButton.d.ts +11 -10
- package/lib/components/SideNav/SideNavItemButton.js.map +1 -1
- package/lib/components/TabBar/TabItem.cjs +1 -1
- package/lib/components/TabBar/TabItem.cjs.map +1 -1
- package/lib/components/TabBar/TabItem.js +1 -1
- package/lib/components/TabBar/TabItem.js.map +1 -1
- package/lib/components/Tooltip/Tooltip.cjs +20 -6
- package/lib/components/Tooltip/Tooltip.cjs.map +1 -1
- package/lib/components/Tooltip/Tooltip.d.ts +4 -2
- package/lib/components/Tooltip/Tooltip.js +20 -6
- package/lib/components/Tooltip/Tooltip.js.map +1 -1
- package/lib/vendor/.pnpm/{react-icons@5.5.0_react@19.2.6 → react-icons@5.6.0_react@19.2.6}/vendor/react-icons/fa6/index.cjs +404 -404
- package/lib/vendor/.pnpm/react-icons@5.6.0_react@19.2.6/vendor/react-icons/fa6/index.cjs.map +1 -0
- package/lib/vendor/.pnpm/{react-icons@5.5.0_react@19.2.6 → react-icons@5.6.0_react@19.2.6}/vendor/react-icons/fa6/index.js +404 -404
- package/lib/vendor/.pnpm/react-icons@5.6.0_react@19.2.6/vendor/react-icons/fa6/index.js.map +1 -0
- package/lib/vendor/.pnpm/{react-icons@5.5.0_react@19.2.6 → react-icons@5.6.0_react@19.2.6}/vendor/react-icons/lib/iconBase.cjs +4 -4
- package/lib/vendor/.pnpm/react-icons@5.6.0_react@19.2.6/vendor/react-icons/lib/iconBase.cjs.map +1 -0
- package/lib/vendor/.pnpm/{react-icons@5.5.0_react@19.2.6 → react-icons@5.6.0_react@19.2.6}/vendor/react-icons/lib/iconBase.js +4 -4
- package/lib/vendor/.pnpm/react-icons@5.6.0_react@19.2.6/vendor/react-icons/lib/iconBase.js.map +1 -0
- package/lib/vendor/.pnpm/{react-icons@5.5.0_react@19.2.6 → react-icons@5.6.0_react@19.2.6}/vendor/react-icons/lib/iconContext.cjs.map +1 -1
- package/lib/vendor/.pnpm/{react-icons@5.5.0_react@19.2.6 → react-icons@5.6.0_react@19.2.6}/vendor/react-icons/lib/iconContext.js.map +1 -1
- package/metadata.json +1 -1
- package/package.json +4 -4
- package/lib/vendor/.pnpm/react-icons@5.5.0_react@19.2.6/vendor/react-icons/fa6/index.cjs.map +0 -1
- package/lib/vendor/.pnpm/react-icons@5.5.0_react@19.2.6/vendor/react-icons/fa6/index.js.map +0 -1
- package/lib/vendor/.pnpm/react-icons@5.5.0_react@19.2.6/vendor/react-icons/lib/iconBase.cjs.map +0 -1
- package/lib/vendor/.pnpm/react-icons@5.5.0_react@19.2.6/vendor/react-icons/lib/iconBase.js.map +0 -1
- /package/lib/vendor/.pnpm/{react-icons@5.5.0_react@19.2.6 → react-icons@5.6.0_react@19.2.6}/vendor/react-icons/lib/iconContext.cjs +0 -0
- /package/lib/vendor/.pnpm/{react-icons@5.5.0_react@19.2.6 → react-icons@5.6.0_react@19.2.6}/vendor/react-icons/lib/iconContext.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabItem.js","sources":["../../../src/components/TabBar/TabItem.tsx"],"sourcesContent":["import {\n type ComponentProps,\n type FC,\n type MouseEvent,\n type PropsWithChildren,\n type ReactNode,\n memo,\n useCallback,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { UnstyledButton } from '../Button'\nimport { FaCircleInfoIcon } from '../Icon'\nimport { Tooltip } from '../Tooltip'\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-TabItem',\n 'shr-group/tabitem',\n 'shr-relative shr-inline-flex shr-items-center shr-gap-0.5 shr-px-1 shr-py-0.75',\n 'hover:shr-bg-white-darken',\n 'focus-visible:shr-focus-indicator focus-visible:shr-z-1',\n 'disabled:shr-cursor-not-allowed disabled:shr-bg-transparent',\n 'aria-selected:before:shr-absolute aria-selected:before:shr-inset-x-0 aria-selected:before:shr-bottom-0 aria-selected:before:shr-z-1 aria-selected:before:shr-block aria-selected:before:shr-h-0.25 aria-selected:before:shr-bg-main aria-selected:before:shr-content-[\"\"]',\n 'forced-colors:aria-selected:before:shr-bg-[Highlight]',\n ],\n label: [\n 'shr-font-bold shr-leading-none shr-text-grey',\n 'group-hover/tabitem:shr-text-black',\n 'group-disabled/tabitem:shr-text-grey/50',\n 'group-aria-selected/tabitem:shr-text-black',\n ],\n suffixWrapper: [\n // Badge など内包要素に依って高さが変わらないようにするため、ネガティブマージンを指定\n '-shr-my-0.25',\n // 内包アイコンの leading を詰める\n '[&_.smarthr-ui-Icon]:shr-block',\n ],\n },\n})\n\ntype AbstractProps = PropsWithChildren<{\n /** タブの ID */\n id: string\n /** ボタン内の末尾に表示する内容 */\n suffix?: ReactNode\n /** `true` のとき、タブが選択状態のスタイルになる */\n selected?: boolean\n /** `true` のとき、タブを無効状態にしてクリック不能にする */\n disabled?: boolean\n /**\n * 無効な理由\n */\n disabledReason?: {\n icon?: ReactNode\n message: ReactNode\n }\n /** タブをクリックした時に発火するコールバック関数 */\n onClick: (tabId: string) => void\n}>\ntype Props = AbstractProps &\n Omit<ComponentProps<typeof UnstyledButton>, keyof AbstractProps | 'aria-selected' | 'type'>\n\nexport const TabItem: FC<Props> = ({ selected = false, disabled, disabledReason, ...rest }) => {\n const tabAttrs = {\n role: 'tab',\n 'aria-selected': selected,\n }\n\n if (disabled && disabledReason) {\n const Icon = disabledReason.icon || <FaCircleInfoIcon color=\"TEXT_GREY\" />\n\n return (\n <Tooltip\n {...tabAttrs}\n message={disabledReason.message}\n
|
|
1
|
+
{"version":3,"file":"TabItem.js","sources":["../../../src/components/TabBar/TabItem.tsx"],"sourcesContent":["import {\n type ComponentProps,\n type FC,\n type MouseEvent,\n type PropsWithChildren,\n type ReactNode,\n memo,\n useCallback,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { UnstyledButton } from '../Button'\nimport { FaCircleInfoIcon } from '../Icon'\nimport { Tooltip } from '../Tooltip'\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-TabItem',\n 'shr-group/tabitem',\n 'shr-relative shr-inline-flex shr-items-center shr-gap-0.5 shr-px-1 shr-py-0.75',\n 'hover:shr-bg-white-darken',\n 'focus-visible:shr-focus-indicator focus-visible:shr-z-1',\n 'disabled:shr-cursor-not-allowed disabled:shr-bg-transparent',\n 'aria-selected:before:shr-absolute aria-selected:before:shr-inset-x-0 aria-selected:before:shr-bottom-0 aria-selected:before:shr-z-1 aria-selected:before:shr-block aria-selected:before:shr-h-0.25 aria-selected:before:shr-bg-main aria-selected:before:shr-content-[\"\"]',\n 'forced-colors:aria-selected:before:shr-bg-[Highlight]',\n ],\n label: [\n 'shr-font-bold shr-leading-none shr-text-grey',\n 'group-hover/tabitem:shr-text-black',\n 'group-disabled/tabitem:shr-text-grey/50',\n 'group-aria-selected/tabitem:shr-text-black',\n ],\n suffixWrapper: [\n // Badge など内包要素に依って高さが変わらないようにするため、ネガティブマージンを指定\n '-shr-my-0.25',\n // 内包アイコンの leading を詰める\n '[&_.smarthr-ui-Icon]:shr-block',\n ],\n },\n})\n\ntype AbstractProps = PropsWithChildren<{\n /** タブの ID */\n id: string\n /** ボタン内の末尾に表示する内容 */\n suffix?: ReactNode\n /** `true` のとき、タブが選択状態のスタイルになる */\n selected?: boolean\n /** `true` のとき、タブを無効状態にしてクリック不能にする */\n disabled?: boolean\n /**\n * 無効な理由\n */\n disabledReason?: {\n icon?: ReactNode\n message: ReactNode\n }\n /** タブをクリックした時に発火するコールバック関数 */\n onClick: (tabId: string) => void\n}>\ntype Props = AbstractProps &\n Omit<ComponentProps<typeof UnstyledButton>, keyof AbstractProps | 'aria-selected' | 'type'>\n\nexport const TabItem: FC<Props> = ({ selected = false, disabled, disabledReason, ...rest }) => {\n const tabAttrs = {\n role: 'tab',\n 'aria-selected': selected,\n }\n\n if (disabled && disabledReason) {\n const Icon = disabledReason.icon || <FaCircleInfoIcon color=\"TEXT_GREY\" />\n\n return (\n <Tooltip\n {...tabAttrs}\n message={disabledReason.message}\n aria-disabled={disabled}\n className=\"focus-visible:shr-focus-indicator\"\n >\n <TabButton {...rest} disabled={disabled} suffix={Icon} />\n </Tooltip>\n )\n }\n\n return <TabButton {...rest} {...tabAttrs} disabled={disabled} />\n}\n\nconst TabButton: FC<Props> = ({ id, children, suffix, onClick, className, ...rest }) => {\n const classNames = useMemo(() => {\n const { wrapper, label, suffixWrapper } = classNameGenerator()\n\n return {\n wrapper: wrapper({ className }),\n label: label(),\n suffixWrapper: suffixWrapper(),\n }\n }, [className])\n\n const actualOnClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => onClick(e.currentTarget.value),\n [onClick],\n )\n\n return (\n <UnstyledButton\n {...rest}\n type=\"button\"\n value={id}\n id={id}\n className={classNames.wrapper}\n onClick={actualOnClick}\n >\n <TabLabel className={classNames.label}>{children}</TabLabel>\n <TabButtonSuffix className={classNames.suffixWrapper}>{suffix}</TabButtonSuffix>\n </UnstyledButton>\n )\n}\n\nconst TabLabel = memo<PropsWithChildren<{ className: string }>>(({ children, className }) => (\n <span className={className}>{children}</span>\n))\nconst TabButtonSuffix = memo<PropsWithChildren<{ className: string }>>(\n ({ children, className }) => children && <span className={className}>{children}</span>,\n)\n"],"names":["tv","_jsx","_jsxs"],"mappings":"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"}
|
|
@@ -31,16 +31,26 @@ const classNameGenerator = index.tv({
|
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
});
|
|
34
|
-
const Tooltip = ({ message, children, triggerType, ellipsisOnly, tabIndex
|
|
34
|
+
const Tooltip = ({ message, children, type = 'description', triggerType, ellipsisOnly, tabIndex, ariaDescribedbyTarget = 'wrapper', className, onPointerEnter, onPointerLeave, onTouchStart, onTouchEnd, onFocus, onBlur, ...rest }) => {
|
|
35
35
|
const [portalRoot, setPortalRoot] = React.useState(null);
|
|
36
36
|
const [isVisible, setIsVisible] = React.useState(false);
|
|
37
37
|
const [rect, setRect] = React.useState(null);
|
|
38
38
|
const ref = React.useRef(null);
|
|
39
39
|
const messageId = React.useId();
|
|
40
40
|
const fullscreenElement = React.useSyncExternalStore(subscribeFullscreenChange, getFullscreenElement, getFullscreenElementOnSSR);
|
|
41
|
+
const [isFocusableChild, setIsFocusableChild] = React.useState(false);
|
|
42
|
+
const [actualTabIndex, setActualTabIndex] = React.useState(tabIndex ?? 0);
|
|
41
43
|
hooks_useEnhancedEffect.useEnhancedEffect(() => {
|
|
42
44
|
setPortalRoot(fullscreenElement ?? document.body);
|
|
43
45
|
}, [fullscreenElement]);
|
|
46
|
+
hooks_useEnhancedEffect.useEnhancedEffect(() => {
|
|
47
|
+
const childElement = ref.current?.querySelector(':scope > :not(.smarthr-ui-VisuallyHiddenText)');
|
|
48
|
+
const focusable = !!childElement &&
|
|
49
|
+
childElement.matches('a[href], button, input, select, textarea, [tabindex]') &&
|
|
50
|
+
!childElement.matches('[tabindex="-1"]');
|
|
51
|
+
setIsFocusableChild(focusable);
|
|
52
|
+
setActualTabIndex(tabIndex !== undefined ? tabIndex : focusable ? undefined : 0);
|
|
53
|
+
}, [tabIndex]);
|
|
44
54
|
const toShowAction = React.useCallback((e) => {
|
|
45
55
|
// Tooltipのtriggerの他の要素(Dropwdown menu buttonで開いたmenu contentとか)に移動されたらtooltipを表示しない
|
|
46
56
|
if (!ref.current?.contains(e.target)) {
|
|
@@ -96,13 +106,17 @@ const Tooltip = ({ message, children, triggerType, ellipsisOnly, tabIndex = 0, a
|
|
|
96
106
|
: toCloseAction, [onBlur, toCloseAction]);
|
|
97
107
|
const isIcon = triggerType === 'icon';
|
|
98
108
|
const actualClassName = React.useMemo(() => classNameGenerator({ isIcon, className }), [isIcon, className]);
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
const isLabel = type === 'label';
|
|
110
|
+
const isInnerTarget = isLabel || isFocusableChild || ariaDescribedbyTarget === 'inner';
|
|
111
|
+
const childrenWithProps = React.useMemo(() => isLabel
|
|
112
|
+
? React.cloneElement(children, { 'aria-labelledby': messageId })
|
|
113
|
+
: isInnerTarget
|
|
114
|
+
? React.cloneElement(children, { 'aria-describedby': messageId })
|
|
115
|
+
: children, [children, isLabel, isInnerTarget, messageId]);
|
|
116
|
+
const actualWrapperAriaDescribedby = React.useMemo(() => (!isInnerTarget ? messageId : undefined), [isInnerTarget, messageId]);
|
|
103
117
|
return (
|
|
104
118
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
105
|
-
jsxRuntime.jsxs("span", { ...rest, ref: ref, tabIndex:
|
|
119
|
+
jsxRuntime.jsxs("span", { ...rest, ref: ref, tabIndex: actualTabIndex, "aria-describedby": actualWrapperAriaDescribedby, onPointerEnter: onDelegatePointerEnter, onTouchStart: onDelegateTouchStart, onFocus: onDelegateFocus, onPointerLeave: onDelegatePointerLeave, onTouchEnd: onDelegateTouchEnd, onBlur: onDelegateBlur, className: actualClassName, children: [portalRoot &&
|
|
106
120
|
ReactDOM.createPortal(jsxRuntime.jsx(components_Tooltip_TooltipPortal.TooltipPortal, { message: message, isVisible: isVisible, parentRect: rect, isIcon: isIcon }), portalRoot), childrenWithProps, jsxRuntime.jsx(MemoizedVisuallyHiddenText, { id: messageId, visible: isVisible, children: message })] }));
|
|
107
121
|
};
|
|
108
122
|
const MemoizedVisuallyHiddenText = React.memo(({ id, visible, children }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.cjs","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["'use client'\n\nimport {\n type BaseSyntheticEvent,\n type ComponentProps,\n type FC,\n type FocusEvent,\n type PointerEvent,\n type PropsWithChildren,\n type ReactElement,\n type ReactNode,\n type TouchEvent,\n cloneElement,\n memo,\n useCallback,\n useId,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useEnhancedEffect } from '../../hooks/useEnhancedEffect'\nimport { VisuallyHiddenText } from '../VisuallyHiddenText'\n\nimport { TooltipPortal } from './TooltipPortal'\n\nconst subscribeFullscreenChange = (callback: () => void) => {\n window.addEventListener('fullscreenchange', callback)\n\n return () => {\n window.removeEventListener('fullscreenchange', callback)\n }\n}\nconst getFullscreenElement = () => document.fullscreenElement\nconst getFullscreenElementOnSSR = () => null\n\ntype AbstractProps = PropsWithChildren<{\n /** ツールチップ内に表示するメッセージ */\n message: ReactNode\n /** ツールチップを表示する対象のタイプ。アイコンの場合は `icon` を指定する */\n triggerType?: 'icon' | 'text'\n /** `true` のとき、ツールチップを表示する対象が省略されている場合のみツールチップ表示を有効にする */\n ellipsisOnly?: boolean\n /** ツールチップを表示する対象の tabIndex 値 */\n tabIndex?: number\n /**
|
|
1
|
+
{"version":3,"file":"Tooltip.cjs","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["'use client'\n\nimport {\n type BaseSyntheticEvent,\n type ComponentProps,\n type FC,\n type FocusEvent,\n type PointerEvent,\n type PropsWithChildren,\n type ReactElement,\n type ReactNode,\n type TouchEvent,\n cloneElement,\n memo,\n useCallback,\n useId,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useEnhancedEffect } from '../../hooks/useEnhancedEffect'\nimport { VisuallyHiddenText } from '../VisuallyHiddenText'\n\nimport { TooltipPortal } from './TooltipPortal'\n\nconst subscribeFullscreenChange = (callback: () => void) => {\n window.addEventListener('fullscreenchange', callback)\n\n return () => {\n window.removeEventListener('fullscreenchange', callback)\n }\n}\nconst getFullscreenElement = () => document.fullscreenElement\nconst getFullscreenElementOnSSR = () => null\n\ntype AbstractProps = PropsWithChildren<{\n /** ツールチップ内に表示するメッセージ */\n message: ReactNode\n /** ツールチップの種類。`label` の場合は children の要素に `aria-labelledby` を付与しアクセシブルネームとして機能する。`description`(デフォルト)の場合は `aria-describedby` を付与し補足説明として機能する */\n type?: 'label' | 'description'\n /** ツールチップを表示する対象のタイプ。アイコンの場合は `icon` を指定する */\n triggerType?: 'icon' | 'text'\n /** `true` のとき、ツールチップを表示する対象が省略されている場合のみツールチップ表示を有効にする */\n ellipsisOnly?: boolean\n /** ツールチップを表示する対象の tabIndex 値 */\n tabIndex?: number\n /** `type` が `description` の場合に `aria-describedby` を付与する対象。children が focusable な場合は常に children に付与されるため無視される */\n ariaDescribedbyTarget?: 'wrapper' | 'inner'\n}>\ntype Props = AbstractProps &\n Omit<ComponentProps<'span'>, keyof AbstractProps | 'aria-describedby' | 'aria-labelledby'>\n\nconst classNameGenerator = tv({\n base: [\n 'smarthr-ui-Tooltip',\n 'shr-relative',\n 'shr-inline-block shr-max-w-full shr-align-bottom',\n 'focus-visible:shr-focus-indicator--outer',\n ],\n variants: {\n isIcon: {\n true: 'shr-leading-[0]',\n },\n },\n})\n\nexport const Tooltip: FC<Props> = ({\n message,\n children,\n type = 'description',\n triggerType,\n ellipsisOnly,\n tabIndex,\n ariaDescribedbyTarget = 'wrapper',\n className,\n onPointerEnter,\n onPointerLeave,\n onTouchStart,\n onTouchEnd,\n onFocus,\n onBlur,\n ...rest\n}) => {\n const [portalRoot, setPortalRoot] = useState<Element | null>(null)\n const [isVisible, setIsVisible] = useState(false)\n const [rect, setRect] = useState<DOMRect | null>(null)\n const ref = useRef<HTMLDivElement>(null)\n const messageId = useId()\n const fullscreenElement = useSyncExternalStore(\n subscribeFullscreenChange,\n getFullscreenElement,\n getFullscreenElementOnSSR,\n )\n\n const [isFocusableChild, setIsFocusableChild] = useState(false)\n const [actualTabIndex, setActualTabIndex] = useState<number | undefined>(tabIndex ?? 0)\n\n useEnhancedEffect(() => {\n setPortalRoot(fullscreenElement ?? document.body)\n }, [fullscreenElement])\n\n useEnhancedEffect(() => {\n const childElement = ref.current?.querySelector<HTMLElement>(\n ':scope > :not(.smarthr-ui-VisuallyHiddenText)',\n )\n\n const focusable =\n !!childElement &&\n childElement.matches('a[href], button, input, select, textarea, [tabindex]') &&\n !childElement.matches('[tabindex=\"-1\"]')\n\n setIsFocusableChild(focusable)\n setActualTabIndex(tabIndex !== undefined ? tabIndex : focusable ? undefined : 0)\n }, [tabIndex])\n\n const toShowAction = useCallback(\n (e: BaseSyntheticEvent) => {\n // Tooltipのtriggerの他の要素(Dropwdown menu buttonで開いたmenu contentとか)に移動されたらtooltipを表示しない\n if (!ref.current?.contains(e.target)) {\n return\n }\n\n if (ellipsisOnly) {\n const outerWidth = parseInt(\n window\n .getComputedStyle(ref.current.parentNode! as HTMLElement, null)\n .width.match(/\\d+/)![0],\n 10,\n )\n\n if (outerWidth < 0 || outerWidth > ref.current.clientWidth) {\n return\n }\n }\n\n setRect(ref.current.getBoundingClientRect())\n setIsVisible(true)\n },\n [ellipsisOnly],\n )\n const onDelegatePointerEnter = useMemo(\n () =>\n onPointerEnter\n ? (e: PointerEvent<HTMLSpanElement>) => {\n onPointerEnter(e)\n toShowAction(e)\n }\n : toShowAction,\n [onPointerEnter, toShowAction],\n )\n const onDelegateTouchStart = useMemo(\n () =>\n onTouchStart\n ? (e: TouchEvent<HTMLSpanElement>) => {\n onTouchStart(e)\n toShowAction(e)\n }\n : toShowAction,\n [onTouchStart, toShowAction],\n )\n const onDelegateFocus = useMemo(\n () =>\n onFocus\n ? (e: FocusEvent<HTMLSpanElement>) => {\n onFocus(e)\n toShowAction(e)\n }\n : toShowAction,\n [onFocus, toShowAction],\n )\n\n const toCloseAction = useCallback(() => setIsVisible(false), [])\n const onDelegatePointerLeave = useMemo(\n () =>\n onPointerLeave\n ? (e: PointerEvent<HTMLSpanElement>) => {\n onPointerLeave(e)\n toCloseAction()\n }\n : toCloseAction,\n [onPointerLeave, toCloseAction],\n )\n const onDelegateTouchEnd = useMemo(\n () =>\n onTouchEnd\n ? (e: TouchEvent<HTMLSpanElement>) => {\n onTouchEnd(e)\n toCloseAction()\n }\n : toCloseAction,\n [onTouchEnd, toCloseAction],\n )\n const onDelegateBlur = useMemo(\n () =>\n onBlur\n ? (e: FocusEvent<HTMLSpanElement>) => {\n onBlur(e)\n toCloseAction()\n }\n : toCloseAction,\n [onBlur, toCloseAction],\n )\n\n const isIcon = triggerType === 'icon'\n const actualClassName = useMemo(\n () => classNameGenerator({ isIcon, className }),\n [isIcon, className],\n )\n const isLabel = type === 'label'\n const isInnerTarget = isLabel || isFocusableChild || ariaDescribedbyTarget === 'inner'\n const childrenWithProps = useMemo(\n () =>\n isLabel\n ? cloneElement(children as ReactElement, { 'aria-labelledby': messageId })\n : isInnerTarget\n ? cloneElement(children as ReactElement, { 'aria-describedby': messageId })\n : children,\n [children, isLabel, isInnerTarget, messageId],\n )\n const actualWrapperAriaDescribedby = useMemo(\n () => (!isInnerTarget ? messageId : undefined),\n [isInnerTarget, messageId],\n )\n\n return (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <span\n {...rest}\n ref={ref}\n tabIndex={actualTabIndex}\n aria-describedby={actualWrapperAriaDescribedby}\n onPointerEnter={onDelegatePointerEnter}\n onTouchStart={onDelegateTouchStart}\n onFocus={onDelegateFocus}\n onPointerLeave={onDelegatePointerLeave}\n onTouchEnd={onDelegateTouchEnd}\n onBlur={onDelegateBlur}\n className={actualClassName}\n >\n {portalRoot &&\n createPortal(\n <TooltipPortal\n message={message}\n isVisible={isVisible}\n parentRect={rect}\n isIcon={isIcon}\n />,\n portalRoot,\n )}\n {childrenWithProps}\n <MemoizedVisuallyHiddenText id={messageId} visible={isVisible}>\n {message}\n </MemoizedVisuallyHiddenText>\n </span>\n )\n}\n\nconst MemoizedVisuallyHiddenText = memo<PropsWithChildren<{ id: string; visible: boolean }>>(\n ({ id, visible, children }) => {\n const hiddenText = useMemo(() => innerText(children), [children])\n\n return (\n <VisuallyHiddenText id={id} aria-hidden={!visible}>\n {hiddenText}\n </VisuallyHiddenText>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;;;;AA8BA;AACE;AAEA;AACE;AACF;AACF;AACA;AACA;AAmBA;AACE;;;;;AAKC;AACD;AACE;AACE;AACD;AACF;AACF;AAEM;;;;AAoBL;AACA;;;AAQA;;AAGE;AACF;;;AAOE;AAEE;AACA;;;AAIJ;AAEA;;AAGI;;;;AAKE;;;AAOA;;;;;;AAOJ;AAGF;AAGM;;;;;AAON;AAGM;;;;;AAON;AAGM;;;;;AAQN;AACA;AAGM;;AAEI;;;AAKV;AAGM;;AAEI;;;AAKV;AAGM;;AAEI;;;AAMV;;AAKA;;AAEA;;AAIM;;AAEE;;;;AAUN;AAcI;AAeR;AAEA;AAEI;AAEA;AAKF;;"}
|
|
@@ -2,15 +2,17 @@ import { type ComponentProps, type FC, type PropsWithChildren, type ReactNode }
|
|
|
2
2
|
type AbstractProps = PropsWithChildren<{
|
|
3
3
|
/** ツールチップ内に表示するメッセージ */
|
|
4
4
|
message: ReactNode;
|
|
5
|
+
/** ツールチップの種類。`label` の場合は children の要素に `aria-labelledby` を付与しアクセシブルネームとして機能する。`description`(デフォルト)の場合は `aria-describedby` を付与し補足説明として機能する */
|
|
6
|
+
type?: 'label' | 'description';
|
|
5
7
|
/** ツールチップを表示する対象のタイプ。アイコンの場合は `icon` を指定する */
|
|
6
8
|
triggerType?: 'icon' | 'text';
|
|
7
9
|
/** `true` のとき、ツールチップを表示する対象が省略されている場合のみツールチップ表示を有効にする */
|
|
8
10
|
ellipsisOnly?: boolean;
|
|
9
11
|
/** ツールチップを表示する対象の tabIndex 値 */
|
|
10
12
|
tabIndex?: number;
|
|
11
|
-
/**
|
|
13
|
+
/** `type` が `description` の場合に `aria-describedby` を付与する対象。children が focusable な場合は常に children に付与されるため無視される */
|
|
12
14
|
ariaDescribedbyTarget?: 'wrapper' | 'inner';
|
|
13
15
|
}>;
|
|
14
|
-
type Props = AbstractProps & Omit<ComponentProps<'span'>, keyof AbstractProps | 'aria-describedby'>;
|
|
16
|
+
type Props = AbstractProps & Omit<ComponentProps<'span'>, keyof AbstractProps | 'aria-describedby' | 'aria-labelledby'>;
|
|
15
17
|
export declare const Tooltip: FC<Props>;
|
|
16
18
|
export {};
|
|
@@ -29,16 +29,26 @@ const classNameGenerator = ce({
|
|
|
29
29
|
},
|
|
30
30
|
},
|
|
31
31
|
});
|
|
32
|
-
const Tooltip = ({ message, children, triggerType, ellipsisOnly, tabIndex
|
|
32
|
+
const Tooltip = ({ message, children, type = 'description', triggerType, ellipsisOnly, tabIndex, ariaDescribedbyTarget = 'wrapper', className, onPointerEnter, onPointerLeave, onTouchStart, onTouchEnd, onFocus, onBlur, ...rest }) => {
|
|
33
33
|
const [portalRoot, setPortalRoot] = useState(null);
|
|
34
34
|
const [isVisible, setIsVisible] = useState(false);
|
|
35
35
|
const [rect, setRect] = useState(null);
|
|
36
36
|
const ref = useRef(null);
|
|
37
37
|
const messageId = useId();
|
|
38
38
|
const fullscreenElement = useSyncExternalStore(subscribeFullscreenChange, getFullscreenElement, getFullscreenElementOnSSR);
|
|
39
|
+
const [isFocusableChild, setIsFocusableChild] = useState(false);
|
|
40
|
+
const [actualTabIndex, setActualTabIndex] = useState(tabIndex ?? 0);
|
|
39
41
|
useEnhancedEffect(() => {
|
|
40
42
|
setPortalRoot(fullscreenElement ?? document.body);
|
|
41
43
|
}, [fullscreenElement]);
|
|
44
|
+
useEnhancedEffect(() => {
|
|
45
|
+
const childElement = ref.current?.querySelector(':scope > :not(.smarthr-ui-VisuallyHiddenText)');
|
|
46
|
+
const focusable = !!childElement &&
|
|
47
|
+
childElement.matches('a[href], button, input, select, textarea, [tabindex]') &&
|
|
48
|
+
!childElement.matches('[tabindex="-1"]');
|
|
49
|
+
setIsFocusableChild(focusable);
|
|
50
|
+
setActualTabIndex(tabIndex !== undefined ? tabIndex : focusable ? undefined : 0);
|
|
51
|
+
}, [tabIndex]);
|
|
42
52
|
const toShowAction = useCallback((e) => {
|
|
43
53
|
// Tooltipのtriggerの他の要素(Dropwdown menu buttonで開いたmenu contentとか)に移動されたらtooltipを表示しない
|
|
44
54
|
if (!ref.current?.contains(e.target)) {
|
|
@@ -94,13 +104,17 @@ const Tooltip = ({ message, children, triggerType, ellipsisOnly, tabIndex = 0, a
|
|
|
94
104
|
: toCloseAction, [onBlur, toCloseAction]);
|
|
95
105
|
const isIcon = triggerType === 'icon';
|
|
96
106
|
const actualClassName = useMemo(() => classNameGenerator({ isIcon, className }), [isIcon, className]);
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
const isLabel = type === 'label';
|
|
108
|
+
const isInnerTarget = isLabel || isFocusableChild || ariaDescribedbyTarget === 'inner';
|
|
109
|
+
const childrenWithProps = useMemo(() => isLabel
|
|
110
|
+
? cloneElement(children, { 'aria-labelledby': messageId })
|
|
111
|
+
: isInnerTarget
|
|
112
|
+
? cloneElement(children, { 'aria-describedby': messageId })
|
|
113
|
+
: children, [children, isLabel, isInnerTarget, messageId]);
|
|
114
|
+
const actualWrapperAriaDescribedby = useMemo(() => (!isInnerTarget ? messageId : undefined), [isInnerTarget, messageId]);
|
|
101
115
|
return (
|
|
102
116
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
103
|
-
jsxs("span", { ...rest, ref: ref, tabIndex:
|
|
117
|
+
jsxs("span", { ...rest, ref: ref, tabIndex: actualTabIndex, "aria-describedby": actualWrapperAriaDescribedby, onPointerEnter: onDelegatePointerEnter, onTouchStart: onDelegateTouchStart, onFocus: onDelegateFocus, onPointerLeave: onDelegatePointerLeave, onTouchEnd: onDelegateTouchEnd, onBlur: onDelegateBlur, className: actualClassName, children: [portalRoot &&
|
|
104
118
|
createPortal(jsx(TooltipPortal, { message: message, isVisible: isVisible, parentRect: rect, isIcon: isIcon }), portalRoot), childrenWithProps, jsx(MemoizedVisuallyHiddenText, { id: messageId, visible: isVisible, children: message })] }));
|
|
105
119
|
};
|
|
106
120
|
const MemoizedVisuallyHiddenText = memo(({ id, visible, children }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.js","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["'use client'\n\nimport {\n type BaseSyntheticEvent,\n type ComponentProps,\n type FC,\n type FocusEvent,\n type PointerEvent,\n type PropsWithChildren,\n type ReactElement,\n type ReactNode,\n type TouchEvent,\n cloneElement,\n memo,\n useCallback,\n useId,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useEnhancedEffect } from '../../hooks/useEnhancedEffect'\nimport { VisuallyHiddenText } from '../VisuallyHiddenText'\n\nimport { TooltipPortal } from './TooltipPortal'\n\nconst subscribeFullscreenChange = (callback: () => void) => {\n window.addEventListener('fullscreenchange', callback)\n\n return () => {\n window.removeEventListener('fullscreenchange', callback)\n }\n}\nconst getFullscreenElement = () => document.fullscreenElement\nconst getFullscreenElementOnSSR = () => null\n\ntype AbstractProps = PropsWithChildren<{\n /** ツールチップ内に表示するメッセージ */\n message: ReactNode\n /** ツールチップを表示する対象のタイプ。アイコンの場合は `icon` を指定する */\n triggerType?: 'icon' | 'text'\n /** `true` のとき、ツールチップを表示する対象が省略されている場合のみツールチップ表示を有効にする */\n ellipsisOnly?: boolean\n /** ツールチップを表示する対象の tabIndex 値 */\n tabIndex?: number\n /**
|
|
1
|
+
{"version":3,"file":"Tooltip.js","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["'use client'\n\nimport {\n type BaseSyntheticEvent,\n type ComponentProps,\n type FC,\n type FocusEvent,\n type PointerEvent,\n type PropsWithChildren,\n type ReactElement,\n type ReactNode,\n type TouchEvent,\n cloneElement,\n memo,\n useCallback,\n useId,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useEnhancedEffect } from '../../hooks/useEnhancedEffect'\nimport { VisuallyHiddenText } from '../VisuallyHiddenText'\n\nimport { TooltipPortal } from './TooltipPortal'\n\nconst subscribeFullscreenChange = (callback: () => void) => {\n window.addEventListener('fullscreenchange', callback)\n\n return () => {\n window.removeEventListener('fullscreenchange', callback)\n }\n}\nconst getFullscreenElement = () => document.fullscreenElement\nconst getFullscreenElementOnSSR = () => null\n\ntype AbstractProps = PropsWithChildren<{\n /** ツールチップ内に表示するメッセージ */\n message: ReactNode\n /** ツールチップの種類。`label` の場合は children の要素に `aria-labelledby` を付与しアクセシブルネームとして機能する。`description`(デフォルト)の場合は `aria-describedby` を付与し補足説明として機能する */\n type?: 'label' | 'description'\n /** ツールチップを表示する対象のタイプ。アイコンの場合は `icon` を指定する */\n triggerType?: 'icon' | 'text'\n /** `true` のとき、ツールチップを表示する対象が省略されている場合のみツールチップ表示を有効にする */\n ellipsisOnly?: boolean\n /** ツールチップを表示する対象の tabIndex 値 */\n tabIndex?: number\n /** `type` が `description` の場合に `aria-describedby` を付与する対象。children が focusable な場合は常に children に付与されるため無視される */\n ariaDescribedbyTarget?: 'wrapper' | 'inner'\n}>\ntype Props = AbstractProps &\n Omit<ComponentProps<'span'>, keyof AbstractProps | 'aria-describedby' | 'aria-labelledby'>\n\nconst classNameGenerator = tv({\n base: [\n 'smarthr-ui-Tooltip',\n 'shr-relative',\n 'shr-inline-block shr-max-w-full shr-align-bottom',\n 'focus-visible:shr-focus-indicator--outer',\n ],\n variants: {\n isIcon: {\n true: 'shr-leading-[0]',\n },\n },\n})\n\nexport const Tooltip: FC<Props> = ({\n message,\n children,\n type = 'description',\n triggerType,\n ellipsisOnly,\n tabIndex,\n ariaDescribedbyTarget = 'wrapper',\n className,\n onPointerEnter,\n onPointerLeave,\n onTouchStart,\n onTouchEnd,\n onFocus,\n onBlur,\n ...rest\n}) => {\n const [portalRoot, setPortalRoot] = useState<Element | null>(null)\n const [isVisible, setIsVisible] = useState(false)\n const [rect, setRect] = useState<DOMRect | null>(null)\n const ref = useRef<HTMLDivElement>(null)\n const messageId = useId()\n const fullscreenElement = useSyncExternalStore(\n subscribeFullscreenChange,\n getFullscreenElement,\n getFullscreenElementOnSSR,\n )\n\n const [isFocusableChild, setIsFocusableChild] = useState(false)\n const [actualTabIndex, setActualTabIndex] = useState<number | undefined>(tabIndex ?? 0)\n\n useEnhancedEffect(() => {\n setPortalRoot(fullscreenElement ?? document.body)\n }, [fullscreenElement])\n\n useEnhancedEffect(() => {\n const childElement = ref.current?.querySelector<HTMLElement>(\n ':scope > :not(.smarthr-ui-VisuallyHiddenText)',\n )\n\n const focusable =\n !!childElement &&\n childElement.matches('a[href], button, input, select, textarea, [tabindex]') &&\n !childElement.matches('[tabindex=\"-1\"]')\n\n setIsFocusableChild(focusable)\n setActualTabIndex(tabIndex !== undefined ? tabIndex : focusable ? undefined : 0)\n }, [tabIndex])\n\n const toShowAction = useCallback(\n (e: BaseSyntheticEvent) => {\n // Tooltipのtriggerの他の要素(Dropwdown menu buttonで開いたmenu contentとか)に移動されたらtooltipを表示しない\n if (!ref.current?.contains(e.target)) {\n return\n }\n\n if (ellipsisOnly) {\n const outerWidth = parseInt(\n window\n .getComputedStyle(ref.current.parentNode! as HTMLElement, null)\n .width.match(/\\d+/)![0],\n 10,\n )\n\n if (outerWidth < 0 || outerWidth > ref.current.clientWidth) {\n return\n }\n }\n\n setRect(ref.current.getBoundingClientRect())\n setIsVisible(true)\n },\n [ellipsisOnly],\n )\n const onDelegatePointerEnter = useMemo(\n () =>\n onPointerEnter\n ? (e: PointerEvent<HTMLSpanElement>) => {\n onPointerEnter(e)\n toShowAction(e)\n }\n : toShowAction,\n [onPointerEnter, toShowAction],\n )\n const onDelegateTouchStart = useMemo(\n () =>\n onTouchStart\n ? (e: TouchEvent<HTMLSpanElement>) => {\n onTouchStart(e)\n toShowAction(e)\n }\n : toShowAction,\n [onTouchStart, toShowAction],\n )\n const onDelegateFocus = useMemo(\n () =>\n onFocus\n ? (e: FocusEvent<HTMLSpanElement>) => {\n onFocus(e)\n toShowAction(e)\n }\n : toShowAction,\n [onFocus, toShowAction],\n )\n\n const toCloseAction = useCallback(() => setIsVisible(false), [])\n const onDelegatePointerLeave = useMemo(\n () =>\n onPointerLeave\n ? (e: PointerEvent<HTMLSpanElement>) => {\n onPointerLeave(e)\n toCloseAction()\n }\n : toCloseAction,\n [onPointerLeave, toCloseAction],\n )\n const onDelegateTouchEnd = useMemo(\n () =>\n onTouchEnd\n ? (e: TouchEvent<HTMLSpanElement>) => {\n onTouchEnd(e)\n toCloseAction()\n }\n : toCloseAction,\n [onTouchEnd, toCloseAction],\n )\n const onDelegateBlur = useMemo(\n () =>\n onBlur\n ? (e: FocusEvent<HTMLSpanElement>) => {\n onBlur(e)\n toCloseAction()\n }\n : toCloseAction,\n [onBlur, toCloseAction],\n )\n\n const isIcon = triggerType === 'icon'\n const actualClassName = useMemo(\n () => classNameGenerator({ isIcon, className }),\n [isIcon, className],\n )\n const isLabel = type === 'label'\n const isInnerTarget = isLabel || isFocusableChild || ariaDescribedbyTarget === 'inner'\n const childrenWithProps = useMemo(\n () =>\n isLabel\n ? cloneElement(children as ReactElement, { 'aria-labelledby': messageId })\n : isInnerTarget\n ? cloneElement(children as ReactElement, { 'aria-describedby': messageId })\n : children,\n [children, isLabel, isInnerTarget, messageId],\n )\n const actualWrapperAriaDescribedby = useMemo(\n () => (!isInnerTarget ? messageId : undefined),\n [isInnerTarget, messageId],\n )\n\n return (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <span\n {...rest}\n ref={ref}\n tabIndex={actualTabIndex}\n aria-describedby={actualWrapperAriaDescribedby}\n onPointerEnter={onDelegatePointerEnter}\n onTouchStart={onDelegateTouchStart}\n onFocus={onDelegateFocus}\n onPointerLeave={onDelegatePointerLeave}\n onTouchEnd={onDelegateTouchEnd}\n onBlur={onDelegateBlur}\n className={actualClassName}\n >\n {portalRoot &&\n createPortal(\n <TooltipPortal\n message={message}\n isVisible={isVisible}\n parentRect={rect}\n isIcon={isIcon}\n />,\n portalRoot,\n )}\n {childrenWithProps}\n <MemoizedVisuallyHiddenText id={messageId} visible={isVisible}>\n {message}\n </MemoizedVisuallyHiddenText>\n </span>\n )\n}\n\nconst MemoizedVisuallyHiddenText = memo<PropsWithChildren<{ id: string; visible: boolean }>>(\n ({ id, visible, children }) => {\n const hiddenText = useMemo(() => innerText(children), [children])\n\n return (\n <VisuallyHiddenText id={id} aria-hidden={!visible}>\n {hiddenText}\n </VisuallyHiddenText>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;;AA8BA;AACE;AAEA;AACE;AACF;AACF;AACA;AACA;AAmBA;AACE;;;;;AAKC;AACD;AACE;AACE;AACD;AACF;AACF;AAEM;;;;AAoBL;AACA;;;AAQA;;AAGE;AACF;;;AAOE;AAEE;AACA;;;AAIJ;AAEA;;AAGI;;;;AAKE;;;AAOA;;;;;;AAOJ;AAGF;AAGM;;;;;AAON;AAGM;;;;;AAON;AAGM;;;;;AAQN;AACA;AAGM;;AAEI;;;AAKV;AAGM;;AAEI;;;AAKV;AAGM;;AAEI;;;AAMV;;AAKA;;AAEA;;AAIM;;AAEE;;;;AAUN;AAcI;AAeR;AAEA;AAEI;AAEA;AAKF;;"}
|