|
1 | 1 | import type {Location, Pathname} from 'history'
|
2 |
| -import styled, {css} from 'styled-components' |
3 |
| -import {get} from '../constants' |
4 | 2 | import type {SxProp} from '../sx'
|
5 |
| -import sx from '../sx' |
6 |
| -import type {ComponentProps} from '../utils/types' |
7 |
| -import {toggleStyledComponent} from '../internal/utils/toggleStyledComponent' |
8 |
| -import {useFeatureFlag} from '../FeatureFlags' |
9 | 3 | import React from 'react'
|
10 | 4 | import {clsx} from 'clsx'
|
11 | 5 | import classes from './Header.module.css'
|
12 | 6 | import type {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
|
| 7 | +import {defaultSxProp} from '../utils/defaultSxProp' |
| 8 | +import Box from '../Box' |
13 | 9 |
|
14 |
| -type StyledHeaderProps = React.ComponentProps<'header'> & SxProp |
15 |
| -type StyledHeaderItemProps = React.ComponentProps<'div'> & SxProp & {full?: boolean} |
16 |
| -type StyledHeaderLinkProps = React.ComponentProps<'a'> & SxProp & {to?: Location | Pathname} |
| 10 | +export type HeaderProps = React.ComponentProps<'header'> & SxProp & {as?: React.ElementType} |
| 11 | +export type HeaderItemProps = React.ComponentProps<'div'> & SxProp & {full?: boolean} |
| 12 | +export type HeaderLinkProps = React.ComponentProps<'a'> & SxProp & {to?: Location | Pathname; as?: React.ElementType} |
17 | 13 |
|
18 |
| -const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_ga' |
19 |
| - |
20 |
| -const StyledHeader = toggleStyledComponent( |
21 |
| - CSS_MODULES_FEATURE_FLAG, |
22 |
| - 'header', |
23 |
| - styled.header<StyledHeaderProps>` |
24 |
| - z-index: 32; |
25 |
| - display: flex; |
26 |
| - padding: ${get('space.3')}; |
27 |
| - font-size: ${get('fontSizes.1')}; |
28 |
| - line-height: ${get('lineHeights.default')}; |
29 |
| - color: ${get('colors.header.text')}; |
30 |
| - background-color: ${get('colors.header.bg')}; |
31 |
| - align-items: center; |
32 |
| - flex-wrap: nowrap; |
33 |
| - overflow: auto; |
34 |
| -
|
35 |
| - ${sx}; |
36 |
| - `, |
37 |
| -) |
38 |
| - |
39 |
| -const Header = React.forwardRef<HTMLElement, StyledHeaderProps>(function Header( |
40 |
| - {children, className, ...rest}, |
| 14 | +const Header = React.forwardRef<HTMLElement, HeaderProps>(function Header( |
| 15 | + {children, className, sx: sxProp = defaultSxProp, as = 'header', ...rest}, |
41 | 16 | forwardRef,
|
42 | 17 | ) {
|
43 |
| - const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) |
| 18 | + if (sxProp !== defaultSxProp || as !== 'header') { |
| 19 | + return ( |
| 20 | + <Box as={as} sx={sxProp} ref={forwardRef} className={clsx(className, classes.Header)} {...rest}> |
| 21 | + {children} |
| 22 | + </Box> |
| 23 | + ) |
| 24 | + } |
44 | 25 | return (
|
45 |
| - <StyledHeader ref={forwardRef} className={clsx(className, {[classes.Header]: enabled})} {...rest}> |
| 26 | + <header ref={forwardRef} className={clsx(className, classes.Header)} {...rest}> |
46 | 27 | {children}
|
47 |
| - </StyledHeader> |
| 28 | + </header> |
48 | 29 | )
|
49 |
| -}) as PolymorphicForwardRefComponent<'header', StyledHeaderProps> |
| 30 | +}) as PolymorphicForwardRefComponent<'header', HeaderProps> |
50 | 31 |
|
51 | 32 | Header.displayName = 'Header'
|
52 | 33 |
|
53 |
| -const StyledHeaderItem = toggleStyledComponent( |
54 |
| - CSS_MODULES_FEATURE_FLAG, |
55 |
| - 'div', |
56 |
| - styled.div<StyledHeaderItemProps>` |
57 |
| - display: flex; |
58 |
| - margin-right: ${get('space.3')}; |
59 |
| - align-self: stretch; |
60 |
| - align-items: center; |
61 |
| - flex-wrap: nowrap; |
62 |
| -
|
63 |
| - ${({full}) => |
64 |
| - full && |
65 |
| - css` |
66 |
| - flex: auto; |
67 |
| - `}; |
68 |
| -
|
69 |
| - ${sx}; |
70 |
| - `, |
71 |
| -) |
72 |
| - |
73 |
| -const HeaderItem = React.forwardRef<HTMLElement, StyledHeaderItemProps>(function HeaderItem( |
74 |
| - {children, className, ...rest}, |
| 34 | +const HeaderItem = React.forwardRef<HTMLDivElement, HeaderItemProps>(function HeaderItem( |
| 35 | + {children, className, sx: sxProp = defaultSxProp, full, ...rest}, |
75 | 36 | forwardRef,
|
76 | 37 | ) {
|
77 |
| - const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) |
| 38 | + if (sxProp !== defaultSxProp) { |
| 39 | + return ( |
| 40 | + <Box |
| 41 | + as={'div'} |
| 42 | + sx={sxProp} |
| 43 | + ref={forwardRef} |
| 44 | + className={clsx(className, classes.HeaderItem)} |
| 45 | + data-full={full} |
| 46 | + {...rest} |
| 47 | + > |
| 48 | + {children} |
| 49 | + </Box> |
| 50 | + ) |
| 51 | + } |
78 | 52 | return (
|
79 |
| - <StyledHeaderItem |
80 |
| - ref={forwardRef} |
81 |
| - className={clsx(className, enabled && classes.HeaderItem)} |
82 |
| - data-full={rest.full} |
83 |
| - {...rest} |
84 |
| - > |
| 53 | + <div ref={forwardRef} className={clsx(className, classes.HeaderItem)} data-full={full} {...rest}> |
85 | 54 | {children}
|
86 |
| - </StyledHeaderItem> |
| 55 | + </div> |
87 | 56 | )
|
88 | 57 | })
|
89 | 58 |
|
90 | 59 | HeaderItem.displayName = 'Header.Item'
|
91 | 60 |
|
92 |
| -const StyledHeaderLink = toggleStyledComponent( |
93 |
| - CSS_MODULES_FEATURE_FLAG, |
94 |
| - 'a', |
95 |
| - styled.a.attrs<StyledHeaderLinkProps>(({to}) => { |
96 |
| - const isReactRouter = typeof to === 'string' |
97 |
| - if (isReactRouter) { |
98 |
| - // according to their docs, NavLink supports aria-current: |
99 |
| - // https://reacttraining.com/react-router/web/api/NavLink/aria-current-string |
100 |
| - return {'aria-current': 'page'} |
101 |
| - } else { |
102 |
| - return {} |
103 |
| - } |
104 |
| - })<StyledHeaderLinkProps>` |
105 |
| - font-weight: ${get('fontWeights.bold')}; |
106 |
| - color: ${get('colors.header.logo')}; |
107 |
| - white-space: nowrap; |
108 |
| - cursor: pointer; |
109 |
| - text-decoration: none; |
110 |
| - display: flex; |
111 |
| - align-items: center; |
112 |
| -
|
113 |
| - &:hover, |
114 |
| - &:focus { |
115 |
| - color: ${get('colors.header.text')}; |
116 |
| - } |
117 |
| -
|
118 |
| - ${sx}; |
119 |
| - `, |
120 |
| -) |
121 |
| - |
122 |
| -const HeaderLink = React.forwardRef<HTMLElement, StyledHeaderLinkProps>(function HeaderLink( |
123 |
| - {children, className, ...rest}, |
| 61 | +const HeaderLink = React.forwardRef<HTMLAnchorElement, HeaderLinkProps>(function HeaderLink( |
| 62 | + {children, className, sx: sxProp = defaultSxProp, as = 'a', ...rest}, |
124 | 63 | forwardRef,
|
125 | 64 | ) {
|
126 |
| - const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) |
| 65 | + if (sxProp !== defaultSxProp || as !== 'a') { |
| 66 | + return ( |
| 67 | + <Box as={as} sx={sxProp} ref={forwardRef} className={clsx(className, classes.HeaderLink)} {...rest}> |
| 68 | + {children} |
| 69 | + </Box> |
| 70 | + ) |
| 71 | + } |
127 | 72 | return (
|
128 |
| - <StyledHeaderLink ref={forwardRef} className={clsx(className, enabled && classes.HeaderLink)} {...rest}> |
| 73 | + <a ref={forwardRef} className={clsx(className, classes.HeaderLink)} {...rest}> |
129 | 74 | {children}
|
130 |
| - </StyledHeaderLink> |
| 75 | + </a> |
131 | 76 | )
|
132 | 77 | })
|
133 | 78 |
|
134 | 79 | HeaderLink.displayName = 'Header.Link'
|
135 | 80 |
|
136 |
| -export type HeaderProps = ComponentProps<typeof Header> |
137 |
| -export type HeaderLinkProps = ComponentProps<typeof HeaderLink> |
138 |
| -export type HeaderItemProps = ComponentProps<typeof HeaderItem> |
139 | 81 | export default Object.assign(Header, {Link: HeaderLink, Item: HeaderItem})
|
0 commit comments