| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import { useEffect, useRef, useState } from 'react';
- import classNames from 'classnames';
- import { isArray } from 'lodash';
- import './index.less';
- import { CheckOutlined } from '@ant-design/icons';
- type RadioCardModelType = 'multiple' | 'singular';
- interface RadioCardItem {
- label: string;
- value: string;
- imgUrl: string;
- }
- export interface RadioCardProps {
- value?: string | string[];
- model?: RadioCardModelType;
- options: RadioCardItem[];
- onChange?: (keys: string | string[]) => void;
- onSelect?: (key: string, selected: boolean, node: RadioCardItem[]) => void;
- }
- export default (props: RadioCardProps) => {
- const { value, model, options, onChange, onSelect } = props;
- const [keys, setKeys] = useState<string[]>([]);
- const isMultiple = useRef<boolean>(true);
- isMultiple.current = !(model && model === 'singular');
- useEffect(() => {
- // 初始化
- setKeys(value ? (isArray(value) ? value : [value]) : []);
- }, [props.value]);
- const getNode = (_keys: string[]) =>
- options.filter((item) => _keys.some((key) => key === item.value));
- const toggleOption = (key: string) => {
- const optionIndex = keys.indexOf(key);
- const newKeys = [...keys];
- if (optionIndex === -1) {
- if (isMultiple.current) {
- newKeys.push(key);
- } else {
- newKeys[0] = key;
- }
- } else {
- newKeys.splice(optionIndex, 1);
- }
- if (!('value' in props)) {
- setKeys(newKeys);
- }
- if (onChange) {
- onChange(isMultiple.current ? newKeys : newKeys[0]);
- }
- if (onSelect) {
- onSelect(key, optionIndex === -1, getNode(newKeys));
- }
- };
- return (
- <div className={'radio-card-items'}>
- {options.map((item) => {
- return (
- <div
- className={classNames('radio-card-item', {
- checked: keys?.includes(item.value),
- })}
- key={item.value}
- onClick={() => {
- toggleOption(item.value);
- }}
- >
- <img width={32} height={32} src={item.imgUrl} alt={''} />
- <span>{item.label}</span>
- <div className={'checked-icon'}>
- <div>
- <CheckOutlined />
- </div>
- </div>
- </div>
- );
- })}
- </div>
- );
- };
|