{"version":3,"sources":["../../src/components/Content.tsx","../../src/theme/theme-utils.ts"],"sourcesContent":["'use client'; // for server side rendering\n\nimport { forwardRef, type ElementType, type ReactNode } from 'react';\nimport { Box, styled } from '@mui/material';\nimport { useThemeProps } from '@mui/material/styles';\nimport { isThemeColor } from '../theme/theme-utils';\n\n/**\n * Different variants represent different application level layouts:\n *\n *  - The \"left-aligned\" variant is a layout with a left aligned navigation menu. This\n *    is traditionally used for applications with several levels of navigation.\n *\n *  - The \"center-aligned\" variant is a standard, horizontally centered application. This\n *    is a fairly conventional layout used for content  rich websites.\n */\nexport type LayoutVariant = 'left-aligned' | 'center-aligned';\n\nexport interface ContentProps {\n    children: ReactNode | ReactNode[];\n    /**\n     * If true, a `<main />` tag is used, which tells web scrapers and accessibility devices\n     * that the content is of significant importance. There should only be a single `<main />\n     * element per page.\n     */\n    main?: boolean;\n    /**\n     * The layout variant to use. Defaults to 'center-aligned'.\n     */\n    layout?: LayoutVariant;\n    className?: string;\n    bgcolor?: string;\n}\n\ninterface ContentOwnerState {\n    main?: boolean;\n    layout?: LayoutVariant;\n    bgcolor?: string;\n}\n\nconst ContentRoot = styled(Box, {\n    name: 'MuiContent',\n    slot: 'root',\n})<{ ownerState: ContentOwnerState; component?: ElementType }>(\n    ({ theme, ownerState: { layout, bgcolor } }) => ({\n        maxWidth: layout === 'center-aligned' ? `${theme.breakpoints.values.lg}px` : undefined,\n        width: '100%',\n        ...(layout === 'center-aligned' ? { margin: '0 auto' } : {}),\n        padding: theme.spacing(3),\n        wordWrap: 'break-word',\n        wordBreak: 'break-word',\n        hyphens: 'auto',\n        // if the user passes a key to the color theme, use the mapped color,\n        // else treat the string as a normal color string\n        background: bgcolor\n            ? isThemeColor(theme, bgcolor)\n                ? theme.color[bgcolor].hex\n                : bgcolor\n            : 'none',\n        [`@media (max-width: ${theme.breakpoints.values.sm}px)`]: {\n            padding: theme.spacing(1.5),\n        },\n    })\n);\n\nexport const Content = forwardRef<HTMLDivElement, ContentProps>(function Content(inProps, ref) {\n    const props = useThemeProps({ props: inProps, name: 'MuiContent' });\n    const { children, className, main, layout = 'center-aligned', bgcolor, ...other } = props;\n    const ownerState: ContentOwnerState = { main, layout, bgcolor };\n    return (\n        <ContentRoot\n            ref={ref}\n            component={main ? 'main' : 'div'}\n            className={className}\n            ownerState={ownerState}\n            {...other}>\n            {children}\n        </ContentRoot>\n    );\n});\n\nexport default Content;\n","import type { PaletteModes } from '@allenai/varnish-theme/mui';\nimport varnishTokens from '@allenai/varnish-theme/mui';\nimport { type Theme } from '@mui/material';\nimport type { TypographyVariant } from '@mui/material/styles';\n\n// importing from @mui/system directly seems to get us around some client component issues in Next\nimport { getContrastRatio } from '@mui/system/colorManipulator';\n\n// Used to convert style object to css for typographic elements like h1...h6\nexport const getTypographyStyle = (\n    theme: Omit<Theme, 'components'>,\n    key: TypographyVariant,\n    includeKey: boolean = true\n) => {\n    const typography = (\n        theme.typography as unknown as Record<string, Record<string, string | number | undefined>>\n    )[key];\n    return `\n    ${includeKey ? `${key} {` : ''}\n      color: ${typography.color};\n      font-family: ${typography.fontFamily};\n      font-weight:  ${typography.fontWeight};\n      font-size:  ${typography.fontSize};\n      line-height:  ${typography.lineHeight};\n      margin:  ${typography.margin};\n    ${includeKey ? '}' : ''}\n  `;\n};\n\nexport const getThemeObjectTokens = <T extends { [index: string]: { value: string | number } }>(\n    themeObject: T,\n    properties: (keyof T)[] = Object.keys(themeObject)\n) => {\n    type RecordOfT = Record<keyof T, string>;\n\n    return properties.reduce((acc: RecordOfT, attribute: keyof T) => {\n        acc[attribute] = themeObject[attribute].value.toString();\n        return acc;\n    }, {} as RecordOfT);\n};\n\ninterface ColorWithContrastRatio {\n    color: string;\n    contrastRatio: number;\n}\nconst getColorWithContrastRatio = (baseColor: string, color: string): ColorWithContrastRatio => {\n    return {\n        color,\n        contrastRatio: getContrastRatio(baseColor, color),\n    };\n};\n\n/**\n *\n * @param backgroundColor The color you want to get the contrast color for\n * @param mode 'light' or 'dark', this determines which palette we pull text colors from\n * @returns The primary or reversed value for the palette mode selected, chosen based on whichever has the better contrast ratio\n */\nexport const getContrastText = (\n    backgroundColor: string,\n    mode: PaletteModes = 'light',\n    desiredContrastRatio = 4.5\n) => {\n    const primaryText = getColorWithContrastRatio(\n        backgroundColor,\n        varnishTokens.palette[mode].text.primary.default.value\n    );\n\n    const reversedText = getColorWithContrastRatio(\n        backgroundColor,\n        varnishTokens.palette[mode].text.primary.reversed.value\n    );\n\n    const secondaryText = getColorWithContrastRatio(\n        backgroundColor,\n        varnishTokens.palette[mode].text.secondary.default.value\n    );\n\n    // HACK: dark-green will always have better contrast than ai2-green. This lets us keep using ai2-green if it's above the contrast ratio we're looking for\n    if (primaryText.contrastRatio >= desiredContrastRatio) {\n        return primaryText.color;\n    }\n\n    // We want the color with the highest contrast ratio at the first index\n    const colorsOrderedByContrastRatio = [primaryText, reversedText, secondaryText].sort(\n        (a, b) => b.contrastRatio - a.contrastRatio\n    );\n\n    return colorsOrderedByContrastRatio[0].color;\n};\n\nexport const isThemeColor = (theme: Theme, key: string): key is keyof typeof theme.color => {\n    return key in theme.color;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBAA6D;AAC7D,sBAA4B;AAC5B,oBAA8B;;;ACH9B,iBAA0B;AAK1B,8BAAiC;AAqF1B,IAAM,eAAe,CAAC,OAAc,QAAiD;AACxF,SAAO,OAAO,MAAM;AACxB;;;ADvBQ;AA9BR,IAAM,kBAAc,wBAAO,qBAAK;AAAA,EAC5B,MAAM;AAAA,EACN,MAAM;AACV,CAAC;AAAA,EACG,CAAC,EAAE,OAAO,YAAY,EAAE,QAAQ,QAAQ,EAAE,OAAO;AAAA,IAC7C,UAAU,WAAW,mBAAmB,GAAG,MAAM,YAAY,OAAO,EAAE,OAAO;AAAA,IAC7E,OAAO;AAAA,IACP,GAAI,WAAW,mBAAmB,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,IAC1D,SAAS,MAAM,QAAQ,CAAC;AAAA,IACxB,UAAU;AAAA,IACV,WAAW;AAAA,IACX,SAAS;AAAA;AAAA;AAAA,IAGT,YAAY,UACN,aAAa,OAAO,OAAO,IACvB,MAAM,MAAM,OAAO,EAAE,MACrB,UACJ;AAAA,IACN,CAAC,sBAAsB,MAAM,YAAY,OAAO,EAAE,KAAK,GAAG;AAAA,MACtD,SAAS,MAAM,QAAQ,GAAG;AAAA,IAC9B;AAAA,EACJ;AACJ;AAEO,IAAM,cAAU,yBAAyC,SAASA,SAAQ,SAAS,KAAK;AAC3F,QAAM,YAAQ,6BAAc,EAAE,OAAO,SAAS,MAAM,aAAa,CAAC;AAClE,QAAM,EAAE,UAAU,WAAW,MAAM,SAAS,kBAAkB,SAAS,GAAG,MAAM,IAAI;AACpF,QAAM,aAAgC,EAAE,MAAM,QAAQ,QAAQ;AAC9D,SACI;AAAA,IAAC;AAAA;AAAA,MACG;AAAA,MACA,WAAW,OAAO,SAAS;AAAA,MAC3B;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MACH;AAAA;AAAA,EACL;AAER,CAAC;AAED,IAAO,kBAAQ;","names":["Content"]}