-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: AppNaviAnchorにelementAsのpropsを追加 #4955
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,40 @@ | ||
import React, { FC, PropsWithChildren, useMemo } from 'react' | ||
import React, { | ||
ComponentPropsWithoutRef, | ||
ComponentType, | ||
ElementType, | ||
FC, | ||
PropsWithoutRef, | ||
ReactElement, | ||
Ref, | ||
forwardRef, | ||
useMemo, | ||
} from 'react' | ||
import { tv } from 'tailwind-variants' | ||
|
||
import { ElementRef, ElementRefProps } from '../../types' | ||
import { ComponentProps as IconProps } from '../Icon' | ||
|
||
import { appNaviItemStyle } from './style' | ||
|
||
export type AppNaviAnchorProps = PropsWithChildren<{ | ||
type ElementProps<T extends ElementType> = Omit< | ||
ComponentPropsWithoutRef<T>, | ||
keyof AppNaviAnchorProps<T> & ElementRefProps<T> | ||
> | ||
|
||
export type AppNaviAnchorProps<T extends ElementType = 'a'> = { | ||
/** アンカーの href */ | ||
href: string | ||
href?: string | ||
/** 表示するアイコンタイプ */ | ||
icon?: React.ComponentType<IconProps> | ||
icon?: ComponentType<IconProps> | ||
/** アクティブ状態であるかどうか */ | ||
current?: boolean | ||
}> | ||
/** next/link などのカスタムコンポーネントを指定します。指定がない場合はデフォルトで `a` タグが使用されます。 */ | ||
elementAs?: T | ||
} | ||
|
||
type AppNaviAnchorComponent = <T extends ElementType = 'a'>( | ||
props: AppNaviAnchorProps<T> & ElementProps<T> & ElementRefProps<T>, | ||
) => ReturnType<FC> | ||
|
||
const appNaviAnchor = tv({ | ||
extend: appNaviItemStyle, | ||
|
@@ -21,24 +43,39 @@ const appNaviAnchor = tv({ | |
}, | ||
}) | ||
|
||
export const AppNaviAnchor: FC<AppNaviAnchorProps> = ({ | ||
children, | ||
href, | ||
icon: Icon, | ||
current = false, | ||
}) => { | ||
const { wrapperStyle, iconStyle } = useMemo(() => { | ||
const { wrapper, icon } = appNaviAnchor({ active: current }) | ||
return { | ||
wrapperStyle: wrapper(), | ||
iconStyle: icon(), | ||
} | ||
}, [current]) | ||
|
||
return ( | ||
<a aria-current={current ? 'page' : undefined} href={href} className={wrapperStyle}> | ||
{Icon && <Icon className={iconStyle} />} | ||
{children} | ||
</a> | ||
) | ||
} | ||
export const AppNaviAnchor: AppNaviAnchorComponent = forwardRef( | ||
<T extends ElementType = 'a'>( | ||
{ | ||
children, | ||
href, | ||
icon: Icon, | ||
current = false, | ||
elementAs, | ||
...others | ||
}: PropsWithoutRef<AppNaviAnchorProps<T>> & ElementProps<T>, | ||
ref: Ref<ElementRef<T>>, | ||
): ReactElement => { | ||
Comment on lines
+46
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. next/link の Link コンポーネントは |
||
const { wrapperStyle, iconStyle } = useMemo(() => { | ||
const { wrapper, icon } = appNaviAnchor({ active: current }) | ||
return { | ||
wrapperStyle: wrapper(), | ||
iconStyle: icon(), | ||
} | ||
}, [current]) | ||
|
||
const Component = elementAs || 'a' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ネイティブ要素の場合、ここ文字列の |
||
|
||
return ( | ||
<Component | ||
{...others} | ||
ref={ref} | ||
href={href} | ||
aria-current={current ? 'page' : undefined} | ||
className={wrapperStyle} | ||
> | ||
{Icon && <Icon className={iconStyle} />} | ||
{children} | ||
</Component> | ||
) | ||
}, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
react routerだとhrefは利用しないので必須ではなくしております
buttonsをサポートしないとなればそもそも消していい
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nits] オプショナルにしちゃって良いなら、ここから削除しちゃっても
ElementProps<T>
の部分で...others
経由で href 使えますかね?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
buttonsのAppNaviAnchor判定でhref使ってるから削除できないんですよね
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
buttons を消す時に対応漏れそうなので、何らかのコードコメントを残してもらえると助かります!(buttons を消すチケットを作ってそっちに書くでも良さそう
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@uknmr
チケット起票しておきます!