您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

color-picker.tsx 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
  2. import { Square } from 'react-feather'
  3. import styled from 'styles'
  4. interface Props {
  5. label: string
  6. color: string
  7. colors: Record<string, string>
  8. onChange: (color: string) => void
  9. }
  10. export default function ColorPicker({ label, color, colors, onChange }: Props) {
  11. return (
  12. <DropdownMenu.Root>
  13. <CurrentColor>
  14. <label>{label}</label>
  15. <ColorIcon color={color} />
  16. </CurrentColor>
  17. <Colors sideOffset={4}>
  18. {Object.entries(colors).map(([name, color]) => (
  19. <ColorButton key={name} title={name} onSelect={() => onChange(color)}>
  20. <ColorIcon color={color} />
  21. </ColorButton>
  22. ))}
  23. </Colors>
  24. </DropdownMenu.Root>
  25. )
  26. }
  27. function ColorIcon({ color }: { color: string }) {
  28. return (
  29. <Square
  30. fill={color}
  31. strokeDasharray={color === 'transparent' ? '2, 3' : 'none'}
  32. />
  33. )
  34. }
  35. const Colors = styled(DropdownMenu.Content, {
  36. display: 'grid',
  37. padding: 4,
  38. gridTemplateColumns: 'repeat(6, 1fr)',
  39. border: '1px solid $border',
  40. backgroundColor: '$panel',
  41. borderRadius: 4,
  42. boxShadow: '0px 5px 15px -5px hsla(206,22%,7%,.15)',
  43. })
  44. const ColorButton = styled(DropdownMenu.Item, {
  45. position: 'relative',
  46. cursor: 'pointer',
  47. height: 32,
  48. width: 32,
  49. border: 'none',
  50. padding: 'none',
  51. background: 'none',
  52. display: 'flex',
  53. alignItems: 'center',
  54. justifyContent: 'center',
  55. '&::before': {
  56. content: "''",
  57. position: 'absolute',
  58. top: 4,
  59. left: 4,
  60. right: 4,
  61. bottom: 4,
  62. pointerEvents: 'none',
  63. zIndex: 0,
  64. },
  65. '&:hover::before': {
  66. backgroundColor: '$hover',
  67. borderRadius: 4,
  68. },
  69. '& svg': {
  70. position: 'relative',
  71. stroke: 'rgba(0,0,0,.2)',
  72. strokeWidth: 1,
  73. zIndex: 1,
  74. },
  75. })
  76. const CurrentColor = styled(DropdownMenu.Trigger, {
  77. position: 'relative',
  78. display: 'flex',
  79. width: '100%',
  80. background: 'none',
  81. border: 'none',
  82. cursor: 'pointer',
  83. outline: 'none',
  84. alignItems: 'center',
  85. justifyContent: 'space-between',
  86. padding: '4px 6px 4px 12px',
  87. '&::before': {
  88. content: "''",
  89. position: 'absolute',
  90. top: 0,
  91. left: 0,
  92. right: 0,
  93. bottom: 0,
  94. pointerEvents: 'none',
  95. zIndex: -1,
  96. },
  97. '&:hover::before': {
  98. backgroundColor: '$hover',
  99. borderRadius: 4,
  100. },
  101. '& label': {
  102. fontFamily: '$ui',
  103. fontSize: '$2',
  104. fontWeight: '$1',
  105. margin: 0,
  106. padding: 0,
  107. },
  108. '& svg': {
  109. position: 'relative',
  110. stroke: 'rgba(0,0,0,.2)',
  111. strokeWidth: 1,
  112. zIndex: 1,
  113. },
  114. })