All files / hooks/use-permission/src types.ts

0% Statements 0/0
0% Branches 0/0
0% Functions 0/0
0% Lines 0/0

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76                                                                                                                                                       
/**
 * Coarse lifecycle status for a permission query.
 *
 * - `idle` — no query has resolved yet (initial render, before the effect runs).
 * - `pending` — a `navigator.permissions.query()` call is in flight.
 * - `granted` / `denied` / `prompt` — the resolved {@link PermissionState}. These
 *   mirror the raw `state` field, so you can branch on either.
 * - `unsupported` — the Permissions API is unavailable in this environment
 *   (SSR, or a browser without `navigator.permissions`).
 * - `error` — the query rejected (e.g. an unknown permission name in a browser
 *   that throws instead of returning `denied`). See {@link UsePermissionReturn.error}.
 */
export type UsePermissionStatus =
  | "idle"
  | "pending"
  | "granted"
  | "denied"
  | "prompt"
  | "unsupported"
  | "error";
 
/**
 * Permission descriptor accepted by {@link usePermission}.
 *
 * A superset of the DOM `PermissionDescriptor` so that *all* permission names
 * typecheck — including the ones missing from the standard `PermissionName`
 * union in `lib.dom` (`'camera'`, `'microphone'`, `'clipboard-read'`, …) and the
 * extra fields required by specific permissions (`userVisibleOnly` for `'push'`,
 * `sysex` for `'midi'`, device fields for `'camera'`). The index signature keeps
 * it forward-compatible with descriptor fields not yet in the lib types.
 *
 * @example
 * ```ts
 * const camera: UsePermissionDescriptor = { name: "camera" };
 * const push: UsePermissionDescriptor = { name: "push", userVisibleOnly: true };
 * const midi: UsePermissionDescriptor = { name: "midi", sysex: true };
 * ```
 */
export interface UsePermissionDescriptor {
  /**
   * The permission name. Accepts the standard `PermissionName` values with
   * autocomplete, plus any other string (e.g. `'camera'`, `'microphone'`) that a
   * given browser supports.
   */
  // eslint-disable-next-line @typescript-eslint/ban-types
  name: PermissionName | (string & {});
  /** Required for the `'push'` permission — must be `true`, browsers reject `false`. */
  userVisibleOnly?: boolean;
  /** Requests SysEx access for the `'midi'` permission. */
  sysex?: boolean;
  /** Forward-compatible with descriptor fields not yet in the lib types. */
  [key: string]: unknown;
}
 
/**
 * Return value of {@link usePermission}.
 *
 * Destructure the field you need — the roadmap's `const { state } = usePermission(...)`
 * reads naturally, while `status`, `isSupported`, and `error` cover the async and
 * unsupported/error edges that a bare `PermissionState` cannot express.
 */
export interface UsePermissionReturn {
  /**
   * The raw permission state (`'granted' | 'denied' | 'prompt'`), or `null` until
   * the first query resolves and whenever the API is unsupported or the query
   * errored.
   */
  state: PermissionState | null;
  /** Coarse lifecycle status. See {@link UsePermissionStatus}. */
  status: UsePermissionStatus;
  /** Whether the Permissions API is available in the current environment. */
  isSupported: boolean;
  /** The error thrown by `navigator.permissions.query()`, if the query rejected. */
  error: Error | null;
}