{"version":3,"file":"SkipToContent.cjs","names":["_styled","_interopRequireDefault","require","_react","_BaseButton","_i18n","_OdysseyDesignTokensContext","_uiShellSharedConstants","_jsxRuntime","e","__esModule","default","StyledContainer","styled","shouldForwardProp","prop","odysseyDesignTokens","left","Spacing4","position","top","Spacing3","zIndex","SKIP_LINKS_Z_INDEX","clip","clipPath","height","overflow","pointerEvents","whiteSpace","width","SkipToContent","appElement","useOdysseyDesignTokens","t","useTranslation","containerRef","useRef","buttonRef","interceptedFromRef","useEffect","hasTabIndex","hasAttribute","hasOutlineStyle","style","getPropertyValue","setAttribute","setProperty","removeAttribute","removeProperty","stopInterceptor","document","removeEventListener","handleKeyDown","keyboardEvent","key","shiftKey","current","contains","activeElement","preventDefault","requestAnimationFrame","focus","addEventListener","resumeFromInterceptedPosition","focusMainContent","useCallback","jsx","ref","children","BaseButton","id","label","onClick","variant","MemoizedSkipToContent","exports","memo","displayName"],"sources":["../../../src/ui-shell/SkipToContent.tsx"],"sourcesContent":["/*!\n * Copyright (c) 2026-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 styled from \"@emotion/styled\";\nimport { memo, useCallback, useEffect, useRef } from \"react\";\n\nimport { BaseButton } from \"../Buttons/BaseButton.js\";\nimport { useTranslation } from \"../i18n.generated/i18n.js\";\nimport { FocusHandle } from \"../inputUtils.js\";\nimport {\n  type DesignTokens,\n  useOdysseyDesignTokens,\n} from \"../OdysseyDesignTokensContext.js\";\nimport { SKIP_LINKS_Z_INDEX } from \"./uiShellSharedConstants.js\";\n\nconst StyledContainer = styled(\"div\", {\n  shouldForwardProp: (prop) => prop !== \"odysseyDesignTokens\",\n})<{ odysseyDesignTokens: DesignTokens }>(({ odysseyDesignTokens }) => ({\n  left: odysseyDesignTokens.Spacing4,\n  position: \"fixed\",\n  top: odysseyDesignTokens.Spacing3,\n  zIndex: SKIP_LINKS_Z_INDEX,\n  // Visually hidden when not focused — the \"sr-only\" pattern. https://www.a11yproject.com/posts/how-to-hide-content/\n  //\n  // We found this method via the A11y Project. It fixes axe color-contrast violations that `opacity: 0` triggers (axe still evaluates contrast on opacity-0 elements because they occupy space in the layout). The sr-only pattern collapses the element to 1×1 px and clips it, which axe — and every modern screen reader — treats as fully hidden. Unlike a large negative `left` offset, it also avoids any risk of a phantom scrollbar.\n  \"&:not(:focus-within)\": {\n    clip: \"rect(0 0 0 0)\",\n    clipPath: \"inset(50%)\",\n    height: \"1px\",\n    overflow: \"hidden\",\n    pointerEvents: \"none\",\n    whiteSpace: \"nowrap\",\n    width: \"1px\",\n  },\n}));\n\ntype SkipToContentProps = {\n  appElement: HTMLDivElement | null;\n};\n\nconst SkipToContent = ({ appElement }: SkipToContentProps) => {\n  const odysseyDesignTokens = useOdysseyDesignTokens();\n  const { t } = useTranslation();\n\n  const containerRef = useRef<HTMLDivElement>(null);\n  const buttonRef = useRef<FocusHandle>(null);\n  const interceptedFromRef = useRef<HTMLElement | null>(null);\n\n  useEffect(() => {\n    if (appElement) {\n      const hasTabIndex = appElement.hasAttribute(\"tabindex\");\n      const hasOutlineStyle =\n        appElement.style.getPropertyValue(\"outline\") !== \"\";\n\n      if (!hasTabIndex) {\n        appElement.setAttribute(\"tabindex\", \"-1\");\n      }\n      if (!hasOutlineStyle) {\n        appElement.style.setProperty(\"outline\", \"none\");\n      }\n\n      return () => {\n        if (!hasTabIndex) {\n          appElement.removeAttribute(\"tabindex\");\n        }\n        if (!hasOutlineStyle) {\n          appElement.style.removeProperty(\"outline\");\n        }\n      };\n    }\n\n    return;\n  }, [appElement]);\n\n  useEffect(() => {\n    const stopInterceptor = () => {\n      document.removeEventListener(\"keydown\", handleKeyDown);\n      document.removeEventListener(\"pointerdown\", stopInterceptor);\n    };\n\n    const handleKeyDown = (keyboardEvent: globalThis.KeyboardEvent) => {\n      if (\n        keyboardEvent.key === \"Tab\" &&\n        !keyboardEvent.shiftKey &&\n        !containerRef.current?.contains(document.activeElement)\n      ) {\n        interceptedFromRef.current = document.activeElement as HTMLElement;\n        keyboardEvent.preventDefault();\n        stopInterceptor();\n\n        requestAnimationFrame(() => {\n          buttonRef.current?.focus();\n        });\n      }\n    };\n\n    document.addEventListener(\"keydown\", handleKeyDown);\n    document.addEventListener(\"pointerdown\", stopInterceptor);\n\n    return stopInterceptor;\n  }, []);\n\n  useEffect(() => {\n    const resumeFromInterceptedPosition = (\n      keyboardEvent: globalThis.KeyboardEvent,\n    ) => {\n      if (\n        interceptedFromRef.current &&\n        keyboardEvent.key === \"Tab\" &&\n        !keyboardEvent.shiftKey &&\n        containerRef.current?.contains(document.activeElement)\n      ) {\n        interceptedFromRef.current.focus();\n        interceptedFromRef.current = null;\n      }\n    };\n\n    document.addEventListener(\"keydown\", resumeFromInterceptedPosition);\n\n    return () => {\n      document.removeEventListener(\"keydown\", resumeFromInterceptedPosition);\n    };\n  }, []);\n\n  const focusMainContent = useCallback(() => {\n    appElement?.focus();\n  }, [appElement]);\n\n  return (\n    <StyledContainer\n      odysseyDesignTokens={odysseyDesignTokens}\n      ref={containerRef}\n    >\n      <BaseButton\n        buttonRef={buttonRef}\n        id=\"skip-to-main-content\"\n        label={t(\"skiplinks.main\")}\n        onClick={focusMainContent}\n        variant=\"primary\"\n      />\n    </StyledContainer>\n  );\n};\n\nconst MemoizedSkipToContent = memo(SkipToContent);\nMemoizedSkipToContent.displayName = \"SkipToContent\";\n\nexport { MemoizedSkipToContent as SkipToContent };\n"],"mappings":"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","ignoreList":[]}