{"version":3,"file":"useMediaQuery.cjs","names":["_react","require","_shim","useMediaQuery","mediaQuery","normalizedMediaQuery","replace","supportsMatchMedia","window","matchMedia","mediaQueryList","useMemo","subscribe","useCallback","notifyReactOfChange","addEventListener","removeEventListener","getSnapshot","matches","getServerSnapshot","useSyncExternalStore","exports","ABSOLUTE_MINIMUM_WIDTH","ABSOLUTE_MINIMUM_HEIGHT","COMPACT_WIDTH_ACTIVATION_BUFFER","COMPACT_HEIGHT_ACTIVATION_BUFFER","COMPACT_MAX_WIDTH","COMPACT_MAX_HEIGHT","COMPACT_CONDITION_BY_AXIS","height","width","toCompactMediaQuery","firstAxis","otherAxis","filter","axis","undefined","map","join","useCompactViewportMatches","isWithinCompactWidth","isWithinCompactHeight","isWithinCompactWidthOrHeight"],"sources":["../../../src/theme/useMediaQuery.ts"],"sourcesContent":["/*!\n * Copyright (c) 2025-present, Okta, Inc. and/or its affiliates. All rights reserved.\n * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the \"License.\")\n *\n * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *\n * See the License for the specific language governing permissions and limitations under the License.\n */\n\nimport { useCallback, useMemo } from \"react\";\n// React's `useSyncExternalStore` does not exist before React 18. Import it from the official backport shim so the hook resolves on React 16.8+/17 consumers too; the shim delegates to the native hook when running on React 18.\nimport { useSyncExternalStore } from \"use-sync-external-store/shim\";\n\nimport { StringWithValue } from \"../StringWithValue.js\";\n\n/**\n * Subscribes to a CSS media query and returns whether it currently matches, re-rendering when the match state changes. Accepts the query with or without a leading `@media` prefix. Uses `useSyncExternalStore` so the match is read synchronously at render time (no tearing, no stale first frame), and degrades to `false` in environments without `matchMedia` (server render, jsdom).\n */\nexport const useMediaQuery = <MediaQuery extends string>(\n  mediaQuery: StringWithValue<MediaQuery>,\n) => {\n  // A leading `@media` prefix is valid CSS but is rejected by `window.matchMedia`, so strip it to accept either form of the query.\n  const normalizedMediaQuery = mediaQuery.replace(/^@media( ?)/m, \"\");\n\n  // jsdom and server environments may not implement `matchMedia`. Guard so the hook degrades to \"no match\" instead of throwing during render.\n  const supportsMatchMedia =\n    typeof window !== \"undefined\" && typeof window.matchMedia !== \"undefined\";\n\n  const mediaQueryList = useMemo(\n    () => (supportsMatchMedia ? window.matchMedia(normalizedMediaQuery) : null),\n    [supportsMatchMedia, normalizedMediaQuery],\n  );\n\n  // `useSyncExternalStore` reads the match synchronously at render time, so every component in a concurrent render sees a consistent value (no tearing) and there is no stale first frame before an effect runs.\n  const subscribe = useCallback(\n    (notifyReactOfChange: () => void) => {\n      if (!mediaQueryList) {\n        return () => {};\n      }\n\n      mediaQueryList.addEventListener(\"change\", notifyReactOfChange);\n\n      return () => {\n        mediaQueryList.removeEventListener(\"change\", notifyReactOfChange);\n      };\n    },\n    [mediaQueryList],\n  );\n\n  const getSnapshot = useCallback(\n    () => mediaQueryList?.matches ?? false,\n    [mediaQueryList],\n  );\n\n  // Server render (and any environment without `matchMedia`) resolves to \"no match\", consistent with the guard above.\n  const getServerSnapshot = useCallback(() => false, []);\n\n  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n};\n\n/**\n * The absolute minimum viewport width, in CSS pixels, that the UI supports. WCAG 1.4.10 (Reflow) requires content to remain usable down to 320px, so this is the hard floor below which layout must not lose information or functionality.\n */\nexport const ABSOLUTE_MINIMUM_WIDTH = 320;\n\n/**\n * The absolute minimum viewport height, in CSS pixels, that the UI supports: the hard floor below which layout must not lose information or functionality.\n */\nexport const ABSOLUTE_MINIMUM_HEIGHT = 256;\n\n// Each axis starts adapting a set distance above its absolute-minimum floor so the UI gets breathing room instead of snapping exactly at the floor. Width uses a small buffer just above the reflow floor. Height uses a much larger one: around 500px the app starts to feel cramped (still usable, but not pleasant), so we adapt the layout there rather than waiting for the 256px floor.\nconst COMPACT_WIDTH_ACTIVATION_BUFFER = 80;\nconst COMPACT_HEIGHT_ACTIVATION_BUFFER = 244;\n\n/**\n * The widest viewport, in CSS pixels, still treated as compact-width. At or below this width the layout adapts toward the absolute-minimum floor.\n */\nexport const COMPACT_MAX_WIDTH =\n  ABSOLUTE_MINIMUM_WIDTH + COMPACT_WIDTH_ACTIVATION_BUFFER;\n\n/**\n * The tallest viewport, in CSS pixels, still treated as compact-height. At or below this height the layout adapts toward the absolute-minimum floor.\n */\nexport const COMPACT_MAX_HEIGHT =\n  ABSOLUTE_MINIMUM_HEIGHT + COMPACT_HEIGHT_ACTIVATION_BUFFER;\n\n/**\n * The `matchMedia` and CSS condition for each axis. This is the only place that turns a threshold into a condition string, so the hook and the style overrides cannot drift.\n */\nconst COMPACT_CONDITION_BY_AXIS = {\n  height: `(max-height: ${COMPACT_MAX_HEIGHT}px)`,\n  width: `(max-width: ${COMPACT_MAX_WIDTH}px)`,\n} as const;\n\n/** The axis names that `toCompactMediaQuery` accepts. */\nexport type CompactViewportAxis = keyof typeof COMPACT_CONDITION_BY_AXIS;\n\n/**\n * Builds the compact CSS `@media` rule for the given axes. The rule matches when any one of those axes is compact. Use the result as a key in a style override object, where a React hook cannot run.\n *\n * Give the name of an axis, not a condition string. The function holds the threshold, so no caller can pass a wrong pixel value, and the compact conditions need no export at all.\n *\n * A viewport has two axes, so the parameters spell out every legal call: one axis, then at most one axis that the first call did not name. TypeScript rejects a call with no axis, a repeated axis, or a third axis.\n *\n * Call `useCompactViewportMatches` in a component instead.\n *\n * This function stays internal to the package. Add it to the public `index.ts` only when a consumer outside the package needs it.\n */\nexport const toCompactMediaQuery = <FirstAxis extends CompactViewportAxis>(\n  firstAxis: FirstAxis,\n  otherAxis?: Exclude<CompactViewportAxis, FirstAxis>,\n) =>\n  `@media ${[firstAxis, otherAxis]\n    .filter((axis) => axis !== undefined)\n    .map((axis) => COMPACT_CONDITION_BY_AXIS[axis])\n    .join(\",\")}`;\n\n/**\n * Reports whether the viewport is within the compact range, i.e. approaching the absolute minimum supported size along either axis (each axis activates at its own buffer above the floor). Returns a match per dimension plus a combined flag so callers can adapt layout (e.g. switch a Dialog to full-screen) as the viewport approaches the WCAG 1.4.10 reflow floor rather than snapping exactly at it.\n *\n * `isWithinCompactWidthOrHeight` is `true` when either dimension is compact. It matches a style override that gives both axes to `toCompactMediaQuery`.\n */\nexport const useCompactViewportMatches = () => {\n  const isWithinCompactWidth = useMediaQuery(COMPACT_CONDITION_BY_AXIS.width);\n  const isWithinCompactHeight = useMediaQuery(COMPACT_CONDITION_BY_AXIS.height);\n\n  return useMemo(\n    () => ({\n      isWithinCompactWidth,\n      isWithinCompactHeight,\n      isWithinCompactWidthOrHeight:\n        isWithinCompactWidth || isWithinCompactHeight,\n    }),\n    [isWithinCompactWidth, isWithinCompactHeight],\n  );\n};\n"],"mappings":"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","ignoreList":[]}