UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

1 lines 6.6 kB
{"version":3,"file":"ThemeProvider.mjs","names":["ThemeProvider","lobeCustomStylish","lobeCustomToken","AntdThemeProvider","AntdConfigProvider"],"sources":["../../src/ThemeProvider/ThemeProvider.tsx"],"sourcesContent":["'use client';\n\nimport { App } from 'antd';\nimport {\n type CustomStylishParams,\n type CustomTokenParams,\n type GetAntdTheme,\n ThemeProvider as AntdThemeProvider,\n} from 'antd-style';\nimport { merge } from 'es-toolkit/compat';\nimport { memo, useCallback, useMemo, useState } from 'react';\n\nimport { useCdnFn } from '@/ConfigProvider';\nimport FontLoader from '@/FontLoader';\nimport { lobeCustomStylish, lobeCustomToken } from '@/styles';\nimport { createLobeAntdTheme } from '@/styles/theme/antdTheme';\nimport { type LobeCustomToken } from '@/types/customToken';\n\nimport AppElementContext from './AppElementContext';\nimport AntdConfigProvider from './ConfigProvider';\nimport { LOBE_THEME_APP_ID } from './constants';\nimport GlobalStyle from './GlobalStyle';\nimport { type ThemeProviderProps } from './type';\n\nconst ThemeProvider = memo<ThemeProviderProps>(\n ({\n children,\n customStylish,\n customToken,\n enableCustomFonts = true,\n enableGlobalStyle = true,\n customFonts,\n customTheme = {},\n className,\n style,\n theme: antdTheme,\n ...rest\n }) => {\n const genCdnUrl = useCdnFn();\n const [appRef, setAppRef] = useState<HTMLDivElement | null>(null);\n\n const webfontUrls = useMemo(\n () =>\n customFonts || [\n genCdnUrl({ path: 'css/index.css', pkg: '@lobehub/webfont-mono' }),\n genCdnUrl({\n path: 'css/index.css',\n pkg: '@lobehub/webfont-harmony-sans',\n }),\n genCdnUrl({\n path: 'css/index.css',\n pkg: '@lobehub/webfont-harmony-sans-sc',\n }),\n genCdnUrl({ path: 'dist/katex.min.css', pkg: 'katex' }),\n ],\n [customFonts, genCdnUrl],\n );\n\n const stylish = useCallback(\n (theme: CustomStylishParams) => ({ ...lobeCustomStylish(theme), ...customStylish?.(theme) }),\n [customStylish],\n );\n\n const token = useCallback(\n (theme: CustomTokenParams) => ({ ...lobeCustomToken(theme), ...customToken?.(theme) }),\n [customToken],\n );\n\n const theme = useCallback<GetAntdTheme>(\n (appearance) => {\n const lobeTheme = createLobeAntdTheme({\n appearance,\n neutralColor: customTheme.neutralColor,\n primaryColor: customTheme.primaryColor,\n });\n return merge(lobeTheme, antdTheme);\n },\n [customTheme.primaryColor, customTheme.neutralColor, antdTheme],\n );\n\n return (\n <>\n {enableCustomFonts &&\n webfontUrls?.length > 0 &&\n webfontUrls.map((webfont) => <FontLoader key={webfont} url={webfont} />)}\n <AntdThemeProvider<LobeCustomToken>\n customStylish={stylish}\n customToken={token}\n theme={theme}\n {...rest}\n >\n <AntdConfigProvider>\n {enableGlobalStyle && <GlobalStyle />}\n\n <App\n className={className}\n style={{ isolation: 'isolate', minHeight: 'inherit', width: 'inherit', ...style }}\n >\n <div id={LOBE_THEME_APP_ID} style={contentsStyle}>\n <AppElementContext value={appRef}>\n {children}\n {/*\n In-tree portal host for Base UI floating components\n (Select, Combobox, etc.). Keeping it inside `<App>` keeps\n the antd-style / emotion theme cascade intact so popups\n render with the correct tokens, while the layout-bearing\n block lets Base UI's Portal actually mount — the outer\n wrapper uses `display: contents` and cannot host portals.\n */}\n <div data-lobe-portal-host=\"\" ref={setAppRef} style={hostPortalHostStyle} />\n </AppElementContext>\n </div>\n </App>\n </AntdConfigProvider>\n </AntdThemeProvider>\n </>\n );\n },\n);\n\nThemeProvider.displayName = 'LobeThemeProvider';\n\nexport default ThemeProvider;\n\nconst hostPortalHostStyle: React.CSSProperties = {\n // `height: 0` keeps the host invisible and gives it no hit region of\n // its own; absolute children (Base UI Positioner) have their own hit\n // region, so we must NOT set `pointer-events: none` here — it would\n // be inherited by popup descendants and break clicks/hover.\n height: 0,\n left: 0,\n // `position: fixed` keeps a stacking context so portaled popups can\n // win over sibling z-indexes. `right: 0` (instead of `width: 0`)\n // gives the host a full viewport-width containing block — without it,\n // Base UI Positioner uses `position: absolute` against a 0-width\n // containing block and collapses text to one character per line.\n position: 'fixed',\n right: 0,\n top: 0,\n zIndex: 1100,\n};\n\nconst contentsStyle: React.CSSProperties = {\n display: 'contents',\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAwBA,MAAMA,kBAAgB,MACnB,EACC,UACA,eACA,aACA,oBAAoB,MACpB,oBAAoB,MACpB,aACA,cAAc,EAAE,EAChB,WACA,OACA,OAAO,WACP,GAAG,WACC;CACJ,MAAM,YAAY,UAAU;CAC5B,MAAM,CAAC,QAAQ,aAAa,SAAgC,KAAK;CAEjE,MAAM,cAAc,cAEhB,eAAe;EACb,UAAU;GAAE,MAAM;GAAiB,KAAK;GAAyB,CAAC;EAClE,UAAU;GACR,MAAM;GACN,KAAK;GACN,CAAC;EACF,UAAU;GACR,MAAM;GACN,KAAK;GACN,CAAC;EACF,UAAU;GAAE,MAAM;GAAsB,KAAK;GAAS,CAAC;EACxD,EACH,CAAC,aAAa,UAAU,CACzB;CAED,MAAM,UAAU,aACb,WAAgC;EAAE,GAAGC,sBAAkB,MAAM;EAAE,GAAG,gBAAgB,MAAM;EAAE,GAC3F,CAAC,cAAc,CAChB;CAED,MAAM,QAAQ,aACX,WAA8B;EAAE,GAAGC,oBAAgB,MAAM;EAAE,GAAG,cAAc,MAAM;EAAE,GACrF,CAAC,YAAY,CACd;CAED,MAAM,QAAQ,aACX,eAAe;AAMd,SAAO,MALW,oBAAoB;GACpC;GACA,cAAc,YAAY;GAC1B,cAAc,YAAY;GAC3B,CACqB,EAAE,UAAU;IAEpC;EAAC,YAAY;EAAc,YAAY;EAAc;EAAU,CAChE;AAED,QACE,qBAAA,YAAA,EAAA,UAAA,CACG,qBACC,aAAa,SAAS,KACtB,YAAY,KAAK,YAAY,oBAAC,YAAD,EAA0B,KAAK,SAAW,EAAzB,QAAyB,CAAC,EAC1E,oBAACC,eAAD;EACE,eAAe;EACf,aAAa;EACN;EACP,GAAI;YAEJ,qBAACC,kBAAD,EAAA,UAAA,CACG,qBAAqB,oBAAC,aAAD,EAAe,CAAA,EAErC,oBAAC,KAAD;GACa;GACX,OAAO;IAAE,WAAW;IAAW,WAAW;IAAW,OAAO;IAAW,GAAG;IAAO;aAEjF,oBAAC,OAAD;IAAK,IAAI;IAAmB,OAAO;cACjC,qBAAC,mBAAD;KAAmB,OAAO;eAA1B,CACG,UASD,oBAAC,OAAD;MAAK,yBAAsB;MAAG,KAAK;MAAW,OAAO;MAAuB,CAAA,CAC1D;;IAChB,CAAA;GACF,CAAA,CACa,EAAA,CAAA;EACH,CAAA,CACnB,EAAA,CAAA;EAGR;AAED,gBAAc,cAAc;AAI5B,MAAM,sBAA2C;CAK/C,QAAQ;CACR,MAAM;CAMN,UAAU;CACV,OAAO;CACP,KAAK;CACL,QAAQ;CACT;AAED,MAAM,gBAAqC,EACzC,SAAS,YACV"}