Update Link for react-router v6 isActive function in style/clasName props
parent
289a9e91e5
commit
6d0edba3b1
|
@ -2,7 +2,7 @@ import { hideNotification } from '@/actions/actions'
|
|||
import { useEngine, useInversionFail } from '@/components/utils/EngineContext'
|
||||
import { Message } from '@/design-system'
|
||||
import { Button } from '@/design-system/buttons'
|
||||
import { GenericButtonOrLinkProps } from '@/design-system/typography/link'
|
||||
import { GenericButtonOrNavLinkProps } from '@/design-system/typography/link'
|
||||
import { RootState } from '@/reducers/rootReducer'
|
||||
import { DottedName } from 'modele-social'
|
||||
import Engine, { RuleNode } from 'publicodes'
|
||||
|
@ -95,7 +95,7 @@ export default function Notifications() {
|
|||
)
|
||||
}
|
||||
|
||||
const HideButton = styled(Button)<GenericButtonOrLinkProps>`
|
||||
const HideButton = styled(Button)<GenericButtonOrNavLinkProps>`
|
||||
&& {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -2,7 +2,6 @@ import { Link } from '@/design-system/typography/link'
|
|||
import { DottedName } from 'modele-social'
|
||||
import { RuleLink as EngineRuleLink } from 'publicodes-react'
|
||||
import React, { useContext } from 'react'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import { EngineContext } from './utils/EngineContext'
|
||||
import { SitePathsContext } from './utils/SitePathsContext'
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Button } from '@/design-system/buttons'
|
||||
import { GenericButtonOrLinkProps } from '@/design-system/typography/link'
|
||||
import { GenericButtonOrNavLinkProps } from '@/design-system/typography/link'
|
||||
import styled from 'styled-components'
|
||||
|
||||
export const Banner = styled.div`
|
||||
|
@ -23,7 +23,7 @@ export const InnerBanner = styled.div`
|
|||
border-radius: 0.375rem;
|
||||
`
|
||||
|
||||
export const HideButton = styled(Button)<GenericButtonOrLinkProps>`
|
||||
export const HideButton = styled(Button)<GenericButtonOrNavLinkProps>`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { FocusStyle } from '@/design-system/global-style'
|
||||
import {
|
||||
GenericButtonOrLinkProps,
|
||||
GenericButtonOrNavLinkProps,
|
||||
useButtonOrLink,
|
||||
} from '@/design-system/typography/link'
|
||||
import { wrapperDebounceEvents } from '@/utils'
|
||||
|
@ -10,7 +10,7 @@ import styled, { css } from 'styled-components'
|
|||
type Size = 'XL' | 'MD' | 'XS' | 'XXS'
|
||||
type Color = 'primary' | 'secondary' | 'tertiary'
|
||||
|
||||
type ButtonProps = GenericButtonOrLinkProps & {
|
||||
type ButtonProps = GenericButtonOrNavLinkProps & {
|
||||
color?: Color
|
||||
children: React.ReactNode
|
||||
size?: Size
|
||||
|
@ -22,7 +22,6 @@ export const Button = forwardRef(function Button(
|
|||
size = 'MD',
|
||||
light = false,
|
||||
color = 'primary' as const,
|
||||
className,
|
||||
isDisabled,
|
||||
...ariaButtonProps
|
||||
}: ButtonProps,
|
||||
|
@ -36,7 +35,6 @@ export const Button = forwardRef(function Button(
|
|||
return (
|
||||
<StyledButton
|
||||
{...buttonOrLinkProps}
|
||||
className={className}
|
||||
$size={size}
|
||||
$light={light}
|
||||
$color={color}
|
||||
|
|
|
@ -2,15 +2,24 @@ import { StyledButton } from '@/design-system/buttons/Button'
|
|||
import { FocusStyle } from '@/design-system/global-style'
|
||||
import { H3, H4, HeadingUnderline } from '@/design-system/typography/heading'
|
||||
import {
|
||||
GenericButtonOrLinkProps,
|
||||
NewWindowLinkIcon,
|
||||
useButtonOrLink,
|
||||
useExternalLinkProps,
|
||||
} from '@/design-system/typography/link'
|
||||
import { Body } from '@/design-system/typography/paragraphs'
|
||||
import React, { ReactHTML, useRef } from 'react'
|
||||
import { AriaButtonProps } from '@react-types/button'
|
||||
import React, { ComponentPropsWithRef, ReactHTML, useRef } from 'react'
|
||||
import { Link as BaseLink } from 'react-router-dom'
|
||||
import styled, { css, ThemeProvider } from 'styled-components'
|
||||
|
||||
type GenericButtonOrLinkProps = (
|
||||
| AriaButtonProps<'a'>
|
||||
| (AriaButtonProps<typeof BaseLink> & ComponentPropsWithRef<typeof BaseLink>)
|
||||
| AriaButtonProps<'button'>
|
||||
) & {
|
||||
openInSameWindow?: true
|
||||
}
|
||||
|
||||
export type GenericCardProps = {
|
||||
title?: React.ReactNode
|
||||
children?: React.ReactNode
|
||||
|
|
|
@ -2,8 +2,8 @@ import { FocusStyle } from '@/design-system/global-style'
|
|||
import { useButton } from '@react-aria/button'
|
||||
import { AriaButtonProps } from '@react-types/button'
|
||||
import React, {
|
||||
ComponentProps,
|
||||
ComponentPropsWithRef,
|
||||
CSSProperties,
|
||||
ForwardedRef,
|
||||
useCallback,
|
||||
useRef,
|
||||
|
@ -59,7 +59,7 @@ export const StyledLink = styled.a<{ $isDisabled?: boolean }>`
|
|||
|
||||
export const Link = React.forwardRef<
|
||||
HTMLAnchorElement | HTMLButtonElement,
|
||||
GenericButtonOrLinkProps & {
|
||||
GenericButtonOrNavLinkProps & {
|
||||
children: React.ReactNode
|
||||
isDisabled?: boolean
|
||||
}
|
||||
|
@ -111,22 +111,56 @@ export function useExternalLinkProps({
|
|||
}
|
||||
}
|
||||
|
||||
export type GenericButtonOrLinkProps = (
|
||||
const CustomNavLink = React.forwardRef(function CustomNavLink(
|
||||
props: ComponentProps<typeof NavLink> & {
|
||||
_style?: ComponentProps<typeof NavLink>['style']
|
||||
_className?: ComponentProps<typeof NavLink>['className']
|
||||
},
|
||||
forwardedRef: ForwardedRef<HTMLAnchorElement | null>
|
||||
) {
|
||||
const navLinkProps = { ...props }
|
||||
delete navLinkProps._style
|
||||
delete navLinkProps._className
|
||||
|
||||
return (
|
||||
<NavLink
|
||||
{...navLinkProps}
|
||||
style={(...p) => ({
|
||||
...props.style,
|
||||
...(typeof props._style === 'function' && props._style(...p)),
|
||||
})}
|
||||
className={(...p) => {
|
||||
const styledClass =
|
||||
(typeof props.className === 'function'
|
||||
? props.className(...p)
|
||||
: props.className) ?? ''
|
||||
|
||||
const originalClass =
|
||||
(typeof props._className === 'function'
|
||||
? props._className(...p)
|
||||
: props._className) ?? ''
|
||||
|
||||
return styledClass + ' ' + originalClass
|
||||
}}
|
||||
ref={forwardedRef}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
export type GenericButtonOrNavLinkProps = (
|
||||
| AriaButtonProps<'a'>
|
||||
| (AriaButtonProps<typeof NavLink> & ComponentPropsWithRef<typeof NavLink>)
|
||||
| AriaButtonProps<'button'>
|
||||
) & {
|
||||
openInSameWindow?: true
|
||||
className?: string
|
||||
style?: CSSProperties
|
||||
}
|
||||
|
||||
export function useButtonOrLink(
|
||||
props: GenericButtonOrLinkProps,
|
||||
props: GenericButtonOrNavLinkProps,
|
||||
forwardedRef: ForwardedRef<HTMLAnchorElement | HTMLButtonElement | null>
|
||||
) {
|
||||
const elementType: 'a' | 'button' | typeof NavLink =
|
||||
'href' in props ? 'a' : 'to' in props ? NavLink : 'button'
|
||||
const elementType: 'a' | 'button' | typeof CustomNavLink =
|
||||
'href' in props ? 'a' : 'to' in props ? CustomNavLink : 'button'
|
||||
|
||||
const defaultRef = useRef<HTMLAnchorElement | HTMLButtonElement | null>(null)
|
||||
const { buttonProps } = useButton({ elementType, ...props }, defaultRef)
|
||||
|
@ -157,10 +191,24 @@ export function useButtonOrLink(
|
|||
)
|
||||
)
|
||||
|
||||
// resolve conflict between styled-component and NavLink style props
|
||||
const styleProps =
|
||||
'to' in props && typeof props.style === 'function'
|
||||
? { _style: props.style, style: undefined }
|
||||
: {}
|
||||
|
||||
// resolve conflict between styled-component and NavLink classname props
|
||||
const classNameProps =
|
||||
'to' in props && typeof props.className === 'function'
|
||||
? { _className: props.className, className: undefined }
|
||||
: {}
|
||||
|
||||
const buttonOrLinkProps = {
|
||||
...initialProps,
|
||||
...buttonProps,
|
||||
...useExternalLinkProps(props),
|
||||
...classNameProps,
|
||||
...styleProps,
|
||||
as: elementType,
|
||||
ref,
|
||||
}
|
||||
|
|
|
@ -8,7 +8,10 @@ import { SitePathsContext } from '@/components/utils/SitePathsContext'
|
|||
import { Item, Select } from '@/design-system/field/Select'
|
||||
import { Container, Grid } from '@/design-system/layout'
|
||||
import { H1 } from '@/design-system/typography/heading'
|
||||
import { GenericButtonOrLinkProps, Link } from '@/design-system/typography/link'
|
||||
import {
|
||||
GenericButtonOrNavLinkProps,
|
||||
Link,
|
||||
} from '@/design-system/typography/link'
|
||||
import { Body } from '@/design-system/typography/paragraphs'
|
||||
import { useFetchData } from '@/hooks/useFetchData'
|
||||
import { useContext, useMemo } from 'react'
|
||||
|
@ -156,7 +159,7 @@ const DesktopGridItem = styled(Grid).attrs({ item: true, lg: 3 })`
|
|||
}
|
||||
`
|
||||
|
||||
const SidebarLink = styled(Link)<GenericButtonOrLinkProps>`
|
||||
const SidebarLink = styled(Link)<GenericButtonOrNavLinkProps>`
|
||||
display: block;
|
||||
border-radius: 0;
|
||||
padding: 0.5rem 1rem;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useIsEmbedded } from '@/components/utils/embeddedContext'
|
||||
import { SitePathsContext } from '@/components/utils/SitePathsContext'
|
||||
import { Link } from '@/design-system/typography/link'
|
||||
import { useRelativeSitePaths } from '@/sitePaths'
|
||||
import { useContext } from 'react'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { Route, Routes } from 'react-router-dom'
|
||||
|
@ -12,19 +13,21 @@ import { StoreProvider } from './StoreContext'
|
|||
import VotreSituation from './VotreSituation'
|
||||
|
||||
export default function ÉconomieCollaborative() {
|
||||
const relativeSitePaths = useRelativeSitePaths()
|
||||
const { économieCollaborative } = useContext(SitePathsContext).simulateurs
|
||||
const iframePath =
|
||||
useSimulatorsData()['économie-collaborative'].iframePath ?? ''
|
||||
const indexPath = useIsEmbedded()
|
||||
? '/iframes/' + iframePath
|
||||
? `/iframes/${iframePath}`
|
||||
: économieCollaborative.index
|
||||
|
||||
return (
|
||||
<TrackChapter chapter1="simulateurs" chapter2="economie_collaborative">
|
||||
<div css="transform: translateY(2rem)">
|
||||
<Link
|
||||
style={({ isActive }) => (isActive ? { display: 'none' } : {})}
|
||||
to={indexPath}
|
||||
end
|
||||
style={({ isActive }) => (isActive ? { display: 'none' } : {})}
|
||||
>
|
||||
←{' '}
|
||||
<Trans i18nKey="économieCollaborative.retourAccueil">
|
||||
|
@ -34,13 +37,11 @@ export default function ÉconomieCollaborative() {
|
|||
</div>
|
||||
<StoreProvider localStorageKey="app::économie-collaborative:v1">
|
||||
<Routes>
|
||||
<Route path={'/'} element={<ActivitésSelection />} />
|
||||
<Route index element={<ActivitésSelection />} />
|
||||
<Route
|
||||
// TODO: react-router 6 use relative path now, we need to get relative path from sitepath instead of this replace
|
||||
path={économieCollaborative.votreSituation.replace(
|
||||
économieCollaborative.index,
|
||||
''
|
||||
)}
|
||||
path={
|
||||
relativeSitePaths.simulateurs.économieCollaborative.votreSituation
|
||||
}
|
||||
element={<VotreSituation />}
|
||||
/>
|
||||
<Route path={':title'} element={<Activité />} />
|
||||
|
|
Loading…
Reference in New Issue