You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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. <h3>{label}</h3>
  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. "& h3": {
  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. })