Files
tools/vue/toolkit/src/composables/browser/useEyeDropper/index.ts
T
robonen ab6d8f6ce0
Publish to NPM / Check version changes and publish (push) Failing after 10m34s
build: bump new versions
2026-06-18 02:57:03 +07:00

99 lines
2.7 KiB
TypeScript

import { shallowRef } from 'vue';
import type { ComputedRef, ShallowRef } from 'vue';
import { defaultWindow } from '@/types';
import type { ConfigurableWindow } from '@/types';
import { useSupported } from '@/composables/utilities/useSupported';
export interface EyeDropperOpenOptions {
/**
* An `AbortSignal` that can be used to cancel the operation.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
*/
signal?: AbortSignal;
}
export interface EyeDropperResult {
/**
* The selected color, in sRGB hexadecimal format (e.g. `#a1b2c3`).
*/
sRGBHex: string;
}
export interface EyeDropper {
open: (options?: EyeDropperOpenOptions) => Promise<EyeDropperResult>;
[Symbol.toStringTag]: 'EyeDropper';
}
export type EyeDropperConstructor = new () => EyeDropper;
export interface UseEyeDropperOptions extends ConfigurableWindow {
/**
* Initial `sRGBHex` value before any color has been picked.
*
* @default ''
*/
initialValue?: string;
}
export interface UseEyeDropperReturn {
/**
* Whether the [EyeDropper API](https://developer.mozilla.org/en-US/docs/Web/API/EyeDropper) is supported
*/
isSupported: ComputedRef<boolean>;
/**
* The most recently picked color, in sRGB hexadecimal format
*/
sRGBHex: ShallowRef<string>;
/**
* Open the eyedropper and let the user pick a color. Resolves with the
* result, or `undefined` when the API is unsupported.
*/
open: (openOptions?: EyeDropperOpenOptions) => Promise<EyeDropperResult | undefined>;
}
/**
* @name useEyeDropper
* @category Browser
* @description Reactive wrapper around the [EyeDropper API](https://developer.mozilla.org/en-US/docs/Web/API/EyeDropper) for picking colors from the screen.
*
* @param {UseEyeDropperOptions} [options={}] Options
* @returns {UseEyeDropperReturn} `isSupported`, `sRGBHex`, and `open()`
*
* @example
* const { isSupported, sRGBHex, open } = useEyeDropper();
* if (isSupported.value)
* await open();
*
* @since 0.0.14
*/
export function useEyeDropper(options: UseEyeDropperOptions = {}): UseEyeDropperReturn {
const {
window = defaultWindow,
initialValue = '',
} = options;
const isSupported = useSupported(() => !!window && 'EyeDropper' in window);
const sRGBHex = shallowRef(initialValue);
async function open(openOptions?: EyeDropperOpenOptions): Promise<EyeDropperResult | undefined> {
if (!isSupported.value || !window)
return;
const EyeDropperCtor = (window as unknown as { EyeDropper: EyeDropperConstructor }).EyeDropper;
const eyeDropper = new EyeDropperCtor();
const result = await eyeDropper.open(openOptions);
sRGBHex.value = result.sRGBHex;
return result;
}
return {
isSupported,
sRGBHex,
open,
};
}