-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add Tooltip component * Fix a11y issues * Fix Text component to receive ref prop * Add PropsCascader utility component * Add prepareForSlot util from @mui/base * Add exports tooltip * Update deps lock file * Fmt * Add change log
- Loading branch information
Showing
11 changed files
with
211 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@4design/for-ui": patch | ||
--- | ||
|
||
feat: Tooltipを追加 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { Children, cloneElement, FC, ForwardedRef, forwardRef, HTMLAttributes, isValidElement, ReactNode } from 'react'; | ||
|
||
type PropsCascaderProps<T extends HTMLAttributes<HTMLElement>> = T & { | ||
children: ReactNode; | ||
}; | ||
|
||
type PropsCascaderComponent = <T extends HTMLAttributes<HTMLElement>>(props: PropsCascaderProps<T>) => ReturnType<FC>; | ||
|
||
export const PropsCascader: PropsCascaderComponent = forwardRef( | ||
<T extends HTMLAttributes<HTMLElement>>( | ||
{ children, ...props }: PropsCascaderProps<T>, | ||
ref: ForwardedRef<HTMLElement>, | ||
) => { | ||
return Children.map(children, (child: ReactNode) => { | ||
if (!isValidElement(child)) { | ||
return child; | ||
} | ||
return cloneElement(child, { ...props, ...child.props, ref }); | ||
}); | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { forwardRef } from 'react'; | ||
import { MdOutlineInfo } from 'react-icons/md'; | ||
import { Meta, StoryObj } from '@storybook/react/types-6-0'; | ||
import { Tooltip, TooltipFrame, TooltipProps } from './Tooltip'; | ||
|
||
type Story = StoryObj<TooltipProps>; | ||
|
||
const TooltipIcon = forwardRef<HTMLSpanElement, object>((props, ref) => ( | ||
<span ref={ref} {...props} className="items-self-end inline-flex w-fit"> | ||
<MdOutlineInfo /> | ||
</span> | ||
)); | ||
|
||
export default { | ||
title: 'Feedback / Tooltip', | ||
component: Tooltip, | ||
} as Meta<typeof Tooltip>; | ||
|
||
export const Playground: Story = { | ||
args: { | ||
title: 'テキスト', | ||
children: <TooltipIcon />, | ||
}, | ||
}; | ||
|
||
export const FrameOnly: Story = { | ||
args: { | ||
title: 'テキスト', | ||
}, | ||
render: (props) => <TooltipFrame {...props} />, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { ComponentPropsWithRef, forwardRef } from 'react'; | ||
import { describe, expect, it } from 'vitest'; | ||
import { render, screen } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { Tooltip } from './Tooltip'; | ||
|
||
const Trigger = forwardRef<HTMLSpanElement, ComponentPropsWithRef<'span'>>((props, ref) => ( | ||
<span ref={ref} {...props} /> | ||
)); | ||
|
||
describe('Tooltip', () => { | ||
it('has rendered children', async () => { | ||
render( | ||
<Tooltip title="description"> | ||
<Trigger>trigger</Trigger> | ||
</Tooltip>, | ||
); | ||
expect(await screen.findByText('trigger')).toBeInTheDocument(); | ||
}); | ||
it('has children with accessible description', async () => { | ||
render( | ||
<Tooltip title="description"> | ||
<Trigger>trigger</Trigger> | ||
</Tooltip>, | ||
); | ||
expect(await screen.findByText('trigger')).toHaveAccessibleDescription('description'); | ||
}); | ||
it('is appeared when focusing trigger', async () => { | ||
const user = userEvent.setup(); | ||
render( | ||
<Tooltip title="description"> | ||
<Trigger>trigger</Trigger> | ||
</Tooltip>, | ||
); | ||
await user.tab(); | ||
expect(await screen.findByRole('tooltip')).toBeInTheDocument(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { ComponentPropsWithRef, FC, forwardRef, useId } from 'react'; | ||
import MuiTooltip, { TooltipProps as MuiTooltipProps } from '@mui/material/Tooltip'; | ||
import { fsx } from '../system/fsx'; | ||
import { PropsCascader } from '../system/PropsCascader'; | ||
import { Text } from '../text'; | ||
import { prepareForSlot } from '../utils/prepareForSlot'; | ||
|
||
export type TooltipProps = Pick<MuiTooltipProps, 'placement' | 'children'> & { | ||
title: string; | ||
}; | ||
|
||
export const TooltipFrame = forwardRef<HTMLSpanElement, ComponentPropsWithRef<'span'>>( | ||
({ children, ...props }, ref) => ( | ||
<Text | ||
{...props} | ||
ref={ref} | ||
size="r" | ||
weight="regular" | ||
className={fsx(`text-shade-white-default bg-shade-dark-default inline-flex rounded px-2`)} | ||
> | ||
{children} | ||
</Text> | ||
), | ||
); | ||
|
||
export const Tooltip: FC<TooltipProps> = ({ children, ...props }) => { | ||
const internalId = useId(); | ||
return ( | ||
<MuiTooltip | ||
id={internalId} | ||
slots={{ | ||
tooltip: prepareForSlot(TooltipFrame), | ||
}} | ||
slotProps={{ | ||
popper: { | ||
keepMounted: true, | ||
style: { | ||
display: undefined, | ||
}, | ||
}, | ||
tooltip: { | ||
style: { | ||
visibility: 'visible', | ||
}, | ||
}, | ||
}} | ||
{...props} | ||
> | ||
<PropsCascader tabIndex={0} aria-describedby={internalId} aria-label={undefined}> | ||
{children} | ||
</PropsCascader> | ||
</MuiTooltip> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './Tooltip'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Retrieved from https://github.com/mui/material-ui/blob/master/packages/mui-base/src/utils/prepareForSlot.tsx | ||
import * as React from 'react'; | ||
|
||
export function prepareForSlot<ComponentType extends React.ElementType>(Component: ComponentType) { | ||
type Props = React.ComponentProps<ComponentType>; | ||
|
||
return React.forwardRef<HTMLElement, Props>(function Slot(props, ref) { | ||
const { ownerState: _, ...other } = props; | ||
return React.createElement<Props>(Component, { | ||
...(other as Props), | ||
ref, | ||
}); | ||
}); | ||
} |