{"version":3,"sources":["../src/hooks/useA11yPreferences.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport {\n  useAccessibilityStore,\n  getColorBlindClass,\n  type AccessibilityPreferences,\n  type ContrastMode,\n  type SaturationMode,\n  type SpacingLevel,\n} from '../store/accessibilityStore';\n\n/**\n * Mapeia cada preferência para a classe que deve ser aplicada no\n * `documentElement`. Valores no estado padrão (`normal` ou 0) não\n * adicionam classe alguma — assim a página fica intacta quando o\n * usuário não ativou nada.\n */\ntype ClassMap = Partial<Record<keyof AccessibilityPreferences, string>>;\n\nconst CONTRAST_CLASS: Record<ContrastMode, string | null> = {\n  normal: null,\n  high: 'a11y-contrast-high',\n  inverted: 'a11y-contrast-inverted',\n};\n\nconst SATURATION_CLASS: Record<SaturationMode, string | null> = {\n  normal: null,\n  grayscale: 'a11y-saturation-grayscale',\n  low: 'a11y-saturation-low',\n};\n\nconst LEVEL_PREFIX: Record<\n  'fontSize' | 'letterSpacing' | 'lineSpacing',\n  string\n> = {\n  fontSize: 'a11y-font-',\n  letterSpacing: 'a11y-letter-spacing-',\n  lineSpacing: 'a11y-line-spacing-',\n};\n\n/** Lista de todas as classes que o widget pode aplicar — usada para limpar */\nconst ALL_A11Y_CLASSES: readonly string[] = [\n  'a11y-contrast-high',\n  'a11y-contrast-inverted',\n  'a11y-saturation-grayscale',\n  'a11y-saturation-low',\n  'a11y-font-1',\n  'a11y-font-2',\n  'a11y-font-3',\n  'a11y-letter-spacing-1',\n  'a11y-letter-spacing-2',\n  'a11y-letter-spacing-3',\n  'a11y-line-spacing-1',\n  'a11y-line-spacing-2',\n  'a11y-line-spacing-3',\n  'a11y-highlight-links',\n  'a11y-no-animations',\n  'a11y-big-cursor',\n  'a11y-dyslexia-font',\n  'a11y-cb-protanopia',\n  'a11y-cb-deuteranopia',\n  'a11y-cb-tritanopia',\n];\n\nconst buildLevelClass = (\n  prefix: string,\n  level: SpacingLevel\n): string | null => {\n  if (level === 0) return null;\n  return `${prefix}${level}`;\n};\n\nconst buildClassMap = (prefs: AccessibilityPreferences): ClassMap => ({\n  contrastMode: CONTRAST_CLASS[prefs.contrastMode] ?? undefined,\n  saturationMode: SATURATION_CLASS[prefs.saturationMode] ?? undefined,\n  fontSize: buildLevelClass(LEVEL_PREFIX.fontSize, prefs.fontSize) ?? undefined,\n  letterSpacing:\n    buildLevelClass(LEVEL_PREFIX.letterSpacing, prefs.letterSpacing) ??\n    undefined,\n  lineSpacing:\n    buildLevelClass(LEVEL_PREFIX.lineSpacing, prefs.lineSpacing) ?? undefined,\n  highlightLinks: prefs.highlightLinks ? 'a11y-highlight-links' : undefined,\n  pauseAnimations: prefs.pauseAnimations ? 'a11y-no-animations' : undefined,\n  bigCursor: prefs.bigCursor ? 'a11y-big-cursor' : undefined,\n  dyslexiaFont: prefs.dyslexiaFont ? 'a11y-dyslexia-font' : undefined,\n  colorBlindMode: getColorBlindClass(prefs.colorBlindMode) ?? undefined,\n});\n\n/**\n * Aplica/remove as classes de acessibilidade no `documentElement`\n * conforme as preferências atuais. Limpa tudo antes de aplicar para\n * garantir um estado consistente mesmo se prefs forem alteradas\n * fora do fluxo normal.\n */\nconst syncDom = (prefs: AccessibilityPreferences) => {\n  if (typeof document === 'undefined') return;\n  const root = document.documentElement;\n\n  ALL_A11Y_CLASSES.forEach((cls) => root.classList.remove(cls));\n\n  const classMap = buildClassMap(prefs);\n  Object.values(classMap).forEach((cls) => {\n    if (cls) root.classList.add(cls);\n  });\n};\n\n/**\n * Hook que sincroniza o store de acessibilidade com o DOM.\n *\n * Deve ser chamado uma vez no nível raiz da aplicação (o\n * componente `AccessibilityWidget` já faz isso). Cada vez que\n * uma preferência muda, as classes correspondentes são aplicadas\n * no `<html>`, sem `!important` no nível do hook — a especificidade\n * é controlada pelo CSS.\n */\nexport const useA11yPreferences = () => {\n  const contrastMode = useAccessibilityStore((s) => s.contrastMode);\n  const saturationMode = useAccessibilityStore((s) => s.saturationMode);\n  const fontSize = useAccessibilityStore((s) => s.fontSize);\n  const letterSpacing = useAccessibilityStore((s) => s.letterSpacing);\n  const lineSpacing = useAccessibilityStore((s) => s.lineSpacing);\n  const highlightLinks = useAccessibilityStore((s) => s.highlightLinks);\n  const pauseAnimations = useAccessibilityStore((s) => s.pauseAnimations);\n  const bigCursor = useAccessibilityStore((s) => s.bigCursor);\n  const dyslexiaFont = useAccessibilityStore((s) => s.dyslexiaFont);\n  const readingAid = useAccessibilityStore((s) => s.readingAid);\n  const keyboardShortcut = useAccessibilityStore((s) => s.keyboardShortcut);\n  const colorBlindMode = useAccessibilityStore((s) => s.colorBlindMode);\n  const ttsMode = useAccessibilityStore((s) => s.ttsMode);\n  const ttsRate = useAccessibilityStore((s) => s.ttsRate);\n  const ttsVoiceId = useAccessibilityStore((s) => s.ttsVoiceId);\n  const librasEnabled = useAccessibilityStore((s) => s.librasEnabled);\n\n  useEffect(() => {\n    syncDom({\n      contrastMode,\n      saturationMode,\n      fontSize,\n      letterSpacing,\n      lineSpacing,\n      highlightLinks,\n      pauseAnimations,\n      bigCursor,\n      dyslexiaFont,\n      readingAid,\n      keyboardShortcut,\n      colorBlindMode,\n      ttsMode,\n      ttsRate,\n      ttsVoiceId,\n      librasEnabled,\n    });\n  }, [\n    contrastMode,\n    saturationMode,\n    fontSize,\n    letterSpacing,\n    lineSpacing,\n    highlightLinks,\n    pauseAnimations,\n    bigCursor,\n    dyslexiaFont,\n    colorBlindMode,\n  ]);\n};\n\nexport const __testing = {\n  buildClassMap,\n  syncDom,\n  ALL_A11Y_CLASSES,\n};\n"],"mappings":"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","names":[]}