Files
react/components/modal/modal-action.tsx
witt d4a1e02430 feat(scaleable): add scaleable props to each component (#531)
* feat(scaleable): add scaleable props to each component

* chore(scaleable): update the exported type

* feat: apply scaleable to components

chore: remove with-default

test: improve testcase for scaleable

chore: resolve test warning

ci: upgrade nodejs to latest lts

docs: fix type error in document site

* docs: update documents to be compatible with scaleable

chore: fix build errors

* chore: remove all size-related attributes

docs: improve guide document

* docs: add scaleable documentation

test: update snapshots

chore: remove unused

* feat: add scaleable to grid components

* docs: improve docs

* test: update snapshots

* fix(grid): fix basic component props
2021-06-23 10:53:30 +08:00

110 lines
2.9 KiB
TypeScript

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 useScaleable, { withScaleable } from '../use-scaleable'
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 } = useScaleable()
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 overrideProps = {
...props,
effect: false,
ref: btnRef,
}
return (
<Button
className={`${resolveClassName} ${className}`}
onClick={clickHandler}
disabled={disabled}
{...overrideProps}>
{children}
{styles}
</Button>
)
},
)
ModalActionComponent.defaultProps = defaultProps
ModalActionComponent.displayName = 'GeistModalAction'
const ModalAction = withScaleable(ModalActionComponent)
export default ModalAction