{"version":3,"file":"useScreen.cjs","sources":["../../../../src/hooks/useScreen/useScreen.ts"],"sourcesContent":["import { useCallback, useEffect, useReducer, useState } from \"react\";\nimport { tokens } from \"../../core/index.js\";\nimport {\n    addMediaQueryListener,\n    getInitialMediaQueryMatch,\n    removeMediaQueryListener,\n} from \"../mediaQueryUtils.js\";\nimport {\n    ActionType,\n    type ScreenAction,\n    type ScreenState,\n    reducer,\n} from \"./state.js\";\n\nconst { breakpoint } = tokens;\n\nconst breakpointsAsNumber = (breakpoint: string): number =>\n    Number.parseInt(breakpoint.replace(\"px\", \"\"));\n\nconst MEDIA_RULES: Record<keyof ScreenState, string> = {\n    isSmallDevice: `(max-width: ${\n        breakpointsAsNumber(breakpoint.medium) - 1\n    }px)`,\n    isMediumDevice: `(min-width: ${breakpoint.medium}) and (max-width: ${\n        breakpointsAsNumber(breakpoint.large) - 1\n    }px)`,\n    isLargeDevice: `(min-width: ${breakpoint.large}) and (max-width: ${\n        breakpointsAsNumber(breakpoint.xl) - 1\n    }px)`,\n    isXlDevice: `(min-width: ${breakpoint.xl})`,\n    isPortrait: \"(orientation: portrait)\",\n    isLandscape: \"(orientation: landscape)\",\n};\n\nconst createAction = (property: keyof ScreenState): ScreenAction => ({\n    type:\n        property === \"isLandscape\" || property === \"isPortrait\"\n            ? ActionType.orientation\n            : ActionType.deviceSize,\n    property,\n});\n\n/**\n * Finn størrelsen og orienteringen til skjermen.\n * @returns Et objekt med boolean som indikerer om skjermstørrelsen er liten, medium, stor eller ekstra stor, og om skjermen er i portrett- eller landskapsmodus.\n */\nexport const useScreen = (): ScreenState => {\n    const [hasMounted, setHasMounted] = useState(false);\n\n    const [device, deviceDispatch] = useReducer(reducer, {\n        isSmallDevice: false,\n        isMediumDevice: false,\n        isLargeDevice: false,\n        isXlDevice: false,\n        isLandscape: false,\n        isPortrait: false,\n    });\n\n    useEffect(() => {\n        setHasMounted(true);\n        const initialMatches = Object.entries(MEDIA_RULES).map(\n            ([key, rule]) => [key, getInitialMediaQueryMatch(rule)],\n        );\n\n        for (const [key, value] of initialMatches) {\n            if (value) {\n                deviceDispatch(createAction(key as keyof ScreenState));\n            }\n        }\n    }, []);\n\n    const createListener = useCallback(\n        (key: keyof ScreenState) => (e: MediaQueryListEvent) => {\n            requestAnimationFrame(() => {\n                if (e.matches) {\n                    deviceDispatch(createAction(key));\n                }\n            });\n        },\n        [],\n    );\n\n    useEffect(() => {\n        if (!hasMounted || !window.matchMedia) {\n            return;\n        }\n        const eventListenerPairs: Array<\n            [MediaQueryList, (e: MediaQueryListEvent) => void]\n        > = [];\n\n        for (const [key, rule] of Object.entries(MEDIA_RULES)) {\n            const queryList = window.matchMedia(rule);\n            const listener = createListener(key as keyof ScreenState);\n            eventListenerPairs.push([queryList, listener]);\n            addMediaQueryListener(queryList, listener);\n        }\n\n        return () => {\n            for (const [queryList, listener] of eventListenerPairs) {\n                removeMediaQueryListener(queryList, listener);\n            }\n        };\n    }, [createListener, hasMounted]);\n\n    return { ...device };\n};\n"],"names":["breakpoint","tokens","breakpointsAsNumber","Number","parseInt","replace","MEDIA_RULES","isSmallDevice","medium","isMediumDevice","large","isLargeDevice","xl","isXlDevice","isPortrait","isLandscape","createAction","property","type","ActionType","orientation","deviceSize","hasMounted","setHasMounted","useState","device","deviceDispatch","useReducer","reducer","useEffect","initialMatches","Object","entries","map","key","rule","getInitialMediaQueryMatch","value","createListener","useCallback","e","requestAnimationFrame","matches","window","matchMedia","eventListenerPairs","queryList","listener","push","addMediaQueryListener","removeMediaQueryListener"],"mappings":"0MAcQA,WAAAA,GAAeC,EAEjBC,EAAuBF,GACzBG,OAAOC,SAASJ,EAAWK,QAAQ,KAAM,KAEvCC,EAAiD,CACnDC,cAAe,eACXL,EAAoBF,EAAWQ,QAAU,OAE7CC,eAAgB,eAAeT,EAAWQ,2BACtCN,EAAoBF,EAAWU,OAAS,OAE5CC,cAAe,eAAeX,EAAWU,0BACrCR,EAAoBF,EAAWY,IAAM,OAEzCC,WAAY,eAAeb,EAAWY,MACtCE,WAAY,0BACZC,YAAa,4BAGXC,EAAgBC,IAAAA,CAClBC,KACiB,gBAAbD,GAA2C,eAAbA,EACxBE,aAAWC,YACXD,EAAAA,WAAWE,WACrBJ,SAAAA,sBAOqB,KACrB,MAAOK,EAAYC,GAAiBC,EAAAA,UAAS,IAEtCC,EAAQC,GAAkBC,EAAAA,WAAWC,EAAAA,QAAS,CACjDrB,eAAe,EACfE,gBAAgB,EAChBE,eAAe,EACfE,YAAY,EACZE,aAAa,EACbD,YAAY,IAGhBe,EAAAA,UAAU,KACNN,GAAc,GACd,MAAMO,EAAiBC,OAAOC,QAAQ1B,GAAa2B,IAC/C,EAAEC,EAAKC,KAAU,CAACD,EAAKE,EAAAA,0BAA0BD,KAGrD,IAAA,MAAYD,EAAKG,KAAUP,EACnBO,GACAX,EAAeV,EAAakB,KAGrC,IAEH,MAAMI,EAAiBC,EAAAA,YAClBL,GAA4BM,IACzBC,sBAAsB,KACdD,EAAEE,SACFhB,EAAeV,EAAakB,OAIxC,IAGJL,OAAAA,EAAAA,UAAU,KACN,IAAKP,IAAeqB,OAAOC,WACvB,OAEJ,MAAMC,EAEF,GAEJ,IAAA,MAAYX,EAAKC,KAASJ,OAAOC,QAAQ1B,GAAc,CACnD,MAAMwC,EAAYH,OAAOC,WAAWT,GAC9BY,EAAWT,EAAeJ,GAChCW,EAAmBG,KAAK,CAACF,EAAWC,IACpCE,EAAAA,sBAAsBH,EAAWC,EACrC,CAEA,MAAO,KACH,IAAA,MAAYD,EAAWC,KAAaF,EAChCK,EAAAA,yBAAyBJ,EAAWC,KAG7C,CAACT,EAAgBhB,IAEb,IAAKG"}