File tree Expand file tree Collapse file tree 7 files changed +147
-2
lines changed
components/examples/use-eye-dropper Expand file tree Collapse file tree 7 files changed +147
-2
lines changed Original file line number Diff line number Diff line change @@ -61,7 +61,7 @@ Based on the [@mantine/hooks](https://github.com/mantinedev/mantine/tree/master/
6161- [ ] use-document-title
6262- [ ] use-document-visibility
6363- [ ] use-event-listener
64- - [ ] use-eye-dropper
64+ - [x ] use-eye-dropper (improved, state management is inside the hook)
6565- [x] use-favicon (improved, more flexible)
6666- [ ] use-fetch
6767- [ ] use-focus-return
@@ -74,7 +74,7 @@ Based on the [@mantine/hooks](https://github.com/mantinedev/mantine/tree/master/
7474- [x] use-hotkeys
7575- [x] use-hover
7676- [x] ~~ use-id~~ (Solid has [ ` createUniqueId ` ] ( https://docs.solidjs.com/reference/component-apis/create-unique-id ) )
77- - [x] use-idle (There is [ ` createIdleTimer ` ] ( https://primitives.solidjs.community/package/idle/ ) solid-primitives as well)
77+ - [x] use-idle (Added, but note that there is [ ` createIdleTimer ` ] ( https://primitives.solidjs.community/package/idle/ ) solid-primitives as well)
7878- [ ] use-in-viewport
7979- [ ] use-input-state
8080- [ ] use-intersection
Original file line number Diff line number Diff line change 1+ ``` tsx
2+ const { color, supported, pickColor } = useEyeDropper ();
3+
4+ return (
5+ <div >
6+ <button onClick = { pickColor } disabled = { ! supported ()} >
7+ Pick Color
8+ </button >
9+
10+ <div >
11+ Current Color: <span style = { { height: 32 , width: 32 , ' background-color' : color () }} />
12+ </div >
13+
14+ <Show when = { supported () !== undefined && ! supported ()} >
15+ <span >Your browser does not support EyeDropper.</span >
16+ </Show >
17+ </div >
18+ );
19+ ```
Original file line number Diff line number Diff line change 1+ import { useEyeDropper } from 'src' ;
2+ import { ExampleBase } from '../example-base' ;
3+ import Code from './use-eye-dropper.code.mdx' ;
4+
5+ import { IconEyeDropper } from 'dev/icons' ;
6+ import { Show } from 'solid-js' ;
7+ import { useMDXComponents } from 'solid-jsx' ;
8+
9+ export function UseEyeDropperExample ( ) {
10+ const { color, supported, pickColor } = useEyeDropper ( ) ;
11+
12+ // @ts -ignore
13+ const components : any = useMDXComponents ( ) ;
14+
15+ return (
16+ < ExampleBase
17+ title = "useEyeDropper"
18+ description = "A hook that gives you the ability to open the browser's EyeDropper API and save it to a signal."
19+ code = { < Code components = { components } /> }
20+ >
21+ < div class = "flex h-full w-full flex-col items-center justify-center gap-5 rounded-md border p-3 py-10 text-center" >
22+ < div class = "flex items-center gap-x-2" >
23+ < button class = "transition active:scale-95" onClick = { pickColor } disabled = { ! supported ( ) } >
24+ < IconEyeDropper />
25+ </ button >
26+
27+ < div class = "flex items-center gap-x-2 text-sm" >
28+ Picked Color: { color ( ) }
29+ < div class = "h-8 w-8 rounded-full border" style = { { 'background-color' : color ( ) } } />
30+ </ div >
31+ </ div >
32+
33+ < Show when = { supported ( ) !== undefined && ! supported ( ) } >
34+ < span class = "text-xs text-red-500" > Your browser does not support EyeDropper.</ span >
35+ </ Show >
36+ </ div >
37+ </ ExampleBase >
38+ ) ;
39+ }
Original file line number Diff line number Diff line change 1+ import { JSX , VoidProps } from 'solid-js' ;
2+
3+ export default function EyeDropper ( props : VoidProps < JSX . SvgSVGAttributes < SVGSVGElement > > ) {
4+ return (
5+ < svg xmlns = "http://www.w3.org/2000/svg" width = "32" height = "32" viewBox = "0 0 256 256" { ...props } >
6+ < g fill = "currentColor" >
7+ < path
8+ d = "m207.8 87.6l-25.37 25.53l4.89 4.88a16 16 0 0 1 0 22.64l-9 9a8 8 0 0 1-11.32 0l-60.68-60.7a8 8 0 0 1 0-11.32l9-9a16 16 0 0 1 22.63 0l4.88 4.89l25-25.11c10.79-10.79 28.37-11.45 39.45-1a28 28 0 0 1 .52 40.19"
9+ opacity = ".2"
10+ />
11+ < path d = "M224 67.3a35.8 35.8 0 0 0-11.26-25.66c-14-13.28-36.72-12.78-50.62 1.13L142.8 62.2a24 24 0 0 0-33.14.77l-9 9a16 16 0 0 0 0 22.64l2 2.06l-51 51a39.75 39.75 0 0 0-10.53 38l-8 18.41A13.68 13.68 0 0 0 36 219.3a15.92 15.92 0 0 0 17.71 3.35L71.23 215a39.89 39.89 0 0 0 37.06-10.75l51-51l2.06 2.06a16 16 0 0 0 22.62 0l9-9a24 24 0 0 0 .74-33.18l19.75-19.87A35.75 35.75 0 0 0 224 67.3M97 193a24 24 0 0 1-24 6a8 8 0 0 0-5.55.31l-18.1 7.91L57 189.41a8 8 0 0 0 .25-5.75A23.88 23.88 0 0 1 63 159l51-51l33.94 34ZM202.13 82l-25.37 25.52a8 8 0 0 0 0 11.3l4.89 4.89a8 8 0 0 1 0 11.32l-9 9L112 83.26l9-9a8 8 0 0 1 11.31 0l4.89 4.89a8 8 0 0 0 5.65 2.34a8 8 0 0 0 5.66-2.36l24.94-25.09c7.81-7.82 20.5-8.18 28.29-.81a20 20 0 0 1 .39 28.7Z" />
12+ </ g >
13+ </ svg >
14+ ) ;
15+ }
Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ import packageJSON from 'src/../package.json';
55// Hooks
66import { UseClickOutsideExample } from 'dev/components/examples/use-click-outside/use-click-outside.example' ;
77import { UseElementSizeExample } from 'dev/components/examples/use-element-size/use-element-size.example' ;
8+ import { UseEyeDropperExample } from 'dev/components/examples/use-eye-dropper/use-eye-dropper.example' ;
89import { UseFaviconExample } from 'dev/components/examples/use-favicon/use-favicon.example' ;
910import { UseHotkeysExample } from 'dev/components/examples/use-hotkeys/use-hotkeys.example' ;
1011import { UseHoverExample } from 'dev/components/examples/use-hover/use-hover.example' ;
@@ -90,6 +91,10 @@ export default function HomePage() {
9091 title : 'useLocalStorage' ,
9192 example : < UseLocalStorageExample /> ,
9293 } ,
94+ {
95+ title : 'useEyeDropper' ,
96+ example : < UseEyeDropperExample /> ,
97+ } ,
9398 ] ;
9499
95100 const filteredList = createMemo ( ( ) => {
Original file line number Diff line number Diff line change 11export * from './use-click-outside/use-click-outside' ;
2+ export * from './use-eye-dropper/use-eye-dropper' ;
23export * from './use-favicon/use-favicon' ;
34export * from './use-hotkeys/use-hotkeys' ;
45export * from './use-hover/use-hover' ;
Original file line number Diff line number Diff line change 1+ import { createSignal , onMount } from 'solid-js' ;
2+
3+ interface EyeDropperOpenOptions {
4+ signal ?: AbortSignal ;
5+ }
6+
7+ export interface EyeDropperOpenReturnType {
8+ sRGBHex : string ;
9+ }
10+
11+ function isOpera ( ) {
12+ return navigator . userAgent . includes ( 'OPR' ) ;
13+ }
14+
15+ /**
16+ * A hook that opens the browser's EyeDropper API.
17+ *
18+ * This has an improvement over Mantine's API. Mantine's is more low-level. Bagon
19+ * prepares states for you by default.
20+ */
21+ export function useEyeDropper ( ) {
22+ const [ color , setColor ] = createSignal < string > ( ) ;
23+ const [ error , setError ] = createSignal < Error | null > ( null ) ;
24+ const [ supported , setSupported ] = createSignal < boolean > ( ) ;
25+
26+ onMount ( ( ) => {
27+ setSupported ( typeof window !== 'undefined' && ! isOpera ( ) && 'EyeDropper' in window ) ;
28+ } ) ;
29+
30+ const open = (
31+ options : EyeDropperOpenOptions = { } ,
32+ ) : Promise < EyeDropperOpenReturnType | undefined > => {
33+ if ( supported ( ) ) {
34+ const eyeDropper = new ( window as any ) . EyeDropper ( ) ;
35+ return eyeDropper . open ( options ) ;
36+ }
37+
38+ return Promise . resolve ( undefined ) ;
39+ } ;
40+
41+ const pickColor = async ( ) => {
42+ try {
43+ const { sRGBHex } = ( await open ( ) ) ! ;
44+ setColor ( sRGBHex ) ;
45+ } catch ( e ) {
46+ setError ( e as Error ) ;
47+ }
48+ } ;
49+
50+ return {
51+ /**
52+ * Improved in bagon.
53+ * - true - supported.
54+ * - false - not supported.
55+ * - undefined - support is not checked yet (initial state so you can check this if you don't want a flicker before support is determined).
56+ */
57+ supported,
58+ open,
59+ /** Added in bagon. */
60+ error,
61+ /** Added in bagon. */
62+ color,
63+ /** Added in bagon. */
64+ pickColor,
65+ } ;
66+ }
You can’t perform that action at this time.
0 commit comments