-
Notifications
You must be signed in to change notification settings - Fork 331
/
Copy pathmodal-action.tsx
112 lines (100 loc) · 2.97 KB
/
modal-action.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
108
109
110
111
112
import React, { MouseEvent, useImperativeHandle, useMemo, useRef } from 'react'
import css from 'styled-jsx/css'
import useTheme from '../use-theme'
import { useModalContext } from './modal-context'
import Button, { ButtonProps } from '../button/button'
import useScale, { withScale } from '../use-scale'
import useClasses from '../use-classes'
type ModalActionEvent = MouseEvent<HTMLButtonElement> & {
close: () => void
}
interface Props {
className?: string
passive?: boolean
disabled?: boolean
onClick?: (event: ModalActionEvent) => void
}
const defaultProps = {
className: '',
passive: false,
disabled: false,
}
export type ModalActionProps = Props & Omit<ButtonProps, keyof Props>
const ModalActionComponent = React.forwardRef<
HTMLButtonElement,
React.PropsWithChildren<ModalActionProps>
>(
(
{
className,
children,
onClick,
passive,
disabled,
...props
}: React.PropsWithChildren<ModalActionProps> & typeof defaultProps,
ref: React.Ref<HTMLButtonElement | null>,
) => {
const theme = useTheme()
const { SCALES } = useScale()
const btnRef = useRef<HTMLButtonElement>(null)
const { close } = useModalContext()
useImperativeHandle(ref, () => btnRef.current)
const clickHandler = (event: MouseEvent<HTMLButtonElement>) => {
if (disabled) return
const actionEvent = Object.assign({}, event, {
close: () => close && close(),
})
onClick && onClick(actionEvent)
}
const color = useMemo(() => {
return passive ? theme.palette.accents_5 : theme.palette.foreground
}, [theme.palette, passive, disabled])
const bgColor = useMemo(() => {
return disabled ? theme.palette.accents_1 : theme.palette.background
}, [theme.palette, disabled])
const { className: resolveClassName, styles } = css.resolve`
button.btn {
font-size: ${SCALES.font(0.75)};
border: none;
color: ${color};
background-color: ${theme.palette.background};
display: flex;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
flex: 1;
height: ${SCALES.height(3.5625)};
border-radius: 0;
min-width: 0;
}
button.btn:hover,
button.btn:focus {
color: ${disabled ? color : theme.palette.foreground};
background-color: ${disabled ? bgColor : theme.palette.accents_1};
}
`
const classes = useClasses(resolveClassName, className)
const overrideProps = {
...props,
effect: false,
ref: btnRef,
}
return (
<Button
className={classes}
onClick={clickHandler}
disabled={disabled}
{...overrideProps}
>
{children}
{styles}
</Button>
)
},
)
ModalActionComponent.defaultProps = defaultProps
ModalActionComponent.displayName = 'GeistModalAction'
const ModalAction = withScale(ModalActionComponent)
export default ModalAction