@lobehub/ui 5.20.0 → 5.20.2
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.
- package/es/Accordion/Accordion.mjs +2 -2
- package/es/Accordion/Accordion.mjs.map +1 -1
- package/es/Accordion/AccordionItem.mjs +2 -2
- package/es/Accordion/AccordionItem.mjs.map +1 -1
- package/es/Checkbox/Checkbox.mjs +2 -2
- package/es/Checkbox/Checkbox.mjs.map +1 -1
- package/es/Checkbox/CheckboxGroup.mjs +2 -2
- package/es/Checkbox/CheckboxGroup.mjs.map +1 -1
- package/es/CodeEditor/CodeEditor.mjs +2 -2
- package/es/CodeEditor/CodeEditor.mjs.map +1 -1
- package/es/ColorSwatches/ColorSwatches.mjs +2 -2
- package/es/ColorSwatches/ColorSwatches.mjs.map +1 -1
- package/es/DraggablePanel/DraggablePanel.mjs +2 -2
- package/es/DraggablePanel/DraggablePanel.mjs.map +1 -1
- package/es/DraggablePanel/components/DraggablePanelHeader.mjs +2 -2
- package/es/DraggablePanel/components/DraggablePanelHeader.mjs.map +1 -1
- package/es/DraggableSideNav/DraggableSideNav.mjs +2 -2
- package/es/DraggableSideNav/DraggableSideNav.mjs.map +1 -1
- package/es/EditableText/EditableText.mjs +2 -2
- package/es/EditableText/EditableText.mjs.map +1 -1
- package/es/EmojiPicker/EmojiPicker.mjs +3 -3
- package/es/EmojiPicker/EmojiPicker.mjs.map +1 -1
- package/es/HotkeyInput/HotkeyInput.mjs +2 -2
- package/es/HotkeyInput/HotkeyInput.mjs.map +1 -1
- package/es/ImageSelect/ImageSelect.mjs +2 -2
- package/es/ImageSelect/ImageSelect.mjs.map +1 -1
- package/es/Markdown/SyntaxMarkdown/CachedMarkdown.mjs +3 -2
- package/es/Markdown/SyntaxMarkdown/CachedMarkdown.mjs.map +1 -1
- package/es/Markdown/plugins/rehypeStreamAnimated.mjs.map +1 -1
- package/es/SearchBar/SearchBar.mjs +2 -2
- package/es/SearchBar/SearchBar.mjs.map +1 -1
- package/es/ThemeProvider/GlobalStyle/global.mjs +3 -2
- package/es/ThemeProvider/GlobalStyle/global.mjs.map +1 -1
- package/es/ThemeProvider/ThemeProvider.mjs +1 -1
- package/es/ThemeProvider/ThemeProvider.mjs.map +1 -1
- package/es/Toc/TocMobile.mjs +2 -2
- package/es/Toc/TocMobile.mjs.map +1 -1
- package/es/base-ui/Button/style.mjs +2 -0
- package/es/base-ui/Button/style.mjs.map +1 -1
- package/es/base-ui/Input/style.d.mts +1 -1
- package/es/base-ui/Segmented/Segmented.mjs +2 -2
- package/es/base-ui/Segmented/Segmented.mjs.map +1 -1
- package/es/base-ui/Select/Select.mjs +35 -6
- package/es/base-ui/Select/Select.mjs.map +1 -1
- package/es/base-ui/Select/helpers.mjs +1 -1
- package/es/base-ui/Select/helpers.mjs.map +1 -1
- package/es/base-ui/Select/hooks.mjs +13 -3
- package/es/base-ui/Select/hooks.mjs.map +1 -1
- package/es/base-ui/Select/parts.mjs +28 -9
- package/es/base-ui/Select/parts.mjs.map +1 -1
- package/es/base-ui/Select/style.mjs +30 -0
- package/es/base-ui/Select/style.mjs.map +1 -1
- package/es/base-ui/Select/type.d.mts +1 -1
- package/es/base-ui/Switch/atoms.mjs +3 -2
- package/es/base-ui/Switch/atoms.mjs.map +1 -1
- package/es/base-ui/Tabs/Tabs.mjs +4 -3
- package/es/base-ui/Tabs/Tabs.mjs.map +1 -1
- package/es/chat/EditableMessage/EditableMessage.mjs +3 -3
- package/es/chat/EditableMessage/EditableMessage.mjs.map +1 -1
- package/es/chat/MessageModal/MessageModal.mjs +3 -3
- package/es/chat/MessageModal/MessageModal.mjs.map +1 -1
- package/es/hooks/useNativeButton.mjs +1 -0
- package/es/hooks/useNativeButton.mjs.map +1 -1
- package/es/mobile/TabBar/TabBar.mjs +2 -2
- package/es/mobile/TabBar/TabBar.mjs.map +1 -1
- package/es/node_modules/@types/hast/index.d.mts +642 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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({\n path: 'css/index.css',\n pkg: '@lobehub/webfont-geist-mono',\n version: '1.0.0',\n }),\n genCdnUrl({\n path: 'css/index.css',\n pkg: '@lobehub/webfont-geist',\n version: '1.0.0',\n }),\n genCdnUrl({\n path: 'css/index.css',\n pkg: '@lobehub/webfont-harmony-sans-sc',\n // pkg: '@lobehub/webfont-harmony-sans-sc-mini',\n version: '1.0.0',\n }),\n genCdnUrl({\n path: 'dist/katex.min.css',\n pkg: 'katex',\n version: '0.17.0',\n }),\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;GACR,MAAM;GACN,KAAK;GACL,SAAS;GACV,CAAC;EACF,UAAU;GACR,MAAM;GACN,KAAK;GACL,SAAS;GACV,CAAC;EACF,UAAU;GACR,MAAM;GACN,KAAK;GAEL,SAAS;GACV,CAAC;EACF,UAAU;GACR,MAAM;GACN,KAAK;GACL,SAAS;GACV,CAAC;EACH,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"}
|
|
1
|
+
{"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({\n path: 'css/index.css',\n pkg: '@lobehub/webfont-geist-mono',\n version: '1.0.0',\n }),\n genCdnUrl({\n path: 'css/index-full.css',\n pkg: '@lobehub/webfont-geist',\n version: '1.0.0',\n }),\n genCdnUrl({\n path: 'css/index.css',\n pkg: '@lobehub/webfont-harmony-sans-sc',\n // pkg: '@lobehub/webfont-harmony-sans-sc-mini',\n version: '1.0.0',\n }),\n genCdnUrl({\n path: 'dist/katex.min.css',\n pkg: 'katex',\n version: '0.17.0',\n }),\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;GACR,MAAM;GACN,KAAK;GACL,SAAS;GACV,CAAC;EACF,UAAU;GACR,MAAM;GACN,KAAK;GACL,SAAS;GACV,CAAC;EACF,UAAU;GACR,MAAM;GACN,KAAK;GAEL,SAAS;GACV,CAAC;EACF,UAAU;GACR,MAAM;GACN,KAAK;GACL,SAAS;GACV,CAAC;EACH,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"}
|
package/es/Toc/TocMobile.mjs
CHANGED
|
@@ -5,11 +5,11 @@ import { mapItems } from "./utils.mjs";
|
|
|
5
5
|
import { memo, useMemo } from "react";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import { Anchor, Collapse, ConfigProvider } from "antd";
|
|
8
|
-
import
|
|
8
|
+
import useControlledState from "use-merge-value";
|
|
9
9
|
import { PanelTopClose, PanelTopOpen } from "lucide-react";
|
|
10
10
|
//#region src/Toc/TocMobile.tsx
|
|
11
11
|
const TocMobile = memo(({ items, activeKey, onChange, getContainer, headerHeight = 64, tocWidth = 176 }) => {
|
|
12
|
-
const [activeLink, setActiveLink] =
|
|
12
|
+
const [activeLink, setActiveLink] = useControlledState("", {
|
|
13
13
|
onChange,
|
|
14
14
|
value: activeKey
|
|
15
15
|
});
|
package/es/Toc/TocMobile.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TocMobile.mjs","names":[
|
|
1
|
+
{"version":3,"file":"TocMobile.mjs","names":[],"sources":["../../src/Toc/TocMobile.tsx"],"sourcesContent":["'use client';\n\nimport { Anchor, Collapse, ConfigProvider } from 'antd';\nimport { PanelTopClose, PanelTopOpen } from 'lucide-react';\nimport { memo, useMemo } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport ActionIcon from '@/ActionIcon';\n\nimport { styles } from './style';\nimport type { TocMobileProps } from './type';\nimport { mapItems } from './utils';\n\nconst TocMobile = memo<TocMobileProps>(\n ({ items, activeKey, onChange, getContainer, headerHeight = 64, tocWidth = 176 }) => {\n // tocWidth is part of the interface but not used in this component\n void tocWidth;\n const [activeLink, setActiveLink] = useControlledState<string>('', {\n onChange,\n value: activeKey,\n });\n\n const activeAnchor = items.find((item) => item.id === activeLink);\n\n const tocItems = useMemo(() => mapItems(items), [items]);\n\n return (\n <ConfigProvider theme={{ token: { fontSize: 12, sizeStep: 3 } }}>\n <section className={styles.mobileCtn}>\n <Collapse\n ghost\n className={styles.expand}\n expandIconPlacement={'end'}\n expandIcon={({ isActive }) => (\n <ActionIcon icon={isActive ? PanelTopClose : PanelTopOpen} size={'small'} />\n )}\n >\n <Collapse.Panel\n forceRender\n header={activeAnchor ? activeAnchor.title : 'TOC'}\n key={'toc'}\n >\n <ConfigProvider theme={{ token: { fontSize: 14, sizeStep: 4 } }}>\n <Anchor\n getContainer={getContainer}\n items={tocItems}\n targetOffset={headerHeight + 48}\n onChange={(currentLink) => {\n setActiveLink(currentLink.replace('#', ''));\n }}\n />\n </ConfigProvider>\n </Collapse.Panel>\n </Collapse>\n </section>\n </ConfigProvider>\n );\n },\n);\n\nTocMobile.displayName = 'TocMobile';\n\nexport default TocMobile;\n"],"mappings":";;;;;;;;;;AAaA,MAAM,YAAY,MACf,EAAE,OAAO,WAAW,UAAU,cAAc,eAAe,IAAI,WAAW,UAAU;CAGnF,MAAM,CAAC,YAAY,iBAAiB,mBAA2B,IAAI;EACjE;EACA,OAAO;EACR,CAAC;CAEF,MAAM,eAAe,MAAM,MAAM,SAAS,KAAK,OAAO,WAAW;CAEjE,MAAM,WAAW,cAAc,SAAS,MAAM,EAAE,CAAC,MAAM,CAAC;AAExD,QACE,oBAAC,gBAAD;EAAgB,OAAO,EAAE,OAAO;GAAE,UAAU;GAAI,UAAU;GAAG,EAAE;YAC7D,oBAAC,WAAD;GAAS,WAAW,OAAO;aACzB,oBAAC,UAAD;IACE,OAAA;IACA,WAAW,OAAO;IAClB,qBAAqB;IACrB,aAAa,EAAE,eACb,oBAAC,YAAD;KAAY,MAAM,WAAW,gBAAgB;KAAc,MAAM;KAAW,CAAA;cAG9E,oBAAC,SAAS,OAAV;KACE,aAAA;KACA,QAAQ,eAAe,aAAa,QAAQ;eAG5C,oBAAC,gBAAD;MAAgB,OAAO,EAAE,OAAO;OAAE,UAAU;OAAI,UAAU;OAAG,EAAE;gBAC7D,oBAAC,QAAD;OACgB;OACd,OAAO;OACP,cAAc,eAAe;OAC7B,WAAW,gBAAgB;AACzB,sBAAc,YAAY,QAAQ,KAAK,GAAG,CAAC;;OAE7C,CAAA;MACa,CAAA;KACF,EAZV,MAYU;IACR,CAAA;GACH,CAAA;EACK,CAAA;EAGtB;AAED,UAAU,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/Button/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nimport { controlHeight } from '@/base-ui/controlSize';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n base: css`\n cursor: pointer;\n\n display: inline-flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n\n box-sizing: border-box;\n border: 1px solid ${cssVar.colorBorder};\n\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n white-space: nowrap;\n\n transition:\n color 160ms cubic-bezier(0.32, 0.72, 0, 1),\n background 160ms cubic-bezier(0.32, 0.72, 0, 1),\n border-color 160ms cubic-bezier(0.32, 0.72, 0, 1),\n box-shadow 160ms cubic-bezier(0.32, 0.72, 0, 1);\n\n &:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px ${cssVar.colorPrimaryBorder};\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.5;\n }\n `,\n\n sizeSmall: css`\n height: ${controlHeight.small}px;\n padding-inline: 8px;\n border-radius: ${cssVar.borderRadiusSM};\n font-size: 12px;\n `,\n\n sizeMiddle: css`\n height: ${controlHeight.middle}px;\n padding-inline: 14px;\n border-radius: ${cssVar.borderRadiusSM};\n font-size: 13px;\n `,\n\n sizeLarge: css`\n height: ${controlHeight.large}px;\n padding-inline: 16px;\n border-radius: ${cssVar.borderRadius};\n font-size: 14px;\n `,\n\n shapeCircle: css`\n padding-inline: 0;\n border-radius: 50%;\n `,\n\n shapeRound: css`\n border-radius: 999px;\n `,\n\n block: css`\n width: 100%;\n `,\n\n iconEnd: css`\n flex-direction: row-reverse;\n `,\n\n iconOnlySmall: css`\n width: 24px;\n padding-inline: 0;\n `,\n\n iconOnlyMiddle: css`\n width: 32px;\n padding-inline: 0;\n `,\n\n iconOnlyLarge: css`\n width: 40px;\n padding-inline: 0;\n `,\n\n iconBox: css`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n `,\n\n spinnerSlot: css`\n overflow: hidden;\n\n width: 0;\n margin-inline-end: -6px;\n\n opacity: 0;\n\n transition:\n width 380ms cubic-bezier(0.22, 1, 0.36, 1),\n margin 380ms cubic-bezier(0.22, 1, 0.36, 1),\n opacity 260ms cubic-bezier(0.22, 1, 0.36, 1);\n `,\n\n spinnerSlotEnd: css`\n margin-inline: -6px 0;\n `,\n\n spinnerSlotShow: css`\n width: 12px;\n margin-inline: 0;\n opacity: 1;\n `,\n\n variantDefault: css`\n background: ${cssVar.colorBgContainer};\n\n /* &:hover/&:active included so the anchor form outranks antd's global a:hover/a:active link color */\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorText};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryBorder};\n color: ${cssVar.colorPrimaryText};\n }\n `,\n\n variantPrimary: css`\n border-color: ${cssVar.colorPrimary};\n background: ${cssVar.colorPrimary};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorBgLayout};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryHover};\n background: ${cssVar.colorPrimaryHover};\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryActive};\n background: ${cssVar.colorPrimaryActive};\n }\n `,\n\n variantDashed: css`\n border-style: dashed;\n background: ${cssVar.colorBgContainer};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorText};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryBorder};\n color: ${cssVar.colorPrimaryText};\n }\n `,\n\n variantFill: css`\n border-color: transparent;\n background: ${cssVar.colorFillTertiary};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorText};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n background: ${cssVar.colorFillSecondary};\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n background: ${cssVar.colorFill};\n }\n `,\n\n variantText: css`\n border-color: transparent;\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorText};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n background: ${cssVar.colorFillSecondary};\n }\n `,\n\n variantLink: css`\n padding-inline: 0;\n border-color: transparent;\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorPrimary};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n color: ${cssVar.colorPrimaryHover};\n background: transparent;\n }\n `,\n\n dangerOutlined: css`\n border-color: ${cssVar.colorError};\n background: ${cssVar.colorBgContainer};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorError};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorErrorHover};\n color: ${cssVar.colorErrorHover};\n background: ${cssVar.colorBgContainer};\n }\n `,\n\n dangerSolid: css`\n border-color: ${cssVar.colorError};\n background: ${cssVar.colorError};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorBgLayout};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorErrorHover};\n background: ${cssVar.colorErrorHover};\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorErrorActive};\n background: ${cssVar.colorErrorActive};\n }\n `,\n\n dangerFill: css`\n border-color: transparent;\n color: ${cssVar.colorError};\n background: ${cssVar.colorErrorBg};\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n color: ${cssVar.colorErrorHover};\n background: ${cssVar.colorErrorBgHover};\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n color: ${cssVar.colorErrorActive};\n background: ${cssVar.colorErrorBgHover};\n }\n `,\n\n dangerInline: css`\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorError};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n color: ${cssVar.colorErrorHover};\n }\n `,\n\n ghostDefault: css`\n border-color: rgb(255 255 255 / 65%);\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: #fff;\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: #fff;\n background: color-mix(in srgb, currentcolor 8%, transparent);\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in srgb, currentcolor 14%, transparent);\n }\n `,\n\n ghostDashed: css`\n border-style: dashed;\n `,\n\n ghostPrimary: css`\n border-color: ${cssVar.colorPrimary};\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorPrimary};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryHover};\n color: ${cssVar.colorPrimaryHover};\n background: color-mix(in srgb, currentcolor 8%, transparent);\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in srgb, currentcolor 14%, transparent);\n }\n `,\n\n ghostDanger: css`\n border-color: ${cssVar.colorError};\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorError};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorErrorHover};\n color: ${cssVar.colorErrorHover};\n background: color-mix(in srgb, currentcolor 8%, transparent);\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in srgb, currentcolor 14%, transparent);\n }\n `,\n\n spinner: css`\n @keyframes base-button-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n display: inline-block;\n\n width: 12px;\n height: 12px;\n border: 1.5px solid currentcolor;\n border-block-start-color: transparent;\n border-radius: 50%;\n\n animation: base-button-spin 0.6s linear infinite;\n `,\n}));\n"],"mappings":";;;AAIA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,MAAM,GAAG;;;;;;;;;wBASa,OAAO,YAAY;;;;;;;;;;;;;;;8BAeb,OAAO,mBAAmB;;;;;;;;;;CAWtD,WAAW,GAAG;cACF,cAAc,MAAM;;qBAEb,OAAO,eAAe;;;CAIzC,YAAY,GAAG;cACH,cAAc,OAAO;;qBAEd,OAAO,eAAe;;;CAIzC,WAAW,GAAG;cACF,cAAc,MAAM;;qBAEb,OAAO,aAAa;;;CAIvC,aAAa,GAAG;;;;CAKhB,YAAY,GAAG;;;CAIf,OAAO,GAAG;;;CAIV,SAAS,GAAG;;;CAIZ,eAAe,GAAG;;;;CAKlB,gBAAgB,GAAG;;;;CAKnB,eAAe,GAAG;;;;CAKlB,SAAS,GAAG;;;;;CAMZ,aAAa,GAAG;;;;;;;;;;;;;CAchB,gBAAgB,GAAG;;;CAInB,iBAAiB,GAAG;;;;;CAMpB,gBAAgB,GAAG;kBACH,OAAO,iBAAiB;;;;;;eAM3B,OAAO,UAAU;;;;sBAIV,OAAO,mBAAmB;eACjC,OAAO,iBAAiB;;;CAIrC,gBAAgB,GAAG;oBACD,OAAO,aAAa;kBACtB,OAAO,aAAa;;;;;eAKvB,OAAO,cAAc;;;;sBAId,OAAO,kBAAkB;oBAC3B,OAAO,kBAAkB;;;;sBAIvB,OAAO,mBAAmB;oBAC5B,OAAO,mBAAmB;;;CAI5C,eAAe,GAAG;;kBAEF,OAAO,iBAAiB;;;;;eAK3B,OAAO,UAAU;;;;sBAIV,OAAO,mBAAmB;eACjC,OAAO,iBAAiB;;;CAIrC,aAAa,GAAG;;kBAEA,OAAO,kBAAkB;;;;;eAK5B,OAAO,UAAU;;;;oBAIZ,OAAO,mBAAmB;;;;oBAI1B,OAAO,UAAU;;;CAInC,aAAa,GAAG;;;;;;;eAOH,OAAO,UAAU;;;;oBAIZ,OAAO,mBAAmB;;;CAI5C,aAAa,GAAG;;;;;;;;eAQH,OAAO,aAAa;;;;eAIpB,OAAO,kBAAkB;;;;CAKtC,gBAAgB,GAAG;oBACD,OAAO,WAAW;kBACpB,OAAO,iBAAiB;;;;;eAK3B,OAAO,WAAW;;;;sBAIX,OAAO,gBAAgB;eAC9B,OAAO,gBAAgB;oBAClB,OAAO,iBAAiB;;;CAI1C,aAAa,GAAG;oBACE,OAAO,WAAW;kBACpB,OAAO,WAAW;;;;;eAKrB,OAAO,cAAc;;;;sBAId,OAAO,gBAAgB;oBACzB,OAAO,gBAAgB;;;;sBAIrB,OAAO,iBAAiB;oBAC1B,OAAO,iBAAiB;;;CAI1C,YAAY,GAAG;;aAEJ,OAAO,WAAW;kBACb,OAAO,aAAa;;;eAGvB,OAAO,gBAAgB;oBAClB,OAAO,kBAAkB;;;;eAI9B,OAAO,iBAAiB;oBACnB,OAAO,kBAAkB;;;CAI3C,cAAc,GAAG;;;;eAIJ,OAAO,WAAW;;;;eAIlB,OAAO,gBAAgB;;;CAIpC,cAAc,GAAG;;;;;;;;;;;;;;;;;;;CAoBjB,aAAa,GAAG;;;CAIhB,cAAc,GAAG;oBACC,OAAO,aAAa;;;;;;eAMzB,OAAO,aAAa;;;;sBAIb,OAAO,kBAAkB;eAChC,OAAO,kBAAkB;;;;;;;;CAStC,aAAa,GAAG;oBACE,OAAO,WAAW;;;;;;eAMvB,OAAO,WAAW;;;;sBAIX,OAAO,gBAAgB;eAC9B,OAAO,gBAAgB;;;;;;;;CASpC,SAAS,GAAG;;;;;;;;;;;;;;;;;CAiBb,EAAE"}
|
|
1
|
+
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/Button/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nimport { controlHeight } from '@/base-ui/controlSize';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n base: css`\n cursor: pointer;\n\n position: relative;\n\n display: inline-flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n\n box-sizing: border-box;\n border: 1px solid ${cssVar.colorBorder};\n\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n white-space: nowrap;\n\n transition:\n color 160ms cubic-bezier(0.32, 0.72, 0, 1),\n background 160ms cubic-bezier(0.32, 0.72, 0, 1),\n border-color 160ms cubic-bezier(0.32, 0.72, 0, 1),\n box-shadow 160ms cubic-bezier(0.32, 0.72, 0, 1);\n\n &:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px ${cssVar.colorPrimaryBorder};\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.5;\n }\n `,\n\n sizeSmall: css`\n height: ${controlHeight.small}px;\n padding-inline: 8px;\n border-radius: ${cssVar.borderRadiusSM};\n font-size: 12px;\n `,\n\n sizeMiddle: css`\n height: ${controlHeight.middle}px;\n padding-inline: 14px;\n border-radius: ${cssVar.borderRadiusSM};\n font-size: 13px;\n `,\n\n sizeLarge: css`\n height: ${controlHeight.large}px;\n padding-inline: 16px;\n border-radius: ${cssVar.borderRadius};\n font-size: 14px;\n `,\n\n shapeCircle: css`\n padding-inline: 0;\n border-radius: 50%;\n `,\n\n shapeRound: css`\n border-radius: 999px;\n `,\n\n block: css`\n width: 100%;\n `,\n\n iconEnd: css`\n flex-direction: row-reverse;\n `,\n\n iconOnlySmall: css`\n width: 24px;\n padding-inline: 0;\n `,\n\n iconOnlyMiddle: css`\n width: 32px;\n padding-inline: 0;\n `,\n\n iconOnlyLarge: css`\n width: 40px;\n padding-inline: 0;\n `,\n\n iconBox: css`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n `,\n\n spinnerSlot: css`\n overflow: hidden;\n\n width: 0;\n margin-inline-end: -6px;\n\n opacity: 0;\n\n transition:\n width 380ms cubic-bezier(0.22, 1, 0.36, 1),\n margin 380ms cubic-bezier(0.22, 1, 0.36, 1),\n opacity 260ms cubic-bezier(0.22, 1, 0.36, 1);\n `,\n\n spinnerSlotEnd: css`\n margin-inline: -6px 0;\n `,\n\n spinnerSlotShow: css`\n width: 12px;\n margin-inline: 0;\n opacity: 1;\n `,\n\n variantDefault: css`\n background: ${cssVar.colorBgContainer};\n\n /* &:hover/&:active included so the anchor form outranks antd's global a:hover/a:active link color */\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorText};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryBorder};\n color: ${cssVar.colorPrimaryText};\n }\n `,\n\n variantPrimary: css`\n border-color: ${cssVar.colorPrimary};\n background: ${cssVar.colorPrimary};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorBgLayout};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryHover};\n background: ${cssVar.colorPrimaryHover};\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryActive};\n background: ${cssVar.colorPrimaryActive};\n }\n `,\n\n variantDashed: css`\n border-style: dashed;\n background: ${cssVar.colorBgContainer};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorText};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryBorder};\n color: ${cssVar.colorPrimaryText};\n }\n `,\n\n variantFill: css`\n border-color: transparent;\n background: ${cssVar.colorFillTertiary};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorText};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n background: ${cssVar.colorFillSecondary};\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n background: ${cssVar.colorFill};\n }\n `,\n\n variantText: css`\n border-color: transparent;\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorText};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n background: ${cssVar.colorFillSecondary};\n }\n `,\n\n variantLink: css`\n padding-inline: 0;\n border-color: transparent;\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorPrimary};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n color: ${cssVar.colorPrimaryHover};\n background: transparent;\n }\n `,\n\n dangerOutlined: css`\n border-color: ${cssVar.colorError};\n background: ${cssVar.colorBgContainer};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorError};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorErrorHover};\n color: ${cssVar.colorErrorHover};\n background: ${cssVar.colorBgContainer};\n }\n `,\n\n dangerSolid: css`\n border-color: ${cssVar.colorError};\n background: ${cssVar.colorError};\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorBgLayout};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorErrorHover};\n background: ${cssVar.colorErrorHover};\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorErrorActive};\n background: ${cssVar.colorErrorActive};\n }\n `,\n\n dangerFill: css`\n border-color: transparent;\n color: ${cssVar.colorError};\n background: ${cssVar.colorErrorBg};\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n color: ${cssVar.colorErrorHover};\n background: ${cssVar.colorErrorBgHover};\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n color: ${cssVar.colorErrorActive};\n background: ${cssVar.colorErrorBgHover};\n }\n `,\n\n dangerInline: css`\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorError};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n color: ${cssVar.colorErrorHover};\n }\n `,\n\n ghostDefault: css`\n border-color: rgb(255 255 255 / 65%);\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: #fff;\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: #fff;\n background: color-mix(in srgb, currentcolor 8%, transparent);\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in srgb, currentcolor 14%, transparent);\n }\n `,\n\n ghostDashed: css`\n border-style: dashed;\n `,\n\n ghostPrimary: css`\n border-color: ${cssVar.colorPrimary};\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorPrimary};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorPrimaryHover};\n color: ${cssVar.colorPrimaryHover};\n background: color-mix(in srgb, currentcolor 8%, transparent);\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in srgb, currentcolor 14%, transparent);\n }\n `,\n\n ghostDanger: css`\n border-color: ${cssVar.colorError};\n background: transparent;\n\n &,\n &:hover,\n &:active {\n color: ${cssVar.colorError};\n }\n\n &:hover:not(:disabled, [aria-disabled='true']) {\n border-color: ${cssVar.colorErrorHover};\n color: ${cssVar.colorErrorHover};\n background: color-mix(in srgb, currentcolor 8%, transparent);\n }\n\n &:active:not(:disabled, [aria-disabled='true']) {\n background: color-mix(in srgb, currentcolor 14%, transparent);\n }\n `,\n\n spinner: css`\n @keyframes base-button-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n display: inline-block;\n\n width: 12px;\n height: 12px;\n border: 1.5px solid currentcolor;\n border-block-start-color: transparent;\n border-radius: 50%;\n\n animation: base-button-spin 0.6s linear infinite;\n `,\n}));\n"],"mappings":";;;AAIA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,MAAM,GAAG;;;;;;;;;;;wBAWa,OAAO,YAAY;;;;;;;;;;;;;;;8BAeb,OAAO,mBAAmB;;;;;;;;;;CAWtD,WAAW,GAAG;cACF,cAAc,MAAM;;qBAEb,OAAO,eAAe;;;CAIzC,YAAY,GAAG;cACH,cAAc,OAAO;;qBAEd,OAAO,eAAe;;;CAIzC,WAAW,GAAG;cACF,cAAc,MAAM;;qBAEb,OAAO,aAAa;;;CAIvC,aAAa,GAAG;;;;CAKhB,YAAY,GAAG;;;CAIf,OAAO,GAAG;;;CAIV,SAAS,GAAG;;;CAIZ,eAAe,GAAG;;;;CAKlB,gBAAgB,GAAG;;;;CAKnB,eAAe,GAAG;;;;CAKlB,SAAS,GAAG;;;;;CAMZ,aAAa,GAAG;;;;;;;;;;;;;CAchB,gBAAgB,GAAG;;;CAInB,iBAAiB,GAAG;;;;;CAMpB,gBAAgB,GAAG;kBACH,OAAO,iBAAiB;;;;;;eAM3B,OAAO,UAAU;;;;sBAIV,OAAO,mBAAmB;eACjC,OAAO,iBAAiB;;;CAIrC,gBAAgB,GAAG;oBACD,OAAO,aAAa;kBACtB,OAAO,aAAa;;;;;eAKvB,OAAO,cAAc;;;;sBAId,OAAO,kBAAkB;oBAC3B,OAAO,kBAAkB;;;;sBAIvB,OAAO,mBAAmB;oBAC5B,OAAO,mBAAmB;;;CAI5C,eAAe,GAAG;;kBAEF,OAAO,iBAAiB;;;;;eAK3B,OAAO,UAAU;;;;sBAIV,OAAO,mBAAmB;eACjC,OAAO,iBAAiB;;;CAIrC,aAAa,GAAG;;kBAEA,OAAO,kBAAkB;;;;;eAK5B,OAAO,UAAU;;;;oBAIZ,OAAO,mBAAmB;;;;oBAI1B,OAAO,UAAU;;;CAInC,aAAa,GAAG;;;;;;;eAOH,OAAO,UAAU;;;;oBAIZ,OAAO,mBAAmB;;;CAI5C,aAAa,GAAG;;;;;;;;eAQH,OAAO,aAAa;;;;eAIpB,OAAO,kBAAkB;;;;CAKtC,gBAAgB,GAAG;oBACD,OAAO,WAAW;kBACpB,OAAO,iBAAiB;;;;;eAK3B,OAAO,WAAW;;;;sBAIX,OAAO,gBAAgB;eAC9B,OAAO,gBAAgB;oBAClB,OAAO,iBAAiB;;;CAI1C,aAAa,GAAG;oBACE,OAAO,WAAW;kBACpB,OAAO,WAAW;;;;;eAKrB,OAAO,cAAc;;;;sBAId,OAAO,gBAAgB;oBACzB,OAAO,gBAAgB;;;;sBAIrB,OAAO,iBAAiB;oBAC1B,OAAO,iBAAiB;;;CAI1C,YAAY,GAAG;;aAEJ,OAAO,WAAW;kBACb,OAAO,aAAa;;;eAGvB,OAAO,gBAAgB;oBAClB,OAAO,kBAAkB;;;;eAI9B,OAAO,iBAAiB;oBACnB,OAAO,kBAAkB;;;CAI3C,cAAc,GAAG;;;;eAIJ,OAAO,WAAW;;;;eAIlB,OAAO,gBAAgB;;;CAIpC,cAAc,GAAG;;;;;;;;;;;;;;;;;;;CAoBjB,aAAa,GAAG;;;CAIhB,cAAc,GAAG;oBACC,OAAO,aAAa;;;;;;eAMzB,OAAO,aAAa;;;;sBAIb,OAAO,kBAAkB;eAChC,OAAO,kBAAkB;;;;;;;;CAStC,aAAa,GAAG;oBACE,OAAO,WAAW;;;;;;eAMvB,OAAO,WAAW;;;;sBAIX,OAAO,gBAAgB;eAC9B,OAAO,gBAAgB;;;;;;;;CASpC,SAAS,GAAG;;;;;;;;;;;;;;;;;CAiBb,EAAE"}
|
|
@@ -25,7 +25,7 @@ declare const styles: {
|
|
|
25
25
|
};
|
|
26
26
|
declare const rootVariants: (props?: ({
|
|
27
27
|
shadow?: boolean | null | undefined;
|
|
28
|
-
size?: "small" | "
|
|
28
|
+
size?: "small" | "middle" | "large" | null | undefined;
|
|
29
29
|
variant?: "filled" | "outlined" | "borderless" | null | undefined;
|
|
30
30
|
} & _$class_variance_authority_types0.ClassProp) | undefined) => string;
|
|
31
31
|
//#endregion
|
|
@@ -3,14 +3,14 @@ import { SegmentedIndicator, SegmentedItem, SegmentedItemIcon, SegmentedItemLabe
|
|
|
3
3
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from "react";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { cx } from "antd-style";
|
|
6
|
-
import
|
|
6
|
+
import useControlledState from "use-merge-value";
|
|
7
7
|
//#region src/base-ui/Segmented/Segmented.tsx
|
|
8
8
|
const normalizeOption = (option) => typeof option === "string" ? {
|
|
9
9
|
label: option,
|
|
10
10
|
value: option
|
|
11
11
|
} : option;
|
|
12
12
|
const Segmented = ({ block = false, className, classNames, defaultValue, disabled = false, glass = false, id, name, onChange, options, ref, shadow = false, size = "middle", style, styles: customStyles, value, variant = "filled", vertical = false }) => {
|
|
13
|
-
const [innerValue, setInnerValue] =
|
|
13
|
+
const [innerValue, setInnerValue] = useControlledState(defaultValue, {
|
|
14
14
|
defaultValue,
|
|
15
15
|
onChange: (next) => {
|
|
16
16
|
if (next != null) onChange?.(next);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Segmented.mjs","names":[
|
|
1
|
+
{"version":3,"file":"Segmented.mjs","names":[],"sources":["../../../src/base-ui/Segmented/Segmented.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport {\n type CSSProperties,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport {\n SegmentedIndicator,\n SegmentedItem,\n SegmentedItemIcon,\n SegmentedItemLabel,\n SegmentedRoot,\n} from './atoms';\nimport type { SegmentedOption, SegmentedProps } from './type';\n\nconst normalizeOption = <Value extends string>(\n option: SegmentedOption<Value> | Value,\n): SegmentedOption<Value> =>\n typeof option === 'string' ? { label: option, value: option } : option;\n\nconst Segmented = <Value extends string = string>({\n block = false,\n className,\n classNames,\n defaultValue,\n disabled = false,\n glass = false,\n id,\n name,\n onChange,\n options,\n ref,\n shadow = false,\n size = 'middle',\n style,\n styles: customStyles,\n value,\n variant = 'filled',\n vertical = false,\n}: SegmentedProps<Value>) => {\n const [innerValue, setInnerValue] = useControlledState<Value | undefined>(defaultValue, {\n defaultValue,\n onChange: (next) => {\n if (next != null) onChange?.(next);\n },\n value,\n });\n\n const listRef = useRef<HTMLDivElement | null>(null);\n\n const mergedRef = useCallback(\n (node: HTMLDivElement | null) => {\n listRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.RefObject<HTMLDivElement | null>).current = node;\n },\n [ref],\n );\n\n const normalizedOptions = useMemo(\n () => (options ?? []).map((o) => normalizeOption<Value>(o)),\n [options],\n );\n\n const updateIndicator = useCallback(() => {\n const list = listRef.current;\n if (!list) return;\n const active = list.querySelector<HTMLElement>('[data-segmented-item][data-pressed]');\n if (!active) {\n list.style.setProperty('--active-item-width', '0px');\n list.style.setProperty('--active-item-height', '0px');\n return;\n }\n list.style.setProperty('--active-item-left', `${active.offsetLeft}px`);\n list.style.setProperty('--active-item-top', `${active.offsetTop}px`);\n list.style.setProperty('--active-item-width', `${active.offsetWidth}px`);\n list.style.setProperty('--active-item-height', `${active.offsetHeight}px`);\n }, []);\n\n useLayoutEffect(() => {\n updateIndicator();\n }, [innerValue, normalizedOptions, vertical, size, block, updateIndicator]);\n\n useEffect(() => {\n const list = listRef.current;\n if (!list || typeof ResizeObserver === 'undefined') return;\n const ro = new ResizeObserver(() => updateIndicator());\n ro.observe(list);\n return () => ro.disconnect();\n }, [updateIndicator]);\n\n const groupValue = useMemo<Value[]>(() => (innerValue != null ? [innerValue] : []), [innerValue]);\n\n const rootStyle: CSSProperties = { ...style, ...customStyles?.root };\n\n return (\n <SegmentedRoot<Value>\n block={block}\n className={cx(classNames?.root, className)}\n disabled={disabled}\n glass={glass}\n id={id}\n orientation={vertical ? 'vertical' : 'horizontal'}\n ref={mergedRef}\n shadow={shadow}\n style={rootStyle}\n value={groupValue}\n variant={variant}\n onValueChange={(next) => {\n const picked = next[0];\n if (picked != null) setInnerValue(picked);\n }}\n >\n <SegmentedIndicator className={classNames?.indicator} style={customStyles?.indicator} />\n {normalizedOptions.map((opt) => (\n <SegmentedItem<Value>\n aria-label={typeof opt.label === 'string' ? opt.label : undefined}\n block={block}\n className={cx(classNames?.item, opt.className)}\n data-segmented-item=\"\"\n disabled={disabled || opt.disabled}\n key={opt.value}\n name={name}\n size={size}\n style={customStyles?.item}\n title={opt.title}\n value={opt.value}\n >\n {opt.icon != null && (\n <SegmentedItemIcon className={classNames?.itemIcon} style={customStyles?.itemIcon}>\n {opt.icon}\n </SegmentedItemIcon>\n )}\n {opt.label != null && (\n <SegmentedItemLabel className={classNames?.itemLabel} style={customStyles?.itemLabel}>\n {opt.label}\n </SegmentedItemLabel>\n )}\n </SegmentedItem>\n ))}\n </SegmentedRoot>\n );\n};\n\nSegmented.displayName = 'Segmented';\n\nexport default Segmented;\n"],"mappings":"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"}
|
|
@@ -14,13 +14,14 @@ import { Select } from "@base-ui/react/select";
|
|
|
14
14
|
const Select$1 = memo(({ allowClear, autoFocus, className, classNames, defaultOpen, defaultValue, disabled, id, labelRender, listHeight = 512, listItemHeight, loading, mode, name, onChange, onOpenChange, onSelect, open, optionRender, options, placeholder, popupClassName, popupMatchSelectWidth, prefix, readOnly, required, behaviorVariant = "default", selectedIndicatorVariant = "check", shadow, showSearch, size = "middle", style, suffixIcon, suffixIconProps, tokenSeparators, value, variant, virtual }) => {
|
|
15
15
|
const { isDarkMode } = useThemeMode();
|
|
16
16
|
const resolvedVariant = variant ?? (isDarkMode ? "filled" : "outlined");
|
|
17
|
+
const isTags = mode === "tags";
|
|
17
18
|
const isMultiple = mode === "multiple" || mode === "tags";
|
|
18
19
|
const isItemAligned = behaviorVariant === "item-aligned";
|
|
19
20
|
const [extraOptions, setExtraOptions] = useState([]);
|
|
20
21
|
useEffect(() => {
|
|
21
22
|
if (mode !== "tags" && extraOptions.length > 0) setExtraOptions([]);
|
|
22
23
|
}, [mode, extraOptions.length]);
|
|
23
|
-
const { appendTagValues, getOption, handleValueChange, normalizedValue, normalizeValue, resolvedOptions, valueArray } = useSelectValue({
|
|
24
|
+
const { appendTagValues, getOption, handleValueChange, normalizedValue, normalizeValue, removeLastTagValue, resolvedOptions, valueArray } = useSelectValue({
|
|
24
25
|
defaultValue,
|
|
25
26
|
extraOptions,
|
|
26
27
|
isMultiple,
|
|
@@ -35,11 +36,20 @@ const Select$1 = memo(({ allowClear, autoFocus, className, classNames, defaultOp
|
|
|
35
36
|
onOpenChange,
|
|
36
37
|
open
|
|
37
38
|
});
|
|
39
|
+
const handleRootValueChange = useCallback((nextValue) => {
|
|
40
|
+
if (!(isTags && !mergedOpen)) handleValueChange(nextValue);
|
|
41
|
+
}, [
|
|
42
|
+
handleValueChange,
|
|
43
|
+
isTags,
|
|
44
|
+
mergedOpen
|
|
45
|
+
]);
|
|
46
|
+
const handleRemoveTag = useCallback((index) => handleValueChange(valueArray.filter((_, itemIndex) => itemIndex !== index)), [handleValueChange, valueArray]);
|
|
38
47
|
const { filteredOptions, handleSearchChange, handleSearchKeyDown, searchValue, shouldShowSearch, stopSearchPropagation } = useSelectSearch({
|
|
39
48
|
appendTagValues,
|
|
40
49
|
handleOpenChange,
|
|
41
50
|
mergedOpen,
|
|
42
51
|
mode,
|
|
52
|
+
removeLastTagValue,
|
|
43
53
|
resolvedOptions,
|
|
44
54
|
showSearch,
|
|
45
55
|
tokenSeparators
|
|
@@ -55,12 +65,16 @@ const Select$1 = memo(({ allowClear, autoFocus, className, classNames, defaultOp
|
|
|
55
65
|
const renderValue = useMemo(() => createTriggerValueRenderer({
|
|
56
66
|
getOption,
|
|
57
67
|
isMultiple,
|
|
68
|
+
isTags,
|
|
58
69
|
labelRender,
|
|
59
70
|
normalizeValue,
|
|
60
|
-
|
|
71
|
+
onRemoveValue: handleRemoveTag,
|
|
72
|
+
placeholder: isTags ? void 0 : placeholder
|
|
61
73
|
}), [
|
|
62
74
|
getOption,
|
|
75
|
+
handleRemoveTag,
|
|
63
76
|
isMultiple,
|
|
77
|
+
isTags,
|
|
64
78
|
labelRender,
|
|
65
79
|
normalizeValue,
|
|
66
80
|
placeholder
|
|
@@ -130,11 +144,13 @@ const Select$1 = memo(({ allowClear, autoFocus, className, classNames, defaultOp
|
|
|
130
144
|
required,
|
|
131
145
|
value: normalizedValue,
|
|
132
146
|
onOpenChange: handleOpenChange,
|
|
133
|
-
onValueChange:
|
|
147
|
+
onValueChange: handleRootValueChange,
|
|
134
148
|
children: [/* @__PURE__ */ jsxs(Select.Trigger, {
|
|
135
|
-
autoFocus,
|
|
149
|
+
autoFocus: !isTags && autoFocus,
|
|
136
150
|
className: triggerClassName,
|
|
137
151
|
disabled,
|
|
152
|
+
nativeButton: !isTags,
|
|
153
|
+
render: isTags ? /* @__PURE__ */ jsx("div", {}) : void 0,
|
|
138
154
|
style,
|
|
139
155
|
children: [
|
|
140
156
|
prefixNode !== null && prefixNode !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
@@ -142,9 +158,21 @@ const Select$1 = memo(({ allowClear, autoFocus, className, classNames, defaultOp
|
|
|
142
158
|
children: prefixNode
|
|
143
159
|
}),
|
|
144
160
|
/* @__PURE__ */ jsx(Select.Value, {
|
|
145
|
-
className: cx(styles$1.value, classNames?.value),
|
|
161
|
+
className: cx(styles$1.value, isTags && styles$1.tagsValue, classNames?.value),
|
|
146
162
|
children: renderValue
|
|
147
163
|
}),
|
|
164
|
+
isTags && /* @__PURE__ */ jsx(SelectSearchInput, {
|
|
165
|
+
inline: true,
|
|
166
|
+
autoFocus,
|
|
167
|
+
classNames,
|
|
168
|
+
disabled,
|
|
169
|
+
placeholder: valueArray.length === 0 ? placeholder : void 0,
|
|
170
|
+
readOnly,
|
|
171
|
+
stopPropagation: stopSearchPropagation,
|
|
172
|
+
value: searchValue,
|
|
173
|
+
onChange: handleSearchChange,
|
|
174
|
+
onKeyDown: handleSearchKeyDown
|
|
175
|
+
}),
|
|
148
176
|
/* @__PURE__ */ jsx(SelectTriggerSuffix, {
|
|
149
177
|
classNames,
|
|
150
178
|
showClear,
|
|
@@ -163,7 +191,7 @@ const Select$1 = memo(({ allowClear, autoFocus, className, classNames, defaultOp
|
|
|
163
191
|
children: /* @__PURE__ */ jsxs(Select.Popup, {
|
|
164
192
|
style: popupStyle,
|
|
165
193
|
className: cx(styles.popup, styles$1.popup, popupClassName, classNames?.popup, classNames?.dropdown),
|
|
166
|
-
children: [shouldShowSearch && /* @__PURE__ */ jsx(SelectSearchInput, {
|
|
194
|
+
children: [shouldShowSearch && !isTags && /* @__PURE__ */ jsx(SelectSearchInput, {
|
|
167
195
|
classNames,
|
|
168
196
|
placeholder,
|
|
169
197
|
stopPropagation: stopSearchPropagation,
|
|
@@ -172,6 +200,7 @@ const Select$1 = memo(({ allowClear, autoFocus, className, classNames, defaultOp
|
|
|
172
200
|
onKeyDown: handleSearchKeyDown
|
|
173
201
|
}), /* @__PURE__ */ jsx(SelectListSection, {
|
|
174
202
|
classNames,
|
|
203
|
+
hasSearch: shouldShowSearch && !isTags,
|
|
175
204
|
isEmpty,
|
|
176
205
|
listContent,
|
|
177
206
|
listItemHeight,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.mjs","names":["Select","menuStyles","styles","BaseSelect"],"sources":["../../../src/base-ui/Select/Select.tsx"],"sourcesContent":["'use client';\n\nimport { Select as BaseSelect } from '@base-ui/react/select';\nimport { cx, useThemeMode } from 'antd-style';\nimport { type MouseEvent } from 'react';\nimport { memo, useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { styles as menuStyles } from '@/base-ui/DropdownMenu/sharedStyle';\n\nimport { SelectPositioner } from './atoms';\nimport { isValueEmpty } from './helpers';\nimport {\n usePortalContainer,\n useSelectOpen,\n useSelectSearch,\n useSelectValue,\n useSelectVirtual,\n} from './hooks';\nimport {\n createTriggerValueRenderer,\n EmptyContent,\n resolveIconNode,\n resolveSuffixIcon,\n SelectListSection,\n SelectSearchInput,\n SelectTriggerSuffix,\n} from './parts';\nimport { renderOptions } from './renderOptions';\nimport { styles, triggerVariants } from './style';\nimport { type SelectOption, type SelectProps } from './type';\n\nconst Select = memo<SelectProps<any>>(\n ({\n allowClear,\n autoFocus,\n className,\n classNames,\n defaultOpen,\n defaultValue,\n disabled,\n id,\n labelRender,\n listHeight = 512,\n listItemHeight,\n loading,\n mode,\n name,\n onChange,\n onOpenChange,\n onSelect,\n open,\n optionRender,\n options,\n placeholder,\n popupClassName,\n popupMatchSelectWidth,\n prefix,\n readOnly,\n required,\n behaviorVariant = 'default',\n selectedIndicatorVariant = 'check',\n shadow,\n showSearch,\n size = 'middle',\n style,\n suffixIcon,\n suffixIconProps,\n tokenSeparators,\n value,\n variant,\n virtual,\n }) => {\n const { isDarkMode } = useThemeMode();\n const resolvedVariant = variant ?? (isDarkMode ? 'filled' : 'outlined');\n const isMultiple = mode === 'multiple' || mode === 'tags';\n const isItemAligned = behaviorVariant === 'item-aligned';\n\n const [extraOptions, setExtraOptions] = useState<SelectOption<any>[]>([]);\n\n useEffect(() => {\n if (mode !== 'tags' && extraOptions.length > 0) {\n setExtraOptions([]);\n }\n }, [mode, extraOptions.length]);\n\n const {\n appendTagValues,\n getOption,\n handleValueChange,\n normalizedValue,\n normalizeValue,\n resolvedOptions,\n valueArray,\n } = useSelectValue({\n defaultValue,\n extraOptions,\n isMultiple,\n onChange,\n onSelect,\n options,\n setExtraOptions,\n value,\n });\n\n const { handleOpenChange, mergedOpen } = useSelectOpen({ defaultOpen, onOpenChange, open });\n\n const {\n filteredOptions,\n handleSearchChange,\n handleSearchKeyDown,\n searchValue,\n shouldShowSearch,\n stopSearchPropagation,\n } = useSelectSearch({\n appendTagValues,\n handleOpenChange,\n mergedOpen,\n mode,\n resolvedOptions,\n showSearch,\n tokenSeparators,\n });\n\n const virtualState = useSelectVirtual({\n filteredOptions,\n listItemHeight,\n size,\n valueArray,\n virtual,\n });\n\n const portalContainer = usePortalContainer();\n\n const renderValue = useMemo(\n () =>\n createTriggerValueRenderer({\n getOption,\n isMultiple,\n labelRender,\n normalizeValue,\n placeholder,\n }),\n [getOption, isMultiple, labelRender, normalizeValue, placeholder],\n );\n\n const hasValue = isMultiple ? valueArray.length > 0 : !isValueEmpty(normalizedValue);\n const showClear = Boolean(allowClear && hasValue && !disabled && !readOnly);\n\n const handleClear = useCallback(\n (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n handleValueChange(isMultiple ? [] : null);\n },\n [handleValueChange, isMultiple],\n );\n\n const prefixNode = useMemo(() => resolveIconNode(prefix), [prefix]);\n const suffixIconNode = useMemo(\n () => resolveSuffixIcon(suffixIcon, suffixIconProps, loading),\n [loading, suffixIcon, suffixIconProps],\n );\n\n const popupStyle = useMemo(() => {\n const maxHeight = isItemAligned ? '80vh' : `${listHeight}px`;\n const baseStyle: React.CSSProperties = {\n maxHeight,\n maxWidth: 'var(--available-width)',\n minWidth: 'var(--anchor-width)',\n ['--lobe-select-popup-max-height' as any]: maxHeight,\n };\n\n if (popupMatchSelectWidth === undefined || popupMatchSelectWidth === true) {\n return baseStyle;\n }\n if (typeof popupMatchSelectWidth === 'number') {\n return {\n ...baseStyle,\n minWidth: popupMatchSelectWidth,\n width: popupMatchSelectWidth,\n };\n }\n return { ...baseStyle, minWidth: 'max-content' };\n }, [isItemAligned, listHeight, popupMatchSelectWidth]);\n\n const triggerClassName = cx(\n triggerVariants({ shadow, size, variant: resolvedVariant }),\n className,\n classNames?.root,\n classNames?.trigger,\n );\n\n const isBoldIndicator = selectedIndicatorVariant === 'bold';\n const itemTextClassName = cx(\n optionRender ? menuStyles.itemContent : menuStyles.label,\n styles.itemText,\n classNames?.itemText,\n );\n\n const isEmpty = filteredOptions.length === 0;\n const listContent = isEmpty ? (\n <EmptyContent classNames={classNames} />\n ) : (\n renderOptions({\n classNames,\n isBoldIndicator,\n items: filteredOptions,\n itemTextClassName,\n listItemHeight,\n optionRender,\n renderVirtualItem: virtualState.renderVirtualItem,\n virtual,\n })\n );\n\n return (\n <BaseSelect.Root\n disabled={disabled}\n id={id}\n modal={isItemAligned}\n multiple={isMultiple}\n name={name}\n open={mergedOpen}\n readOnly={readOnly}\n required={required}\n value={normalizedValue}\n onOpenChange={handleOpenChange}\n onValueChange={handleValueChange}\n >\n <BaseSelect.Trigger\n autoFocus={autoFocus}\n className={triggerClassName}\n disabled={disabled}\n style={style}\n >\n {prefixNode !== null && prefixNode !== undefined && (\n <span className={cx(styles.prefix, classNames?.prefix)}>{prefixNode}</span>\n )}\n <BaseSelect.Value className={cx(styles.value, classNames?.value)}>\n {renderValue}\n </BaseSelect.Value>\n <SelectTriggerSuffix\n classNames={classNames}\n showClear={showClear}\n suffixIconNode={suffixIconNode}\n onClear={handleClear}\n />\n </BaseSelect.Trigger>\n\n <BaseSelect.Portal container={portalContainer}>\n <SelectPositioner\n align=\"start\"\n alignItemWithTrigger={isItemAligned}\n className={styles.positioner}\n side=\"bottom\"\n sideOffset={6}\n >\n <BaseSelect.Popup\n style={popupStyle}\n className={cx(\n menuStyles.popup,\n styles.popup,\n popupClassName,\n classNames?.popup,\n classNames?.dropdown,\n )}\n >\n {shouldShowSearch && (\n <SelectSearchInput\n classNames={classNames}\n placeholder={placeholder}\n stopPropagation={stopSearchPropagation}\n value={searchValue}\n onChange={handleSearchChange}\n onKeyDown={handleSearchKeyDown}\n />\n )}\n <SelectListSection\n classNames={classNames}\n isEmpty={isEmpty}\n listContent={listContent}\n listItemHeight={listItemHeight}\n virtual={virtual}\n virtualState={virtualState}\n />\n </BaseSelect.Popup>\n </SelectPositioner>\n </BaseSelect.Portal>\n </BaseSelect.Root>\n );\n },\n);\n\nSelect.displayName = 'Select';\n\nexport default Select;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Select.mjs","names":["Select","menuStyles","styles","BaseSelect"],"sources":["../../../src/base-ui/Select/Select.tsx"],"sourcesContent":["'use client';\n\nimport { Select as BaseSelect } from '@base-ui/react/select';\nimport { cx, useThemeMode } from 'antd-style';\nimport { type MouseEvent } from 'react';\nimport { memo, useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { styles as menuStyles } from '@/base-ui/DropdownMenu/sharedStyle';\n\nimport { SelectPositioner } from './atoms';\nimport { isValueEmpty } from './helpers';\nimport {\n usePortalContainer,\n useSelectOpen,\n useSelectSearch,\n useSelectValue,\n useSelectVirtual,\n} from './hooks';\nimport {\n createTriggerValueRenderer,\n EmptyContent,\n resolveIconNode,\n resolveSuffixIcon,\n SelectListSection,\n SelectSearchInput,\n SelectTriggerSuffix,\n} from './parts';\nimport { renderOptions } from './renderOptions';\nimport { styles, triggerVariants } from './style';\nimport { type SelectOption, type SelectProps } from './type';\n\nconst Select = memo<SelectProps<any>>(\n ({\n allowClear,\n autoFocus,\n className,\n classNames,\n defaultOpen,\n defaultValue,\n disabled,\n id,\n labelRender,\n listHeight = 512,\n listItemHeight,\n loading,\n mode,\n name,\n onChange,\n onOpenChange,\n onSelect,\n open,\n optionRender,\n options,\n placeholder,\n popupClassName,\n popupMatchSelectWidth,\n prefix,\n readOnly,\n required,\n behaviorVariant = 'default',\n selectedIndicatorVariant = 'check',\n shadow,\n showSearch,\n size = 'middle',\n style,\n suffixIcon,\n suffixIconProps,\n tokenSeparators,\n value,\n variant,\n virtual,\n }) => {\n const { isDarkMode } = useThemeMode();\n const resolvedVariant = variant ?? (isDarkMode ? 'filled' : 'outlined');\n const isTags = mode === 'tags';\n const isMultiple = mode === 'multiple' || mode === 'tags';\n const isItemAligned = behaviorVariant === 'item-aligned';\n\n const [extraOptions, setExtraOptions] = useState<SelectOption<any>[]>([]);\n\n useEffect(() => {\n if (mode !== 'tags' && extraOptions.length > 0) {\n setExtraOptions([]);\n }\n }, [mode, extraOptions.length]);\n\n const {\n appendTagValues,\n getOption,\n handleValueChange,\n normalizedValue,\n normalizeValue,\n removeLastTagValue,\n resolvedOptions,\n valueArray,\n } = useSelectValue({\n defaultValue,\n extraOptions,\n isMultiple,\n onChange,\n onSelect,\n options,\n setExtraOptions,\n value,\n });\n\n const { handleOpenChange, mergedOpen } = useSelectOpen({ defaultOpen, onOpenChange, open });\n\n const handleRootValueChange = useCallback(\n (nextValue: any) => {\n if (!(isTags && !mergedOpen)) handleValueChange(nextValue);\n },\n [handleValueChange, isTags, mergedOpen],\n );\n\n const handleRemoveTag = useCallback(\n (index: number) =>\n handleValueChange(valueArray.filter((_, itemIndex) => itemIndex !== index)),\n [handleValueChange, valueArray],\n );\n\n const {\n filteredOptions,\n handleSearchChange,\n handleSearchKeyDown,\n searchValue,\n shouldShowSearch,\n stopSearchPropagation,\n } = useSelectSearch({\n appendTagValues,\n handleOpenChange,\n mergedOpen,\n mode,\n removeLastTagValue,\n resolvedOptions,\n showSearch,\n tokenSeparators,\n });\n\n const virtualState = useSelectVirtual({\n filteredOptions,\n listItemHeight,\n size,\n valueArray,\n virtual,\n });\n\n const portalContainer = usePortalContainer();\n\n const renderValue = useMemo(\n () =>\n createTriggerValueRenderer({\n getOption,\n isMultiple,\n isTags,\n labelRender,\n normalizeValue,\n onRemoveValue: handleRemoveTag,\n placeholder: isTags ? undefined : placeholder,\n }),\n [getOption, handleRemoveTag, isMultiple, isTags, labelRender, normalizeValue, placeholder],\n );\n\n const hasValue = isMultiple ? valueArray.length > 0 : !isValueEmpty(normalizedValue);\n const showClear = Boolean(allowClear && hasValue && !disabled && !readOnly);\n\n const handleClear = useCallback(\n (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n handleValueChange(isMultiple ? [] : null);\n },\n [handleValueChange, isMultiple],\n );\n\n const prefixNode = useMemo(() => resolveIconNode(prefix), [prefix]);\n const suffixIconNode = useMemo(\n () => resolveSuffixIcon(suffixIcon, suffixIconProps, loading),\n [loading, suffixIcon, suffixIconProps],\n );\n\n const popupStyle = useMemo(() => {\n const maxHeight = isItemAligned ? '80vh' : `${listHeight}px`;\n const baseStyle: React.CSSProperties = {\n maxHeight,\n maxWidth: 'var(--available-width)',\n minWidth: 'var(--anchor-width)',\n ['--lobe-select-popup-max-height' as any]: maxHeight,\n };\n\n if (popupMatchSelectWidth === undefined || popupMatchSelectWidth === true) {\n return baseStyle;\n }\n if (typeof popupMatchSelectWidth === 'number') {\n return {\n ...baseStyle,\n minWidth: popupMatchSelectWidth,\n width: popupMatchSelectWidth,\n };\n }\n return { ...baseStyle, minWidth: 'max-content' };\n }, [isItemAligned, listHeight, popupMatchSelectWidth]);\n\n const triggerClassName = cx(\n triggerVariants({ shadow, size, variant: resolvedVariant }),\n className,\n classNames?.root,\n classNames?.trigger,\n );\n\n const isBoldIndicator = selectedIndicatorVariant === 'bold';\n const itemTextClassName = cx(\n optionRender ? menuStyles.itemContent : menuStyles.label,\n styles.itemText,\n classNames?.itemText,\n );\n\n const isEmpty = filteredOptions.length === 0;\n const listContent = isEmpty ? (\n <EmptyContent classNames={classNames} />\n ) : (\n renderOptions({\n classNames,\n isBoldIndicator,\n items: filteredOptions,\n itemTextClassName,\n listItemHeight,\n optionRender,\n renderVirtualItem: virtualState.renderVirtualItem,\n virtual,\n })\n );\n\n return (\n <BaseSelect.Root\n disabled={disabled}\n id={id}\n modal={isItemAligned}\n multiple={isMultiple}\n name={name}\n open={mergedOpen}\n readOnly={readOnly}\n required={required}\n value={normalizedValue}\n onOpenChange={handleOpenChange}\n onValueChange={handleRootValueChange}\n >\n <BaseSelect.Trigger\n autoFocus={!isTags && autoFocus}\n className={triggerClassName}\n disabled={disabled}\n nativeButton={!isTags}\n render={isTags ? <div /> : undefined}\n style={style}\n >\n {prefixNode !== null && prefixNode !== undefined && (\n <span className={cx(styles.prefix, classNames?.prefix)}>{prefixNode}</span>\n )}\n <BaseSelect.Value\n className={cx(styles.value, isTags && styles.tagsValue, classNames?.value)}\n >\n {renderValue}\n </BaseSelect.Value>\n {isTags && (\n <SelectSearchInput\n inline\n autoFocus={autoFocus}\n classNames={classNames}\n disabled={disabled}\n placeholder={valueArray.length === 0 ? placeholder : undefined}\n readOnly={readOnly}\n stopPropagation={stopSearchPropagation}\n value={searchValue}\n onChange={handleSearchChange}\n onKeyDown={handleSearchKeyDown}\n />\n )}\n <SelectTriggerSuffix\n classNames={classNames}\n showClear={showClear}\n suffixIconNode={suffixIconNode}\n onClear={handleClear}\n />\n </BaseSelect.Trigger>\n\n <BaseSelect.Portal container={portalContainer}>\n <SelectPositioner\n align=\"start\"\n alignItemWithTrigger={isItemAligned}\n className={styles.positioner}\n side=\"bottom\"\n sideOffset={6}\n >\n <BaseSelect.Popup\n style={popupStyle}\n className={cx(\n menuStyles.popup,\n styles.popup,\n popupClassName,\n classNames?.popup,\n classNames?.dropdown,\n )}\n >\n {shouldShowSearch && !isTags && (\n <SelectSearchInput\n classNames={classNames}\n placeholder={placeholder}\n stopPropagation={stopSearchPropagation}\n value={searchValue}\n onChange={handleSearchChange}\n onKeyDown={handleSearchKeyDown}\n />\n )}\n <SelectListSection\n classNames={classNames}\n hasSearch={shouldShowSearch && !isTags}\n isEmpty={isEmpty}\n listContent={listContent}\n listItemHeight={listItemHeight}\n virtual={virtual}\n virtualState={virtualState}\n />\n </BaseSelect.Popup>\n </SelectPositioner>\n </BaseSelect.Portal>\n </BaseSelect.Root>\n );\n },\n);\n\nSelect.displayName = 'Select';\n\nexport default Select;\n"],"mappings":"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"}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
const isGroupOption = (option) => Boolean(option.options);
|
|
3
3
|
const getOptionSearchText = (option) => {
|
|
4
4
|
if (typeof option.label === "string" || typeof option.label === "number") return String(option.label);
|
|
5
|
-
if (typeof option.value === "string" || typeof option.value === "number") return String(option.value);
|
|
6
5
|
if (option.title) return option.title;
|
|
6
|
+
if (typeof option.value === "string" || typeof option.value === "number") return String(option.value);
|
|
7
7
|
return "";
|
|
8
8
|
};
|
|
9
9
|
const escapeRegExp = (value) => value.replaceAll(/[$()*+.?[\\\]^{|}]/g, "\\$&");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.mjs","names":[],"sources":["../../../src/base-ui/Select/helpers.ts"],"sourcesContent":["import { type SelectOption, type SelectOptionGroup, type SelectOptions } from './type';\n\nexport const isGroupOption = <Value>(\n option: SelectOption<Value> | SelectOptionGroup<Value>,\n): option is SelectOptionGroup<Value> => Boolean((option as SelectOptionGroup<Value>).options);\n\nexport const getOptionSearchText = <Value>(option: SelectOption<Value>) => {\n if (typeof option.label === 'string' || typeof option.label === 'number') {\n return String(option.label);\n }\n if (typeof option.value === 'string' || typeof option.value === 'number') {\n return String(option.value);\n }\n
|
|
1
|
+
{"version":3,"file":"helpers.mjs","names":[],"sources":["../../../src/base-ui/Select/helpers.ts"],"sourcesContent":["import { type SelectOption, type SelectOptionGroup, type SelectOptions } from './type';\n\nexport const isGroupOption = <Value>(\n option: SelectOption<Value> | SelectOptionGroup<Value>,\n): option is SelectOptionGroup<Value> => Boolean((option as SelectOptionGroup<Value>).options);\n\nexport const getOptionSearchText = <Value>(option: SelectOption<Value>) => {\n if (typeof option.label === 'string' || typeof option.label === 'number') {\n return String(option.label);\n }\n if (option.title) return option.title;\n if (typeof option.value === 'string' || typeof option.value === 'number') {\n return String(option.value);\n }\n return '';\n};\n\nconst escapeRegExp = (value: string) => value.replaceAll(/[$()*+.?[\\\\\\]^{|}]/g, '\\\\$&');\n\nexport const splitBySeparators = (value: string, separators?: string[]) => {\n if (!separators || separators.length === 0) return [value];\n const pattern = separators.map(escapeRegExp).join('|');\n return value.split(new RegExp(pattern, 'g'));\n};\n\nexport const countVirtualItems = (items: SelectOptions) =>\n items.reduce((count, item) => {\n if (isGroupOption(item)) {\n return count + item.options.length + 1;\n }\n return count + 1;\n }, 0);\n\nexport const isValueEmpty = (value: unknown) =>\n value === null || value === undefined || value === '';\n\nexport const normalizeValueFor = (isMultiple: boolean) => (nextValue: any) => {\n if (isMultiple) {\n if (Array.isArray(nextValue)) return nextValue;\n if (nextValue === null || nextValue === undefined) return [];\n return [nextValue];\n }\n if (Array.isArray(nextValue)) return nextValue[0] ?? null;\n return nextValue === undefined ? null : nextValue;\n};\n"],"mappings":";AAEA,MAAa,iBACX,WACuC,QAAS,OAAoC,QAAQ;AAE9F,MAAa,uBAA8B,WAAgC;AACzE,KAAI,OAAO,OAAO,UAAU,YAAY,OAAO,OAAO,UAAU,SAC9D,QAAO,OAAO,OAAO,MAAM;AAE7B,KAAI,OAAO,MAAO,QAAO,OAAO;AAChC,KAAI,OAAO,OAAO,UAAU,YAAY,OAAO,OAAO,UAAU,SAC9D,QAAO,OAAO,OAAO,MAAM;AAE7B,QAAO;;AAGT,MAAM,gBAAgB,UAAkB,MAAM,WAAW,uBAAuB,OAAO;AAEvF,MAAa,qBAAqB,OAAe,eAA0B;AACzE,KAAI,CAAC,cAAc,WAAW,WAAW,EAAG,QAAO,CAAC,MAAM;CAC1D,MAAM,UAAU,WAAW,IAAI,aAAa,CAAC,KAAK,IAAI;AACtD,QAAO,MAAM,MAAM,IAAI,OAAO,SAAS,IAAI,CAAC;;AAG9C,MAAa,qBAAqB,UAChC,MAAM,QAAQ,OAAO,SAAS;AAC5B,KAAI,cAAc,KAAK,CACrB,QAAO,QAAQ,KAAK,QAAQ,SAAS;AAEvC,QAAO,QAAQ;GACd,EAAE;AAEP,MAAa,gBAAgB,UAC3B,UAAU,QAAQ,UAAU,KAAA,KAAa,UAAU;AAErD,MAAa,qBAAqB,gBAAyB,cAAmB;AAC5E,KAAI,YAAY;AACd,MAAI,MAAM,QAAQ,UAAU,CAAE,QAAO;AACrC,MAAI,cAAc,QAAQ,cAAc,KAAA,EAAW,QAAO,EAAE;AAC5D,SAAO,CAAC,UAAU;;AAEpB,KAAI,MAAM,QAAQ,UAAU,CAAE,QAAO,UAAU,MAAM;AACrD,QAAO,cAAc,KAAA,IAAY,OAAO"}
|
|
@@ -71,7 +71,7 @@ function useSelectValue({ defaultValue, extraOptions, isMultiple, onChange, onSe
|
|
|
71
71
|
} else {
|
|
72
72
|
if (!isValueEmpty(normalizedNextValue) && !Object.is(previousValue, normalizedNextValue)) onSelect?.(normalizedNextValue, getOption(normalizedNextValue));
|
|
73
73
|
if (value === void 0) setUncontrolledValue(normalizedNextValue);
|
|
74
|
-
onChange?.(normalizedNextValue, isValueEmpty(normalizedNextValue) ? void 0 : getOption(normalizedNextValue));
|
|
74
|
+
onChange?.(isValueEmpty(normalizedNextValue) ? void 0 : normalizedNextValue, isValueEmpty(normalizedNextValue) ? void 0 : getOption(normalizedNextValue));
|
|
75
75
|
}
|
|
76
76
|
previousValueRef.current = normalizedNextValue;
|
|
77
77
|
}, [
|
|
@@ -86,7 +86,7 @@ function useSelectValue({ defaultValue, extraOptions, isMultiple, onChange, onSe
|
|
|
86
86
|
appendTagValues: useCallback((rawValues) => {
|
|
87
87
|
const valuesToAdd = rawValues.map((val) => val.trim()).filter(Boolean);
|
|
88
88
|
if (!valuesToAdd.length) return;
|
|
89
|
-
const nextValues = [...valueArray];
|
|
89
|
+
const nextValues = [...Array.isArray(previousValueRef.current) ? previousValueRef.current : valueArray];
|
|
90
90
|
const newOptionValues = valuesToAdd.filter((val) => !optionMap.has(val));
|
|
91
91
|
if (newOptionValues.length > 0) setExtraOptions((prev) => {
|
|
92
92
|
const existingValues = new Set(prev.map((item) => item.value));
|
|
@@ -115,6 +115,10 @@ function useSelectValue({ defaultValue, extraOptions, isMultiple, onChange, onSe
|
|
|
115
115
|
normalizeValue,
|
|
116
116
|
optionMap,
|
|
117
117
|
resolvedOptions,
|
|
118
|
+
removeLastTagValue: useCallback(() => {
|
|
119
|
+
const currentValues = Array.isArray(previousValueRef.current) ? previousValueRef.current : valueArray;
|
|
120
|
+
if (currentValues.length > 0) handleValueChange(currentValues.slice(0, -1));
|
|
121
|
+
}, [handleValueChange, valueArray]),
|
|
118
122
|
valueArray
|
|
119
123
|
};
|
|
120
124
|
}
|
|
@@ -132,7 +136,7 @@ function useSelectOpen({ defaultOpen, onOpenChange, open }) {
|
|
|
132
136
|
mergedOpen
|
|
133
137
|
};
|
|
134
138
|
}
|
|
135
|
-
function useSelectSearch({ appendTagValues, handleOpenChange, mergedOpen, mode, resolvedOptions, showSearch, tokenSeparators }) {
|
|
139
|
+
function useSelectSearch({ appendTagValues, handleOpenChange, mergedOpen, mode, removeLastTagValue, resolvedOptions, showSearch, tokenSeparators }) {
|
|
136
140
|
const [searchValue, setSearchValue] = useState("");
|
|
137
141
|
const shouldShowSearch = Boolean(showSearch || mode === "tags");
|
|
138
142
|
useEffect(() => {
|
|
@@ -162,6 +166,11 @@ function useSelectSearch({ appendTagValues, handleOpenChange, mergedOpen, mode,
|
|
|
162
166
|
return;
|
|
163
167
|
}
|
|
164
168
|
if (mode !== "tags") return;
|
|
169
|
+
if (event.key === "Backspace" && !searchValue) {
|
|
170
|
+
event.preventDefault();
|
|
171
|
+
removeLastTagValue();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
165
174
|
const isSeparator = tokenSeparators?.includes(event.key);
|
|
166
175
|
if (event.key === "Enter" || isSeparator) {
|
|
167
176
|
event.preventDefault();
|
|
@@ -173,6 +182,7 @@ function useSelectSearch({ appendTagValues, handleOpenChange, mergedOpen, mode,
|
|
|
173
182
|
appendTagValues,
|
|
174
183
|
handleOpenChange,
|
|
175
184
|
mode,
|
|
185
|
+
removeLastTagValue,
|
|
176
186
|
searchValue,
|
|
177
187
|
tokenSeparators
|
|
178
188
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.mjs","names":[],"sources":["../../../src/base-ui/Select/hooks.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ChangeEvent,\n type HTMLAttributes,\n type KeyboardEvent,\n type MutableRefObject,\n type Ref,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useAppElement } from '@/ThemeProvider';\n\nimport {\n countVirtualItems,\n getOptionSearchText,\n isGroupOption,\n isValueEmpty,\n normalizeValueFor,\n splitBySeparators,\n} from './helpers';\nimport {\n type SelectOption,\n type SelectOptions,\n type SelectProps,\n type SelectRootChangeEventDetails,\n type SelectSize,\n} from './type';\n\ninterface UseSelectValueParams {\n defaultValue: SelectProps['defaultValue'];\n extraOptions: SelectOption<any>[];\n isMultiple: boolean;\n onChange: SelectProps['onChange'];\n onSelect: SelectProps['onSelect'];\n options: SelectOptions<any> | undefined;\n setExtraOptions: React.Dispatch<React.SetStateAction<SelectOption<any>[]>>;\n value: SelectProps['value'];\n}\n\nexport function useSelectValue({\n defaultValue,\n extraOptions,\n isMultiple,\n onChange,\n onSelect,\n options,\n setExtraOptions,\n value,\n}: UseSelectValueParams) {\n const [uncontrolledValue, setUncontrolledValue] = useState<any>(() => {\n if (defaultValue !== undefined) return defaultValue;\n return isMultiple ? [] : null;\n });\n\n const normalizeValue = useMemo(() => normalizeValueFor(isMultiple), [isMultiple]);\n\n const mergedValue = value !== undefined ? value : uncontrolledValue;\n const normalizedValue = useMemo(() => normalizeValue(mergedValue), [mergedValue, normalizeValue]);\n\n const valueArray = useMemo(() => {\n if (isMultiple) return normalizedValue as any[];\n return isValueEmpty(normalizedValue) ? [] : [normalizedValue];\n }, [isMultiple, normalizedValue]);\n\n const { optionMap, resolvedOptions } = useMemo(() => {\n const baseOptions = options ?? [];\n const optionValueMap = new Map<any, SelectOption<any>>();\n\n const addOption = (item: SelectOption<any>) => {\n if (!optionValueMap.has(item.value)) {\n optionValueMap.set(item.value, item);\n }\n };\n\n baseOptions.forEach((item) => {\n if (isGroupOption(item)) {\n item.options.forEach(addOption);\n } else {\n addOption(item);\n }\n });\n\n const filteredExtraOptions = extraOptions.filter((item) => !optionValueMap.has(item.value));\n filteredExtraOptions.forEach(addOption);\n const mergedOptions: SelectOptions<any> = [...baseOptions, ...filteredExtraOptions];\n\n const missingValueOptions: SelectOption<any>[] = valueArray\n .filter((val) => !optionValueMap.has(val))\n .map((val) => ({ label: String(val), value: val }));\n missingValueOptions.forEach(addOption);\n\n return {\n optionMap: optionValueMap,\n resolvedOptions: missingValueOptions.length\n ? [...mergedOptions, ...missingValueOptions]\n : mergedOptions,\n };\n }, [extraOptions, options, valueArray]);\n\n const getOption = useCallback(\n (optionValue: any): SelectOption<any> => {\n const matched = optionMap.get(optionValue);\n if (matched) return matched;\n if (optionValue && typeof optionValue === 'object' && 'label' in optionValue) {\n return { label: (optionValue as any).label, value: optionValue };\n }\n return { label: String(optionValue), value: optionValue };\n },\n [optionMap],\n );\n\n const previousValueRef = useRef<any>(normalizedValue);\n useEffect(() => {\n previousValueRef.current = normalizedValue;\n }, [normalizedValue]);\n\n const handleValueChange = useCallback(\n (nextValue: any) => {\n const normalizedNextValue = normalizeValue(nextValue);\n const previousValue = previousValueRef.current;\n\n if (isMultiple) {\n const prevValues = Array.isArray(previousValue) ? previousValue : [];\n const nextValues = Array.isArray(normalizedNextValue) ? normalizedNextValue : [];\n const addedValues = nextValues.filter(\n (val) => !prevValues.some((prev) => Object.is(prev, val)),\n );\n addedValues.forEach((val) => onSelect?.(val, getOption(val)));\n\n if (value === undefined) setUncontrolledValue(nextValues);\n onChange?.(\n nextValues,\n nextValues.map((val) => getOption(val)),\n );\n } else {\n if (!isValueEmpty(normalizedNextValue) && !Object.is(previousValue, normalizedNextValue)) {\n onSelect?.(normalizedNextValue, getOption(normalizedNextValue));\n }\n if (value === undefined) setUncontrolledValue(normalizedNextValue);\n onChange?.(\n normalizedNextValue,\n isValueEmpty(normalizedNextValue) ? undefined : getOption(normalizedNextValue),\n );\n }\n\n previousValueRef.current = normalizedNextValue;\n },\n [getOption, isMultiple, normalizeValue, onChange, onSelect, value],\n );\n\n const appendTagValues = useCallback(\n (rawValues: string[]) => {\n const valuesToAdd = rawValues.map((val) => val.trim()).filter(Boolean);\n if (!valuesToAdd.length) return;\n\n const nextValues = [...valueArray];\n const newOptionValues = valuesToAdd.filter((val) => !optionMap.has(val));\n\n if (newOptionValues.length > 0) {\n setExtraOptions((prev) => {\n const existingValues = new Set(prev.map((item) => item.value));\n const merged = [...prev];\n newOptionValues.forEach((val) => {\n if (!existingValues.has(val)) {\n merged.push({ label: val, value: val });\n }\n });\n return merged;\n });\n }\n\n valuesToAdd.forEach((val) => {\n if (!nextValues.some((item) => Object.is(item, val))) {\n nextValues.push(val);\n }\n });\n\n if (nextValues.length !== valueArray.length) {\n handleValueChange(nextValues);\n }\n },\n [handleValueChange, optionMap, setExtraOptions, valueArray],\n );\n\n return {\n appendTagValues,\n getOption,\n handleValueChange,\n normalizedValue,\n normalizeValue,\n optionMap,\n resolvedOptions,\n valueArray,\n };\n}\n\ninterface UseSelectOpenParams {\n defaultOpen: boolean | undefined;\n onOpenChange: SelectProps['onOpenChange'];\n open: boolean | undefined;\n}\n\nexport function useSelectOpen({ defaultOpen, onOpenChange, open }: UseSelectOpenParams) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState(Boolean(defaultOpen));\n\n useEffect(() => {\n if (open !== undefined) setUncontrolledOpen(open);\n }, [open]);\n\n const mergedOpen = open ?? uncontrolledOpen;\n\n const handleOpenChange = useCallback(\n (nextOpen: boolean, eventDetails?: SelectRootChangeEventDetails) => {\n onOpenChange?.(nextOpen, eventDetails);\n if (open === undefined) setUncontrolledOpen(nextOpen);\n },\n [onOpenChange, open],\n );\n\n return { handleOpenChange, mergedOpen };\n}\n\ninterface UseSelectSearchParams {\n appendTagValues: (values: string[]) => void;\n handleOpenChange: (nextOpen: boolean) => void;\n mergedOpen: boolean;\n mode: SelectProps['mode'];\n resolvedOptions: SelectOptions;\n showSearch: boolean | undefined;\n tokenSeparators: string[] | undefined;\n}\n\nexport function useSelectSearch({\n appendTagValues,\n handleOpenChange,\n mergedOpen,\n mode,\n resolvedOptions,\n showSearch,\n tokenSeparators,\n}: UseSelectSearchParams) {\n const [searchValue, setSearchValue] = useState('');\n const shouldShowSearch = Boolean(showSearch || mode === 'tags');\n\n useEffect(() => {\n if (!mergedOpen) setSearchValue('');\n }, [mergedOpen]);\n\n const handleSearchChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n const nextValue = event.target.value;\n if (mode === 'tags') {\n const parts = splitBySeparators(nextValue, tokenSeparators);\n if (parts.length > 1) {\n const pending = parts.pop() ?? '';\n appendTagValues(parts.filter(Boolean));\n setSearchValue(pending);\n return;\n }\n }\n setSearchValue(nextValue);\n },\n [appendTagValues, mode, tokenSeparators],\n );\n\n const handleSearchKeyDown = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n event.stopPropagation();\n\n if (event.key === 'Escape') {\n handleOpenChange(false);\n return;\n }\n if (mode !== 'tags') return;\n\n const isSeparator = tokenSeparators?.includes(event.key);\n if (event.key === 'Enter' || isSeparator) {\n event.preventDefault();\n event.stopPropagation();\n appendTagValues([searchValue]);\n setSearchValue('');\n }\n },\n [appendTagValues, handleOpenChange, mode, searchValue, tokenSeparators],\n );\n\n // Stop propagation in capture phase + on keyup to block base-ui Popup-level\n // `useTypeahead` (and any ancestor typeahead) from hijacking the search\n // input's first-letter focus behavior. Do not remove.\n const stopSearchPropagation = useCallback((event: KeyboardEvent<HTMLInputElement>) => {\n event.stopPropagation();\n }, []);\n\n const filteredOptions = useMemo(() => {\n if (!shouldShowSearch || !searchValue.trim()) return resolvedOptions;\n const query = searchValue.trim().toLowerCase();\n\n return resolvedOptions\n .map((item) => {\n if (isGroupOption(item)) {\n const groupItems = item.options.filter((option) =>\n getOptionSearchText(option).toLowerCase().includes(query),\n );\n if (!groupItems.length) return null;\n return { ...item, options: groupItems };\n }\n return getOptionSearchText(item).toLowerCase().includes(query) ? item : null;\n })\n .filter(Boolean) as SelectOptions;\n }, [resolvedOptions, searchValue, shouldShowSearch]);\n\n return {\n filteredOptions,\n handleSearchChange,\n handleSearchKeyDown,\n searchValue,\n shouldShowSearch,\n stopSearchPropagation,\n };\n}\n\ninterface UseSelectVirtualParams {\n filteredOptions: SelectOptions;\n listItemHeight: number | undefined;\n size: SelectSize;\n valueArray: any[];\n virtual: boolean | undefined;\n}\n\nexport function useSelectVirtual({\n filteredOptions,\n listItemHeight,\n size,\n valueArray,\n virtual,\n}: UseSelectVirtualParams) {\n const listRef = useRef<HTMLDivElement | null>(null);\n const pointerScrollRef = useRef(false);\n const pointerScrollTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const renderVirtualItem = useCallback((props: HTMLAttributes<HTMLDivElement>) => {\n const { ref, ...rest } = props as HTMLAttributes<HTMLDivElement> & {\n ref?: Ref<HTMLDivElement>;\n };\n\n return (\n <div\n {...rest}\n ref={(node) => {\n if (node) {\n node.scrollIntoView = (...args) => {\n if (!pointerScrollRef.current) {\n HTMLElement.prototype.scrollIntoView.call(node, ...args);\n }\n };\n }\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref && 'current' in ref) {\n (ref as MutableRefObject<HTMLDivElement | null>).current = node;\n }\n }}\n />\n );\n }, []);\n\n const markPointerScroll = useCallback(() => {\n pointerScrollRef.current = true;\n if (pointerScrollTimeoutRef.current) {\n clearTimeout(pointerScrollTimeoutRef.current);\n }\n pointerScrollTimeoutRef.current = setTimeout(() => {\n pointerScrollRef.current = false;\n }, 120);\n }, []);\n\n const handleListScroll = useCallback(() => {\n if (!virtual || !pointerScrollRef.current) return;\n const listElement = listRef.current;\n const activeElement = document.activeElement;\n if (listElement && activeElement && listElement.contains(activeElement)) {\n listElement.focus({ preventScroll: true });\n }\n }, [virtual]);\n\n useEffect(() => {\n return () => {\n if (pointerScrollTimeoutRef.current) {\n clearTimeout(pointerScrollTimeoutRef.current);\n }\n };\n }, []);\n\n const virtualListStyle = useMemo(() => {\n if (!virtual) return undefined;\n const rowCount = countVirtualItems(filteredOptions);\n const maxVisibleRows = 6;\n const estimatedRowHeight =\n listItemHeight ?? (size === 'large' ? 40 : size === 'small' ? 28 : 32);\n const visibleRows = Math.min(Math.max(rowCount, 1), maxVisibleRows);\n const estimatedHeight = visibleRows * estimatedRowHeight + 8;\n\n return {\n height: `min(${estimatedHeight}px, var(--lobe-select-available-height, var(--available-height)))`,\n };\n }, [filteredOptions, listItemHeight, size, virtual]);\n\n const keepMountedIndices = useMemo(() => {\n if (!virtual || valueArray.length === 0) return undefined;\n const selectedSet = new Set(valueArray);\n const indices: number[] = [];\n let index = 0;\n\n filteredOptions.forEach((item) => {\n if (isGroupOption(item)) {\n if (item.options.some((option) => selectedSet.has(option.value))) {\n indices.push(index);\n }\n index += 1;\n return;\n }\n if (selectedSet.has(item.value)) indices.push(index);\n index += 1;\n });\n\n return indices.length ? indices : undefined;\n }, [filteredOptions, valueArray, virtual]);\n\n return {\n handleListScroll,\n keepMountedIndices,\n listRef,\n markPointerScroll,\n renderVirtualItem,\n virtualListStyle,\n };\n}\n\nexport function usePortalContainer() {\n const appElement = useAppElement();\n // `appElement` is the ThemeProvider wrapper div, which uses `display: contents`\n // so it has no layout box. `@base-ui/react/select` fails to mount its Popup\n // into a `display: contents` container in certain hosts (editor/chat inputs\n // with focus traps). Fall back to `document.body` in that case; keep the\n // original behavior when the wrapper has a real layout (older themes, SSR\n // snapshot, etc.).\n return useMemo(() => {\n if (typeof window === 'undefined') return appElement;\n if (!(appElement instanceof HTMLElement)) return undefined;\n const display = window.getComputedStyle(appElement).display;\n return display === 'contents' ? document.body : appElement;\n }, [appElement]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hooks.mjs","names":[],"sources":["../../../src/base-ui/Select/hooks.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ChangeEvent,\n type HTMLAttributes,\n type KeyboardEvent,\n type MutableRefObject,\n type Ref,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { useAppElement } from '@/ThemeProvider';\n\nimport {\n countVirtualItems,\n getOptionSearchText,\n isGroupOption,\n isValueEmpty,\n normalizeValueFor,\n splitBySeparators,\n} from './helpers';\nimport {\n type SelectOption,\n type SelectOptions,\n type SelectProps,\n type SelectRootChangeEventDetails,\n type SelectSize,\n} from './type';\n\ninterface UseSelectValueParams {\n defaultValue: SelectProps['defaultValue'];\n extraOptions: SelectOption<any>[];\n isMultiple: boolean;\n onChange: SelectProps['onChange'];\n onSelect: SelectProps['onSelect'];\n options: SelectOptions<any> | undefined;\n setExtraOptions: React.Dispatch<React.SetStateAction<SelectOption<any>[]>>;\n value: SelectProps['value'];\n}\n\nexport function useSelectValue({\n defaultValue,\n extraOptions,\n isMultiple,\n onChange,\n onSelect,\n options,\n setExtraOptions,\n value,\n}: UseSelectValueParams) {\n const [uncontrolledValue, setUncontrolledValue] = useState<any>(() => {\n if (defaultValue !== undefined) return defaultValue;\n return isMultiple ? [] : null;\n });\n\n const normalizeValue = useMemo(() => normalizeValueFor(isMultiple), [isMultiple]);\n\n const mergedValue = value !== undefined ? value : uncontrolledValue;\n const normalizedValue = useMemo(() => normalizeValue(mergedValue), [mergedValue, normalizeValue]);\n\n const valueArray = useMemo(() => {\n if (isMultiple) return normalizedValue as any[];\n return isValueEmpty(normalizedValue) ? [] : [normalizedValue];\n }, [isMultiple, normalizedValue]);\n\n const { optionMap, resolvedOptions } = useMemo(() => {\n const baseOptions = options ?? [];\n const optionValueMap = new Map<any, SelectOption<any>>();\n\n const addOption = (item: SelectOption<any>) => {\n if (!optionValueMap.has(item.value)) {\n optionValueMap.set(item.value, item);\n }\n };\n\n baseOptions.forEach((item) => {\n if (isGroupOption(item)) {\n item.options.forEach(addOption);\n } else {\n addOption(item);\n }\n });\n\n const filteredExtraOptions = extraOptions.filter((item) => !optionValueMap.has(item.value));\n filteredExtraOptions.forEach(addOption);\n const mergedOptions: SelectOptions<any> = [...baseOptions, ...filteredExtraOptions];\n\n const missingValueOptions: SelectOption<any>[] = valueArray\n .filter((val) => !optionValueMap.has(val))\n .map((val) => ({ label: String(val), value: val }));\n missingValueOptions.forEach(addOption);\n\n return {\n optionMap: optionValueMap,\n resolvedOptions: missingValueOptions.length\n ? [...mergedOptions, ...missingValueOptions]\n : mergedOptions,\n };\n }, [extraOptions, options, valueArray]);\n\n const getOption = useCallback(\n (optionValue: any): SelectOption<any> => {\n const matched = optionMap.get(optionValue);\n if (matched) return matched;\n if (optionValue && typeof optionValue === 'object' && 'label' in optionValue) {\n return { label: (optionValue as any).label, value: optionValue };\n }\n return { label: String(optionValue), value: optionValue };\n },\n [optionMap],\n );\n\n const previousValueRef = useRef<any>(normalizedValue);\n useEffect(() => {\n previousValueRef.current = normalizedValue;\n }, [normalizedValue]);\n\n const handleValueChange = useCallback(\n (nextValue: any) => {\n const normalizedNextValue = normalizeValue(nextValue);\n const previousValue = previousValueRef.current;\n\n if (isMultiple) {\n const prevValues = Array.isArray(previousValue) ? previousValue : [];\n const nextValues = Array.isArray(normalizedNextValue) ? normalizedNextValue : [];\n const addedValues = nextValues.filter(\n (val) => !prevValues.some((prev) => Object.is(prev, val)),\n );\n addedValues.forEach((val) => onSelect?.(val, getOption(val)));\n\n if (value === undefined) setUncontrolledValue(nextValues);\n onChange?.(\n nextValues,\n nextValues.map((val) => getOption(val)),\n );\n } else {\n if (!isValueEmpty(normalizedNextValue) && !Object.is(previousValue, normalizedNextValue)) {\n onSelect?.(normalizedNextValue, getOption(normalizedNextValue));\n }\n if (value === undefined) setUncontrolledValue(normalizedNextValue);\n onChange?.(\n isValueEmpty(normalizedNextValue) ? undefined : normalizedNextValue,\n isValueEmpty(normalizedNextValue) ? undefined : getOption(normalizedNextValue),\n );\n }\n\n previousValueRef.current = normalizedNextValue;\n },\n [getOption, isMultiple, normalizeValue, onChange, onSelect, value],\n );\n\n const appendTagValues = useCallback(\n (rawValues: string[]) => {\n const valuesToAdd = rawValues.map((val) => val.trim()).filter(Boolean);\n if (!valuesToAdd.length) return;\n\n const currentValues = Array.isArray(previousValueRef.current)\n ? previousValueRef.current\n : valueArray;\n const nextValues = [...currentValues];\n const newOptionValues = valuesToAdd.filter((val) => !optionMap.has(val));\n\n if (newOptionValues.length > 0) {\n setExtraOptions((prev) => {\n const existingValues = new Set(prev.map((item) => item.value));\n const merged = [...prev];\n newOptionValues.forEach((val) => {\n if (!existingValues.has(val)) {\n merged.push({ label: val, value: val });\n }\n });\n return merged;\n });\n }\n\n valuesToAdd.forEach((val) => {\n if (!nextValues.some((item) => Object.is(item, val))) {\n nextValues.push(val);\n }\n });\n\n if (nextValues.length !== valueArray.length) {\n handleValueChange(nextValues);\n }\n },\n [handleValueChange, optionMap, setExtraOptions, valueArray],\n );\n\n const removeLastTagValue = useCallback(() => {\n const currentValues = Array.isArray(previousValueRef.current)\n ? previousValueRef.current\n : valueArray;\n if (currentValues.length > 0) handleValueChange(currentValues.slice(0, -1));\n }, [handleValueChange, valueArray]);\n\n return {\n appendTagValues,\n getOption,\n handleValueChange,\n normalizedValue,\n normalizeValue,\n optionMap,\n resolvedOptions,\n removeLastTagValue,\n valueArray,\n };\n}\n\ninterface UseSelectOpenParams {\n defaultOpen: boolean | undefined;\n onOpenChange: SelectProps['onOpenChange'];\n open: boolean | undefined;\n}\n\nexport function useSelectOpen({ defaultOpen, onOpenChange, open }: UseSelectOpenParams) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState(Boolean(defaultOpen));\n\n useEffect(() => {\n if (open !== undefined) setUncontrolledOpen(open);\n }, [open]);\n\n const mergedOpen = open ?? uncontrolledOpen;\n\n const handleOpenChange = useCallback(\n (nextOpen: boolean, eventDetails?: SelectRootChangeEventDetails) => {\n onOpenChange?.(nextOpen, eventDetails);\n if (open === undefined) setUncontrolledOpen(nextOpen);\n },\n [onOpenChange, open],\n );\n\n return { handleOpenChange, mergedOpen };\n}\n\ninterface UseSelectSearchParams {\n appendTagValues: (values: string[]) => void;\n handleOpenChange: (nextOpen: boolean) => void;\n mergedOpen: boolean;\n mode: SelectProps['mode'];\n removeLastTagValue: () => void;\n resolvedOptions: SelectOptions;\n showSearch: boolean | undefined;\n tokenSeparators: string[] | undefined;\n}\n\nexport function useSelectSearch({\n appendTagValues,\n handleOpenChange,\n mergedOpen,\n mode,\n removeLastTagValue,\n resolvedOptions,\n showSearch,\n tokenSeparators,\n}: UseSelectSearchParams) {\n const [searchValue, setSearchValue] = useState('');\n const shouldShowSearch = Boolean(showSearch || mode === 'tags');\n\n useEffect(() => {\n if (!mergedOpen) setSearchValue('');\n }, [mergedOpen]);\n\n const handleSearchChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n const nextValue = event.target.value;\n if (mode === 'tags') {\n const parts = splitBySeparators(nextValue, tokenSeparators);\n if (parts.length > 1) {\n const pending = parts.pop() ?? '';\n appendTagValues(parts.filter(Boolean));\n setSearchValue(pending);\n return;\n }\n }\n setSearchValue(nextValue);\n },\n [appendTagValues, mode, tokenSeparators],\n );\n\n const handleSearchKeyDown = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n event.stopPropagation();\n\n if (event.key === 'Escape') {\n handleOpenChange(false);\n return;\n }\n if (mode !== 'tags') return;\n\n if (event.key === 'Backspace' && !searchValue) {\n event.preventDefault();\n removeLastTagValue();\n return;\n }\n\n const isSeparator = tokenSeparators?.includes(event.key);\n if (event.key === 'Enter' || isSeparator) {\n event.preventDefault();\n event.stopPropagation();\n appendTagValues([searchValue]);\n setSearchValue('');\n }\n },\n [appendTagValues, handleOpenChange, mode, removeLastTagValue, searchValue, tokenSeparators],\n );\n\n // Stop propagation in capture phase + on keyup to block base-ui Popup-level\n // `useTypeahead` (and any ancestor typeahead) from hijacking the search\n // input's first-letter focus behavior. Do not remove.\n const stopSearchPropagation = useCallback((event: KeyboardEvent<HTMLInputElement>) => {\n event.stopPropagation();\n }, []);\n\n const filteredOptions = useMemo(() => {\n if (!shouldShowSearch || !searchValue.trim()) return resolvedOptions;\n const query = searchValue.trim().toLowerCase();\n\n return resolvedOptions\n .map((item) => {\n if (isGroupOption(item)) {\n const groupItems = item.options.filter((option) =>\n getOptionSearchText(option).toLowerCase().includes(query),\n );\n if (!groupItems.length) return null;\n return { ...item, options: groupItems };\n }\n return getOptionSearchText(item).toLowerCase().includes(query) ? item : null;\n })\n .filter(Boolean) as SelectOptions;\n }, [resolvedOptions, searchValue, shouldShowSearch]);\n\n return {\n filteredOptions,\n handleSearchChange,\n handleSearchKeyDown,\n searchValue,\n shouldShowSearch,\n stopSearchPropagation,\n };\n}\n\ninterface UseSelectVirtualParams {\n filteredOptions: SelectOptions;\n listItemHeight: number | undefined;\n size: SelectSize;\n valueArray: any[];\n virtual: boolean | undefined;\n}\n\nexport function useSelectVirtual({\n filteredOptions,\n listItemHeight,\n size,\n valueArray,\n virtual,\n}: UseSelectVirtualParams) {\n const listRef = useRef<HTMLDivElement | null>(null);\n const pointerScrollRef = useRef(false);\n const pointerScrollTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const renderVirtualItem = useCallback((props: HTMLAttributes<HTMLDivElement>) => {\n const { ref, ...rest } = props as HTMLAttributes<HTMLDivElement> & {\n ref?: Ref<HTMLDivElement>;\n };\n\n return (\n <div\n {...rest}\n ref={(node) => {\n if (node) {\n node.scrollIntoView = (...args) => {\n if (!pointerScrollRef.current) {\n HTMLElement.prototype.scrollIntoView.call(node, ...args);\n }\n };\n }\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref && 'current' in ref) {\n (ref as MutableRefObject<HTMLDivElement | null>).current = node;\n }\n }}\n />\n );\n }, []);\n\n const markPointerScroll = useCallback(() => {\n pointerScrollRef.current = true;\n if (pointerScrollTimeoutRef.current) {\n clearTimeout(pointerScrollTimeoutRef.current);\n }\n pointerScrollTimeoutRef.current = setTimeout(() => {\n pointerScrollRef.current = false;\n }, 120);\n }, []);\n\n const handleListScroll = useCallback(() => {\n if (!virtual || !pointerScrollRef.current) return;\n const listElement = listRef.current;\n const activeElement = document.activeElement;\n if (listElement && activeElement && listElement.contains(activeElement)) {\n listElement.focus({ preventScroll: true });\n }\n }, [virtual]);\n\n useEffect(() => {\n return () => {\n if (pointerScrollTimeoutRef.current) {\n clearTimeout(pointerScrollTimeoutRef.current);\n }\n };\n }, []);\n\n const virtualListStyle = useMemo(() => {\n if (!virtual) return undefined;\n const rowCount = countVirtualItems(filteredOptions);\n const maxVisibleRows = 6;\n const estimatedRowHeight =\n listItemHeight ?? (size === 'large' ? 40 : size === 'small' ? 28 : 32);\n const visibleRows = Math.min(Math.max(rowCount, 1), maxVisibleRows);\n const estimatedHeight = visibleRows * estimatedRowHeight + 8;\n\n return {\n height: `min(${estimatedHeight}px, var(--lobe-select-available-height, var(--available-height)))`,\n };\n }, [filteredOptions, listItemHeight, size, virtual]);\n\n const keepMountedIndices = useMemo(() => {\n if (!virtual || valueArray.length === 0) return undefined;\n const selectedSet = new Set(valueArray);\n const indices: number[] = [];\n let index = 0;\n\n filteredOptions.forEach((item) => {\n if (isGroupOption(item)) {\n if (item.options.some((option) => selectedSet.has(option.value))) {\n indices.push(index);\n }\n index += 1;\n return;\n }\n if (selectedSet.has(item.value)) indices.push(index);\n index += 1;\n });\n\n return indices.length ? indices : undefined;\n }, [filteredOptions, valueArray, virtual]);\n\n return {\n handleListScroll,\n keepMountedIndices,\n listRef,\n markPointerScroll,\n renderVirtualItem,\n virtualListStyle,\n };\n}\n\nexport function usePortalContainer() {\n const appElement = useAppElement();\n // `appElement` is the ThemeProvider wrapper div, which uses `display: contents`\n // so it has no layout box. `@base-ui/react/select` fails to mount its Popup\n // into a `display: contents` container in certain hosts (editor/chat inputs\n // with focus traps). Fall back to `document.body` in that case; keep the\n // original behavior when the wrapper has a real layout (older themes, SSR\n // snapshot, etc.).\n return useMemo(() => {\n if (typeof window === 'undefined') return appElement;\n if (!(appElement instanceof HTMLElement)) return undefined;\n const display = window.getComputedStyle(appElement).display;\n return display === 'contents' ? document.body : appElement;\n }, [appElement]);\n}\n"],"mappings":"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"}
|