@edrlab/thorium-web 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/{ThPreferencesAdapter-L1H6gzmu.d.mts → ThPreferencesAdapter-B3a-f5v-.d.mts} +25 -18
  2. package/dist/{ThSettingsWrapper-DWEA4hYF.d.mts → ThSettingsWrapper-DtzcwzYX.d.mts} +4 -4
  3. package/dist/{actions-BjeRjaJU.d.mts → actions-C33UN3Ji.d.mts} +18 -4
  4. package/dist/{actionsReducer-B32cq2mB.d.mts → actionsReducer-Bzcj3wk3.d.mts} +1 -1
  5. package/dist/{chunk-NUXGQWED.mjs → chunk-2NCN2AG2.mjs} +3 -3
  6. package/dist/{chunk-NUXGQWED.mjs.map → chunk-2NCN2AG2.mjs.map} +1 -1
  7. package/dist/{chunk-IVXRCKWR.mjs → chunk-2T65MDBR.mjs} +4 -4
  8. package/dist/{chunk-IVXRCKWR.mjs.map → chunk-2T65MDBR.mjs.map} +1 -1
  9. package/dist/{chunk-KVUG6BNI.mjs → chunk-63LKYJFG.mjs} +62 -56
  10. package/dist/chunk-63LKYJFG.mjs.map +1 -0
  11. package/dist/chunk-AQSJDL63.mjs +193 -0
  12. package/dist/chunk-AQSJDL63.mjs.map +1 -0
  13. package/dist/{chunk-TSLTLQ6O.mjs → chunk-BBCSLDQT.mjs} +144 -86
  14. package/dist/chunk-BBCSLDQT.mjs.map +1 -0
  15. package/dist/{chunk-QUSGPT5M.mjs → chunk-BCXKBHU3.mjs} +34 -15
  16. package/dist/chunk-BCXKBHU3.mjs.map +1 -0
  17. package/dist/{chunk-T5ENYSDJ.mjs → chunk-DQDOOTCE.mjs} +3 -3
  18. package/dist/{chunk-T5ENYSDJ.mjs.map → chunk-DQDOOTCE.mjs.map} +1 -1
  19. package/dist/chunk-GNROODJB.mjs +9 -0
  20. package/dist/chunk-GNROODJB.mjs.map +1 -0
  21. package/dist/{chunk-SZAVAQ6S.mjs → chunk-GRYEOCGD.mjs} +8 -5
  22. package/dist/chunk-GRYEOCGD.mjs.map +1 -0
  23. package/dist/{chunk-PXXWEMNL.mjs → chunk-KJ55Q63A.mjs} +220 -106
  24. package/dist/chunk-KJ55Q63A.mjs.map +1 -0
  25. package/dist/{chunk-5LUMM7FW.mjs → chunk-KOR74F6M.mjs} +9 -41
  26. package/dist/chunk-KOR74F6M.mjs.map +1 -0
  27. package/dist/{chunk-WLVE3WNW.mjs → chunk-PAFJZH7O.mjs} +12 -7
  28. package/dist/chunk-PAFJZH7O.mjs.map +1 -0
  29. package/dist/{chunk-XRFLDNAY.mjs → chunk-PRQBFBJ7.mjs} +123 -56
  30. package/dist/chunk-PRQBFBJ7.mjs.map +1 -0
  31. package/dist/{chunk-6MONB2DN.mjs → chunk-Y5X74VW7.mjs} +52 -146
  32. package/dist/chunk-Y5X74VW7.mjs.map +1 -0
  33. package/dist/{chunk-P6ILEQ5P.mjs → chunk-ZD4LTF6G.mjs} +17 -9
  34. package/dist/chunk-ZD4LTF6G.mjs.map +1 -0
  35. package/dist/components/Audio/index.css +12 -1
  36. package/dist/components/Audio/index.css.map +1 -1
  37. package/dist/components/Audio/index.d.mts +17 -15
  38. package/dist/components/Audio/index.mjs +11 -11
  39. package/dist/components/Epub/index.css +12 -1
  40. package/dist/components/Epub/index.css.map +1 -1
  41. package/dist/components/Epub/index.d.mts +14 -13
  42. package/dist/components/Epub/index.mjs +12 -12
  43. package/dist/components/Misc/index.mjs +5 -5
  44. package/dist/components/Reader/index.css +12 -1
  45. package/dist/components/Reader/index.css.map +1 -1
  46. package/dist/components/Reader/index.d.mts +12 -11
  47. package/dist/components/Reader/index.mjs +26 -24
  48. package/dist/components/Reader/index.mjs.map +1 -1
  49. package/dist/components/WebPub/index.css +12 -1
  50. package/dist/components/WebPub/index.css.map +1 -1
  51. package/dist/components/WebPub/index.d.mts +14 -13
  52. package/dist/components/WebPub/index.mjs +12 -12
  53. package/dist/core/Components/index.d.mts +7 -6
  54. package/dist/core/Components/index.mjs +2 -2
  55. package/dist/core/Helpers/index.d.mts +1 -1
  56. package/dist/core/Helpers/index.mjs +1 -1
  57. package/dist/core/Hooks/index.d.mts +6 -5
  58. package/dist/core/Hooks/index.mjs +1 -1
  59. package/dist/i18n/index.mjs +3 -3
  60. package/dist/keyboardUtilities-BCP3UcLb.d.mts +30 -0
  61. package/dist/lib/index.d.mts +17 -9
  62. package/dist/lib/index.mjs +2 -2
  63. package/dist/locales/da/thorium-web.json +37 -2
  64. package/dist/locales/fi/thorium-web.json +1 -1
  65. package/dist/locales/fr/thorium-web.json +1 -1
  66. package/dist/locales/he/thorium-web.json +9 -0
  67. package/dist/locales/it/thorium-web.json +22 -0
  68. package/dist/locales/lt/thorium-web.json +26 -1
  69. package/dist/locales/sv/thorium-web.json +22 -0
  70. package/dist/next-lib/index.mjs +1 -1
  71. package/dist/next-lib/index.mjs.map +1 -1
  72. package/dist/preferences/index.d.mts +14 -23
  73. package/dist/preferences/index.mjs +4 -4
  74. package/dist/{settingsReducer-DLaT2wUB.d.mts → settingsReducer-Pp9aoiiC.d.mts} +1 -1
  75. package/dist/{useAudioNavigator-CWXyNWq1.d.mts → useAudioNavigator-pGwxhXLj.d.mts} +4 -1
  76. package/dist/{useContrast-Bo7cDw_X.d.mts → useContrast-Bl08zDTU.d.mts} +2 -7
  77. package/dist/{usePreferences-D8NU1yhP.d.mts → usePreferences-Cy7-JN2x.d.mts} +4 -8
  78. package/dist/{useReaderTransitions-BQGzKeY2.d.mts → useReaderTransitions-Zvomj9RQ.d.mts} +30 -21
  79. package/package.json +7 -7
  80. package/dist/chunk-5LUMM7FW.mjs.map +0 -1
  81. package/dist/chunk-6MONB2DN.mjs.map +0 -1
  82. package/dist/chunk-B3WDMWCT.mjs +0 -9
  83. package/dist/chunk-B3WDMWCT.mjs.map +0 -1
  84. package/dist/chunk-KVUG6BNI.mjs.map +0 -1
  85. package/dist/chunk-MLEYTQGK.mjs +0 -60
  86. package/dist/chunk-MLEYTQGK.mjs.map +0 -1
  87. package/dist/chunk-P6ILEQ5P.mjs.map +0 -1
  88. package/dist/chunk-PXXWEMNL.mjs.map +0 -1
  89. package/dist/chunk-QUSGPT5M.mjs.map +0 -1
  90. package/dist/chunk-SZAVAQ6S.mjs.map +0 -1
  91. package/dist/chunk-TSLTLQ6O.mjs.map +0 -1
  92. package/dist/chunk-WLVE3WNW.mjs.map +0 -1
  93. package/dist/chunk-XRFLDNAY.mjs.map +0 -1
  94. package/dist/keyboardUtilities-BWAyLS_D.d.mts +0 -56
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/WebPub/Hooks/usePreferencesConfig.ts","../src/components/WebPub/Hooks/useInjectablesConfig.ts","../src/components/WebPub/Hooks/useReaderInit.ts","../src/components/WebPub/Hooks/useWebPubKeyboardPeripherals.ts","../src/components/WebPub/StatefulReader.tsx"],"names":["useMemo","useState","useRef","useCallback","timeline"],"mappings":"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","file":"chunk-63LKYJFG.mjs","sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\n\nimport { IWebPubPreferences, TextAlignment } from \"@readium/navigator\";\nimport { ThLineHeightOptions, ThSettingsKeys } from \"@/preferences/models\";\nimport { FontMetadata } from \"@/preferences/services/fonts\";\nimport { WebPubCSSSettings } from \"@/core/Hooks/WebPub/useWebPubSettingsCache\";\nimport { useSettingsComponentStatus } from \"@/components/Settings/hooks/useSettingsComponentStatus\";\nimport { useLineHeight } from \"@/components/Settings/Spacing/hooks/useLineHeight\";\n\ninterface UseWebPubPreferencesConfigProps {\n settings: WebPubCSSSettings;\n fontLanguage: string;\n hasDisplayTransformability: boolean;\n getFontMetadata: (fontFamily: string) => FontMetadata;\n}\n\nexport const useWebPubPreferencesConfig = ({\n settings,\n fontLanguage,\n hasDisplayTransformability,\n getFontMetadata,\n}: UseWebPubPreferencesConfigProps) => {\n const { processedValues: lineHeightOptions } = useLineHeight();\n const { isComponentUsed: isFontFamilyUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.fontFamily,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isFontWeightUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.fontWeight,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isHyphensUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.hyphens,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isLigaturesUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.ligatures,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isNoRubyUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.noRuby,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isLetterSpacingUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.letterSpacing,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isLineHeightUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.lineHeight,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isParagraphIndentUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.paragraphIndent,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isParagraphSpacingUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.paragraphSpacing,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isTextAlignUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.textAlign,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isTextNormalizeUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.textNormalize,\n publicationType: \"webpub\",\n });\n\n const { isComponentUsed: isWordSpacingUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.wordSpacing,\n publicationType: \"webpub\",\n });\n\n const webPubPreferences = useMemo(() => {\n const preferences: IWebPubPreferences = {\n zoom: settings.zoom\n };\n\n if (hasDisplayTransformability) {\n if (isFontFamilyUsed) preferences.fontFamily = getFontMetadata(settings.fontFamily[fontLanguage] ?? \"\")?.fontStack || null;\n if (isFontWeightUsed) preferences.fontWeight = settings.fontWeight;\n if (isLigaturesUsed) preferences.ligatures = settings.ligatures;\n if (isNoRubyUsed) preferences.noRuby = settings.noRuby;\n if (isLetterSpacingUsed) preferences.letterSpacing = settings.letterSpacing;\n if (isLineHeightUsed) preferences.lineHeight = settings.lineHeight === null\n ? null\n : lineHeightOptions[settings.lineHeight as ThLineHeightOptions.small | ThLineHeightOptions.medium | ThLineHeightOptions.large];\n if (isParagraphIndentUsed) preferences.paragraphIndent = settings.paragraphIndent;\n if (isParagraphSpacingUsed) preferences.paragraphSpacing = settings.paragraphSpacing;\n if (isTextAlignUsed) preferences.textAlign = settings.textAlign as TextAlignment | null | undefined;\n if (isHyphensUsed && settings.textAlign !== \"publisher\") preferences.hyphens = settings.hyphens;\n if (isTextNormalizeUsed) preferences.textNormalization = settings.textNormalization;\n if (isWordSpacingUsed) preferences.wordSpacing = settings.wordSpacing;\n }\n\n return preferences;\n }, [\n settings,\n fontLanguage,\n hasDisplayTransformability,\n getFontMetadata,\n isFontFamilyUsed,\n isFontWeightUsed,\n isHyphensUsed,\n isLigaturesUsed,\n isNoRubyUsed,\n isLetterSpacingUsed,\n isLineHeightUsed,\n isParagraphIndentUsed,\n isParagraphSpacingUsed,\n isTextAlignUsed,\n isTextNormalizeUsed,\n isWordSpacingUsed,\n lineHeightOptions\n ]);\n\n return { webPubPreferences };\n};\n","\"use client\";\n\nimport { useMemo } from \"react\";\n\nimport { IInjectablesConfig } from \"@readium/navigator\";\nimport { InjectableFontResources } from \"@/preferences/services/fonts\";\n\ninterface UseWebPubInjectablesConfigProps {\n isFontFamilyUsed: boolean;\n fontLanguage: string;\n getFontInjectables: (options?: { language?: string } | { key?: string }, optimize?: boolean) => InjectableFontResources | null;\n}\n\nexport const useWebPubInjectablesConfig = ({\n isFontFamilyUsed,\n fontLanguage,\n getFontInjectables,\n}: UseWebPubInjectablesConfigProps) => {\n const injectables = useMemo(() => {\n let injectablesConfig: IInjectablesConfig | undefined;\n\n if (isFontFamilyUsed) {\n const fontResources = getFontInjectables({ language: fontLanguage });\n if (fontResources) {\n injectablesConfig = {\n allowedDomains: fontResources.allowedDomains,\n rules: [{\n resources: [/\\.xhtml$/, /\\.html$/],\n prepend: fontResources.prepend,\n append: fontResources.append\n }]\n };\n }\n }\n\n return injectablesConfig;\n }, [isFontFamilyUsed, fontLanguage, getFontInjectables]);\n\n return { injectables };\n};\n","\"use client\";\n\nimport { useCallback, useEffect, useState, useRef } from \"react\";\n\nimport { Locator, Publication } from \"@readium/shared\";\nimport { WebPubNavigatorListeners, IContentProtectionConfig } from \"@readium/navigator\";\nimport { ThPreferences } from \"@/preferences\";\nimport { FontMetadata, InjectableFontResources } from \"@/preferences/services/fonts\";\nimport { WebPubStatelessCache } from \"@/core/Hooks/WebPub/useWebPubSettingsCache\";\n\nimport { useWebPubPreferencesConfig } from \"./usePreferencesConfig\";\nimport { useWebPubInjectablesConfig } from \"./useInjectablesConfig\";\nimport { useWebPubNavigator, WebPubNavigatorLoadProps } from \"@/core/Hooks/WebPub/useWebPubNavigator\";\nimport { IKeyboardPeripheralsConfig } from \"@readium/navigator\";\n\ninterface UseWebPubReaderInitProps {\n container: React.RefObject<HTMLDivElement | null>;\n publication: Publication | null;\n initialPosition: Locator | null;\n listeners: WebPubNavigatorListeners;\n preferences: ThPreferences;\n cache: React.RefObject<WebPubStatelessCache>;\n isFontFamilyUsed: boolean;\n fontLanguage: string;\n hasDisplayTransformability: boolean;\n getFontMetadata: (fontId: string) => FontMetadata;\n injectFontResources: (resources: InjectableFontResources | null) => void;\n removeFontResources: () => void;\n getFontInjectables: (options?: { language?: string } | { key?: string }, optimize?: boolean) => InjectableFontResources | null;\n contentProtectionConfig?: IContentProtectionConfig;\n keyboardPeripherals?: IKeyboardPeripheralsConfig;\n onNavigatorReady?: () => void;\n onNavigatorLoaded?: () => void;\n onCleanup?: () => void;\n}\n\nexport const useWebPubReaderInit = ({\n container,\n publication,\n initialPosition,\n listeners,\n preferences,\n cache,\n isFontFamilyUsed,\n fontLanguage,\n hasDisplayTransformability,\n getFontMetadata,\n injectFontResources,\n removeFontResources,\n getFontInjectables,\n contentProtectionConfig,\n keyboardPeripherals,\n onNavigatorReady,\n onNavigatorLoaded,\n onCleanup,\n}: UseWebPubReaderInitProps) => {\n const [navigatorReady, setNavigatorReady] = useState(false);\n\n const { webPubPreferences } = useWebPubPreferencesConfig({\n settings: cache.current.settings,\n fontLanguage,\n hasDisplayTransformability,\n getFontMetadata,\n });\n\n const { injectables } = useWebPubInjectablesConfig({\n isFontFamilyUsed,\n fontLanguage,\n getFontInjectables,\n });\n\n const handleCleanup = useCallback(() => {\n removeFontResources();\n onCleanup?.();\n }, [removeFontResources, onCleanup]);\n\n const { WebPubNavigatorLoad, WebPubNavigatorDestroy } = useWebPubNavigator();\n const isNavigatorLoadedWebPub = useRef(false);\n \n useEffect(() => {\n // Only initialize once, never re-render\n if (!publication || isNavigatorLoadedWebPub.current) return;\n\n // Add container protection\n if (!container.current) {\n console.error(\"Container ref is not available for navigator initialization\");\n return;\n }\n\n const config: WebPubNavigatorLoadProps = {\n container: container.current,\n publication,\n listeners,\n initialPosition: initialPosition ? new Locator(initialPosition) : undefined,\n preferences: webPubPreferences,\n defaults: {\n experiments: preferences.experiments?.webPub || null\n },\n injectables,\n contentProtection: contentProtectionConfig,\n keyboardPeripherals,\n };\n\n isNavigatorLoadedWebPub.current = true;\n \n // Call onNavigatorReady outside of navigator load\n onNavigatorReady?.();\n \n // Pass onNavigatorLoaded as the callback to WebPubNavigatorLoad\n WebPubNavigatorLoad(config, () => {\n // Set navigatorReady to true only after navigator actually loads\n setNavigatorReady(true);\n onNavigatorLoaded?.();\n });\n\n return () => {\n if (isNavigatorLoadedWebPub.current) {\n setNavigatorReady(false);\n WebPubNavigatorDestroy(() => {\n isNavigatorLoadedWebPub.current = false;\n handleCleanup();\n });\n }\n };\n }, []);\n\n // Handle font resource injection\n useEffect(() => {\n if (isFontFamilyUsed) {\n const fontResources = getFontInjectables({ language: fontLanguage });\n if (fontResources) {\n injectFontResources(getFontInjectables(undefined, true));\n }\n }\n }, [isFontFamilyUsed, fontLanguage, getFontInjectables, injectFontResources]);\n\n return {\n navigatorReady,\n };\n};\n","import { useMemo } from \"react\";\nimport { IKeyboardPeripheralsConfig } from \"@readium/navigator\";\nimport { useActionsPreferences } from \"@/preferences/hooks/useActionsPreferences\";\nimport { NavPeripheralType, toActionPeripheralType, ZOOM_IN_KEY_COMBOS, ZOOM_OUT_KEY_COMBOS } from \"@/helpers/peripherals\";\n\nexport const useWebPubKeyboardPeripherals = (): IKeyboardPeripheralsConfig => {\n const { actionsKeys } = useActionsPreferences();\n\n return useMemo(() => {\n const config: IKeyboardPeripheralsConfig = [\n { type: NavPeripheralType.zoomIn, keyCombos: [...ZOOM_IN_KEY_COMBOS] },\n { type: NavPeripheralType.zoomOut, keyCombos: [...ZOOM_OUT_KEY_COMBOS] },\n ];\n\n for (const [key, tokens] of Object.entries(actionsKeys)) {\n const shortcut = tokens?.shortcut;\n if (shortcut) config.push({ type: toActionPeripheralType(key), keyCombos: shortcut.keyCombos });\n }\n\n return config;\n }, [actionsKeys]);\n};\n","\"use client\";\n\nimport { useState, useRef, useCallback, useMemo, useLayoutEffect } from \"react\";\n\nimport readerStyles from \"../assets/styles/thorium-web.reader.app.module.css\";\n\nimport { StatefulReaderProps } from \"../Reader/StatefulReaderWrapper\";\n\nimport {\n ThLayoutUI,\n ThDocumentTitleFormat,\n ThProgressionFormat, \n ThSpacingSettingsKeys,\n ThSettingsKeys\n} from \"@/preferences/models\";\n\nimport { ThPluginRegistry } from \"../Plugins/PluginRegistry\";\n\nimport { ThPluginProvider } from \"../Plugins/PluginProvider\";\nimport { NavigatorProvider } from \"@/core/Navigator\";\n\nimport {\n BasicTextSelection,\n ContextMenuEvent,\n FrameClickEvent,\n SuspiciousActivityEvent,\n} from \"@readium/navigator-html-injectables\";\nimport { WebPubNavigatorListeners } from \"@readium/navigator\";\nimport {\n Locator,\n Publication\n} from \"@readium/shared\";\n\nimport { StatefulDockingWrapper } from \"../Docking/StatefulDockingWrapper\";\nimport { StatefulReaderHeader } from \"../StatefulReaderHeader\";\nimport { StatefulReaderFooter } from \"../StatefulReaderFooter\";\nimport { PositionStorage } from \"../Reader/StatefulReaderWrapper\";\n\nimport { usePreferences } from \"@/preferences/hooks/usePreferences\";\nimport { useSettingsComponentStatus } from \"@/components/Settings/hooks/useSettingsComponentStatus\";\nimport { useWebPubNavigator } from \"@/core/Hooks/WebPub\";\nimport { useWebPubSettingsCache } from \"@/core/Hooks/WebPub/useWebPubSettingsCache\";\nimport { useWebPubReaderInit } from \"./Hooks/useReaderInit\";\nimport { useWebPubKeyboardPeripherals } from \"./Hooks/useWebPubKeyboardPeripherals\";\nimport { useFullscreen } from \"@/core/Hooks/useFullscreen\";\nimport { useI18n } from \"@/i18n/useI18n\";\nimport { useTimeline } from \"@/core/Hooks/useTimeline\";\nimport { usePositionStorage } from \"@/hooks/usePositionStorage\";\nimport { useDocumentTitle } from \"@/core/Hooks/useDocumentTitle\";\nimport { useSpacingPresets } from \"../Settings/Spacing/hooks/useSpacingPresets\";\nimport { useFonts } from \"@/core/Hooks/fonts/useFonts\";\n\nimport { useAppSelector, useAppDispatch } from \"@/lib/hooks\";\nimport { \n setLoading,\n setHovering, \n toggleImmersive, \n setFullscreen,\n} from \"@/lib/readerReducer\";\nimport { \n setTimeline,\n setPublicationStart,\n setPublicationEnd\n} from \"@/lib/publicationReducer\";\n\nimport classNames from \"classnames\";\nimport { createDefaultPlugin } from \"../Plugins/helpers/createDefaultPlugin\";\nimport { getReaderClassNames } from \"../Helpers/getReaderClassNames\";\nimport { resolveContentProtectionConfig } from \"@/preferences/models/protection\";\nimport { NavPeripheralType, fromActionPeripheralType } from \"@/helpers/peripherals\";\nimport { toggleActionOpen } from \"@/lib/actionsReducer\";\nimport { useZoomCallbacks } from \"@/components/Settings/hooks/useZoomCallbacks\";\n\nexport const ExperimentalWebPubStatefulReader = ({\n publication,\n localDataKey,\n plugins,\n positionStorage,\n containerRefSetter\n}: StatefulReaderProps) => {\n const [pluginsRegistered, setPluginsRegistered] = useState(false);\n\n useLayoutEffect(() => {\n if (plugins && plugins.length > 0) {\n plugins.forEach(plugin => {\n ThPluginRegistry.register(plugin);\n });\n } else {\n ThPluginRegistry.register(createDefaultPlugin());\n }\n setPluginsRegistered(true);\n }, [plugins]);\n\n if (!pluginsRegistered) {\n return null;\n }\n\n return (\n <>\n <ThPluginProvider>\n <StatefulReaderInner publication={ publication } localDataKey={ localDataKey } positionStorage={ positionStorage } containerRefSetter={ containerRefSetter } />\n </ThPluginProvider>\n </>\n );\n};\n\nconst StatefulReaderInner = ({ publication, localDataKey, positionStorage, containerRefSetter }: { publication: Publication; localDataKey: string | null; positionStorage?: PositionStorage; containerRefSetter?: (el: Element | null) => void }) => {\n const { preferences, getFontMetadata, getFontInjectables } = usePreferences();\n const { t } = useI18n();\n const { getEffectiveSpacingValue } = useSpacingPresets();\n const { injectFontResources, removeFontResources } = useFonts();\n\n // Check if font family component is being used\n const { isComponentUsed: isFontFamilyUsed } = useSettingsComponentStatus({\n settingsKey: ThSettingsKeys.fontFamily,\n publicationType: \"webpub\",\n });\n\n const container = useRef<HTMLDivElement>(null);\n\n const textAlign = useAppSelector(state => state.webPubSettings.textAlign);\n const fontFamily = useAppSelector(state => state.webPubSettings.fontFamily);\n const fontWeight = useAppSelector(state => state.webPubSettings.fontWeight);\n const hyphens = useAppSelector(state => state.webPubSettings.hyphens);\n const ligatures = useAppSelector(state => state.webPubSettings.ligatures);\n const noRuby = useAppSelector(state => state.webPubSettings.noRuby);\n const letterSpacing = getEffectiveSpacingValue(ThSpacingSettingsKeys.letterSpacing);\n const lineHeight = getEffectiveSpacingValue(ThSpacingSettingsKeys.lineHeight);\n const paragraphIndent = getEffectiveSpacingValue(ThSpacingSettingsKeys.paragraphIndent);\n const paragraphSpacing = getEffectiveSpacingValue(ThSpacingSettingsKeys.paragraphSpacing);\n const publisherStyles = useAppSelector(state => state.webPubSettings.publisherStyles);\n const textNormalization = useAppSelector(state => state.webPubSettings.textNormalization);\n const wordSpacing = getEffectiveSpacingValue(ThSpacingSettingsKeys.wordSpacing);\n const zoom = useAppSelector(state => state.webPubSettings.zoom);\n const fontLanguage = useAppSelector(state => state.publication.fontLanguage);\n const hasDisplayTransformability = useAppSelector(state => state.publication.hasDisplayTransformability);\n const isImmersive = useAppSelector(state => state.reader.isImmersive);\n const isHovering = useAppSelector(state => state.reader.isHovering);\n const breakpoint = useAppSelector(state => state.theming.breakpoint);\n const containerBreakpoint = useAppSelector(state => state.theming.containerBreakpoint);\n\n const cache = useWebPubSettingsCache(\n fontFamily,\n fontWeight,\n hyphens,\n letterSpacing,\n ligatures,\n lineHeight,\n noRuby,\n paragraphIndent,\n paragraphSpacing,\n publisherStyles,\n textAlign,\n textNormalization,\n wordSpacing,\n zoom\n );\n\n const layoutUI = preferences.theming.layout.ui?.webPub || ThLayoutUI.stacked;\n\n const dispatch = useAppDispatch();\n const profile = useAppSelector(state => state.reader.profile);\n const keyboardPeripherals = useWebPubKeyboardPeripherals();\n\n const onFsChange = useCallback((isFullscreen: boolean) => {\n dispatch(setFullscreen(isFullscreen));\n }, [dispatch]);\n \n useFullscreen(onFsChange);\n\n const webPubNavigator = useWebPubNavigator();\n const { \n currentPositions,\n canGoBackward,\n canGoForward,\n } = webPubNavigator;\n\n const { setLocalData, getLocalData, localData } = usePositionStorage(localDataKey, positionStorage);\n\n const timeline = useTimeline({\n publication: publication,\n currentLocation: localData,\n currentPositions: currentPositions() || [],\n positionsList: undefined,\n onChange: (timeline) => {\n dispatch(setTimeline(timeline));\n }\n });\n\n const documentTitleFormat = preferences.metadata?.documentTitle?.format;\n\n let documentTitle: string | undefined;\n\n if (documentTitleFormat) {\n if (typeof documentTitleFormat === \"object\" && \"key\" in documentTitleFormat) {\n const translatedTitle = t(documentTitleFormat.key);\n documentTitle = translatedTitle !== documentTitleFormat.key \n ? translatedTitle \n : documentTitleFormat.fallback;\n } else {\n switch (documentTitleFormat) {\n case ThDocumentTitleFormat.title:\n documentTitle = timeline?.title;\n break;\n case ThDocumentTitleFormat.chapter:\n documentTitle = timeline?.progression?.currentChapter;\n break;\n case ThDocumentTitleFormat.titleAndChapter:\n if (timeline?.title && timeline?.progression?.currentChapter) {\n documentTitle = `${ timeline.title } – ${ timeline.progression.currentChapter }`;\n }\n break;\n case ThDocumentTitleFormat.none:\n documentTitle = undefined;\n break;\n default: \n documentTitle = documentTitleFormat;\n break;\n }\n }\n }\n\n useDocumentTitle(documentTitle);\n\n const toggleIsImmersive = useCallback(() => {\n // If tap/click in iframe, then header/footer no longer hoovering\n dispatch(setHovering(false));\n dispatch(toggleImmersive());\n }, [dispatch]);\n\n const { zoomIn, zoomOut } = useZoomCallbacks(webPubNavigator);\n\n const listeners: WebPubNavigatorListeners = useMemo(() => ({\n frameLoaded: async function (_wnd: Window): Promise<void> {},\n positionChanged: async function (locator: Locator): Promise<void> {\n setLocalData(locator);\n\n if (canGoBackward()) {\n dispatch(setPublicationStart(false));\n } else {\n dispatch(setPublicationStart(true));\n }\n\n if (canGoForward()) {\n dispatch(setPublicationEnd(false));\n } else {\n dispatch(setPublicationEnd(true));\n }\n },\n tap: function (_e: FrameClickEvent): boolean {\n toggleIsImmersive();\n return true;\n },\n click: function (_e: FrameClickEvent): boolean {\n return false;\n },\n zoom: function (_scale: number): void { },\n scroll: function (_delta: number): void { },\n customEvent: function (_key: string, _data: unknown): void { },\n handleLocator: function (locator: Locator): boolean {\n const href = locator.href;\n\n if (\n href.startsWith(\"http://\") ||\n href.startsWith(\"https://\") ||\n href.startsWith(\"mailto:\") ||\n href.startsWith(\"tel:\")\n ) {\n if (confirm(`Open \"${href}\" ?`)) window.open(href, \"_blank\");\n } else {\n console.warn(\"Unhandled locator\", locator);\n }\n return false;\n },\n textSelected: function (_selection: BasicTextSelection): void {},\n contentProtection: function (_type: string, _data: SuspiciousActivityEvent): void {},\n contextMenu: function (_data: ContextMenuEvent): void {},\n peripheral: function (data): void {\n switch (data.type) {\n case NavPeripheralType.zoomIn: zoomIn(); break;\n case NavPeripheralType.zoomOut: zoomOut(); break;\n default: {\n const actionKey = fromActionPeripheralType(data.type);\n if (actionKey && profile) dispatch(toggleActionOpen({ key: actionKey, profile }));\n }\n }\n },\n }), [setLocalData, canGoBackward, canGoForward, dispatch, toggleIsImmersive, zoomIn, zoomOut, profile]);\n\n const initialPosition = useMemo(() => getLocalData(), [getLocalData]);\n\n // Initialize reader using the new composite hook\n useWebPubReaderInit({\n container,\n publication,\n initialPosition,\n listeners,\n preferences,\n cache,\n isFontFamilyUsed,\n fontLanguage,\n hasDisplayTransformability,\n getFontMetadata,\n injectFontResources,\n removeFontResources,\n getFontInjectables,\n contentProtectionConfig: resolveContentProtectionConfig(preferences.contentProtection, t),\n keyboardPeripherals,\n onNavigatorReady: () => {\n dispatch(setLoading(false));\n },\n });\n\n return (\n <>\n <NavigatorProvider visualNavigator={ webPubNavigator }>\n <main className={ readerStyles.main }>\n <StatefulDockingWrapper>\n <div\n ref={ containerRefSetter }\n className={\n classNames(\n getReaderClassNames({\n isScroll: true,\n isImmersive,\n isHovering,\n layoutUI,\n breakpoint,\n containerBreakpoint\n })\n )\n }\n >\n <StatefulReaderHeader \n actionKeys={ preferences.actions.webPubOrder }\n actionsOrder={ preferences.actions.webPubOrder }\n layout={ layoutUI } \n runningHeadFormatPref={ preferences.theming.header?.runningHead?.format?.webPub }\n />\n\n <article className={ readerStyles.wrapper } aria-label={ t(\"reader.app.publicationWrapper\") }>\n <div id=\"thorium-web-container\" className={ readerStyles.iframeContainer } ref={ container }></div>\n </article>\n\n <StatefulReaderFooter \n layout={ layoutUI } \n progressionFormatPref={ preferences.theming.progression?.format?.webPub }\n progressionFormatFallback={ ThProgressionFormat.readingOrderIndex }\n />\n </div>\n </StatefulDockingWrapper>\n </main>\n </NavigatorProvider>\n </>\n)};"]}
@@ -0,0 +1,193 @@
1
+ import { useState, useRef, useCallback, useLayoutEffect, useEffect, useMemo } from 'react';
2
+
3
+ // src/core/Components/Actions/hooks/useCollapsibility.ts
4
+ var ThCollapsibilityVisibility = /* @__PURE__ */ ((ThCollapsibilityVisibility2) => {
5
+ ThCollapsibilityVisibility2["always"] = "always";
6
+ ThCollapsibilityVisibility2["partially"] = "partially";
7
+ ThCollapsibilityVisibility2["overflow"] = "overflow";
8
+ return ThCollapsibilityVisibility2;
9
+ })(ThCollapsibilityVisibility || {});
10
+ var useCollapsibility = (items, prefs, breakpoint, containerRef) => {
11
+ const isSpaceFit = prefs.collapse === true;
12
+ const [partialInBar, setPartialInBar] = useState(Number.MAX_SAFE_INTEGER);
13
+ const lastCountRef = useRef(Number.MAX_SAFE_INTEGER);
14
+ const keyToElement = useRef(/* @__PURE__ */ new Map());
15
+ const itemWidthsRef = useRef(/* @__PURE__ */ new Map());
16
+ const alwaysKeysRef = useRef([]);
17
+ const orderedPartialKeysRef = useRef([]);
18
+ const hasOverflowRef = useRef(false);
19
+ const columnGapRef = useRef(0);
20
+ const rafIdRef = useRef(null);
21
+ const specRef = useRef("");
22
+ const computeLayout = useCallback((containerWidth) => {
23
+ if (!containerWidth) return;
24
+ const widths = itemWidthsRef.current;
25
+ const alwaysKeys = alwaysKeysRef.current;
26
+ const partialKeys = orderedPartialKeysRef.current;
27
+ const gap = columnGapRef.current;
28
+ const N_a = alwaysKeys.length;
29
+ const alwaysTotal = alwaysKeys.reduce((s, k) => s + (widths.get(k) ?? 0), 0);
30
+ const partialWidths = partialKeys.map((k) => widths.get(k) ?? 0);
31
+ const partialTotal = partialWidths.reduce((s, w) => s + w, 0);
32
+ let newCount;
33
+ const noMenuTotal = alwaysTotal + partialTotal + gap * Math.max(0, N_a + partialKeys.length - 1);
34
+ if (!hasOverflowRef.current && noMenuTotal <= containerWidth) {
35
+ newCount = partialKeys.length;
36
+ } else {
37
+ const menuW = widths.values().next().value ?? 0;
38
+ if (!menuW) return;
39
+ let count = 0, usedPartial = 0;
40
+ for (const w of partialWidths) {
41
+ const totalGap = gap * Math.max(0, N_a + count + 1);
42
+ if (alwaysTotal + usedPartial + w + menuW + totalGap <= containerWidth) {
43
+ usedPartial += w;
44
+ count++;
45
+ } else {
46
+ break;
47
+ }
48
+ }
49
+ newCount = count;
50
+ }
51
+ if (newCount !== lastCountRef.current) {
52
+ lastCountRef.current = newCount;
53
+ setPartialInBar(newCount);
54
+ }
55
+ }, []);
56
+ const remeasureAndCompute = useCallback((containerWidth) => {
57
+ if (!containerRef?.current) return;
58
+ for (const [key, el] of keyToElement.current) {
59
+ itemWidthsRef.current.set(key, el.getBoundingClientRect().width);
60
+ }
61
+ columnGapRef.current = parseFloat(getComputedStyle(containerRef.current).columnGap) || 0;
62
+ computeLayout(containerWidth ?? containerRef.current.getBoundingClientRect().width);
63
+ }, [containerRef, computeLayout]);
64
+ const remeasureAndComputeRef = useRef(remeasureAndCompute);
65
+ useLayoutEffect(() => {
66
+ remeasureAndComputeRef.current = remeasureAndCompute;
67
+ }, [remeasureAndCompute]);
68
+ useLayoutEffect(() => {
69
+ if (!isSpaceFit || !containerRef?.current) return;
70
+ const spec = items.map((i) => `${i.key}:${prefs.keys[i.key]?.visibility ?? ""}`).join(",");
71
+ const widthsMissing = items.some((i) => !(itemWidthsRef.current.get(i.key) ?? 0));
72
+ if (spec === specRef.current && !widthsMissing) return;
73
+ specRef.current = spec;
74
+ const always = [], partial = [];
75
+ let hasOverflow = false;
76
+ for (const item of items) {
77
+ const v = prefs.keys[item.key]?.visibility;
78
+ if (v === "overflow" /* overflow */) hasOverflow = true;
79
+ else if (v === "always" /* always */) always.push(item.key);
80
+ else partial.push(item.key);
81
+ }
82
+ alwaysKeysRef.current = always;
83
+ orderedPartialKeysRef.current = partial;
84
+ hasOverflowRef.current = hasOverflow;
85
+ remeasureAndCompute(containerRef.current.getBoundingClientRect().width);
86
+ }, [isSpaceFit, items, prefs, containerRef, remeasureAndCompute]);
87
+ useEffect(() => {
88
+ if (!isSpaceFit || !containerRef?.current) return;
89
+ const observer = new ResizeObserver((entries) => {
90
+ const w = entries[0]?.contentRect.width;
91
+ if (w === void 0) return;
92
+ if (rafIdRef.current !== null) cancelAnimationFrame(rafIdRef.current);
93
+ rafIdRef.current = requestAnimationFrame(() => {
94
+ rafIdRef.current = null;
95
+ remeasureAndCompute(w);
96
+ });
97
+ });
98
+ observer.observe(containerRef.current);
99
+ return () => {
100
+ observer.disconnect();
101
+ if (rafIdRef.current !== null) cancelAnimationFrame(rafIdRef.current);
102
+ };
103
+ }, [isSpaceFit, containerRef, remeasureAndCompute]);
104
+ const ghostObserverRef = useRef(null);
105
+ const getGhostRef = useCallback((el) => {
106
+ ghostObserverRef.current?.disconnect();
107
+ ghostObserverRef.current = null;
108
+ if (el && isSpaceFit) {
109
+ const observer = new ResizeObserver(() => {
110
+ if (rafIdRef.current !== null) cancelAnimationFrame(rafIdRef.current);
111
+ rafIdRef.current = requestAnimationFrame(() => {
112
+ rafIdRef.current = null;
113
+ remeasureAndComputeRef.current();
114
+ });
115
+ });
116
+ observer.observe(el);
117
+ ghostObserverRef.current = observer;
118
+ }
119
+ }, [isSpaceFit]);
120
+ const getItemRef = useCallback((key) => (el) => {
121
+ if (el) {
122
+ keyToElement.current.set(key, el);
123
+ } else {
124
+ keyToElement.current.delete(key);
125
+ itemWidthsRef.current.delete(key);
126
+ }
127
+ }, []);
128
+ const [actionIcons, menuItems] = useMemo(() => {
129
+ const actionIcons2 = [];
130
+ const menuItems2 = [];
131
+ if (!prefs.collapse) {
132
+ items.forEach((item) => actionIcons2.push(item));
133
+ return [actionIcons2, menuItems2];
134
+ }
135
+ if (prefs.collapse === true) {
136
+ const barPartialSet = /* @__PURE__ */ new Set();
137
+ let partialCount = 0;
138
+ for (const item of items) {
139
+ if (prefs.keys[item.key]?.visibility === "partially" /* partially */) {
140
+ if (partialCount < partialInBar) {
141
+ barPartialSet.add(item.key);
142
+ partialCount++;
143
+ }
144
+ }
145
+ }
146
+ for (const item of items) {
147
+ const v = prefs.keys[item.key]?.visibility;
148
+ if (v === "overflow" /* overflow */ || v === "partially" /* partially */ && !barPartialSet.has(item.key)) {
149
+ menuItems2.push(item);
150
+ } else {
151
+ actionIcons2.push(item);
152
+ }
153
+ }
154
+ return [actionIcons2, menuItems2];
155
+ }
156
+ let countdown = 0;
157
+ if (breakpoint) {
158
+ const prefForBreakpoint = prefs.collapse[breakpoint];
159
+ if (prefForBreakpoint) {
160
+ const partialCount = items.filter((i) => prefs.keys[i.key]?.visibility === "partially" /* partially */).length;
161
+ const overflowCount = items.filter((i) => prefs.keys[i.key]?.visibility === "overflow" /* overflow */).length;
162
+ const collapsibleCount = partialCount + overflowCount;
163
+ if (prefForBreakpoint === "all") {
164
+ countdown = overflowCount;
165
+ } else if (!isNaN(prefForBreakpoint)) {
166
+ countdown = Math.max(0, collapsibleCount - (prefForBreakpoint - 1));
167
+ }
168
+ }
169
+ }
170
+ [...items].reverse().forEach((item) => {
171
+ const actionPref = prefs.keys[item.key];
172
+ if (actionPref.visibility === "overflow" /* overflow */) {
173
+ menuItems2.unshift(item);
174
+ --countdown;
175
+ } else if (actionPref.visibility === "partially" /* partially */) {
176
+ if (countdown > 0) {
177
+ menuItems2.unshift(item);
178
+ --countdown;
179
+ } else {
180
+ actionIcons2.unshift(item);
181
+ }
182
+ } else {
183
+ actionIcons2.unshift(item);
184
+ }
185
+ });
186
+ return [actionIcons2, menuItems2];
187
+ }, [items, prefs, breakpoint, partialInBar]);
188
+ return { ActionIcons: actionIcons, MenuItems: menuItems, getItemRef, getGhostRef };
189
+ };
190
+
191
+ export { ThCollapsibilityVisibility, useCollapsibility };
192
+ //# sourceMappingURL=chunk-AQSJDL63.mjs.map
193
+ //# sourceMappingURL=chunk-AQSJDL63.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/Components/Actions/hooks/useCollapsibility.ts"],"names":["ThCollapsibilityVisibility","actionIcons","menuItems"],"mappings":"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","file":"chunk-AQSJDL63.mjs","sourcesContent":["\"use client\";\n\nimport { RefObject, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\n\nimport { ThActionEntry } from \"../ThActionsBar\";\n\nexport type ThCollapsibility = boolean | Record<string, number | \"all\">;\n\nexport enum ThCollapsibilityVisibility {\n always = \"always\",\n partially = \"partially\",\n overflow = \"overflow\"\n}\n\nexport interface CollapsiblePref {\n displayOrder: string[];\n collapse: ThCollapsibility;\n keys: {\n [key: string]: {\n [key: string]: any;\n visibility: ThCollapsibilityVisibility;\n };\n }\n}\n\nexport const useCollapsibility = (\n items: ThActionEntry<string>[],\n prefs: CollapsiblePref,\n breakpoint?: string,\n containerRef?: RefObject<HTMLElement | null>\n) => {\n const isSpaceFit = prefs.collapse === true;\n\n // --- Space-fit mode (collapse: true) ---\n // How many `partially` items currently fit in the bar.\n // MAX_SAFE_INTEGER = \"assume all fit\" — corrected by useLayoutEffect before first paint.\n const [partialInBar, setPartialInBar] = useState<number>(Number.MAX_SAFE_INTEGER);\n const lastCountRef = useRef<number>(Number.MAX_SAFE_INTEGER);\n\n // Ghost element tracking — spans wrapping each item in the hidden measurement clone.\n // The ghost always renders all items, so widths are stable regardless of bar state.\n const keyToElement = useRef(new Map<string, HTMLElement>());\n const itemWidthsRef = useRef(new Map<string, number>());\n\n // Inputs for computeLayout, kept in refs so the function is stable\n const alwaysKeysRef = useRef<string[]>([]);\n const orderedPartialKeysRef = useRef<string[]>([]);\n const hasOverflowRef = useRef<boolean>(false);\n const columnGapRef = useRef<number>(0);\n\n // Shared rAF handle — both ResizeObservers dequeue into the same frame slot.\n const rafIdRef = useRef<number | null>(null);\n\n // Tracks the last spec so categorization is skipped when nothing meaningful changed.\n const specRef = useRef<string>(\"\");\n\n // computeLayout reads only refs — no closure over props, truly stable.\n // Called from remeasureAndCompute after fresh DOM reads.\n const computeLayout = useCallback((containerWidth: number) => {\n if (!containerWidth) return;\n\n const widths = itemWidthsRef.current;\n const alwaysKeys = alwaysKeysRef.current;\n const partialKeys = orderedPartialKeysRef.current;\n const gap = columnGapRef.current;\n\n const N_a = alwaysKeys.length;\n const alwaysTotal = alwaysKeys.reduce((s, k) => s + (widths.get(k) ?? 0), 0);\n const partialWidths = partialKeys.map(k => widths.get(k) ?? 0);\n const partialTotal = partialWidths.reduce((s, w) => s + w, 0);\n\n let newCount: number;\n\n // Check if everything fits without an overflow menu trigger\n const noMenuTotal = alwaysTotal + partialTotal + gap * Math.max(0, N_a + partialKeys.length - 1);\n if (!hasOverflowRef.current && noMenuTotal <= containerWidth) {\n newCount = partialKeys.length;\n } else {\n // Need the overflow menu trigger — use first measured width as proxy\n // (all icon buttons are the same size)\n const menuW = widths.values().next().value ?? 0;\n if (!menuW) return;\n\n let count = 0, usedPartial = 0;\n for (const w of partialWidths) {\n // Items in bar at this step: N_a always + count partial + 1 new partial + 1 menu trigger\n const totalGap = gap * Math.max(0, N_a + count + 1);\n if (alwaysTotal + usedPartial + w + menuW + totalGap <= containerWidth) {\n usedPartial += w;\n count++;\n } else {\n break;\n }\n }\n newCount = count;\n }\n\n if (newCount !== lastCountRef.current) {\n lastCountRef.current = newCount;\n setPartialInBar(newCount);\n }\n }, []);\n\n // Re-measures all ghost item widths and the container gap, then calls computeLayout.\n // getBoundingClientRect and getComputedStyle are cheap when called from a rAF callback\n // or useLayoutEffect (layout is already computed by the browser at those points).\n // Passing containerWidth avoids a second getBoundingClientRect on the container when\n // the caller already has it (e.g. from ResizeObserver contentRect).\n const remeasureAndCompute = useCallback((containerWidth?: number) => {\n if (!containerRef?.current) return;\n for (const [key, el] of keyToElement.current) {\n itemWidthsRef.current.set(key, el.getBoundingClientRect().width);\n }\n columnGapRef.current = parseFloat(getComputedStyle(containerRef.current).columnGap) || 0;\n computeLayout(containerWidth ?? containerRef.current.getBoundingClientRect().width);\n }, [containerRef, computeLayout]);\n\n // Kept in a ref so the ghost observer's rAF closure is always current\n // without the observer needing to re-subscribe when the function identity changes.\n const remeasureAndComputeRef = useRef(remeasureAndCompute);\n useLayoutEffect(() => { remeasureAndComputeRef.current = remeasureAndCompute; }, [remeasureAndCompute]);\n\n // Categorize items by visibility and do initial measurement before first paint.\n // useLayoutEffect runs synchronously after DOM mutations — so the initial\n // correction happens before the user sees anything.\n // The spec guard skips the effect when items/prefs object references are unstable\n // but nothing meaningful changed, UNLESS widths haven't been populated yet\n // (ghost elements not yet measured on first mount).\n useLayoutEffect(() => {\n if (!isSpaceFit || !containerRef?.current) return;\n\n const spec = items.map(i => `${i.key}:${prefs.keys[i.key]?.visibility ?? \"\"}`).join(\",\");\n const widthsMissing = items.some(i => !(itemWidthsRef.current.get(i.key) ?? 0));\n if (spec === specRef.current && !widthsMissing) return;\n specRef.current = spec;\n\n const always: string[] = [], partial: string[] = [];\n let hasOverflow = false;\n\n for (const item of items) {\n const v = prefs.keys[item.key]?.visibility;\n if (v === ThCollapsibilityVisibility.overflow) hasOverflow = true;\n else if (v === ThCollapsibilityVisibility.always) always.push(item.key);\n else partial.push(item.key);\n }\n\n alwaysKeysRef.current = always;\n orderedPartialKeysRef.current = partial;\n hasOverflowRef.current = hasOverflow;\n\n remeasureAndCompute(containerRef.current.getBoundingClientRect().width);\n }, [isSpaceFit, items, prefs, containerRef, remeasureAndCompute]);\n\n // Container ResizeObserver — fires when the container width changes.\n // Batched via rAF so we compute at most once per frame, not once per pixel.\n // Re-measures item widths each time so icon size changes (e.g. zoom) that also\n // cause a container reflow are picked up automatically.\n useEffect(() => {\n if (!isSpaceFit || !containerRef?.current) return;\n\n const observer = new ResizeObserver(entries => {\n const w = entries[0]?.contentRect.width;\n if (w === undefined) return;\n\n if (rafIdRef.current !== null) cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n remeasureAndCompute(w);\n });\n });\n\n observer.observe(containerRef.current);\n return () => {\n observer.disconnect();\n if (rafIdRef.current !== null) cancelAnimationFrame(rafIdRef.current);\n };\n }, [isSpaceFit, containerRef, remeasureAndCompute]);\n\n // Ghost wrapper ResizeObserver — fires when icon sizes change independently of\n // container width (e.g. app-level zoom on a fixed-width container).\n // Implemented as a callback ref so the observer is set up directly on mount\n // without a separate state variable or useEffect dependency on a mutable ref.\n const ghostObserverRef = useRef<ResizeObserver | null>(null);\n const getGhostRef = useCallback((el: HTMLDivElement | null) => {\n ghostObserverRef.current?.disconnect();\n ghostObserverRef.current = null;\n if (el && isSpaceFit) {\n const observer = new ResizeObserver(() => {\n if (rafIdRef.current !== null) cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n remeasureAndComputeRef.current();\n });\n });\n observer.observe(el);\n ghostObserverRef.current = observer;\n }\n }, [isSpaceFit]);\n\n // Ref callback factory — attaches to ghost spans for width measurement.\n // Harmless noop in other modes.\n const getItemRef = useCallback((key: string) => (el: HTMLElement | null) => {\n if (el) {\n keyToElement.current.set(key, el);\n } else {\n keyToElement.current.delete(key);\n itemWidthsRef.current.delete(key);\n }\n }, []);\n\n // --- Triage ---\n\n const [actionIcons, menuItems] = useMemo(() => {\n const actionIcons: ThActionEntry<string>[] = [];\n const menuItems: ThActionEntry<string>[] = [];\n\n if (!prefs.collapse) {\n items.forEach((item) => actionIcons.push(item));\n return [actionIcons, menuItems];\n }\n\n if (prefs.collapse === true) {\n // Build the set of partial keys that fit in the bar (first N in displayOrder)\n const barPartialSet = new Set<string>();\n let partialCount = 0;\n for (const item of items) {\n if (prefs.keys[item.key]?.visibility === ThCollapsibilityVisibility.partially) {\n if (partialCount < partialInBar) {\n barPartialSet.add(item.key);\n partialCount++;\n }\n }\n }\n\n for (const item of items) {\n const v = prefs.keys[item.key]?.visibility;\n if (v === ThCollapsibilityVisibility.overflow || (v === ThCollapsibilityVisibility.partially && !barPartialSet.has(item.key))) {\n menuItems.push(item);\n } else {\n actionIcons.push(item);\n }\n }\n\n return [actionIcons, menuItems];\n }\n\n // collapse: Record — breakpoint-based triage (existing logic)\n let countdown: number = 0;\n\n if (breakpoint) {\n const prefForBreakpoint = prefs.collapse[breakpoint];\n if (prefForBreakpoint) {\n // `always` items are never collapsed, so count only partially + overflow items\n const partialCount = items.filter(i => prefs.keys[i.key]?.visibility === ThCollapsibilityVisibility.partially).length;\n const overflowCount = items.filter(i => prefs.keys[i.key]?.visibility === ThCollapsibilityVisibility.overflow).length;\n const collapsibleCount = partialCount + overflowCount;\n\n if (prefForBreakpoint === \"all\") {\n countdown = overflowCount;\n } else if (!isNaN(prefForBreakpoint)) {\n countdown = Math.max(0, collapsibleCount - (prefForBreakpoint - 1));\n }\n }\n }\n\n // Creating a shallow copy so that actionsOrder doesn't mutate between rerenders\n [...items].reverse().forEach((item) => {\n const actionPref = prefs.keys[item.key];\n if (actionPref.visibility === ThCollapsibilityVisibility.overflow) {\n menuItems.unshift(item);\n --countdown;\n } else if (actionPref.visibility === ThCollapsibilityVisibility.partially) {\n if (countdown > 0) {\n menuItems.unshift(item);\n --countdown;\n } else {\n actionIcons.unshift(item);\n }\n } else {\n actionIcons.unshift(item);\n }\n });\n\n return [actionIcons, menuItems];\n }, [items, prefs, breakpoint, partialInBar]);\n\n return { ActionIcons: actionIcons, MenuItems: menuItems, getItemRef, getGhostRef };\n}\n"]}