SettingListItem.tsx 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. import { cloneElement, Fragment, isValidElement, useId, type ReactElement, type ReactNode } from 'react';
  2. import { Col, Row } from 'antd';
  3. import './SettingListItem.css';
  4. interface SettingListItemProps {
  5. paddings?: 'small' | 'default';
  6. title?: ReactNode;
  7. description?: ReactNode;
  8. children?: ReactNode;
  9. control?: ReactNode;
  10. }
  11. export default function SettingListItem({
  12. paddings = 'default',
  13. title,
  14. description,
  15. children,
  16. control,
  17. }: SettingListItemProps) {
  18. const padding = paddings === 'small' ? '10px 20px' : '20px';
  19. const titleId = useId();
  20. const node = control ?? children;
  21. const labelledNode = title && isValidElement(node) && node.type !== Fragment
  22. ? cloneElement(node as ReactElement<{ 'aria-labelledby'?: string }>, { 'aria-labelledby': titleId })
  23. : node;
  24. return (
  25. <div className="setting-list-item" style={{ padding }}>
  26. <Row gutter={[8, 16]} style={{ width: '100%' }}>
  27. <Col xs={24} lg={12}>
  28. <div className="setting-list-meta">
  29. {title && <div className="setting-list-title" id={titleId}>{title}</div>}
  30. {description && <div className="setting-list-description">{description}</div>}
  31. </div>
  32. </Col>
  33. <Col xs={24} lg={12}>
  34. {labelledNode}
  35. </Col>
  36. </Row>
  37. </div>
  38. );
  39. }