Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

color-picker.tsx 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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 fill={color} strokeDasharray={color === 'none' ? '2, 3' : 'none'} />
  30. )
  31. }
  32. const Colors = styled(DropdownMenu.Content, {
  33. display: 'grid',
  34. padding: 4,
  35. gridTemplateColumns: 'repeat(6, 1fr)',
  36. border: '1px solid $border',
  37. backgroundColor: '$panel',
  38. borderRadius: 4,
  39. boxShadow: '0px 5px 15px -5px hsla(206,22%,7%,.15)',
  40. })
  41. const ColorButton = styled(DropdownMenu.Item, {
  42. position: 'relative',
  43. cursor: 'pointer',
  44. height: 32,
  45. width: 32,
  46. border: 'none',
  47. padding: 'none',
  48. background: 'none',
  49. display: 'flex',
  50. alignItems: 'center',
  51. justifyContent: 'center',
  52. '&::before': {
  53. content: "''",
  54. position: 'absolute',
  55. top: 4,
  56. left: 4,
  57. right: 4,
  58. bottom: 4,
  59. pointerEvents: 'none',
  60. zIndex: 0,
  61. },
  62. '&:hover::before': {
  63. backgroundColor: '$hover',
  64. borderRadius: 4,
  65. },
  66. '& svg': {
  67. position: 'relative',
  68. stroke: 'rgba(0,0,0,.2)',
  69. strokeWidth: 1,
  70. zIndex: 1,
  71. },
  72. })
  73. const CurrentColor = styled(DropdownMenu.Trigger, {
  74. position: 'relative',
  75. display: 'flex',
  76. width: '100%',
  77. background: 'none',
  78. border: 'none',
  79. cursor: 'pointer',
  80. outline: 'none',
  81. alignItems: 'center',
  82. justifyContent: 'space-between',
  83. padding: '4px 6px 4px 12px',
  84. '&::before': {
  85. content: "''",
  86. position: 'absolute',
  87. top: 0,
  88. left: 0,
  89. right: 0,
  90. bottom: 0,
  91. pointerEvents: 'none',
  92. zIndex: -1,
  93. },
  94. '&:hover::before': {
  95. backgroundColor: '$hover',
  96. borderRadius: 4,
  97. },
  98. '& label': {
  99. fontFamily: '$ui',
  100. fontSize: '$2',
  101. fontWeight: '$1',
  102. margin: 0,
  103. padding: 0,
  104. },
  105. '& svg': {
  106. position: 'relative',
  107. stroke: 'rgba(0,0,0,.2)',
  108. strokeWidth: 1,
  109. zIndex: 1,
  110. },
  111. })