-
Notifications
You must be signed in to change notification settings - Fork 32
/
section-notice.tsx
107 lines (97 loc) · 3.49 KB
/
section-notice.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React, {
ComponentProps,
FC,
KeyboardEvent,
KeyboardEventHandler,
MouseEvent,
MouseEventHandler,
ReactElement, useEffect, useState
} from 'react'
import cx from 'classnames'
import { EbayNoticeContent } from '../ebay-notice-base/components/ebay-notice-content'
import NoticeContent from '../common/notice-utils/notice-content'
import { EbayIcon, Icon } from '../ebay-icon'
import { EbaySectionNoticeFooter } from './index'
import { randomId } from '../common/random-id'
export type SectionNoticeStatus = 'general' | 'none' | 'attention' | 'confirmation' | 'information' | 'education'
export type Props = ComponentProps<'section'> & {
status?: SectionNoticeStatus;
'aria-label'?: string;
'aria-roledescription'?: string;
className?: string;
a11yDismissText?: string;
onDismiss?: MouseEventHandler & KeyboardEventHandler;
educationIcon?: Icon;
iconClass?: string;
prominent?: boolean;
}
const EbaySectionNotice: FC<Props> = ({
status = 'general',
children,
className,
'aria-label': ariaLabel,
'aria-roledescription': ariaRoleDescription = 'Notice',
a11yDismissText,
educationIcon,
iconClass,
prominent,
onDismiss = () => {},
...rest
}) => {
const [dismissed, setDismissed] = useState(false)
const [rId, setRandomId] = useState('')
useEffect(() => {
setRandomId(randomId())
}, [])
const childrenArray = React.Children.toArray(children) as ReactElement[]
const content = childrenArray.find(({ type }) => type === EbayNoticeContent)
const hasStatus = status !== 'general' && status !== 'none'
const isEducational = status === 'education'
let iconName = null
if (hasStatus) {
if (isEducational) {
iconName = educationIcon || 'lightbulb24'
} else {
iconName = `${status}Filled16` as Icon
}
}
if (!content) {
throw new Error(`EbaySectionNotice: Please use a EbayNoticeContent that defines the content of the notice`)
}
const handleDismissed = (event: MouseEvent & KeyboardEvent) => {
setDismissed(true)
onDismiss(event)
}
return dismissed ? null : (
<section
{...rest}
className={cx(className, `section-notice`, {
[`section-notice--${status}`]: hasStatus,
'section-notice--education': isEducational && prominent,
'section-notice--large-icon': isEducational
})}
role="region"
aria-label={!hasStatus ? ariaLabel : null}
aria-labelledby={hasStatus ? `section-notice-${status}-${rId}` : null}
aria-roledescription={ariaRoleDescription}>
{iconName && (
<div className="section-notice__header" id={`section-notice-${status}-${rId}`}>
<EbayIcon className={iconClass} name={iconName} a11yText={ariaLabel} a11yVariant="label" />
</div>
)}
<NoticeContent {...content.props} type="section" />
{children}
{a11yDismissText && (
<EbaySectionNoticeFooter>
<button
aria-label={a11yDismissText}
className="fake-link page-notice__dismiss"
onClick={handleDismissed as any}>
<EbayIcon name="close16" />
</button>
</EbaySectionNoticeFooter>
)}
</section>
)
}
export default EbaySectionNotice