feat: color picker

This commit is contained in:
trafficlunar 2024-12-26 20:01:42 +00:00
parent 6ddcd1bbdf
commit ab88691838
5 changed files with 519 additions and 1 deletions

View file

@ -16,11 +16,13 @@
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-menubar": "^1.1.2",
"@radix-ui/react-scroll-area": "^1.2.1",
"@radix-ui/react-separator": "^1.1.1",
"@radix-ui/react-slider": "^1.2.2",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-toggle": "^1.1.0",
"@radix-ui/react-toggle-group": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.6",
"@uiw/react-color": "^2.3.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.464.0",

View file

@ -26,6 +26,9 @@ importers:
'@radix-ui/react-scroll-area':
specifier: ^1.2.1
version: 1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-separator':
specifier: ^1.1.1
version: 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-slider':
specifier: ^1.2.2
version: 1.2.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -41,6 +44,9 @@ importers:
'@radix-ui/react-tooltip':
specifier: ^1.1.6
version: 1.1.6(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color':
specifier: ^2.3.4
version: 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
class-variance-authority:
specifier: ^0.7.1
version: 0.7.1
@ -1066,6 +1072,19 @@ packages:
'@types/react-dom':
optional: true
'@radix-ui/react-separator@1.1.1':
resolution: {integrity: sha512-RRiNRSrD8iUiXriq/Y5n4/3iE8HzqgLHsusUSg5jVpU2+3tqcUFPJXHDymwEypunc2sWxDUS3UC+rkZRlHedsw==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-slider@1.2.2':
resolution: {integrity: sha512-sNlU06ii1/ZcbHf8I9En54ZPW0Vil/yPVg4vQMcFNjrIx51jsHbFl1HYHQvCIWJSr1q0ZmA+iIs/ZTv8h7HHSA==}
peerDependencies:
@ -1483,6 +1502,156 @@ packages:
resolution: {integrity: sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@uiw/color-convert@2.3.4':
resolution: {integrity: sha512-av3PvCeP8o4H2a81n+vJwEEv8qGnQNonfCTiH9kO/CMQR1BvhGYijduM7RJzgHaAaVpE01opjNICQRyEx5qKVg==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
'@uiw/react-color-alpha@2.3.4':
resolution: {integrity: sha512-mY3ZgXocDcxe+g8vyBcajE8xWjLkxhGpH42wB/wZG+sfWn9NFnHhsPBop8MwTY8VCQU7EbKLl/DKNr+0k6REcg==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-block@2.3.4':
resolution: {integrity: sha512-xtVy6ipO3aviUwRhUe+E3WGddYhUo1P7eESnJ3bMoM2LVkxaeI5BsvKea5DV1Zu4UB/5SsdYCxFY4P3OGoQFiA==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-chrome@2.3.4':
resolution: {integrity: sha512-wen2nTjFHUXp6Vu8Vhez8FEWnU4Y+nzT0bQK+UrEr8yjSFxjIO+G6zwZrR0Anaz6advWwBCqIIOQP+VzA/mOZA==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-circle@2.3.4':
resolution: {integrity: sha512-3uhDZB/TYqE0+f2sKGVuJl3d8ogBGrjHeGDz6dZu0F25CLVNqO7g3xzwYYqI1ea/8d2cRd2s6GtM2LmvVJtIpQ==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-colorful@2.3.4':
resolution: {integrity: sha512-hUZsp0/c6H6UHPzNhPTYRfFQWRj7AN1P+GelC0YAjhtwsOeXqFE3cIqcTwrUlO+59a5ATpcJDK7RCH/G791KUA==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-compact@2.3.4':
resolution: {integrity: sha512-+wtZ18VuoLeOoAQMpGm3es7xQ9XcK0F87V2cpebauqrkCk50QC3MaWvFIekW3AO9m8zt+kC3UH/e5Y3127nctg==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-editable-input-hsla@2.3.4':
resolution: {integrity: sha512-vPFJn5mfnmE7JYh9xVHfeKzDYL06E1An6iasNagTE0WS74y6a7QwqPRwQgMBMJYJrZiuTCv9IOClAZ6qAo9I2g==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-editable-input-rgba@2.3.4':
resolution: {integrity: sha512-dEmGpdEjJcIybYAKBqhP+Ei5UK7Gh47Wk7k/Spj2VOLNTx10JEGXTzjtLnQJ+jVOYUw3EMG0sTr9b7bCgHpGXg==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-editable-input@2.3.4':
resolution: {integrity: sha512-Bbb+FJxCXJl6Z4mqJVh6WY6NXYAbKet91n7RXq6scOSLRj2zxzjzmEkWBgwoWaLZ9Efl8I7fiTksaImjQcMLZA==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-github@2.3.4':
resolution: {integrity: sha512-T7pjuokZCQ1FcFsLTypfRHHf34GSlYHIkUG8pE9rEJY1qiOCJwmUg0PWAnWdCiGft4oho7mtMnmjsGNGUWQo6w==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-hue@2.3.4':
resolution: {integrity: sha512-ND3u2GUqUSurc/3ogCT+pu8R6iKV1x1t6I4O6TtQhQ3DSzZ0TQZum8uRNQ12t8kkswGXeyS7JjcRq0+sJBVQlw==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-material@2.3.4':
resolution: {integrity: sha512-u9oEv3kUaeuYJTOCFrFqFCk3YFvYKt1rg4NmWccmp9OEGrpAfZDZ+KJGBj0nMTbxzClqiMFwQxUDgW8fPsJxTA==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-name@2.3.4':
resolution: {integrity: sha512-0sd4XYpT3oyZk25FkoTTnQJtIOJkA01tnaa9eNzb4uXdcWh9+EpFFUpemPi+1yVOktXVMKpT1fiU6dbXnl8/fw==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
'@uiw/react-color-saturation@2.3.4':
resolution: {integrity: sha512-wpV2w77SEXjcOAtGp1t/c0OJT8q/BpSPE+CkvdowUfmxy1xWZ7lVOdRBZry3QHRvWevfJCIPxz6Nhgj194scPQ==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-shade-slider@2.3.4':
resolution: {integrity: sha512-tS+dM1yTk07SDSKVpreuC2MUiq/umxZ+RMto4HqfSbWMVbBNMMVcTYi60+w/lcz5xJwGYRCKkeg7QmEhKXtUXA==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-sketch@2.3.4':
resolution: {integrity: sha512-7w1KWwLf422tZQDxs4m+d1owXbgp0VJoZd6cbcj3Jz9qL1omyWi5Q7MgENM0br/ibG2OhwIza9sXezOuXQbQbg==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-slider@2.3.4':
resolution: {integrity: sha512-t1OVLSTpqxXaqHbZ1NGhUd+c5UBtnC4Tcjk+UkR8DD3gOoDvxmFWW1zfX0u2l9PYtsDsc15xWB4ET3uPRX7AzA==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-swatch@2.3.4':
resolution: {integrity: sha512-tl0wsu58MUeWUaKwi7zBKSkgLqugUWEYMOHDtooUvd96/dox0aPrB8KjH7J/2SaxAZzqUNMEEumGwuD3cmI2iw==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color-wheel@2.3.4':
resolution: {integrity: sha512-kTaHC8YoIeppahcnIvQBJfzWmtCzwIGV0/C28eN3YH9LGQeDV5vYAYSJ31Y1PWdM5xLwaATa06q8+X0wOSId9Q==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-color@2.3.4':
resolution: {integrity: sha512-OtwtwLQq66ZTxmAn2YoVUYwbw8coS++uPdcHJs+z2MQSiTUBU1UW/vtbpySsrTod0vH28ZXM4Onn/Kbn+KYOEw==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@uiw/react-drag-event-interactive@2.3.4':
resolution: {integrity: sha512-j2y2MjgriyarQhD7R8zii4Ily3hWp+IkbvpmDD75f1PZL71IJDKswAHG1bO/bEXpI1l5GVJTn7NPfS9kxbCqnw==}
peerDependencies:
'@babel/runtime': '>=7.19.0'
react: '>=16.9.0'
react-dom: '>=16.9.0'
'@vitejs/plugin-react@4.3.4':
resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==}
engines: {node: ^14.18.0 || >=16.0.0}
@ -1613,6 +1782,14 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
colors-named-hex@1.0.2:
resolution: {integrity: sha512-k6kq1e1pUCQvSVwIaGFq2l0LrkAPQZWyeuZn1Z8nOiYSEZiKoFj4qx690h2Kd34DFl9Me0gKS6MUwAMBJj8nuA==}
engines: {node: '>=14.16'}
colors-named@1.0.2:
resolution: {integrity: sha512-2ANq2r393PV9njYUD66UdfBcxR1slMqRA3QRTWgCx49JoCJ+kOhyfbQYxKJbPZQIhZUcNjVOs5AlyY1WwXec3w==}
engines: {node: '>=14.16'}
commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
@ -3437,6 +3614,15 @@ snapshots:
'@types/react': 18.3.12
'@types/react-dom': 18.3.1
'@radix-ui/react-separator@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
optionalDependencies:
'@types/react': 18.3.12
'@types/react-dom': 18.3.1
'@radix-ui/react-slider@1.2.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@radix-ui/number': 1.1.0
@ -3833,6 +4019,206 @@ snapshots:
'@typescript-eslint/types': 8.17.0
eslint-visitor-keys: 4.2.0
'@uiw/color-convert@2.3.4(@babel/runtime@7.26.0)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/react-color-alpha@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-drag-event-interactive': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-block@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-editable-input': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-swatch': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-chrome@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-alpha': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input-hsla': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input-rgba': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-github': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-hue': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-saturation': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-circle@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-swatch': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-colorful@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-alpha': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-hue': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-saturation': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-compact@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-editable-input': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input-rgba': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-swatch': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-editable-input-hsla@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-editable-input-rgba': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-editable-input-rgba@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-editable-input': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-editable-input@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-github@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-swatch': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-hue@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-alpha': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-material@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-editable-input': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input-rgba': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-name@2.3.4(@babel/runtime@7.26.0)':
dependencies:
'@babel/runtime': 7.26.0
colors-named: 1.0.2
colors-named-hex: 1.0.2
'@uiw/react-color-saturation@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-drag-event-interactive': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-shade-slider@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-alpha': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-sketch@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-alpha': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input-rgba': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-hue': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-saturation': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-swatch': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-slider@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-alpha': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-swatch@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color-wheel@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-drag-event-interactive': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-color@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
'@uiw/color-convert': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-alpha': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-block': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-chrome': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-circle': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-colorful': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-compact': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input-hsla': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-editable-input-rgba': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-github': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-hue': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-material': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-name': 2.3.4(@babel/runtime@7.26.0)
'@uiw/react-color-saturation': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-shade-slider': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-sketch': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-slider': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-swatch': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@uiw/react-color-wheel': 2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@uiw/react-drag-event-interactive@2.3.4(@babel/runtime@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@babel/runtime': 7.26.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@vitejs/plugin-react@4.3.4(vite@6.0.2(@types/node@22.10.1)(jiti@1.21.6)(yaml@2.6.1))':
dependencies:
'@babel/core': 7.26.0
@ -3967,6 +4353,10 @@ snapshots:
color-name@1.1.4: {}
colors-named-hex@1.0.2: {}
colors-named@1.0.2: {}
commander@4.1.1: {}
concat-map@0.0.1: {}

View file

@ -0,0 +1,93 @@
import { useContext, useEffect, useMemo, useState } from "react";
import { Alpha, ShadeSlider, Wheel, hsvaToHex, hsvaToRgba, rgbaToHsva } from "@uiw/react-color";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ToolContext } from "@/context/Tool";
import { findBlockFromRgb } from "@/utils/findBlockFromRgb";
import _blockData from "@/data/blocks/programmer-art/data.json";
import { Button } from "../ui/button";
const blockData: BlockData = _blockData;
function ColorPicker() {
const { selectedBlock, setSelectedBlock } = useContext(ToolContext);
const [hsva, setHsva] = useState({ h: 0, s: 0, v: 49.4, a: 1 });
const rgb = useMemo(() => hsvaToRgba(hsva), [hsva]);
const limitRgba = (x: number) => Math.min(Math.max(x, 0), 255);
useEffect(() => {
const blockInfo = blockData[selectedBlock];
const rgbColor = { r: blockInfo.color[0], g: blockInfo.color[1], b: blockInfo.color[2], a: blockInfo.color[3] / 255 };
setHsva(rgbaToHsva(rgbColor));
}, [selectedBlock]);
const onClickSet = () => {
const block = findBlockFromRgb(rgb.r, rgb.g, rgb.b, rgb.a * 255);
setSelectedBlock(block);
};
return (
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col gap-2">
<Wheel width={125} height={125} color={hsva} onChange={(color) => setHsva(color.hsva)} />
<ShadeSlider hsva={hsva} onChange={(newShade) => setHsva({ ...hsva, ...newShade })} />
<Alpha hsva={hsva} onChange={(newAlpha) => setHsva({ ...hsva, ...newAlpha })} />
</div>
<div className="relative">
<div className="flex gap-2 items-center">
<Label htmlFor="r">R</Label>
<Input
name="r"
type="number"
className="h-8"
value={rgb.r}
onChange={(e) => setHsva(rgbaToHsva({ ...rgb, r: limitRgba(parseInt(e.target.value)) }))}
/>
</div>
<div className="flex gap-2 items-center">
<Label htmlFor="g">G</Label>
<Input
name="g"
type="number"
className="h-8"
value={rgb.g}
onChange={(e) => setHsva(rgbaToHsva({ ...rgb, g: limitRgba(parseInt(e.target.value)) }))}
/>
</div>
<div className="flex gap-2 items-center">
<Label htmlFor="b">B</Label>
<Input
name="b"
type="number"
className="h-8"
value={rgb.b}
onChange={(e) => setHsva(rgbaToHsva({ ...rgb, b: limitRgba(parseInt(e.target.value)) }))}
/>
</div>
<div className="flex gap-2 items-center">
<Label htmlFor="a">A</Label>
<Input
name="a"
type="number"
className="h-8"
value={Math.floor(rgb.a * 255)}
onChange={(e) => setHsva(rgbaToHsva({ ...rgb, a: limitRgba(parseInt(e.target.value)) }))}
/>
</div>
<div className="w-full h-2 mt-1" style={{ backgroundColor: hsvaToHex(hsva) }}></div>
<Button variant="outline" onClick={onClickSet} className="mt-1 h-8 w-full">
Set
</Button>
</div>
</div>
);
}
export default ColorPicker;

View file

@ -3,8 +3,9 @@ import { useEffect, useRef, useState } from "react";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
import SelectorBlocks from "./SelectorBlocks";
import ColorPicker from "./ColorPicker";
import Radius from "./Radius";
import SelectorBlocks from "./SelectorBlocks";
function ToolSettings() {
const divRef = useRef<HTMLDivElement>(null);
@ -19,6 +20,9 @@ function ToolSettings() {
return (
<div className="w-72 border-l border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-950 p-2 pb-0 flex flex-col h-full gap-2">
<ColorPicker />
<Separator />
<Radius />
<Separator />

View file

@ -0,0 +1,29 @@
import * as React from "react"
import * as SeparatorPrimitive from "@radix-ui/react-separator"
import { cn } from "@/lib/utils"
const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(
(
{ className, orientation = "horizontal", decorative = true, ...props },
ref
) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
orientation={orientation}
className={cn(
"shrink-0 bg-zinc-200 dark:bg-zinc-800",
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
className
)}
{...props}
/>
)
)
Separator.displayName = SeparatorPrimitive.Root.displayName
export { Separator }