mirror of
https://github.com/zhigang1992/react.git
synced 2026-01-31 09:08:41 +08:00
feat(checkbox): add support of different sizes
This commit is contained in:
@@ -2,26 +2,40 @@ import React, { useEffect, useMemo, useState } from 'react'
|
||||
import withDefaults from '../utils/with-defaults'
|
||||
import { CheckboxContext } from './checkbox-context'
|
||||
import useWarning from '../utils/use-warning'
|
||||
import { NormalSizes } from '../utils/prop-types'
|
||||
|
||||
interface Props {
|
||||
value: string[]
|
||||
disabled?: boolean
|
||||
size?: NormalSizes
|
||||
onChange?: (values: string[]) => void
|
||||
className?: string
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
disabled: false,
|
||||
size: 'small' as NormalSizes,
|
||||
className: '',
|
||||
}
|
||||
|
||||
type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof Props>
|
||||
export type CheckboxGroupProps = Props & typeof defaultProps & NativeAttrs
|
||||
|
||||
export const getCheckboxSize = (size: NormalSizes): string => {
|
||||
const sizes: { [key in NormalSizes]: string } = {
|
||||
mini: '.75rem',
|
||||
small: '.875rem',
|
||||
medium: '1rem',
|
||||
large: '1.125rem',
|
||||
}
|
||||
return sizes[size]
|
||||
}
|
||||
|
||||
const CheckboxGroup: React.FC<React.PropsWithChildren<CheckboxGroupProps>> = ({
|
||||
disabled,
|
||||
onChange,
|
||||
value,
|
||||
size,
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
@@ -47,6 +61,7 @@ const CheckboxGroup: React.FC<React.PropsWithChildren<CheckboxGroupProps>> = ({
|
||||
values: selfVal,
|
||||
}
|
||||
}, [disabled, selfVal])
|
||||
const fontSize = useMemo(() => getCheckboxSize(size), [size])
|
||||
|
||||
useEffect(() => {
|
||||
setSelfVal(value)
|
||||
@@ -58,7 +73,8 @@ const CheckboxGroup: React.FC<React.PropsWithChildren<CheckboxGroupProps>> = ({
|
||||
{children}
|
||||
<style jsx>{`
|
||||
.group :global(label) {
|
||||
margin-right: 1.875rem;
|
||||
margin-right: calc(${fontSize} * 2);
|
||||
--checkbox-size: ${fontSize};
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
|
||||
@@ -20,12 +20,7 @@ const CheckboxIcon: React.FC<Props> = ({ disabled, checked }) => {
|
||||
return (
|
||||
<>
|
||||
{checked ? (
|
||||
<svg
|
||||
width="12px"
|
||||
height="12px"
|
||||
viewBox="0 0 17 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<svg viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12.1429 0H3.85714C1.7269 0 0 1.79086 0 4V12C0 14.2091 1.7269 16 3.85714 16H12.1429C14.2731 16 16 14.2091 16 12V4C16 1.79086 14.2731 0 12.1429 0Z"
|
||||
fill={fill}
|
||||
@@ -33,12 +28,7 @@ const CheckboxIcon: React.FC<Props> = ({ disabled, checked }) => {
|
||||
<path d="M16 3L7.72491 11L5 8" stroke={bg} strokeWidth="1.5" />
|
||||
</svg>
|
||||
) : (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="12px"
|
||||
height="12px"
|
||||
viewBox="0 0 12 12"
|
||||
fill="none">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="none">
|
||||
<path
|
||||
d="M8.5 0.5H3.5C1.84315 0.5 0.5 1.84315 0.5 3.5V8.5C0.5 10.1569 1.84315 11.5 3.5 11.5H8.5C10.1569 11.5 11.5 10.1569 11.5 8.5V3.5C11.5 1.84315 10.1569 0.5 8.5 0.5Z"
|
||||
stroke={stroke}
|
||||
@@ -48,8 +38,8 @@ const CheckboxIcon: React.FC<Props> = ({ disabled, checked }) => {
|
||||
<style jsx>{`
|
||||
svg {
|
||||
display: inline-flex;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
width: calc(0.86 * var(--checkbox-size));
|
||||
height: calc(0.86 * var(--checkbox-size));
|
||||
user-select: none;
|
||||
opacity: ${disabled ? 0.4 : 1};
|
||||
cursor: ${disabled ? 'not-allowed' : 'pointer'};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useCheckbox } from './checkbox-context'
|
||||
import CheckboxGroup from './checkbox-group'
|
||||
import CheckboxGroup, { getCheckboxSize } from './checkbox-group'
|
||||
import CheckboxIcon from './checkbox.icon'
|
||||
import useWarning from '../utils/use-warning'
|
||||
import { NormalSizes } from '../utils/prop-types'
|
||||
|
||||
interface CheckboxEventTarget {
|
||||
checked: boolean
|
||||
@@ -20,6 +21,7 @@ interface Props {
|
||||
disabled?: boolean
|
||||
initialChecked?: boolean
|
||||
onChange?: (e: CheckboxEvent) => void
|
||||
size?: NormalSizes
|
||||
className?: string
|
||||
value?: string
|
||||
}
|
||||
@@ -27,6 +29,7 @@ interface Props {
|
||||
const defaultProps = {
|
||||
disabled: false,
|
||||
initialChecked: false,
|
||||
size: 'small' as NormalSizes,
|
||||
className: '',
|
||||
value: '',
|
||||
}
|
||||
@@ -41,6 +44,7 @@ const Checkbox: React.FC<CheckboxProps> = ({
|
||||
onChange,
|
||||
className,
|
||||
children,
|
||||
size,
|
||||
value,
|
||||
...props
|
||||
}) => {
|
||||
@@ -51,7 +55,6 @@ const Checkbox: React.FC<CheckboxProps> = ({
|
||||
if (inGroup && checked) {
|
||||
useWarning('Remove props "checked" when [Checkbox] component is in the group.', 'Checkbox')
|
||||
}
|
||||
|
||||
if (inGroup) {
|
||||
useEffect(() => {
|
||||
const next = values.includes(value)
|
||||
@@ -60,6 +63,7 @@ const Checkbox: React.FC<CheckboxProps> = ({
|
||||
}, [values.join(',')])
|
||||
}
|
||||
|
||||
const fontSize = useMemo(() => getCheckboxSize(size), [size])
|
||||
const changeHandle = useCallback(
|
||||
(ev: React.ChangeEvent) => {
|
||||
if (isDisabled) return
|
||||
@@ -94,20 +98,21 @@ const Checkbox: React.FC<CheckboxProps> = ({
|
||||
|
||||
<style jsx>{`
|
||||
label {
|
||||
height: 0.875rem;
|
||||
line-height: 0.875rem;
|
||||
--checkbox-size: ${fontSize};
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: auto;
|
||||
cursor: ${isDisabled ? 'not-allowed' : 'pointer'};
|
||||
opacity: ${isDisabled ? 0.75 : 1};
|
||||
height: var(--checkbox-size);
|
||||
line-height: var(--checkbox-size);
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 0.875rem;
|
||||
line-height: 0.875rem;
|
||||
padding-left: 0.5rem;
|
||||
font-size: var(--checkbox-size);
|
||||
line-height: var(--checkbox-size);
|
||||
padding-left: calc(var(--checkbox-size) * 0.57);
|
||||
user-select: none;
|
||||
cursor: ${isDisabled ? 'not-allowed' : 'pointer'};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user